Merge "feat(mediatek): add APU init flow" into integration
diff --git a/.gitignore b/.gitignore
index 1f4efb6..ab2c0c4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,6 +31,8 @@
 tools/stm32image/stm32image
 tools/stm32image/stm32image.exe
 tools/sptool/__pycache__/
+tools/encrypt_fw/encrypt_fw
+tools/encrypt_fw/encrypt_fw.exe
 
 # GNU GLOBAL files
 GPATH
diff --git a/.husky/pre-commit b/.husky/pre-commit
new file mode 100755
index 0000000..afcb1f6
--- /dev/null
+++ b/.husky/pre-commit
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+# shellcheck source=./_/husky.sh
+. "$(dirname "$0")/_/husky.sh"
+
+"$(dirname "$0")/pre-commit.copyright" "$@"
diff --git a/.husky/pre-commit.copyright b/.husky/pre-commit.copyright
new file mode 100755
index 0000000..a4dfee8
--- /dev/null
+++ b/.husky/pre-commit.copyright
@@ -0,0 +1,63 @@
+#!/bin/bash
+
+# A hook script that checks if files staged for commit have updated Arm copyright year.
+# In case they are not - updates the years and prompts user to add them to the change.
+# This hook is called on "git commit" after changes have been staged, but before commit
+# message has to be provided.
+
+RED="\033[00;31m"
+YELLOW="\033[00;33m"
+BLANK="\033[00;00m"
+
+FILES=`git diff --cached --name-only HEAD`
+YEAR_NOW=`date +"%Y"`
+
+YEAR_RGX="[0-9][0-9][0-9][0-9]"
+ARM_RGX="\(ARM\|Arm\|arm\)"
+
+exit_code=0
+
+function user_warning() {
+	echo -e "Copyright of $RED$FILE$BLANK is out of date/incorrect"
+	echo -e "Updated copyright to"
+	grep -nr "opyright.*$YEAR_RGX.*$ARM_RGX" "$FILE"
+	echo
+}
+
+while read -r FILE; do
+	if [ -z "$FILE" ]
+	then
+		break
+	fi
+	# Check if correct copyright notice is in file.
+	# To reduce false positives, we assume files with no
+	# copyright notice do not require it.
+	if ! grep "opyright.*$YEAR_NOW.*$ARM_RGX" "$FILE">/dev/null 2>&1
+	then
+		# If it is "from_date - to_date" type of entry - change to_date entry.
+		if grep "opyright.*$YEAR_RGX.*-.*$YEAR_RGX.*$ARM_RGX" "$FILE" >/dev/null 2>&1
+		then
+			exit_code=1
+			sed -i "s/\(opyright.*\)$YEAR_RGX\(.*$ARM_RGX\)/\1$(date +"%Y"), Arm/" $FILE
+			user_warning
+		# If it is single "date" type of entry - add the copyright extension to current year.
+		elif grep "opyright.*$YEAR_RGX.*$ARM_RGX" "$FILE" >/dev/null 2>&1
+		then
+			exit_code=1
+			sed -i "s/\(opyright.*$YEAR_RGX\)\(.*$ARM_RGX\)/\1-$(date +"%Y"), Arm/" $FILE
+			user_warning
+		fi
+	# Even if the year is correct - verify that Arm copyright is formatted correctly.
+	elif grep "opyright.*\(ARM\|arm\)" "$FILE">/dev/null 2>&1
+	then
+		exit_code=1
+		sed -i "s/\(opyright.*\)\(ARM\|arm\)/\1Arm/" $FILE
+		user_warning
+	fi
+done <<< "$FILES"
+
+if [ $exit_code -eq 1 ]
+then
+	echo -e "$RED""Please stage updated files$BLANK before commiting or use$YELLOW git commit --no-verify$BLANK to skip copyright check"
+fi
+exit $exit_code
diff --git a/.readthedocs.yaml b/.readthedocs.yaml
new file mode 100644
index 0000000..2b418ae
--- /dev/null
+++ b/.readthedocs.yaml
@@ -0,0 +1,24 @@
+# Copyright (c) 2023, Arm Limited. All rights reserved
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Configuration file for the readthedocs deploy
+# Available at https://trustedfirmware-a.readthedocs.io/en/latest/
+
+
+# readthedocs config version
+version: 2
+
+build:
+  os: ubuntu-22.04 # Ubuntu Jammy LTS
+  tools:
+    python: "3.10"
+  apt_packages:
+    - plantuml
+
+python:
+  install:
+    - requirements: docs/requirements.txt
+
+sphinx:
+  configuration: docs/conf.py
diff --git a/Makefile b/Makefile
index f4d623e..d242722 100644
--- a/Makefile
+++ b/Makefile
@@ -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
 #
@@ -153,6 +153,9 @@
 ENABLE_FEAT_ECV = 1
 ENABLE_FEAT_FGT = 1
 
+# RME enables CSV2_2 extension by default.
+ENABLE_FEAT_CSV2_2 = 1
+
 endif
 
 # USE_SPINLOCK_CAS requires AArch64 build
@@ -442,6 +445,8 @@
 
 GCC_V_OUTPUT		:=	$(shell $(CC) -v 2>&1)
 
+TF_LDFLAGS		+=	-z noexecstack
+
 # LD = armlink
 ifneq ($(findstring armlink,$(notdir $(LD))),)
 TF_LDFLAGS		+=	--diag_error=warning --lto_level=O1
@@ -453,6 +458,10 @@
 # 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
+
 ifeq ($(ENABLE_LTO),1)
 	ifeq (${ARCH},aarch64)
 		TF_LDFLAGS	+=	-flto -fuse-linker-plugin
@@ -468,12 +477,21 @@
 
 # LD = gcc-ld (ld) or llvm-ld (ld.lld) or other
 else
-TF_LDFLAGS		+=	--fatal-warnings -O1
+# 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		+=	-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
+# 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))
+TF_LDFLAGS		+=	$(TF_LDFLAGS_$(ARCH)) --fatal-warnings
 endif
 endif
 
@@ -499,6 +517,13 @@
 				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
 endif
@@ -628,6 +653,22 @@
 
 include ${PLAT_MAKEFILE_FULL}
 
+# 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
+# BL2 in EL3
+
+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
+else ifeq (${ENABLE_RME},1)
+	BL2_RUNS_AT_EL3	:=	1
+else
+	BL2_RUNS_AT_EL3	:=	0
+endif
+
 $(eval $(call MAKE_PREREQ_DIR,${BUILD_PLAT}))
 
 ifeq (${ARM_ARCH_MAJOR},7)
@@ -649,21 +690,25 @@
 endif
 
 ifeq ($(ENABLE_PIE),1)
-ifeq ($(BL2_AT_EL3),1)
+ifeq ($(RESET_TO_BL2),1)
 ifneq ($(BL2_IN_XIP_MEM),1)
+	BL2_CPPFLAGS	+=	-fpie
 	BL2_CFLAGS	+=	-fpie
 	BL2_LDFLAGS	+=	$(PIE_LDFLAGS)
 endif
 endif
-	BL31_CFLAGS	+=	-fpie
+	BL31_CPPFLAGS	+=	-fpie
+	BL31_CFLAGS 	+=	-fpie
 	BL31_LDFLAGS	+=	$(PIE_LDFLAGS)
+
+	BL32_CPPFLAGS	+=	-fpie
 	BL32_CFLAGS	+=	-fpie
 	BL32_LDFLAGS	+=	$(PIE_LDFLAGS)
 endif
 
 ifeq (${ARCH},aarch64)
 BL1_CPPFLAGS += -DIMAGE_AT_EL3
-ifeq ($(BL2_AT_EL3),1)
+ifeq ($(RESET_TO_BL2),1)
 BL2_CPPFLAGS += -DIMAGE_AT_EL3
 else
 BL2_CPPFLAGS += -DIMAGE_AT_EL1
@@ -740,9 +785,9 @@
 $(error USE_COHERENT_MEM cannot be enabled with HW_ASSISTED_COHERENCY)
 endif
 
-#For now, BL2_IN_XIP_MEM is only supported when BL2_AT_EL3 is 1.
-ifeq ($(BL2_AT_EL3)-$(BL2_IN_XIP_MEM),0-1)
-$(error "BL2_IN_XIP_MEM is only supported when BL2_AT_EL3 is enabled")
+#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")
 endif
 
 # For RAS_EXTENSION, require that EAs are handled in EL3 first
@@ -816,6 +861,10 @@
     $(info FEATURE_DETECTION is an experimental feature)
 endif
 
+ifneq ($(ENABLE_SME_FOR_NS), 0)
+    $(info ENABLE_SME_FOR_NS is an experimental feature)
+endif
+
 ifeq (${ARM_XLAT_TABLES_LIB_V1}, 1)
     ifeq (${ALLOW_RO_XLAT_TABLES}, 1)
         $(error "ALLOW_RO_XLAT_TABLES requires translation tables library v2")
@@ -832,7 +881,7 @@
 ifeq (${ARCH},aarch32)
 
     # SME/SVE only supported on AArch64
-    ifeq (${ENABLE_SME_FOR_NS},1)
+    ifneq (${ENABLE_SME_FOR_NS},0)
         $(error "ENABLE_SME_FOR_NS cannot be used with ARCH=aarch32")
     endif
     ifeq (${ENABLE_SVE_FOR_NS},1)
@@ -853,7 +902,7 @@
 
 # Ensure ENABLE_RME is not used with SME
 ifeq (${ENABLE_RME},1)
-    ifeq (${ENABLE_SME_FOR_NS},1)
+    ifneq (${ENABLE_SME_FOR_NS},0)
         $(error "ENABLE_SME_FOR_NS cannot be used with ENABLE_RME")
     endif
 endif
@@ -873,7 +922,7 @@
 # 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)
+    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)
@@ -1047,19 +1096,16 @@
         DISABLE_MTPMU \
         DYN_DISABLE_AUTH \
         EL3_EXCEPTION_HANDLING \
-        ENABLE_AMU \
         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_NS \
         ENABLE_SME_FOR_SWD \
-        ENABLE_SPE_FOR_LOWER_ELS \
-        ENABLE_SVE_FOR_NS \
         ENABLE_SVE_FOR_SWD \
         ERROR_DEPRECATED \
         FAULT_INJECTION_SUPPORT \
@@ -1076,6 +1122,7 @@
         PLAT_RSS_NOT_SUPPORTED \
         PROGRAMMABLE_RESET_ADDRESS \
         PSCI_EXTENDED_STATE_ID \
+        PSCI_OS_INIT_MODE \
         RESET_TO_BL31 \
         RESET_TO_BL31_WITH_PARAMS \
         SAVE_KEYS \
@@ -1095,7 +1142,7 @@
         USE_ROMLIB \
         USE_TBBR_DEFS \
         WARMBOOT_ENABLE_DCACHE_EARLY \
-        BL2_AT_EL3 \
+        RESET_TO_BL2 \
         BL2_IN_XIP_MEM \
         BL2_INV_DCACHE \
         USE_SPINLOCK_CAS \
@@ -1106,7 +1153,6 @@
         COT_DESC_IN_DTB \
         USE_SP804_TIMER \
         PSA_FWU_SUPPORT \
-        ENABLE_SYS_REG_TRACE_FOR_NS \
         ENABLE_MPMM \
         ENABLE_MPMM_FCONF \
         SIMICS_BUILD \
@@ -1128,7 +1174,7 @@
         ENABLE_TRBE_FOR_NS \
         ENABLE_BTI \
         ENABLE_PAUTH \
-        ENABLE_FEAT_AMUv1 \
+        ENABLE_FEAT_AMU \
         ENABLE_FEAT_AMUv1p1 \
         ENABLE_FEAT_CSV2_2 \
         ENABLE_FEAT_DIT \
@@ -1138,11 +1184,15 @@
         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_SPE_FOR_NS \
+        ENABLE_SYS_REG_TRACE_FOR_NS \
+        ENABLE_SME_FOR_NS \
+        ENABLE_SVE_FOR_NS \
         ENABLE_TRF_FOR_NS \
         FW_ENC_STATUS \
         NR_OF_FW_BANKS \
@@ -1183,7 +1233,7 @@
         CTX_INCLUDE_NEVE_REGS \
         DECRYPTION_SUPPORT_${DECRYPTION_SUPPORT} \
         DISABLE_MTPMU \
-        ENABLE_AMU \
+        ENABLE_FEAT_AMU \
         ENABLE_AMU_AUXILIARY_COUNTERS \
         ENABLE_AMU_FCONF \
         AMU_RESTRICT_COUNTERS \
@@ -1198,7 +1248,7 @@
         ENABLE_RUNTIME_INSTRUMENTATION \
         ENABLE_SME_FOR_NS \
         ENABLE_SME_FOR_SWD \
-        ENABLE_SPE_FOR_LOWER_ELS \
+        ENABLE_SPE_FOR_NS \
         ENABLE_SVE_FOR_NS \
         ENABLE_SVE_FOR_SWD \
         ENCRYPT_BL31 \
@@ -1217,6 +1267,7 @@
         PLAT_RSS_NOT_SUPPORTED \
         PROGRAMMABLE_RESET_ADDRESS \
         PSCI_EXTENDED_STATE_ID \
+        PSCI_OS_INIT_MODE \
         RAS_EXTENSION \
         RESET_TO_BL31 \
         RESET_TO_BL31_WITH_PARAMS \
@@ -1240,7 +1291,8 @@
         USE_ROMLIB \
         USE_TBBR_DEFS \
         WARMBOOT_ENABLE_DCACHE_EARLY \
-        BL2_AT_EL3 \
+        RESET_TO_BL2 \
+        BL2_RUNS_AT_EL3	\
         BL2_IN_XIP_MEM \
         BL2_INV_DCACHE \
         USE_SPINLOCK_CAS \
@@ -1263,7 +1315,6 @@
         ENABLE_MPMM \
         ENABLE_MPMM_FCONF \
         ENABLE_FEAT_FGT \
-        ENABLE_FEAT_AMUv1 \
         ENABLE_FEAT_ECV \
         SIMICS_BUILD \
         ENABLE_FEAT_AMUv1p1 \
@@ -1271,6 +1322,7 @@
         ENABLE_FEAT_VHE \
         ENABLE_FEAT_CSV2_2 \
         ENABLE_FEAT_PAN \
+        ENABLE_FEAT_TCR2 \
         FEATURE_DETECTION \
         TWED_DELAY \
         ENABLE_FEAT_TWED \
@@ -1347,7 +1399,7 @@
 endif
 
 ifeq (${NEED_BL2},yes)
-ifeq (${BL2_AT_EL3}, 0)
+ifeq (${RESET_TO_BL2}, 0)
 FIP_BL2_ARGS := tb-fw
 endif
 
diff --git a/bl1/bl1.ld.S b/bl1/bl1.ld.S
index c4ec5fe..bec234b 100644
--- a/bl1/bl1.ld.S
+++ b/bl1/bl1.ld.S
@@ -1,13 +1,12 @@
 /*
- * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 /*
- * The .data section gets copied from ROM to RAM at runtime.
- * Its LMA should be 16-byte aligned to allow efficient copying of 16-bytes
- * aligned regions in it.
+ * The .data section gets copied from ROM to RAM at runtime. Its LMA should be
+ * 16-byte aligned to allow efficient copying of 16-bytes aligned regions in it.
  * Its VMA must be page-aligned as it marks the first read/write page.
  */
 #define DATA_ALIGN	16
@@ -24,23 +23,26 @@
     RAM (rwx): ORIGIN = BL1_RW_BASE, LENGTH = BL1_RW_LIMIT - BL1_RW_BASE
 }
 
-SECTIONS
-{
+SECTIONS {
     . = BL1_RO_BASE;
+
     ASSERT(. == ALIGN(PAGE_SIZE),
-           "BL1_RO_BASE address is not aligned on a page boundary.")
+        "BL1_RO_BASE address is not aligned on a page boundary.")
 
 #if SEPARATE_CODE_AND_RODATA
     .text . : {
         __TEXT_START__ = .;
+
         *bl1_entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(.text*))
         *(.vectors)
+
         . = ALIGN(PAGE_SIZE);
+
         __TEXT_END__ = .;
     } >ROM
 
-    /* .ARM.extab and .ARM.exidx are only added because Clang need them */
+    /* .ARM.extab and .ARM.exidx are only added because Clang needs them */
     .ARM.extab . : {
         *(.ARM.extab* .gnu.linkonce.armextab.*)
     } >ROM
@@ -51,51 +53,57 @@
 
     .rodata . : {
         __RODATA_START__ = .;
+
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-	RODATA_COMMON
+        RODATA_COMMON
 
         /*
          * No need to pad out the .rodata section to a page boundary. Next is
          * the .data section, which can mapped in ROM with the same memory
          * attributes as the .rodata section.
          *
-         * Pad out to 16 bytes though as .data section needs to be 16 byte
-         * aligned and lld does not align the LMA to the aligment specified
+         * Pad out to 16 bytes though as .data section needs to be 16-byte
+         * aligned and lld does not align the LMA to the alignment specified
          * on the .data section.
          */
         __RODATA_END__ = .;
-         . = ALIGN(16);
+
+        . = ALIGN(16);
     } >ROM
-#else
-    ro . : {
+#else /* SEPARATE_CODE_AND_RODATA */
+    .ro . : {
         __RO_START__ = .;
+
         *bl1_entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(.text*))
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-	RODATA_COMMON
+        RODATA_COMMON
 
         *(.vectors)
+
         __RO_END__ = .;
 
         /*
-         * Pad out to 16 bytes as .data section needs to be 16 byte aligned and
-         * lld does not align the LMA to the aligment specified on the .data
-         * section.
+         * Pad out to 16 bytes as the .data section needs to be 16-byte aligned
+         * and lld does not align the LMA to the alignment specified on the
+         * .data section.
          */
-         . = ALIGN(16);
+        . = ALIGN(16);
     } >ROM
-#endif
+#endif /* SEPARATE_CODE_AND_RODATA */
 
     ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
-           "cpu_ops not defined for this platform.")
+        "cpu_ops not defined for this platform.")
 
     . = BL1_RW_BASE;
+
     ASSERT(BL1_RW_BASE == ALIGN(PAGE_SIZE),
-           "BL1_RW_BASE address is not aligned on a page boundary.")
+        "BL1_RW_BASE address is not aligned on a page boundary.")
 
     DATA_SECTION >RAM AT>ROM
+
     __DATA_RAM_START__ = __DATA_START__;
     __DATA_RAM_END__ = __DATA_END__;
 
@@ -105,24 +113,26 @@
 
 #if USE_COHERENT_MEM
     /*
-     * The base address of the coherent memory section must be page-aligned (4K)
-     * to guarantee that the coherent data are stored on their own pages and
-     * are not mixed with normal data.  This is required to set up the correct
-     * memory attributes for the coherent data page tables.
+     * The base address of the coherent memory section must be page-aligned to
+     * guarantee that the coherent data are stored on their own pages and are
+     * not mixed with normal data. This is required to set up the correct memory
+     * attributes for the coherent data page tables.
      */
-    coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
+    .coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
         __COHERENT_RAM_START__ = .;
-        *(tzfw_coherent_mem)
+        *(.tzfw_coherent_mem)
         __COHERENT_RAM_END_UNALIGNED__ = .;
+
         /*
-         * Memory page(s) mapped to this section will be marked
-         * as device memory.  No other unexpected data must creep in.
-         * Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as device
+         * memory. No other unexpected data must creep in. Ensure the rest of
+         * the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __COHERENT_RAM_END__ = .;
     } >RAM
-#endif
+#endif /* USE_COHERENT_MEM */
 
     __BL1_RAM_START__ = ADDR(.data);
     __BL1_RAM_END__ = .;
@@ -135,15 +145,16 @@
      * of BL1's actual content in Trusted ROM.
      */
     __BL1_ROM_END__ =  __DATA_ROM_START__ + __DATA_SIZE__;
+
     ASSERT(__BL1_ROM_END__ <= BL1_RO_LIMIT,
-           "BL1's ROM content has exceeded its limit.")
+        "BL1's ROM content has exceeded its limit.")
 
     __BSS_SIZE__ = SIZEOF(.bss);
 
 #if USE_COHERENT_MEM
     __COHERENT_RAM_UNALIGNED_SIZE__ =
         __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
-#endif
+#endif /* USE_COHERENT_MEM */
 
     ASSERT(. <= BL1_RW_LIMIT, "BL1's RW section has exceeded its limit.")
 }
diff --git a/bl1/bl1.mk b/bl1/bl1.mk
index 9f63fd5..0c43f13 100644
--- a/bl1/bl1.mk
+++ b/bl1/bl1.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
 #
@@ -29,4 +29,4 @@
 BL1_SOURCES		+=	bl1/bl1_fwu.c
 endif
 
-BL1_LINKERFILE		:=	bl1/bl1.ld.S
+BL1_DEFAULT_LINKER_SCRIPT_SOURCE := bl1/bl1.ld.S
diff --git a/bl1/bl1_fwu.c b/bl1/bl1_fwu.c
index b70bffd..6d4dc7e 100644
--- a/bl1/bl1_fwu.c
+++ b/bl1/bl1_fwu.c
@@ -420,7 +420,7 @@
 		 * Image is in RESET state.
 		 * Check the parameters and authenticate the source image in place.
 		 */
-		if (bl1_plat_mem_check(image_src, image_size,	\
+		if (bl1_plat_mem_check(image_src, image_size,
 					desc->ep_info.h.attr) != 0) {
 			WARN("BL1-FWU: Authentication arguments source/size not mapped\n");
 			return -ENOMEM;
diff --git a/bl2/bl2.ld.S b/bl2/bl2.ld.S
index 80cf7db..458a12b 100644
--- a/bl2/bl2.ld.S
+++ b/bl2/bl2.ld.S
@@ -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
  */
@@ -15,28 +15,31 @@
     RAM (rwx): ORIGIN = BL2_BASE, LENGTH = BL2_LIMIT - BL2_BASE
 }
 
-
-SECTIONS
-{
+SECTIONS {
     . = BL2_BASE;
+
     ASSERT(. == ALIGN(PAGE_SIZE),
-           "BL2_BASE address is not aligned on a page boundary.")
+        "BL2_BASE address is not aligned on a page boundary.")
 
 #if SEPARATE_CODE_AND_RODATA
     .text . : {
         __TEXT_START__ = .;
+
 #if ENABLE_RME
         *bl2_rme_entrypoint.o(.text*)
 #else /* ENABLE_RME */
         *bl2_entrypoint.o(.text*)
 #endif /* ENABLE_RME */
+
         *(SORT_BY_ALIGNMENT(.text*))
         *(.vectors)
+
         . = ALIGN(PAGE_SIZE);
+
         __TEXT_END__ = .;
     } >RAM
 
-    /* .ARM.extab and .ARM.exidx are only added because Clang need them */
+    /* .ARM.extab and .ARM.exidx are only added because Clang needs them */
     .ARM.extab . : {
         *(.ARM.extab* .gnu.linkonce.armextab.*)
     } >RAM
@@ -47,39 +50,41 @@
 
     .rodata . : {
         __RODATA_START__ = .;
+
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-	RODATA_COMMON
+        RODATA_COMMON
 
         . = ALIGN(PAGE_SIZE);
+
         __RODATA_END__ = .;
     } >RAM
-#else
-    ro . : {
+#else /* SEPARATE_CODE_AND_RODATA */
+    .ro . : {
         __RO_START__ = .;
+
         *bl2_entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(.text*))
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-	RODATA_COMMON
+        RODATA_COMMON
 
         *(.vectors)
+
         __RO_END_UNALIGNED__ = .;
+
         /*
-         * Memory page(s) mapped to this section will be marked as
-         * read-only, executable.  No RW data from the next section must
-         * creep in.  Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as read-only,
+         * executable. No RW data from the next section must creep in. Ensure
+         * that the rest of the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __RO_END__ = .;
     } >RAM
-#endif
+#endif /* SEPARATE_CODE_AND_RODATA */
 
-    /*
-     * Define a linker symbol to mark start of the RW memory area for this
-     * image.
-     */
-    __RW_START__ = . ;
+    __RW_START__ = .;
 
     DATA_SECTION >RAM
     STACK_SECTION >RAM
@@ -88,29 +93,27 @@
 
 #if USE_COHERENT_MEM
     /*
-     * The base address of the coherent memory section must be page-aligned (4K)
-     * to guarantee that the coherent data are stored on their own pages and
-     * are not mixed with normal data.  This is required to set up the correct
+     * The base address of the coherent memory section must be page-aligned to
+     * guarantee that the coherent data are stored on their own pages and are
+     * not mixed with normal data.  This is required to set up the correct
      * memory attributes for the coherent data page tables.
      */
-    coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
+    .coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
         __COHERENT_RAM_START__ = .;
-        *(tzfw_coherent_mem)
+        *(.tzfw_coherent_mem)
         __COHERENT_RAM_END_UNALIGNED__ = .;
+
         /*
-         * Memory page(s) mapped to this section will be marked
-         * as device memory.  No other unexpected data must creep in.
-         * Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as device
+         * memory. No other unexpected data must creep in. Ensure the rest of
+         * the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __COHERENT_RAM_END__ = .;
     } >RAM
-#endif
+#endif /* USE_COHERENT_MEM */
 
-    /*
-     * Define a linker symbol to mark end of the RW memory area for this
-     * image.
-     */
     __RW_END__ = .;
     __BL2_END__ = .;
 
@@ -119,7 +122,7 @@
 #if USE_COHERENT_MEM
     __COHERENT_RAM_UNALIGNED_SIZE__ =
         __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
-#endif
+#endif /* USE_COHERENT_MEM */
 
     ASSERT(. <= BL2_LIMIT, "BL2 image has exceeded its limit.")
 }
diff --git a/bl2/bl2.mk b/bl2/bl2.mk
index 7a973e5..778e2c3 100644
--- a/bl2/bl2.mk
+++ b/bl2/bl2.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
 #
@@ -23,12 +23,12 @@
 				bl2/${ARCH}/bl2_el3_exceptions.S	\
 				bl2/${ARCH}/bl2_run_next_image.S	\
 				${GPT_LIB_SRCS}
-BL2_LINKERFILE		:=	bl2/bl2.ld.S
+BL2_DEFAULT_LINKER_SCRIPT_SOURCE := bl2/bl2.ld.S
 
-else ifeq (${BL2_AT_EL3},0)
+else ifeq (${RESET_TO_BL2},0)
 # Normal operation, no RME, no BL2 at EL3
 BL2_SOURCES		+=	bl2/${ARCH}/bl2_entrypoint.S
-BL2_LINKERFILE		:=	bl2/bl2.ld.S
+BL2_DEFAULT_LINKER_SCRIPT_SOURCE := bl2/bl2.ld.S
 
 else
 # BL2 at EL3, no RME
@@ -46,5 +46,5 @@
 BL2_SOURCES		+=	lib/cpus/aarch64/dsu_helpers.S
 endif
 
-BL2_LINKERFILE		:=	bl2/bl2_el3.ld.S
+BL2_DEFAULT_LINKER_SCRIPT_SOURCE := bl2/bl2_el3.ld.S
 endif
diff --git a/bl2/bl2_el3.ld.S b/bl2/bl2_el3.ld.S
index c95706c..aa457fa 100644
--- a/bl2/bl2_el3.ld.S
+++ b/bl2/bl2_el3.ld.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,140 +15,158 @@
 #if BL2_IN_XIP_MEM
     ROM (rx): ORIGIN = BL2_RO_BASE, LENGTH = BL2_RO_LIMIT - BL2_RO_BASE
     RAM (rwx): ORIGIN = BL2_RW_BASE, LENGTH = BL2_RW_LIMIT - BL2_RW_BASE
-#else
+#else /* BL2_IN_XIP_MEM */
     RAM (rwx): ORIGIN = BL2_BASE, LENGTH = BL2_LIMIT - BL2_BASE
-#endif
+#endif /* BL2_IN_XIP_MEM */
+
 #if SEPARATE_BL2_NOLOAD_REGION
     RAM_NOLOAD (rw!a): ORIGIN = BL2_NOLOAD_START, LENGTH = BL2_NOLOAD_LIMIT - BL2_NOLOAD_START
-#else
-#define RAM_NOLOAD RAM
-#endif
+#else /* SEPARATE_BL2_NOLOAD_REGION */
+#   define RAM_NOLOAD RAM
+#endif /* SEPARATE_BL2_NOLOAD_REGION */
 }
 
 #if !BL2_IN_XIP_MEM
-#define ROM RAM
-#endif
+#   define ROM RAM
+#endif /* !BL2_IN_XIP_MEM */
 
-SECTIONS
-{
+SECTIONS {
 #if BL2_IN_XIP_MEM
     . = BL2_RO_BASE;
+
     ASSERT(. == ALIGN(PAGE_SIZE),
-           "BL2_RO_BASE address is not aligned on a page boundary.")
-#else
+        "BL2_RO_BASE address is not aligned on a page boundary.")
+#else /* BL2_IN_XIP_MEM */
     . = BL2_BASE;
+
     ASSERT(. == ALIGN(PAGE_SIZE),
-           "BL2_BASE address is not aligned on a page boundary.")
-#endif
+        "BL2_BASE address is not aligned on a page boundary.")
+#endif /* BL2_IN_XIP_MEM */
 
 #if SEPARATE_CODE_AND_RODATA
     .text . : {
         __TEXT_START__ = .;
-	__TEXT_RESIDENT_START__ = .;
-	*bl2_el3_entrypoint.o(.text*)
-	*(.text.asm.*)
-	__TEXT_RESIDENT_END__ = .;
+        __TEXT_RESIDENT_START__ = .;
+
+        *bl2_el3_entrypoint.o(.text*)
+        *(.text.asm.*)
+
+        __TEXT_RESIDENT_END__ = .;
+
         *(SORT_BY_ALIGNMENT(.text*))
         *(.vectors)
+
         . = ALIGN(PAGE_SIZE);
+
         __TEXT_END__ = .;
-     } >ROM
+    } >ROM
 
     .rodata . : {
         __RODATA_START__ = .;
+
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-	RODATA_COMMON
+        RODATA_COMMON
 
         . = ALIGN(PAGE_SIZE);
+
         __RODATA_END__ = .;
     } >ROM
 
     ASSERT(__TEXT_RESIDENT_END__ - __TEXT_RESIDENT_START__ <= PAGE_SIZE,
-          "Resident part of BL2 has exceeded its limit.")
-#else
-    ro . : {
+        "Resident part of BL2 has exceeded its limit.")
+#else /* SEPARATE_CODE_AND_RODATA */
+    .ro . : {
         __RO_START__ = .;
-	__TEXT_RESIDENT_START__ = .;
-	*bl2_el3_entrypoint.o(.text*)
-	*(.text.asm.*)
-	__TEXT_RESIDENT_END__ = .;
+        __TEXT_RESIDENT_START__ = .;
+
+        *bl2_el3_entrypoint.o(.text*)
+        *(.text.asm.*)
+
+        __TEXT_RESIDENT_END__ = .;
+
         *(SORT_BY_ALIGNMENT(.text*))
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-	RODATA_COMMON
+        RODATA_COMMON
 
         *(.vectors)
+
         __RO_END_UNALIGNED__ = .;
+
         /*
-         * Memory page(s) mapped to this section will be marked as
-         * read-only, executable.  No RW data from the next section must
-         * creep in.  Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as read-only,
+         * executable. No RW data from the next section must creep in. Ensure
+         * that the rest of the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
 
         __RO_END__ = .;
     } >ROM
-#endif
+#endif /* SEPARATE_CODE_AND_RODATA */
 
     ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
-          "cpu_ops not defined for this platform.")
+        "cpu_ops not defined for this platform.")
 
 #if BL2_IN_XIP_MEM
     . = BL2_RW_BASE;
+
     ASSERT(BL2_RW_BASE == ALIGN(PAGE_SIZE),
            "BL2_RW_BASE address is not aligned on a page boundary.")
-#endif
+#endif /* BL2_IN_XIP_MEM */
 
-    /*
-     * Define a linker symbol to mark start of the RW memory area for this
-     * image.
-     */
-    __RW_START__ = . ;
+    __RW_START__ = .;
 
     DATA_SECTION >RAM AT>ROM
+
     __DATA_RAM_START__ = __DATA_START__;
     __DATA_RAM_END__ = __DATA_END__;
 
     RELA_SECTION >RAM
+
 #if SEPARATE_BL2_NOLOAD_REGION
     SAVED_ADDR = .;
+
     . = BL2_NOLOAD_START;
+
     __BL2_NOLOAD_START__ = .;
-#endif
+#endif /* SEPARATE_BL2_NOLOAD_REGION */
+
     STACK_SECTION >RAM_NOLOAD
     BSS_SECTION >RAM_NOLOAD
     XLAT_TABLE_SECTION >RAM_NOLOAD
+
 #if SEPARATE_BL2_NOLOAD_REGION
     __BL2_NOLOAD_END__ = .;
+
     . = SAVED_ADDR;
-#endif
+#endif /* SEPARATE_BL2_NOLOAD_REGION */
 
 #if USE_COHERENT_MEM
     /*
-     * The base address of the coherent memory section must be page-aligned (4K)
-     * to guarantee that the coherent data are stored on their own pages and
-     * are not mixed with normal data.  This is required to set up the correct
+     * The base address of the coherent memory section must be page-aligned to
+     * guarantee that the coherent data are stored on their own pages and are
+     * not mixed with normal data.  This is required to set up the correct
      * memory attributes for the coherent data page tables.
      */
-    coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
+    .coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
         __COHERENT_RAM_START__ = .;
-        *(tzfw_coherent_mem)
+
+        *(.tzfw_coherent_mem)
+
         __COHERENT_RAM_END_UNALIGNED__ = .;
+
         /*
-         * Memory page(s) mapped to this section will be marked
-         * as device memory.  No other unexpected data must creep in.
-         * Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as device
+         * memory. No other unexpected data must creep in. Ensure the rest of
+         * the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __COHERENT_RAM_END__ = .;
     } >RAM
-#endif
+#endif /* USE_COHERENT_MEM */
 
-    /*
-     * Define a linker symbol to mark end of the RW memory area for this
-     * image.
-     */
     __RW_END__ = .;
     __BL2_END__ = .;
 
@@ -165,23 +183,24 @@
 
     /*
      * The .data section is the last PROGBITS section so its end marks the end
-     * of BL2's RO content in XIP memory..
+     * of BL2's RO content in XIP memory.
      */
     __BL2_ROM_END__ =  __DATA_ROM_START__ + __DATA_SIZE__;
+
     ASSERT(__BL2_ROM_END__ <= BL2_RO_LIMIT,
            "BL2's RO content has exceeded its limit.")
-#endif
-    __BSS_SIZE__ = SIZEOF(.bss);
+#endif /* BL2_IN_XIP_MEM */
 
+    __BSS_SIZE__ = SIZEOF(.bss);
 
 #if USE_COHERENT_MEM
     __COHERENT_RAM_UNALIGNED_SIZE__ =
         __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
-#endif
+#endif /* USE_COHERENT_MEM */
 
 #if BL2_IN_XIP_MEM
     ASSERT(. <= BL2_RW_LIMIT, "BL2's RW content has exceeded its limit.")
-#else
+#else /* BL2_IN_XIP_MEM */
     ASSERT(. <= BL2_LIMIT, "BL2 image has exceeded its limit.")
-#endif
+#endif /* BL2_IN_XIP_MEM */
 }
diff --git a/bl2/bl2_main.c b/bl2/bl2_main.c
index 5da8037..ce83692 100644
--- a/bl2/bl2_main.c
+++ b/bl2/bl2_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,9 +27,9 @@
 #define NEXT_IMAGE	"BL32"
 #endif
 
-#if BL2_AT_EL3
+#if RESET_TO_BL2
 /*******************************************************************************
- * Setup function for BL2 when BL2_AT_EL3=1
+ * Setup function for BL2 when RESET_TO_BL2=1
  ******************************************************************************/
 void bl2_el3_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
 		   u_register_t arg3)
@@ -48,9 +48,10 @@
 	assert(is_armv8_3_pauth_present());
 #endif /* CTX_INCLUDE_PAUTH_REGS */
 }
-#else /* BL2_AT_EL3 */
+#else /* RESET_TO_BL2 */
+
 /*******************************************************************************
- * Setup function for BL2 when BL2_AT_EL3=0
+ * Setup function for BL2 when RESET_TO_BL2=0
  ******************************************************************************/
 void bl2_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
 	       u_register_t arg3)
@@ -69,7 +70,7 @@
 	assert(is_armv8_3_pauth_present());
 #endif /* CTX_INCLUDE_PAUTH_REGS */
 }
-#endif /* BL2_AT_EL3 */
+#endif /* RESET_TO_BL2 */
 
 /*******************************************************************************
  * The only thing to do in BL2 is to load further images and pass control to
@@ -107,7 +108,7 @@
 	/* Teardown the Measured Boot backend */
 	bl2_plat_mboot_finish();
 
-#if !BL2_AT_EL3 && !ENABLE_RME
+#if !BL2_RUNS_AT_EL3
 #ifndef __aarch64__
 	/*
 	 * For AArch32 state BL1 and BL2 share the MMU setup.
@@ -132,7 +133,8 @@
 	 * be passed to next BL image as an argument.
 	 */
 	smc(BL1_SMC_RUN_IMAGE, (unsigned long)next_bl_ep_info, 0, 0, 0, 0, 0, 0);
-#else /* if BL2_AT_EL3 || ENABLE_RME */
+#else /* if BL2_RUNS_AT_EL3 */
+
 	NOTICE("BL2: Booting " NEXT_IMAGE "\n");
 	print_entry_point_info(next_bl_ep_info);
 	console_flush();
@@ -145,5 +147,5 @@
 #endif /* ENABLE_PAUTH */
 
 	bl2_run_next_image(next_bl_ep_info);
-#endif /* BL2_AT_EL3 && ENABLE_RME */
+#endif /* BL2_RUNS_AT_EL3 */
 }
diff --git a/bl2u/bl2u.ld.S b/bl2u/bl2u.ld.S
index a7752a4..52a925b 100644
--- a/bl2u/bl2u.ld.S
+++ b/bl2u/bl2u.ld.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,67 +17,69 @@
     RAM (rwx): ORIGIN = BL2U_BASE, LENGTH = BL2U_LIMIT - BL2U_BASE
 }
 
-
-SECTIONS
-{
+SECTIONS {
     . = BL2U_BASE;
+
     ASSERT(. == ALIGN(PAGE_SIZE),
-           "BL2U_BASE address is not aligned on a page boundary.")
+        "BL2U_BASE address is not aligned on a page boundary.")
 
 #if SEPARATE_CODE_AND_RODATA
     .text . : {
         __TEXT_START__ = .;
+
         *bl2u_entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(.text*))
         *(.vectors)
+
         . = ALIGN(PAGE_SIZE);
+
         __TEXT_END__ = .;
-     } >RAM
+    } >RAM
 
-     /* .ARM.extab and .ARM.exidx are only added because Clang need them */
-     .ARM.extab . : {
+    /* .ARM.extab and .ARM.exidx are only added because Clang needs them */
+    .ARM.extab . : {
         *(.ARM.extab* .gnu.linkonce.armextab.*)
-     } >RAM
+    } >RAM
 
-     .ARM.exidx . : {
+    .ARM.exidx . : {
         *(.ARM.exidx* .gnu.linkonce.armexidx.*)
-     } >RAM
+    } >RAM
 
     .rodata . : {
         __RODATA_START__ = .;
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-	RODATA_COMMON
+        RODATA_COMMON
 
         . = ALIGN(PAGE_SIZE);
         __RODATA_END__ = .;
     } >RAM
-#else
-    ro . : {
+#else /* SEPARATE_CODE_AND_RODATA */
+    .ro . : {
         __RO_START__ = .;
+
         *bl2u_entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(.text*))
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-	RODATA_COMMON
+        RODATA_COMMON
 
         *(.vectors)
+
         __RO_END_UNALIGNED__ = .;
+
         /*
-         * Memory page(s) mapped to this section will be marked as
-         * read-only, executable.  No RW data from the next section must
-         * creep in.  Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as read-only,
+         * executable. No RW data from the next section must creep in. Ensure
+         * that the rest of the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __RO_END__ = .;
     } >RAM
-#endif
+#endif /* SEPARATE_CODE_AND_RODATA */
 
-    /*
-     * Define a linker symbol to mark start of the RW memory area for this
-     * image.
-     */
-    __RW_START__ = . ;
+    __RW_START__ = .;
 
     DATA_SECTION >RAM
     STACK_SECTION >RAM
@@ -86,29 +88,27 @@
 
 #if USE_COHERENT_MEM
     /*
-     * The base address of the coherent memory section must be page-aligned (4K)
-     * to guarantee that the coherent data are stored on their own pages and
-     * are not mixed with normal data.  This is required to set up the correct
+     * The base address of the coherent memory section must be page-aligned to
+     * guarantee that the coherent data are stored on their own pages and are
+     * not mixed with normal data.  This is required to set up the correct
      * memory attributes for the coherent data page tables.
      */
-    coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
+    .coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
         __COHERENT_RAM_START__ = .;
-        *(tzfw_coherent_mem)
+        *(.tzfw_coherent_mem)
         __COHERENT_RAM_END_UNALIGNED__ = .;
+
         /*
-         * Memory page(s) mapped to this section will be marked
-         * as device memory.  No other unexpected data must creep in.
-         * Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as device
+         * memory. No other unexpected data must creep in. Ensure the rest of
+         * the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __COHERENT_RAM_END__ = .;
     } >RAM
-#endif
+#endif /* USE_COHERENT_MEM */
 
-    /*
-     * Define a linker symbol to mark end of the RW memory area for this
-     * image.
-     */
     __RW_END__ = .;
     __BL2U_END__ = .;
 
diff --git a/bl2u/bl2u.mk b/bl2u/bl2u.mk
index b4d7634..9f29bde 100644
--- a/bl2u/bl2u.mk
+++ b/bl2u/bl2u.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2017, 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,4 +12,4 @@
 BL2U_SOURCES		+=	common/aarch64/early_exceptions.S
 endif
 
-BL2U_LINKERFILE		:=	bl2u/bl2u.ld.S
+BL2U_DEFAULT_LINKER_SCRIPT_SOURCE := bl2u/bl2u.ld.S
diff --git a/bl31/aarch64/crash_reporting.S b/bl31/aarch64/crash_reporting.S
index d56b513..4cec110 100644
--- a/bl31/aarch64/crash_reporting.S
+++ b/bl31/aarch64/crash_reporting.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,8 +15,8 @@
 
 	.globl	report_unhandled_exception
 	.globl	report_unhandled_interrupt
-	.globl	el3_panic
-	.globl	elx_panic
+	.globl	report_el3_panic
+	.globl	report_elx_panic
 
 #if CRASH_REPORTING
 
@@ -64,7 +64,7 @@
 x30_msg:
 	.asciz "x30"
 excpt_msg_el:
-	.asciz "Unhandled Exception from EL"
+	.asciz "Unhandled Exception from lower EL.\n"
 
 	/*
 	 * Helper function to print from crash buf.
@@ -194,28 +194,20 @@
 	/* -----------------------------------------------------
 	 * This function allows to report a crash from the lower
 	 * exception level (if crash reporting is enabled) when
-	 * panic() is invoked from C Runtime.
+	 * lower_el_panic() is invoked from C Runtime.
 	 * It prints the CPU state via the crash console making
 	 * use of 'cpu_context' structure where general purpose
 	 * registers are saved and the crash buf.
 	 * This function will not return.
-	 *
- 	 * x0: Exception level
 	 * -----------------------------------------------------
 	 */
-func elx_panic
+func report_elx_panic
 	msr	spsel, #MODE_SP_ELX
-	mov	x8, x0
 
 	/* Print the crash message */
 	adr	x4, excpt_msg_el
 	bl	asm_print_str
 
-	/* Print exception level */
-	add	x0, x8, #'0'
-	bl	plat_crash_console_putc
-	bl	asm_print_newline
-
 	/* Report x0 - x29 values stored in 'gpregs_ctx' structure */
 	/* Store the ascii list pointer in x6 */
 	adr	x6, gp_regs
@@ -295,7 +287,7 @@
 	mrs	x2, sctlr_el1
 	mrs	x1, tcr_el1
 	b	test_pauth
-endfunc	elx_panic
+endfunc	report_elx_panic
 
 	/* -----------------------------------------------------
 	 * This function allows to report a crash (if crash
@@ -305,7 +297,7 @@
 	 * will not return.
 	 * -----------------------------------------------------
 	 */
-func el3_panic
+func report_el3_panic
 	msr	spsel, #MODE_SP_ELX
 	prepare_crash_buf_save_x0_x1
 	adr	x0, panic_msg
@@ -463,7 +455,7 @@
 
 	/* Done reporting */
 	no_ret	plat_panic_handler
-endfunc el3_panic
+endfunc report_el3_panic
 
 #else	/* CRASH_REPORTING */
 func report_unhandled_exception
diff --git a/bl31/aarch64/ea_delegate.S b/bl31/aarch64/ea_delegate.S
index dbb3234..9419476 100644
--- a/bl31/aarch64/ea_delegate.S
+++ b/bl31/aarch64/ea_delegate.S
@@ -16,9 +16,8 @@
 #include <context.h>
 
 	.globl	handle_lower_el_ea_esb
-	.globl  handle_lower_el_async_ea
-	.globl	enter_lower_el_sync_ea
-	.globl	enter_lower_el_async_ea
+	.globl	handle_lower_el_sync_ea
+	.globl	handle_lower_el_async_ea
 
 
 /*
@@ -42,17 +41,12 @@
  * Implementation Defined Exceptions. If any other kind of exception is detected,
  * then this function reports unhandled exception.
  *
- * Since it's part of exception vector, this function doesn't expect any GP
- * registers to have been saved. It delegates the handling of the EA to platform
- * handler, and upon successfully handling the EA, exits EL3; otherwise panics.
+ * It delegates the handling of the EA to platform handler, and upon successfully
+ * handling the EA, exits EL3; otherwise panics.
+ *
+ * This function assumes x30 has been saved.
  */
-func enter_lower_el_sync_ea
-	/*
-	 * Explicitly save x30 so as to free up a register and to enable
-	 * branching.
-	 */
-	str	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
-
+func handle_lower_el_sync_ea
 	mrs	x30, esr_el3
 	ubfx	x30, x30, #ESR_EC_SHIFT, #ESR_EC_LENGTH
 
@@ -114,24 +108,19 @@
 	/* Synchronous exceptions other than the above are assumed to be EA */
 	ldr	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
 	no_ret	report_unhandled_exception
-endfunc enter_lower_el_sync_ea
+endfunc handle_lower_el_sync_ea
 
 
 /*
  * This function handles SErrors from lower ELs.
  *
- * Since it's part of exception vector, this function doesn't expect any GP
- * registers to have been saved. It delegates the handling of the EA to platform
- * handler, and upon successfully handling the EA, exits EL3; otherwise panics.
+ * It delegates the handling of the EA to platform handler, and upon successfully
+ * handling the EA, exits EL3; otherwise panics.
+ *
+ * This function assumes x30 has been saved.
  */
-func enter_lower_el_async_ea
-	/*
-	 * Explicitly save x30 so as to free up a register and to enable
-	 * branching
-	 */
-	str	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
+func handle_lower_el_async_ea
 
-handle_lower_el_async_ea:
 	/*
 	 * Save general purpose and ARMv8.3-PAuth registers (if enabled).
 	 * If Secure Cycle Counter is not disabled in MDCR_EL3 when
@@ -153,7 +142,7 @@
 	/* el3_exit assumes SP_EL0 on entry */
 	msr	spsel, #MODE_SP_EL0
 	b	el3_exit
-endfunc enter_lower_el_async_ea
+endfunc handle_lower_el_async_ea
 
 
 /*
@@ -201,7 +190,7 @@
 	 */
 	ubfx	x2, x1, #ESR_EC_SHIFT, #ESR_EC_LENGTH
 	cmp	x2, EC_SERROR
-	b.ne	do_panic
+	b.ne	el3_panic
 	/*
 	 * Check for Implementation Defined Syndrome. If so, skip checking
 	 * Uncontainable error type from the syndrome as the format is unknown.
diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S
index 0c60859..2fa9f06 100644
--- a/bl31/aarch64/runtime_exceptions.S
+++ b/bl31/aarch64/runtime_exceptions.S
@@ -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
  */
@@ -40,6 +40,14 @@
 	.globl	serror_aarch32
 
 	/*
+	 * Save LR and make x30 available as most of the routines in vector entry
+	 * need a free register
+	 */
+	.macro save_x30
+	str	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
+	.endm
+
+	/*
 	 * Macro that prepares entry to EL3 upon taking an exception.
 	 *
 	 * With RAS_EXTENSION, this macro synchronizes pending errors with an ESB
@@ -47,7 +55,7 @@
 	 * delegated to platform EA handler.
 	 *
 	 * Without RAS_EXTENSION, this macro synchronizes pending errors using
-         * a DSB, unmasks Asynchronous External Aborts and saves X30 before
+	 * a DSB, unmasks Asynchronous External Aborts and saves X30 before
 	 * setting the flag CTX_IS_IN_EL3.
 	 */
 	.macro check_and_unmask_ea
@@ -58,12 +66,6 @@
 	/* Unmask the SError interrupt */
 	msr	daifclr, #DAIF_ABT_BIT
 
-	/*
-	 * Explicitly save x30 so as to free up a register and to enable
-	 * branching
-	 */
-	str	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
-
 	/* Check for SErrors synchronized by the ESB instruction */
 	mrs	x30, DISR_EL1
 	tbz	x30, #DISR_A_BIT, 1f
@@ -108,11 +110,7 @@
 	/* Use ISB for the above unmask operation to take effect immediately */
 	isb
 
-	/*
-	 * Refer Note 1.
-	 * No need to restore X30 as macros following this modify x30 anyway.
-	 */
-	str	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
+	/* Refer Note 1. */
 	mov 	x30, #1
 	str	x30, [sp, #CTX_EL3STATE_OFFSET + CTX_IS_IN_EL3]
 	dmb	sy
@@ -153,7 +151,7 @@
 
 	/* Synchronous exceptions other than the above are assumed to be EA */
 	ldr	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
-	b	enter_lower_el_sync_ea
+	b	handle_lower_el_sync_ea
 	.endm
 
 
@@ -316,7 +314,7 @@
 	 * triggered due to explicit synchronization in EL3. Refer Note 1.
 	 */
 	/* Assumes SP_EL3 on entry */
-	str	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
+	save_x30
 	ldr	x30, [sp, #CTX_EL3STATE_OFFSET + CTX_IS_IN_EL3]
 	cbnz	x30, 1f
 
@@ -338,32 +336,36 @@
 	 * to a valid cpu context where the general purpose and system register
 	 * state can be saved.
 	 */
+	save_x30
 	apply_at_speculative_wa
 	check_and_unmask_ea
 	handle_sync_exception
 end_vector_entry sync_exception_aarch64
 
 vector_entry irq_aarch64
+	save_x30
 	apply_at_speculative_wa
 	check_and_unmask_ea
 	handle_interrupt_exception irq_aarch64
 end_vector_entry irq_aarch64
 
 vector_entry fiq_aarch64
+	save_x30
 	apply_at_speculative_wa
 	check_and_unmask_ea
 	handle_interrupt_exception fiq_aarch64
 end_vector_entry fiq_aarch64
 
 vector_entry serror_aarch64
+	save_x30
 	apply_at_speculative_wa
 #if RAS_EXTENSION
 	msr	daifclr, #DAIF_ABT_BIT
-	b	enter_lower_el_async_ea
 #else
 	check_and_unmask_ea
-	b handle_lower_el_async_ea
 #endif
+	b	handle_lower_el_async_ea
+
 end_vector_entry serror_aarch64
 
 	/* ---------------------------------------------------------------------
@@ -377,32 +379,36 @@
 	 * to a valid cpu context where the general purpose and system register
 	 * state can be saved.
 	 */
+	save_x30
 	apply_at_speculative_wa
 	check_and_unmask_ea
 	handle_sync_exception
 end_vector_entry sync_exception_aarch32
 
 vector_entry irq_aarch32
+	save_x30
 	apply_at_speculative_wa
 	check_and_unmask_ea
 	handle_interrupt_exception irq_aarch32
 end_vector_entry irq_aarch32
 
 vector_entry fiq_aarch32
+	save_x30
 	apply_at_speculative_wa
 	check_and_unmask_ea
 	handle_interrupt_exception fiq_aarch32
 end_vector_entry fiq_aarch32
 
 vector_entry serror_aarch32
+	save_x30
 	apply_at_speculative_wa
 #if RAS_EXTENSION
 	msr	daifclr, #DAIF_ABT_BIT
-	b	enter_lower_el_async_ea
 #else
 	check_and_unmask_ea
-	b handle_lower_el_async_ea
 #endif
+	b	handle_lower_el_async_ea
+
 end_vector_entry serror_aarch32
 
 #ifdef MONITOR_TRAPS
@@ -500,6 +506,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
@@ -507,11 +524,10 @@
 	 * A service/dispatcher can retrieve the SVE hint bit state from
 	 * flags using the appropriate helper.
 	 */
+2:
 	bfi	x7, x0, #FUNCID_SVE_HINT_SHIFT, #FUNCID_SVE_HINT_MASK
 	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
@@ -563,7 +579,7 @@
 	 */
 
 	tst	w0, w0
-	b.mi	do_panic	/* negative return value: panic */
+	b.mi	elx_panic	/* negative return value: panic */
 	b.eq	1f		/* zero: do not change ELR_EL3 */
 
 	/* advance the PC to continue after the instruction */
@@ -578,7 +594,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 309e752..c829058 100644
--- a/bl31/bl31.ld.S
+++ b/bl31/bl31.ld.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,137 +11,145 @@
 OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
 ENTRY(bl31_entrypoint)
 
-
 MEMORY {
     RAM (rwx): ORIGIN = BL31_BASE, LENGTH = BL31_LIMIT - BL31_BASE
+
 #if SEPARATE_NOBITS_REGION
     NOBITS (rw!a): ORIGIN = BL31_NOBITS_BASE, LENGTH = BL31_NOBITS_LIMIT - BL31_NOBITS_BASE
-#else
-#define NOBITS RAM
-#endif
+#else /* SEPARATE_NOBITS_REGION */
+#   define NOBITS RAM
+#endif /* SEPARATE_NOBITS_REGION */
 }
 
 #ifdef PLAT_EXTRA_LD_SCRIPT
-#include <plat.ld.S>
-#endif
+#   include <plat.ld.S>
+#endif /* PLAT_EXTRA_LD_SCRIPT */
 
-SECTIONS
-{
+SECTIONS {
     . = BL31_BASE;
+
     ASSERT(. == ALIGN(PAGE_SIZE),
-           "BL31_BASE address is not aligned on a page boundary.")
+        "BL31_BASE address is not aligned on a page boundary.")
 
     __BL31_START__ = .;
 
 #if SEPARATE_CODE_AND_RODATA
     .text . : {
         __TEXT_START__ = .;
+
         *bl31_entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(SORT(.text*)))
         *(.vectors)
+
         . = ALIGN(PAGE_SIZE);
+
         __TEXT_END__ = .;
     } >RAM
 
     .rodata . : {
         __RODATA_START__ = .;
+
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-#if PLAT_EXTRA_RODATA_INCLUDES
-#include <plat.ld.rodata.inc>
-#endif
+#   if PLAT_EXTRA_RODATA_INCLUDES
+#       include <plat.ld.rodata.inc>
+#   endif /* PLAT_EXTRA_RODATA_INCLUDES */
 
-	RODATA_COMMON
+        RODATA_COMMON
 
-        /* Place pubsub sections for events */
         . = ALIGN(8);
-#include <lib/el3_runtime/pubsub_events.h>
+
+#   include <lib/el3_runtime/pubsub_events.h>
 
         . = ALIGN(PAGE_SIZE);
+
         __RODATA_END__ = .;
     } >RAM
-#else
-    ro . : {
+#else /* SEPARATE_CODE_AND_RODATA */
+    .ro . : {
         __RO_START__ = .;
+
         *bl31_entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(.text*))
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-	RODATA_COMMON
+        RODATA_COMMON
 
-        /* Place pubsub sections for events */
         . = ALIGN(8);
-#include <lib/el3_runtime/pubsub_events.h>
+
+#   include <lib/el3_runtime/pubsub_events.h>
 
         *(.vectors)
+
         __RO_END_UNALIGNED__ = .;
+
         /*
          * Memory page(s) mapped to this section will be marked as read-only,
-         * executable.  No RW data from the next section must creep in.
-         * Ensure the rest of the current memory page is unused.
+         * executable. No RW data from the next section must creep in. Ensure
+         * that the rest of the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __RO_END__ = .;
     } >RAM
-#endif
+#endif /* SEPARATE_CODE_AND_RODATA */
 
     ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
-           "cpu_ops not defined for this platform.")
+        "cpu_ops not defined for this platform.")
 
 #if SPM_MM
-#ifndef SPM_SHIM_EXCEPTIONS_VMA
-#define SPM_SHIM_EXCEPTIONS_VMA         RAM
-#endif
+#   ifndef SPM_SHIM_EXCEPTIONS_VMA
+#       define SPM_SHIM_EXCEPTIONS_VMA RAM
+#   endif /* SPM_SHIM_EXCEPTIONS_VMA */
 
     /*
      * Exception vectors of the SPM shim layer. They must be aligned to a 2K
-     * address, but we need to place them in a separate page so that we can set
-     * individual permissions to them, so the actual alignment needed is 4K.
+     * address but we need to place them in a separate page so that we can set
+     * individual permissions on them, so the actual alignment needed is the
+     * page size.
      *
      * There's no need to include this into the RO section of BL31 because it
      * doesn't need to be accessed by BL31.
      */
-    spm_shim_exceptions : ALIGN(PAGE_SIZE) {
+    .spm_shim_exceptions : ALIGN(PAGE_SIZE) {
         __SPM_SHIM_EXCEPTIONS_START__ = .;
+
         *(.spm_shim_exceptions)
+
         . = ALIGN(PAGE_SIZE);
+
         __SPM_SHIM_EXCEPTIONS_END__ = .;
     } >SPM_SHIM_EXCEPTIONS_VMA AT>RAM
 
-    PROVIDE(__SPM_SHIM_EXCEPTIONS_LMA__ = LOADADDR(spm_shim_exceptions));
-    . = LOADADDR(spm_shim_exceptions) + SIZEOF(spm_shim_exceptions);
-#endif
+    PROVIDE(__SPM_SHIM_EXCEPTIONS_LMA__ = LOADADDR(.spm_shim_exceptions));
 
-    /*
-     * Define a linker symbol to mark start of the RW memory area for this
-     * image.
-     */
-    __RW_START__ = . ;
+    . = LOADADDR(.spm_shim_exceptions) + SIZEOF(.spm_shim_exceptions);
+#endif /* SPM_MM */
+
+    __RW_START__ = .;
 
     DATA_SECTION >RAM
     RELA_SECTION >RAM
 
 #ifdef BL31_PROGBITS_LIMIT
     ASSERT(. <= BL31_PROGBITS_LIMIT, "BL31 progbits has exceeded its limit.")
-#endif
+#endif /* BL31_PROGBITS_LIMIT */
 
 #if SEPARATE_NOBITS_REGION
-    /*
-     * Define a linker symbol to mark end of the RW memory area for this
-     * image.
-     */
     . = ALIGN(PAGE_SIZE);
+
     __RW_END__ = .;
     __BL31_END__ = .;
 
     ASSERT(. <= BL31_LIMIT, "BL31 image has exceeded its limit.")
 
     . = BL31_NOBITS_BASE;
+
     ASSERT(. == ALIGN(PAGE_SIZE),
-           "BL31 NOBITS base address is not aligned on a page boundary.")
+        "BL31 NOBITS base address is not aligned on a page boundary.")
 
     __NOBITS_START__ = .;
-#endif
+#endif /* SEPARATE_NOBITS_REGION */
 
     STACK_SECTION >NOBITS
     BSS_SECTION >NOBITS
@@ -149,49 +157,44 @@
 
 #if USE_COHERENT_MEM
     /*
-     * The base address of the coherent memory section must be page-aligned (4K)
-     * to guarantee that the coherent data are stored on their own pages and
-     * are not mixed with normal data.  This is required to set up the correct
+     * The base address of the coherent memory section must be page-aligned to
+     * guarantee that the coherent data are stored on their own pages and are
+     * not mixed with normal data.  This is required to set up the correct
      * memory attributes for the coherent data page tables.
      */
-    coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
+    .coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
         __COHERENT_RAM_START__ = .;
+
         /*
-         * Bakery locks are stored in coherent memory
-         *
-         * Each lock's data is contiguous and fully allocated by the compiler
+         * Bakery locks are stored in coherent memory. Each lock's data is
+         * contiguous and fully allocated by the compiler.
          */
-        *(bakery_lock)
-        *(tzfw_coherent_mem)
+        *(.bakery_lock)
+        *(.tzfw_coherent_mem)
+
         __COHERENT_RAM_END_UNALIGNED__ = .;
+
         /*
-         * Memory page(s) mapped to this section will be marked
-         * as device memory.  No other unexpected data must creep in.
-         * Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as device
+         * memory. No other unexpected data must creep in. Ensure the rest of
+         * the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __COHERENT_RAM_END__ = .;
     } >NOBITS
-#endif
+#endif /* USE_COHERENT_MEM */
 
 #if SEPARATE_NOBITS_REGION
-    /*
-     * Define a linker symbol to mark end of the NOBITS memory area for this
-     * image.
-     */
     __NOBITS_END__ = .;
 
     ASSERT(. <= BL31_NOBITS_LIMIT, "BL31 NOBITS region has exceeded its limit.")
-#else
-    /*
-     * Define a linker symbol to mark end of the RW memory area for this
-     * image.
-     */
+#else /* SEPARATE_NOBITS_REGION */
     __RW_END__ = .;
     __BL31_END__ = .;
 
     ASSERT(. <= BL31_LIMIT, "BL31 image has exceeded its limit.")
-#endif
+#endif /* SEPARATE_NOBITS_REGION */
 
     /DISCARD/ : {
         *(.dynsym .dynstr .hash .gnu.hash)
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index ac15f9f..4d151ab 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.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
 #
@@ -87,11 +87,11 @@
 				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)
+ifneq (${ENABLE_FEAT_AMU},0)
 BL31_SOURCES		+=	${AMU_SOURCES}
 endif
 
@@ -99,32 +99,32 @@
 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)
+ifneq (${ENABLE_SVE_FOR_NS},0)
 BL31_SOURCES		+=	lib/extensions/sve/sve.c
 endif
 endif
 
-ifeq (${ENABLE_MPAM_FOR_LOWER_ELS},1)
+ifneq (${ENABLE_MPAM_FOR_LOWER_ELS},0)
 BL31_SOURCES		+=	lib/extensions/mpam/mpam.c
 endif
 
-ifeq (${ENABLE_TRBE_FOR_NS},1)
+ifneq (${ENABLE_TRBE_FOR_NS},0)
 BL31_SOURCES		+=	lib/extensions/trbe/trbe.c
 endif
 
-ifeq (${ENABLE_BRBE_FOR_NS},1)
+ifneq (${ENABLE_BRBE_FOR_NS},0)
 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
 
-ifeq (${ENABLE_TRF_FOR_NS},1)
+ifneq (${ENABLE_TRF_FOR_NS},0)
 BL31_SOURCES		+=	lib/extensions/trf/aarch64/trf.c
 endif
 
@@ -157,7 +157,7 @@
 				${MBEDTLS_SOURCES}
 endif
 
-BL31_LINKERFILE		:=	bl31/bl31.ld.S
+BL31_DEFAULT_LINKER_SCRIPT_SOURCE := bl31/bl31.ld.S
 
 # Flag used to indicate if Crash reporting via console should be included
 # in BL31. This defaults to being present in DEBUG builds only
diff --git a/bl32/sp_min/sp_min.ld.S b/bl32/sp_min/sp_min.ld.S
index 475affa..1695e1e 100644
--- a/bl32/sp_min/sp_min.ld.S
+++ b/bl32/sp_min/sp_min.ld.S
@@ -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
  */
@@ -16,130 +16,132 @@
 }
 
 #ifdef PLAT_SP_MIN_EXTRA_LD_SCRIPT
-#include <plat_sp_min.ld.S>
-#endif
+#   include <plat_sp_min.ld.S>
+#endif /* PLAT_SP_MIN_EXTRA_LD_SCRIPT */
 
-SECTIONS
-{
+SECTIONS {
     . = BL32_BASE;
+
     ASSERT(. == ALIGN(PAGE_SIZE),
-           "BL32_BASE address is not aligned on a page boundary.")
+        "BL32_BASE address is not aligned on a page boundary.")
 
 #if SEPARATE_CODE_AND_RODATA
     .text . : {
         __TEXT_START__ = .;
+
         *entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(.text*))
         *(.vectors)
+
         . = ALIGN(PAGE_SIZE);
+
         __TEXT_END__ = .;
     } >RAM
 
-     /* .ARM.extab and .ARM.exidx are only added because Clang need them */
-     .ARM.extab . : {
+    /* .ARM.extab and .ARM.exidx are only added because Clang needs them */
+    .ARM.extab . : {
         *(.ARM.extab* .gnu.linkonce.armextab.*)
-     } >RAM
+    } >RAM
 
-     .ARM.exidx . : {
+    .ARM.exidx . : {
         *(.ARM.exidx* .gnu.linkonce.armexidx.*)
-     } >RAM
+    } >RAM
 
     .rodata . : {
         __RODATA_START__ = .;
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-	RODATA_COMMON
+        RODATA_COMMON
 
-        /* Place pubsub sections for events */
         . = ALIGN(8);
-#include <lib/el3_runtime/pubsub_events.h>
+
+#   include <lib/el3_runtime/pubsub_events.h>
 
         . = ALIGN(PAGE_SIZE);
+
         __RODATA_END__ = .;
     } >RAM
-#else
-    ro . : {
+#else /* SEPARATE_CODE_AND_RODATA */
+    .ro . : {
         __RO_START__ = .;
+
         *entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(.text*))
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-	RODATA_COMMON
+        RODATA_COMMON
 
-        /* Place pubsub sections for events */
         . = ALIGN(8);
-#include <lib/el3_runtime/pubsub_events.h>
+
+#   include <lib/el3_runtime/pubsub_events.h>
 
         *(.vectors)
+
         __RO_END_UNALIGNED__ = .;
 
         /*
-         * Memory page(s) mapped to this section will be marked as
-         * read-only, executable.  No RW data from the next section must
-         * creep in.  Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as device
+         * memory. No other unexpected data must creep in. Ensure that the rest
+         * of the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __RO_END__ = .;
     } >RAM
-#endif
+#endif /* SEPARATE_CODE_AND_RODATA */
 
     ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
-           "cpu_ops not defined for this platform.")
-    /*
-     * Define a linker symbol to mark start of the RW memory area for this
-     * image.
-     */
-    __RW_START__ = . ;
+        "cpu_ops not defined for this platform.")
+
+    __RW_START__ = .;
 
     DATA_SECTION >RAM
     RELA_SECTION >RAM
 
 #ifdef BL32_PROGBITS_LIMIT
     ASSERT(. <= BL32_PROGBITS_LIMIT, "BL32 progbits has exceeded its limit.")
-#endif
+#endif /* BL32_PROGBITS_LIMIT */
 
     STACK_SECTION >RAM
     BSS_SECTION >RAM
     XLAT_TABLE_SECTION >RAM
 
-     __BSS_SIZE__ = SIZEOF(.bss);
+    __BSS_SIZE__ = SIZEOF(.bss);
 
 #if USE_COHERENT_MEM
     /*
-     * The base address of the coherent memory section must be page-aligned (4K)
-     * to guarantee that the coherent data are stored on their own pages and
-     * are not mixed with normal data.  This is required to set up the correct
+     * The base address of the coherent memory section must be page-aligned to
+     * guarantee that the coherent data are stored on their own pages and are
+     * not mixed with normal data.  This is required to set up the correct
      * memory attributes for the coherent data page tables.
      */
-    coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
+    .coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
         __COHERENT_RAM_START__ = .;
+
         /*
-         * Bakery locks are stored in coherent memory
-         *
-         * Each lock's data is contiguous and fully allocated by the compiler
+         * Bakery locks are stored in coherent memory. Each lock's data is
+         * contiguous and fully allocated by the compiler.
          */
-        *(bakery_lock)
-        *(tzfw_coherent_mem)
+        *(.bakery_lock)
+        *(.tzfw_coherent_mem)
+
         __COHERENT_RAM_END_UNALIGNED__ = .;
+
         /*
-         * Memory page(s) mapped to this section will be marked
-         * as device memory.  No other unexpected data must creep in.
-         * Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as device
+         * memory. No other unexpected data must creep in. Ensure that the rest
+         * of the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __COHERENT_RAM_END__ = .;
     } >RAM
 
     __COHERENT_RAM_UNALIGNED_SIZE__ =
         __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
-#endif
+#endif /* USE_COHERENT_MEM */
 
-    /*
-     * Define a linker symbol to mark the end of the RW memory area for this
-     * image.
-     */
     __RW_END__ = .;
-
     __BL32_END__ = .;
 
     /DISCARD/ : {
diff --git a/bl32/sp_min/sp_min.mk b/bl32/sp_min/sp_min.mk
index ab1287d..0e5c142 100644
--- a/bl32/sp_min/sp_min.mk
+++ b/bl32/sp_min/sp_min.mk
@@ -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
 #
@@ -28,7 +28,7 @@
 BL32_SOURCES		+=	lib/pmf/pmf_main.c
 endif
 
-ifeq (${ENABLE_AMU},1)
+ifneq (${ENABLE_FEAT_AMU},0)
 BL32_SOURCES		+=	${AMU_SOURCES}
 endif
 
@@ -46,15 +46,15 @@
 				services/std_svc/trng/trng_entropy_pool.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
 
-ifeq (${ENABLE_TRF_FOR_NS},1)
+ifneq (${ENABLE_TRF_FOR_NS},0)
 BL32_SOURCES		+=	lib/extensions/trf/aarch32/trf.c
 endif
 
-BL32_LINKERFILE	:=	bl32/sp_min/sp_min.ld.S
+BL32_DEFAULT_LINKER_SCRIPT_SOURCE := bl32/sp_min/sp_min.ld.S
 
 # Include the platform-specific SP_MIN Makefile
 # If no platform-specific SP_MIN Makefile exists, it means SP_MIN is not supported
diff --git a/bl32/tsp/tsp.ld.S b/bl32/tsp/tsp.ld.S
index d86ae55..a6658dd 100644
--- a/bl32/tsp/tsp.ld.S
+++ b/bl32/tsp/tsp.ld.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,71 +11,73 @@
 OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
 ENTRY(tsp_entrypoint)
 
-
 MEMORY {
     RAM (rwx): ORIGIN = TSP_SEC_MEM_BASE, LENGTH = TSP_SEC_MEM_SIZE
 }
 
-
-SECTIONS
-{
+SECTIONS {
     . = BL32_BASE;
+
     ASSERT(. == ALIGN(PAGE_SIZE),
-           "BL32_BASE address is not aligned on a page boundary.")
+        "BL32_BASE address is not aligned on a page boundary.")
 
 #if SEPARATE_CODE_AND_RODATA
     .text . : {
         __TEXT_START__ = .;
+
         *tsp_entrypoint.o(.text*)
         *(.text*)
         *(.vectors)
+
         . = ALIGN(PAGE_SIZE);
+
         __TEXT_END__ = .;
     } >RAM
 
     .rodata . : {
         __RODATA_START__ = .;
+
         *(.rodata*)
 
-	RODATA_COMMON
+        RODATA_COMMON
 
         . = ALIGN(PAGE_SIZE);
+
         __RODATA_END__ = .;
     } >RAM
-#else
-    ro . : {
+#else /* SEPARATE_CODE_AND_RODATA */
+    .ro . : {
         __RO_START__ = .;
+
         *tsp_entrypoint.o(.text*)
         *(.text*)
         *(.rodata*)
 
-	RODATA_COMMON
+        RODATA_COMMON
 
         *(.vectors)
 
         __RO_END_UNALIGNED__ = .;
+
         /*
-         * Memory page(s) mapped to this section will be marked as
-         * read-only, executable.  No RW data from the next section must
-         * creep in.  Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as read-only,
+         * executable. No RW data from the next section must creep in. Ensure
+         * that the rest of the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __RO_END__ = .;
     } >RAM
-#endif
+#endif /* SEPARATE_CODE_AND_RODATA */
 
-    /*
-     * Define a linker symbol to mark start of the RW memory area for this
-     * image.
-     */
-    __RW_START__ = . ;
+    __RW_START__ = .;
 
     DATA_SECTION >RAM
     RELA_SECTION >RAM
 
 #ifdef TSP_PROGBITS_LIMIT
     ASSERT(. <= TSP_PROGBITS_LIMIT, "TSP progbits has exceeded its limit.")
-#endif
+#endif /* TSP_PROGBITS_LIMIT */
 
     STACK_SECTION >RAM
     BSS_SECTION >RAM
@@ -83,29 +85,27 @@
 
 #if USE_COHERENT_MEM
     /*
-     * The base address of the coherent memory section must be page-aligned (4K)
-     * to guarantee that the coherent data are stored on their own pages and
-     * are not mixed with normal data.  This is required to set up the correct
-     * memory attributes for the coherent data page tables.
+     * The base address of the coherent memory section must be page-aligned to
+     * guarantee that the coherent data are stored on their own pages and are
+     * not mixed with normal data. This is required to set up the correct memory
+     * attributes for the coherent data page tables.
      */
-    coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
+    .coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
         __COHERENT_RAM_START__ = .;
-        *(tzfw_coherent_mem)
+        *(.tzfw_coherent_mem)
         __COHERENT_RAM_END_UNALIGNED__ = .;
+
         /*
-         * Memory page(s) mapped to this section will be marked
-         * as device memory.  No other unexpected data must creep in.
-         * Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as device
+         * memory. No other unexpected data must creep in. Ensure that the rest
+         * of the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __COHERENT_RAM_END__ = .;
     } >RAM
-#endif
+#endif /* USE_COHERENT_MEM */
 
-    /*
-     * Define a linker symbol to mark the end of the RW memory area for this
-     * image.
-     */
     __RW_END__ = .;
     __BL32_END__ = .;
 
@@ -114,10 +114,11 @@
     }
 
     __BSS_SIZE__ = SIZEOF(.bss);
+
 #if USE_COHERENT_MEM
     __COHERENT_RAM_UNALIGNED_SIZE__ =
         __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
-#endif
+#endif /* USE_COHERENT_MEM */
 
     ASSERT(. <= BL32_LIMIT, "BL32 image has exceeded its limit.")
 }
diff --git a/bl32/tsp/tsp.mk b/bl32/tsp/tsp.mk
index c31b9b5..cfffbdb 100644
--- a/bl32/tsp/tsp.mk
+++ b/bl32/tsp/tsp.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
 #
@@ -22,7 +22,7 @@
 				common/aarch64/early_exceptions.S	\
 				lib/locks/exclusive/aarch64/spinlock.S
 
-BL32_LINKERFILE		:=	bl32/tsp/tsp.ld.S
+BL32_DEFAULT_LINKER_SCRIPT_SOURCE := bl32/tsp/tsp.ld.S
 
 # This flag determines if the TSPD initializes BL32 in tspd_init() (synchronous
 # method) or configures BL31 to pass control to BL32 instead of BL33
diff --git a/bl32/tsp/tsp_ffa_main.c b/bl32/tsp/tsp_ffa_main.c
index 2c53977..268d329 100644
--- a/bl32/tsp/tsp_ffa_main.c
+++ b/bl32/tsp/tsp_ffa_main.c
@@ -201,7 +201,7 @@
 	/* Only expecting to be sent memory from NWd so map accordingly. */
 	mem_attrs |= MT_NS;
 
-	for (uint32_t i = 0U; i < composite->address_range_count; i++) {
+	for (int32_t i = 0; i < (int32_t)composite->address_range_count; i++) {
 		size_t size = composite->address_range_array[i].page_count * PAGE_SIZE;
 
 		ptr = (char *) composite->address_range_array[i].address;
@@ -211,7 +211,7 @@
 				size, mem_attrs);
 
 		if (ret != 0) {
-			ERROR("Failed [%u] mmap_add_dynamic_region %u (%lx) (%lx) (%x)!\n",
+			ERROR("Failed [%d] mmap_add_dynamic_region %u (%lx) (%lx) (%x)!\n",
 				i, ret,
 				(uint64_t)composite->address_range_array[i].address,
 				size, mem_attrs);
diff --git a/common/aarch32/debug.S b/common/aarch32/debug.S
index ae0bb7a..2937f56 100644
--- a/common/aarch32/debug.S
+++ b/common/aarch32/debug.S
@@ -12,7 +12,7 @@
 	.globl	asm_print_hex
 	.globl	asm_print_hex_bits
 	.globl	asm_assert
-	.globl	do_panic
+	.globl	el3_panic
 	.globl	report_exception
 	.globl	report_prefetch_abort
 	.globl	report_data_abort
@@ -159,14 +159,14 @@
 endfunc asm_print_hex
 
 	/***********************************************************
-	 * The common implementation of do_panic for all BL stages
+	 * The common implementation of el3_panic for all BL stages
 	 ***********************************************************/
 
 .section .rodata.panic_str, "aS"
 	panic_msg: .asciz "PANIC at PC : 0x"
 	panic_end: .asciz "\r\n"
 
-func do_panic
+func el3_panic
 	/* Have LR copy point to PC at the time of panic */
 	sub	r6, lr, #4
 
@@ -194,7 +194,7 @@
 _panic_handler:
 	mov	lr, r6
 	b	plat_panic_handler
-endfunc do_panic
+endfunc el3_panic
 
 	/***********************************************************
 	 * This function is called from the vector table for
diff --git a/common/aarch64/debug.S b/common/aarch64/debug.S
index 742e022..8768a1f 100644
--- a/common/aarch64/debug.S
+++ b/common/aarch64/debug.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2023 Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,7 +13,8 @@
 	.globl	asm_print_hex_bits
 	.globl	asm_print_newline
 	.globl	asm_assert
-	.globl	do_panic
+	.globl	el3_panic
+	.globl	elx_panic
 
 /* Since the max decimal input number is 65536 */
 #define MAX_DEC_DIVISOR		10000
@@ -145,54 +146,33 @@
 endfunc asm_print_newline
 
 	/***********************************************************
-	 * The common implementation of do_panic for all BL stages
+	 * The common implementation of el3_panic for all BL stages
 	 ***********************************************************/
 
 .section .rodata.panic_str, "aS"
 	panic_msg: .asciz "PANIC at PC : 0x"
 
+func elx_panic
+#if CRASH_REPORTING && defined(IMAGE_BL31)
+	b	report_elx_panic
+#endif /* CRASH_REPORTING && IMAGE_BL31 */
+
+	b	panic_common
+endfunc elx_panic
+
 /* ---------------------------------------------------------------------------
- * do_panic assumes that it is invoked from a C Runtime Environment ie a
+ * el3_panic assumes that it is invoked from a C Runtime Environment ie a
  * valid stack exists. This call will not return.
  * Clobber list : if CRASH_REPORTING is not enabled then x30, x0 - x6
  * ---------------------------------------------------------------------------
  */
 
-/* This is for the non el3 BL stages to compile through */
-	.weak el3_panic
-	.weak elx_panic
-
-func do_panic
-#if CRASH_REPORTING
-	str	x0, [sp, #-0x10]!
-	mrs	x0, currentel
-	ubfx	x0, x0, #MODE_EL_SHIFT, #MODE_EL_WIDTH
-	cmp	x0, #MODE_EL3
-#if !HANDLE_EA_EL3_FIRST_NS
-	ldr	x0, [sp], #0x10
-	b.eq	el3_panic
-#else
-	b.ne	to_panic_common
-
-	/* Check EL the exception taken from */
-	mrs	x0, spsr_el3
-	ubfx	x0, x0, #SPSR_EL_SHIFT, #SPSR_EL_WIDTH
-	cmp	x0, #MODE_EL3
-	b.ne	elx_panic
-	ldr	x0, [sp], #0x10
-	b	el3_panic
-
-to_panic_common:
-	ldr	x0, [sp], #0x10
-#endif /* HANDLE_EA_EL3_FIRST_NS */
-#endif /* CRASH_REPORTING */
+func el3_panic
+#if CRASH_REPORTING && defined(IMAGE_BL31)
+	b	report_el3_panic
+#endif /* CRASH_REPORTING && IMAGE_BL31 */
 
 panic_common:
-/*
- * el3_panic will be redefined by the BL31
- * crash reporting mechanism (if enabled)
- */
-el3_panic:
 	mov	x6, x30
 	bl	plat_crash_console_init
 
@@ -218,4 +198,5 @@
 	 * called, not the address of the call from el3_panic. */
 	mov	x30, x6
 	b	plat_panic_handler
-endfunc do_panic
+
+endfunc el3_panic
diff --git a/common/feat_detect.c b/common/feat_detect.c
index a8c40f7..9394304 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
  */
@@ -36,59 +36,28 @@
 /*******************************************************************************
  * Function : check_feature
  * Check for a valid combination of build time flags (ENABLE_FEAT_xxx) and
- * feature availability on the hardware.
- * Panics if a feature is forcefully enabled, but not available on the PE.
+ * feature availability on the hardware. <min> is the smallest feature
+ * ID field value that is required for that feature.
+ * Triggers a panic later if a feature is forcefully enabled, but not
+ * available on the PE. Also will panic if the hardware feature ID field
+ * is larger than the maximum known and supported number, specified by <max>.
  *
  * We force inlining here to let the compiler optimise away the whole check
  * if the feature is disabled at build time (FEAT_STATE_DISABLED).
  ******************************************************************************/
 static inline void __attribute((__always_inline__))
-check_feature(int state, unsigned long field, const char *feat_name)
+check_feature(int state, unsigned long field, const char *feat_name,
+	      unsigned int min, unsigned int max)
 {
-	if (state == FEAT_STATE_ALWAYS && field == 0U) {
+	if (state == FEAT_STATE_ALWAYS && field < min) {
 		ERROR("FEAT_%s not supported by the PE\n", feat_name);
 		tainted = true;
 	}
-}
-
-/******************************************
- * 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
+	if (state >= FEAT_STATE_ALWAYS && field > max) {
+		ERROR("FEAT_%s is version %ld, but is only known up to version %d\n",
+		      feat_name, field, max);
+		tainted = true;
+	}
 }
 
 /*******************************************************************************
@@ -121,48 +90,6 @@
 #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_TRF (Self-hosted Trace Extensions)
- ***************************************************/
-static void read_feat_trf(void)
-{
-#if (ENABLE_TRF_FOR_NS == FEAT_STATE_ALWAYS)
-	feat_detect_panic(is_arm8_4_feat_trf_present(), "TRF");
-#endif
-}
-
 /************************************************
  * Feature : FEAT_MTE (Memory Tagging Extension)
  ***********************************************/
@@ -175,16 +102,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)
  ***************************************************/
@@ -195,39 +112,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)
  *************************************************/
@@ -239,26 +123,6 @@
 #endif
 }
 
-/******************************************************
- * Feature : FEAT_BRBE (Branch Record Buffer Extension)
- *****************************************************/
-static void read_feat_brbe(void)
-{
-#if (ENABLE_BRBE_FOR_NS == FEAT_STATE_ALWAYS)
-	feat_detect_panic(is_feat_brbe_present(), "BRBE");
-#endif
-}
-
-/******************************************************
- * Feature : FEAT_TRBE (Trace Buffer Extension)
- *****************************************************/
-static void read_feat_trbe(void)
-{
-#if (ENABLE_TRBE_FOR_NS == FEAT_STATE_ALWAYS)
-	feat_detect_panic(is_feat_trbe_present(), "TRBE");
-#endif
-}
-
 /******************************************************************
  * Feature : FEAT_RNG_TRAP (Trapping support for RNDR/RNDRRS)
  *****************************************************************/
@@ -297,47 +161,65 @@
 	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);
 
 	/* 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);
 
 	/* v8.3 features */
 	read_feat_pauth();
 
 	/* v8.4 features */
 	read_feat_dit();
-	check_feature(ENABLE_FEAT_AMUv1, read_feat_amu_id_field(), "AMUv1");
-	read_feat_mpam();
-	read_feat_nv2();
-	read_feat_sel2();
-	read_feat_trf();
+	check_feature(ENABLE_FEAT_AMU, read_feat_amu_id_field(),
+		      "AMUv1", 1, 2);
+	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_FGT, read_feat_fgt_id_field(), "FGT");
-	read_feat_ecv();
-	read_feat_twed();
+	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);
+	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);
 
 	/* v8.7 features */
-	check_feature(ENABLE_FEAT_HCX, read_feat_hcx_id_field(), "HCX");
+	check_feature(ENABLE_FEAT_HCX, read_feat_hcx_id_field(), "HCX", 1, 1);
+
+	/* v8.9 features */
+	check_feature(ENABLE_FEAT_TCR2, read_feat_tcrx_id_field(),
+		      "TCR2", 1, 1);
 
 	/* v9.0 features */
-	read_feat_brbe();
-	read_feat_trbe();
+	check_feature(ENABLE_BRBE_FOR_NS, read_feat_brbe_id_field(),
+		      "BRBE", 1, 2);
+	check_feature(ENABLE_TRBE_FOR_NS, read_feat_trbe_id_field(),
+		      "TRBE", 1, 1);
 
 	/* v9.2 features */
+	check_feature(ENABLE_SME_FOR_NS, read_feat_sme_id_field(),
+		      "SME", 1, 2);
 	read_feat_rme();
 
 	if (tainted) {
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index 914c959..db412f5 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -543,6 +543,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/
 
@@ -909,6 +913,8 @@
 .. _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
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/fconf/fconf_properties.rst b/docs/components/fconf/fconf_properties.rst
index 20cc758..3479576 100644
--- a/docs/components/fconf/fconf_properties.rst
+++ b/docs/components/fconf/fconf_properties.rst
@@ -20,7 +20,9 @@
 
 - load-address [mandatory]
     - value type: <u64>
-    - Physical loading base address of the configuration.
+    - Physical loading base address of the configuration. 
+      If secondary-load-address is also provided (see below), then this is the
+      primary load address.
 
 - max-size [mandatory]
     - value type: <u32>
@@ -30,10 +32,11 @@
     - value type: <u32>
     - Image ID of the configuration.
 
-- ns-load-address [optional]
+- secondary-load-address [optional]
     - value type: <u64>
-    - Physical loading base address of the configuration in the non-secure
-      memory.
-      Only needed by those configuration files which require being loaded
-      in secure memory (at load-address) as well as in non-secure memory
-      e.g. HW_CONFIG
+    - A platform uses this physical address to copy the configuration to
+      another location during the boot-flow.
+
+--------------
+
+*Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/components/ffa-manifest-binding.rst b/docs/components/ffa-manifest-binding.rst
index 7483c90..1061ca0 100644
--- a/docs/components/ffa-manifest-binding.rst
+++ b/docs/components/ffa-manifest-binding.rst
@@ -128,18 +128,19 @@
 
    - This field supersedes the managed-exit field in the FF-A v1.0 spec.
 
+- other-s-interrupts-action
+   - value type: <u32>
+   - Specifies the action that the SPMC must take in response to a Other-Secure
+     physical interrupt.
+
+      - 0x0: Other-Secure interrupt is queued
+      - 0x1: Other-Secure interrupt is signaled
+
 - has-primary-scheduler
    - value type: <empty>
    - Presence of this field indicates that the partition implements the primary
      scheduler. If so, run-time EL must be EL1.
 
-- run-time-model
-   - value type: <u32>
-   - Run time model that the SPM must enforce for this SP:
-
-      - 0x0: Run to completion
-      - 0x1: Preemptible
-
 - time-slice-mem
    - value type: <empty>
    - Presence of this field indicates that the partition doesn't expect the
@@ -286,6 +287,18 @@
           - PPI:  0b01
           - SGI:  0b00
 
+- interrupts-target
+   - value type: <prop-encoded-array>
+   - A list of (id, mpdir upper bits, mpidr lower bits) tuples describing which
+     mpidr the interrupt is routed to, where:
+
+      - id: The <u32> interrupt ID. Must be one of those specified in the
+            "interrupts" field.
+      - mpidr upper bits: The <u32> describing the upper bits of the 64 bits
+                          mpidr
+      - mpidr lower bits: The <u32> describing the lower bits of the 64 bits
+                          mpidr
+
 - exclusive-access
    - value type: <empty>
    - Presence of this field implies that this endpoint must be granted exclusive
diff --git a/docs/components/rmm-el3-comms-spec.rst b/docs/components/rmm-el3-comms-spec.rst
index 25c4269..6b57c0e 100644
--- a/docs/components/rmm-el3-comms-spec.rst
+++ b/docs/components/rmm-el3-comms-spec.rst
@@ -53,7 +53,7 @@
     consistency with the versioning schemes used in other parts of RMM.
 
 This document specifies the 0.1 version of Boot Interface ABI and RMM-EL3
-services specification and the 0.1 version of the Boot Manifest.
+services specification and the 0.2 version of the Boot Manifest.
 
 .. _rmm_el3_boot_interface:
 
@@ -71,7 +71,7 @@
 
 The Boot Interface ABI defines a set of register conventions and
 also a memory based manifest file to pass information from EL3 to RMM. The
-boot manifest and the associated platform data in it can be dynamically created
+Boot Manifest and the associated platform data in it can be dynamically created
 by EL3 and there is no restriction on how the data can be obtained (e.g by DTB,
 hoblist or other).
 
@@ -99,7 +99,7 @@
    x0,Linear index of this PE. This index starts from 0 and must be less than the maximum number of CPUs to be supported at runtime (see x2).
    x1,Version for this Boot Interface as defined in :ref:`rmm_el3_ifc_versioning`.
    x2,Maximum number of CPUs to be supported at runtime. RMM should ensure that it can support this maximum number.
-   x3,Base address for the shared buffer used for communication between EL3 firmware and RMM. This buffer must be of 4KB size (1 page). The boot manifest must be present at the base of this shared buffer during cold boot.
+   x3,Base address for the shared buffer used for communication between EL3 firmware and RMM. This buffer must be of 4KB size (1 page). The Boot Manifest must be present at the base of this shared buffer during cold boot.
 
 During cold boot, EL3 firmware needs to allocate a 4KB page that will be
 passed to RMM in x3. This memory will be used as shared buffer for communication
@@ -162,8 +162,8 @@
    ``E_RMM_BOOT_CPUS_OUT_OF_RAGE``,Number of CPUs reported by EL3 larger than maximum supported by RMM,-3
    ``E_RMM_BOOT_CPU_ID_OUT_OF_RAGE``,Current CPU Id is higher or equal than the number of CPUs supported by RMM,-4
    ``E_RMM_BOOT_INVALID_SHARED_BUFFER``,Invalid pointer to shared memory area,-5
-   ``E_RMM_BOOT_MANIFEST_VERSION_NOT_SUPPORTED``,Version reported by the boot manifest not supported by RMM,-6
-   ``E_RMM_BOOT_MANIFEST_DATA_ERROR``,Error parsing core boot manifest,-7
+   ``E_RMM_BOOT_MANIFEST_VERSION_NOT_SUPPORTED``,Version reported by the Boot Manifest not supported by RMM,-6
+   ``E_RMM_BOOT_MANIFEST_DATA_ERROR``,Error parsing core Boot Manifest,-7
 
 For any error detected in RMM during cold or warm boot, RMM will return back to
 EL3 using ``RMM_BOOT_COMPLETE`` SMC with an appropriate error code. It is
@@ -177,25 +177,28 @@
 Boot Manifest
 ~~~~~~~~~~~~~
 
-During cold boot, EL3 Firmware passes a memory boot manifest to RMM containing
+During cold boot, EL3 Firmware passes a memory Boot Manifest to RMM containing
 platform information.
 
-This boot manifest is versioned independently of the boot interface, to help
-evolve the boot manifest independent of the rest of Boot Manifest.
-The current version for the boot manifest is ``v0.1`` and the rules explained
+This Boot Manifest is versioned independently of the Boot Interface, to help
+evolve the former independent of the latter.
+The current version for the Boot Manifest is ``v0.2`` and the rules explained
 in :ref:`rmm_el3_ifc_versioning` apply on this version as well.
 
-The boot manifest is divided into two different components:
+The Boot Manifest v0.2 has the following fields:
 
-   - Core Manifest: This is the generic parameters passed to RMM by EL3 common to all platforms.
-   - Platform data: This is defined by the platform owner and contains information specific to that platform.
+   - version : Version of the Manifest (v0.2)
+   - plat_data : Pointer to the platform specific data and not specified by this
+     document. These data are optional and can be NULL.
+   - plat_dram : Structure encoding the NS DRAM information on the platform. This
+     field is also optional and platform can choose to zero out this structure if
+     RMM does not need EL3 to send this information during the boot.
 
-For the current version of the manifest, the core manifest contains a pointer
-to the platform data. EL3 must ensure that the whole boot manifest,
-including the platform data, if available, fits inside the RMM EL3 shared
-buffer.
+For the current version of the Boot Manifest, the core manifest contains a pointer
+to the platform data. EL3 must ensure that the whole Boot Manifest, including
+the platform data, if available, fits inside the RMM EL3 shared buffer.
 
-For the type specification of the RMM Boot Manifest v0.1, refer to
+For the data structure specification of Boot Manifest, refer to
 :ref:`rmm_el3_manifest_struct`
 
 .. _runtime_services_and_interface:
@@ -525,19 +528,59 @@
 RMM-EL3 Boot Manifest structure
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-The RMM-EL3 Boot Manifest structure contains platform boot information passed
-from EL3 to RMM. The width of the Boot Manifest is 128 bits
-
-.. image:: ../resources/diagrams/rmm_el3_manifest_struct.png
+The RMM-EL3 Boot Manifest v0.2 structure contains platform boot information passed
+from EL3 to RMM. The size of the Boot Manifest is 40 bytes.
 
 The members of the RMM-EL3 Boot Manifest structure are shown in the following
 table:
 
-.. csv-table::
-   :header: "Name", "Range", "Type", Description
-   :widths: 2 1 1 4
++-----------+--------+----------------+----------------------------------------+
+|   Name    | Offset |     Type       |               Description              |
++===========+========+================+========================================+
+| version   |   0    |   uint32_t     | Boot Manifest version                  |
++-----------+--------+----------------+----------------------------------------+
+| padding   |   4    |   uint32_t     | Reserved, set to 0                     |
++-----------+--------+----------------+----------------------------------------+
+| plat_data |   8    |   uintptr_t    | Pointer to Platform Data section       |
++-----------+--------+----------------+----------------------------------------+
+| plat_dram |   16   | ns_dram_info   | NS DRAM Layout Info structure          |
++-----------+--------+----------------+----------------------------------------+
+
+.. _ns_dram_info_struct:
+
+NS DRAM Layout Info structure
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+NS DRAM Layout Info structure contains information about platform Non-secure
+DRAM layout. The members of this structure are shown in the table below:
+
++-----------+--------+----------------+----------------------------------------+
+|   Name    | Offset |     Type       |               Description              |
++===========+========+================+========================================+
+| num_banks |   0    |   uint64_t     | Number of NS DRAM banks                |
++-----------+--------+----------------+----------------------------------------+
+| banks     |   8    | ns_dram_bank * | Pointer to 'ns_dram_bank'[] array      |
++-----------+--------+----------------+----------------------------------------+
+| checksum  |   16   |   uint64_t     | Checksum                               |
++-----------+--------+----------------+----------------------------------------+
+
+Checksum is calculated as two's complement sum of 'num_banks', 'banks' pointer
+and DRAM banks data array pointed by it.
+
+.. _ns_dram_bank_struct:
+
+NS DRAM Bank structure
+~~~~~~~~~~~~~~~~~~~~~~
+
+NS DRAM Bank structure contains information about each Non-secure DRAM bank:
+
++-----------+--------+----------------+----------------------------------------+
+|   Name    | Offset |     Type       |               Description              |
++===========+========+================+========================================+
+|   base    |   0    |   uintptr_t    | Base address                           |
++-----------+--------+----------------+----------------------------------------+
+|   size    |   8    |   uint64_t     | Size of bank in bytes                  |
++-----------+--------+----------------+----------------------------------------+
+
+
 
-   ``Version Minor``,15:0,uint16_t,Version Minor part of the Boot Manifest Version.
-   ``Version Major``,30:16,uint16_t,Version Major part of the Boot Manifest Version.
-   ``RES0``,31,bit,Reserved. Set to 0.
-   ``Platform Data``,127:64,Address,Pointer to the Platform Data section of the Boot Manifest.
diff --git a/docs/components/spd/optee-dispatcher.rst b/docs/components/spd/optee-dispatcher.rst
index 63baccc..81476f1 100644
--- a/docs/components/spd/optee-dispatcher.rst
+++ b/docs/components/spd/optee-dispatcher.rst
@@ -6,9 +6,26 @@
 To build and execute OP-TEE follow the instructions at
 `OP-TEE build.git`_
 
+There are two different modes for loading the OP-TEE OS. The default mode will
+load it as the BL32 payload during boot, and is the recommended technique for
+platforms to use. There is also another technique that will load OP-TEE OS after
+boot via an SMC call by enabling the option for OPTEE_ALLOW_SMC_LOAD that was
+specifically added for ChromeOS. Loading OP-TEE via an SMC call may be insecure
+depending upon the platform configuration. If using that option, be sure to
+understand the risks involved with allowing the Trusted OS to be loaded this
+way. ChromeOS uses a boot flow where it verifies the signature of the firmware
+before executing it, and then only if the signature is valid will the 'secrets'
+used by the TEE become accessible. The firmware then verifies the signature of
+the kernel using depthcharge, and the kernel verifies the rootfs using
+dm-verity.  The SMC call to load OP-TEE is then invoked immediately after the
+kernel finishes loading and before any attack vectors can be opened up by
+mounting writable filesystems or opening network/device connections. this
+ensures the platform is 'closed' and running signed code through the point where
+OP-TEE is loaded.
+
 --------------
 
-*Copyright (c) 2014-2018, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.*
 
 .. _OP-TEE OS: https://github.com/OP-TEE/build
 .. _OP-TEE build.git: https://github.com/OP-TEE/build
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index 5b67299..0f1f92a 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -317,6 +317,10 @@
    CPU. 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.
+
 -  ``ERRATA_A78_2772019``: This applies errata 2772019 workaround to Cortex-A78
    CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1, and r1p2, and
    it is still open.
@@ -345,6 +349,14 @@
 
 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.
@@ -361,6 +373,14 @@
   Cortex-A78C CPU. This needs to be enabled for revisions r0p1 and r0p2. This
   erratum 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.
+
+- ``ERRATA_A78C_2779484`` : This applies errata 2779484 workaround to
+  Cortex-A78C CPU. This needs to be enabled for revisions r0p1 and r0p2.
+  This erratum is still open.
+
 For Cortex-X1 CPU, the following errata build flags are defined:
 
 - ``ERRATA_X1_1821534`` : This applies errata 1821534 workaround to Cortex-X1
@@ -472,6 +492,10 @@
    CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1 and r1p2 of the
    CPU. It is still open.
 
+-  ``ERRATA_V1_2743233``: This applies erratum 2743233 workaround to Neoverse-V1
+   CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1, and r1p2 of the
+   CPU. It is still open.
+
 -  ``ERRATA_V1_2779461``: This applies erratum 2779461 workaround to Neoverse-V1
    CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1, r1p2 of the
    CPU. It is still open.
diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst
index 84bba18..97f3550 100644
--- a/docs/design/firmware-design.rst
+++ b/docs/design/firmware-design.rst
@@ -25,7 +25,6 @@
 :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.
@@ -484,8 +483,8 @@
 as its only purpose is to ensure TF-A BL2 is entered at S-EL1. To avoid
 this waste, a special mode enables BL2 to execute at EL3, which allows
 a non-TF-A Boot ROM to load and jump directly to BL2. This mode is selected
-when the build flag BL2_AT_EL3 is enabled. The main differences in this
-mode are:
+when the build flag RESET_TO_BL2 is enabled.
+The main differences in this mode are:
 
 #. BL2 includes the reset code and the mailbox mechanism to differentiate
    cold boot and warm boot. It runs at EL3 doing the arch
@@ -900,7 +899,7 @@
 A runtime service is registered using the ``DECLARE_RT_SVC()`` macro, specifying
 the name of the service, the range of OENs covered, the type of service and
 initialization and call handler functions. This macro instantiates a ``const struct rt_svc_desc`` for the service with these details (see ``runtime_svc.h``).
-This structure is allocated in a special ELF section ``rt_svc_descs``, enabling
+This structure is allocated in a special ELF section ``.rt_svc_descs``, enabling
 the framework to find all service descriptors included into BL31.
 
 The specific service for a SMC Function is selected based on the OEN and call
@@ -1330,7 +1329,7 @@
 (priority, group, configuration). Each element of the array shall be populated
 by the macro ``INTR_PROP_DESC()``. The macro takes the following arguments:
 
-- 10-bit interrupt number,
+- 13-bit interrupt number,
 
 - 8-bit interrupt priority,
 
@@ -2165,7 +2164,7 @@
 has been redesigned. The changes utilise the characteristic of Lamport's Bakery
 algorithm mentioned earlier. The bakery_lock structure only allocates the memory
 for a single CPU. The macro ``DEFINE_BAKERY_LOCK`` allocates all the bakery locks
-needed for a CPU into a section ``bakery_lock``. The linker allocates the memory
+needed for a CPU into a section ``.bakery_lock``. The linker allocates the memory
 for other cores by using the total size allocated for the bakery_lock section
 and multiplying it with (PLATFORM_CORE_COUNT - 1). This enables software to
 perform software cache maintenance on the lock data structure without running
@@ -2193,7 +2192,7 @@
 
 ::
 
-    bakery_lock section start
+    .bakery_lock section start
     |----------------|
     | `bakery_info_t`| <-- Lock_0 per-CPU field
     |    Lock_0      |     for CPU0
@@ -2230,7 +2229,7 @@
 
 Consider a system of 2 CPUs with 'N' bakery locks as shown above. For an
 operation on Lock_N, the corresponding ``bakery_info_t`` in both CPU0 and CPU1
-``bakery_lock`` section need to be fetched and appropriate cache operations need
+``.bakery_lock`` section need to be fetched and appropriate cache operations need
 to be performed for each access.
 
 On Arm Platforms, bakery locks are used in psci (``psci_locks``) and power controller
@@ -2752,7 +2751,7 @@
 
 --------------
 
-*Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.*
+*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
diff --git a/docs/design_documents/index.rst b/docs/design_documents/index.rst
index 3e20c07..d20fc58 100644
--- a/docs/design_documents/index.rst
+++ b/docs/design_documents/index.rst
@@ -9,6 +9,8 @@
    context_mgmt_rework
    measured_boot_poc
    drtm_poc
+   rss
+   psci_osi_mode
 
 --------------
 
diff --git a/docs/design_documents/measured_boot_poc.rst b/docs/design_documents/measured_boot_poc.rst
index 3ae539b..2e25057 100644
--- a/docs/design_documents/measured_boot_poc.rst
+++ b/docs/design_documents/measured_boot_poc.rst
@@ -6,7 +6,7 @@
 security state can be attested later.
 
 The current implementation of the driver included in Trusted Firmware-A
-(TF-A) stores the measurements into a `TGC event log`_ in secure
+(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.
 
@@ -24,7 +24,7 @@
    platforms might have different needs and configurations (e.g. different
    SHA algorithms) and they might also use different types of TPM services
    (or even a different type of service to provide the attestation)
-   and therefore the instuctions given here might not apply in such scenarios.
+   and therefore the instructions given here might not apply in such scenarios.
 
 Components
 ~~~~~~~~~~
@@ -497,11 +497,11 @@
 
 --------------
 
-*Copyright (c) 2021, Arm Limited. All rights reserved.*
+*Copyright (c) 2021-2023, Arm Limited. All rights reserved.*
 
 .. _OP-TEE Toolkit: https://github.com/OP-TEE/build
 .. _ms-tpm-20-ref: https://github.com/microsoft/ms-tpm-20-ref
 .. _Get and build the solution: https://optee.readthedocs.io/en/latest/building/gits/build.html#get-and-build-the-solution
 .. _Armv8-A Foundation Platform (For Linux Hosts Only): https://developer.arm.com/tools-and-software/simulation-models/fixed-virtual-platforms/arm-ecosystem-models
 .. _tpm2-tools: https://github.com/tpm2-software/tpm2-tools
-.. _TGC event log: https://trustedcomputinggroup.org/resource/tcg-efi-platform-specification/
+.. _TCG event log: https://trustedcomputinggroup.org/resource/tcg-efi-platform-specification/
diff --git a/docs/design_documents/psci_osi_mode.rst b/docs/design_documents/psci_osi_mode.rst
new file mode 100644
index 0000000..3296e27
--- /dev/null
+++ b/docs/design_documents/psci_osi_mode.rst
@@ -0,0 +1,716 @@
+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: RFC
+
+.. 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.
+
+* Update the return type of the platform specific ``pwr_domain_suspend``
+  handler from ``void`` to ``int``, to allow the platform to optionally perform
+  validations based on hardware states.
+
+.. 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/design_documents/rss.rst b/docs/design_documents/rss.rst
new file mode 100644
index 0000000..2be8067
--- /dev/null
+++ b/docs/design_documents/rss.rst
@@ -0,0 +1,611 @@
+Runtime Security Subsystem (RSS)
+================================
+
+This document focuses on the relationship between the Runtime Security Subsystem
+(RSS) and the application processor (AP). According to the ARM reference design
+the RSS is an independent core next to the AP and the SCP on the same die. It
+provides fundamental security guarantees and runtime services for the rest of
+the system (e.g.: trusted boot, measured boot, platform attestation,
+key management, and key derivation).
+
+At power up RSS boots first from its private ROM code. It validates and loads
+its own images and the initial images of SCP and AP. When AP and SCP are
+released from reset and their initial code is loaded then they continue their
+own boot process, which is the same as on non-RSS systems. Please refer to the
+``RSS documentation`` [1]_ for more details about the RSS boot flow.
+
+The last stage of the RSS firmware is a persistent, runtime component. Much
+like AP_BL31, this is a passive entity which has no periodical task to do and
+just waits for external requests from other subsystems. RSS and other
+subsystems can communicate with each other over message exchange. RSS waits
+in idle for the incoming request, handles them, and sends a response then goes
+back to idle.
+
+RSS communication layer
+-----------------------
+
+The communication between RSS and other subsystems are primarily relying on the
+Message Handling Unit (MHU) module. The number of MHU interfaces between RSS
+and other cores is IMPDEF. Besides MHU other modules also could take part in
+the communication. RSS is capable of mapping the AP memory to its address space.
+Thereby either RSS core itself or a DMA engine if it is present, can move the
+data between memory belonging to RSS or AP. In this way, a bigger amount of data
+can be transferred in a short time.
+
+The MHU comes in pairs. There is a sender and receiver side. They are connected
+to each other. An MHU interface consists of two pairs of MHUs, one sender and
+one receiver on both sides. Bidirectional communication is possible over an
+interface. One pair provides message sending from AP to RSS and the other pair
+from RSS to AP. The sender and receiver are connected via channels. There is an
+IMPDEF number of channels (e.g: 4-16) between a sender and a receiver module.
+
+The RSS communication layer provides two ways for message exchange:
+
+- ``Embedded messaging``: The full message, including header and payload, are
+  exchanged over the MHU channels. A channel is capable of delivering a single
+  word. The sender writes the data to the channel register on its side and the
+  receiver can read the data from the channel on the other side. One dedicated
+  channel is used for signalling. It does not deliver any payload it is just
+  meant for signalling that the sender loaded the data to the channel registers
+  so the receiver can read them. The receiver uses the same channel to signal
+  that data was read. Signalling happens via IRQ. If the message is longer than
+  the data fit to the channel registers then the message is sent over in
+  multiple rounds. Both, sender and receiver allocate a local buffer for the
+  messages. Data is copied from/to these buffers to/from the channel registers.
+- ``Pointer-access messaging``: The message header and the payload are
+  separated and they are conveyed in different ways. The header is sent
+  over the channels, similar to the embedded messaging but the payload is
+  copied over by RSS core (or by DMA) between the sender and the receiver. This
+  could be useful in the case of long messages because transaction time is less
+  compared to the embedded messaging mode. Small payloads are copied by the RSS
+  core because setting up DMA would require more CPU cycles. The payload is
+  either copied into an internal buffer or directly read-written by RSS. Actual
+  behavior depends on RSS setup, whether the partition supports memory-mapped
+  ``iovec``. Therefore, the sender must handle both cases and prevent access to
+  the memory, where payload data lives, while the RSS handles the request.
+
+The RSS communication layer supports both ways of messaging in parallel. It is
+decided at runtime based on the message size which way to transfer the message.
+
+.. code-block:: bash
+
+    +----------------------------------------------+       +-------------------+
+    |                                              |       |                   |
+    |                      AP                      |       |                   |
+    |                                              |  +--->|       SRAM        |
+    +----------------------------------------------|  |    |                   |
+    |              BL1 / BL2 / BL31                |  |    |                   |
+    +----------------------------------------------+  |    +-------------------+
+             |                           ^            |        ^           ^
+             |  send                 IRQ | receive    |direct  |           |
+             V                           |            |access  |           |
+    +--------------------+    +--------------------+  |        |           |
+    |      MHU sender    |    |    MHU receiver    |  |        | Copy data |
+    +--------------------+    +--------------------+  |        |           |
+       | |           | |          | |           | |   |        |           |
+       | | channels  | |          | | channels  | |   |        |           |
+       | | e.g: 4-16 | |          | | e.g: 4-16 | |   |        V           |
+    +--------------------+    +--------------------+  |    +-------+       |
+    |     MHU receiver   |    |     MHU sender     |  | +->|  DMA  |       |
+    +--------------------+    +--------------------+  | |  +-------+       |
+             |                           ^            | |      ^           |
+        IRQ  |  receive                  | send       | |      | Copy data |
+             V                           |            | |      V           V
+    +----------------------------------------------+  | |  +-------------------+
+    |                                              |--+-+  |                   |
+    |                  RSS                         |       |      SRAM         |
+    |                                              |       |                   |
+    +----------------------------------------------+       +-------------------+
+
+.. Note::
+
+    The RSS communication layer is not prepared for concurrent execution. The
+    current use case only requires message exchange during the boot phase. In
+    the boot phase, only a single core is running and the rest of the cores are
+    in reset.
+
+Message structure
+^^^^^^^^^^^^^^^^^
+A description of the message format can be found in the ``RSS communication
+design`` [2]_ document.
+
+Source files
+^^^^^^^^^^^^
+- RSS comms:  ``drivers/arm/rss``
+- MHU driver: ``drivers/arm/mhu``
+
+
+API for communication over MHU
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+The API is defined in these header files:
+
+- ``include/drivers/arm/rss_comms.h``
+- ``include/drivers/arm/mhu.h``
+
+RSS provided runtime services
+-----------------------------
+
+RSS provides the following runtime services:
+
+- ``Measured boot``: Securely store the firmware measurements which were
+  computed during the boot process and the associated metadata (image
+  description, measurement algorithm, etc.). More info on measured boot service
+  in RSS can be found in the ``measured_boot_integration_guide`` [3]_ .
+- ``Delegated attestation``: Query the platform attestation token and derive a
+  delegated attestation key. More info on the delegated attestation service
+  in RSS can be found in the ``delegated_attestation_integration_guide`` [4]_ .
+- ``OTP assets management``: RSS provides access for AP to assets in OTP.
+  These are keys for image signature verification and non-volatile counters
+  for anti-rollback protection. Only RSS has direct access to the OTP. Public
+  keys used by AP during the trusted boot process can be requested from RSS.
+  Furthermore, AP can request RSS to increase a non-volatile counter. Please
+  refer to the ``RSS key management`` [5]_ document for more details.
+
+Runtime service API
+^^^^^^^^^^^^^^^^^^^
+The RSS provided runtime services implement a PSA aligned API. The parameter
+encoding follows the PSA client protocol described in the
+``Firmware Framework for M`` [6]_ document in chapter 4.4. The implementation is
+restricted to the static handle use case therefore only the ``psa_call`` API is
+implemented.
+
+
+Software and API layers
+^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: bash
+
+    +----------------+         +---------------------+
+    |   BL1 / BL2    |         |       BL31          |
+    +----------------+         +---------------------+
+      |                         |
+      | extend_measurement()    | get_delegated_key()
+      |                         | get_platform_token()
+      V                         V
+    +----------------+         +---------------------+
+    |  PSA protocol  |         |    PSA protocol     |
+    +----------------+         +---------------------+
+         |                               |
+         | psa_call()                    | psa_call()
+         |                               |
+         V                               V
+    +------------------------------------------------+
+    |         RSS communication protocol             |
+    +------------------------------------------------+
+         |                     ^
+         | mhu_send_data()     | mhu_receive_data()
+         |                     |
+         V                     |
+    +------------------------------------------------+
+    |                 MHU driver                     |
+    +------------------------------------------------+
+               |                      ^
+               | Register access      | IRQ
+               V                      |
+    +------------------------------------------------+
+    |             MHU HW on AP side                  |
+    +------------------------------------------------+
+                         ^
+                         | Physical wires
+                         |
+                         V
+    +------------------------------------------------+
+    |             MHU HW on RSS side                 |
+    +------------------------------------------------+
+             |                        ^
+             | IRQ                    | Register access
+             V                        |
+    +------------------------------------------------+
+    |                 MHU driver                     |
+    +------------------------------------------------+
+             |                        |
+             V                        V
+    +---------------+       +------------------------+
+    | Measured boot |       | Delegated attestation  |
+    | service       |       | service                |
+    +---------------+       +------------------------+
+
+
+RSS based Measured Boot
+-----------------------
+
+Measured Boot is the process of cryptographically measuring (computing the hash
+value of a binary) the code and critical data used at boot time. The
+measurement must be stored in a tamper-resistant way, so the security state
+of the device can be attested later to an external party. RSS provides a runtime
+service which is meant to store measurements and associated metadata alongside.
+
+Data is stored in internal SRAM which is only accessible by the secure runtime
+firmware of RSS. Data is stored in so-called measurement slots. A platform has
+IMPDEF number of measurement slots. The measurement storage follows extend
+semantics. This means that measurements are not stored directly (as it was
+taken) instead they contribute to the current value of the measurement slot.
+The extension implements this logic, where ``||`` stands for concatenation:
+
+.. code-block:: bash
+
+    new_value_of_measurement_slot = Hash(old_value_of_measurement_slot || measurement)
+
+Supported hash algorithms: sha-256, sha-512
+
+Measured Boot API
+^^^^^^^^^^^^^^^^^
+
+Defined here:
+
+- ``include/lib/psa/measured_boot.h``
+
+.. code-block:: c
+
+    psa_status_t
+    rss_measured_boot_extend_measurement(uint8_t        index,
+                                         const uint8_t *signer_id,
+                                         size_t         signer_id_size,
+                                         const uint8_t *version,
+                                         size_t         version_size,
+                                         uint32_t       measurement_algo,
+                                         const uint8_t *sw_type,
+                                         size_t         sw_type_size,
+                                         const uint8_t *measurement_value,
+                                         size_t         measurement_value_size,
+                                         bool           lock_measurement);
+
+Measured Boot Metadata
+^^^^^^^^^^^^^^^^^^^^^^
+
+The following metadata can be stored alongside the measurement:
+
+- ``Signer-id``: Mandatory. The hash of the firmware image signing public key.
+- ``Measurement algorithm``: Optional. The hash algorithm which was used to
+  compute the measurement (e.g.: sha-256, etc.).
+- ``Version info``: Optional. The firmware version info (e.g.: 2.7).
+- ``SW type``: Optional. Short text description (e.g.: BL1, BL2, BL31, etc.)
+
+.. Note::
+    Signer-id and version info is not implemented in TF-A yet.
+
+The caller must specify in which measurement slot to extend a certain
+measurement and metadata. A measurement slot can be extended by multiple
+measurements. The default value is IMPDEF. All measurement slot is cleared at
+reset, there is no other way to clear them. In the reference implementation,
+the measurement slots are initialized to 0. At the first call to extend the
+measurement in a slot, the extend operation uses the default value of the
+measurement slot. All upcoming extend operation on the same slot contributes
+to the previous value of that measurement slot.
+
+The following rules are kept when a slot is extended multiple times:
+
+- ``Signer-id`` must be the same as the previous call(s), otherwise a
+  PSA_ERROR_NOT_PERMITTED error code is returned.
+
+- ``Measurement algorithm``: must be the same as the previous call(s),
+  otherwise, a PSA_ERROR_NOT_PERMITTED error code is returned.
+
+In case of error no further action is taken (slot is not locked). If there is
+a valid data in a sub-sequent call then measurement slot will be extended. The
+rest of the metadata is handled as follows when a measurement slot is extended
+multiple times:
+
+- ``SW type``: Cleared.
+- ``Version info``: Cleared.
+
+.. Note::
+
+    Extending multiple measurements in the same slot leads to some metadata
+    information loss. Since RSS is not constrained on special HW resources to
+    store the measurements and metadata, therefore it is worth considering to
+    store all of them one by one in distinct slots. However, they are one-by-one
+    included in the platform attestation token. So, the number of distinct
+    firmware image measurements has an impact on the size of the attestation
+    token.
+
+The allocation of the measurement slot among RSS, Root and Realm worlds is
+platform dependent. The platform must provide an allocation of the measurement
+slot at build time. An example can be found in
+``tf-a/plat/arm/board/tc/tc_bl1_measured_boot.c``
+Furthermore, the memory, which holds the metadata is also statically allocated
+in RSS memory. Some of the fields have a static value (measurement algorithm),
+and some of the values have a dynamic value (measurement value) which is updated
+by the bootloaders when the firmware image is loaded and measured. The metadata
+structure is defined in
+``include/drivers/measured_boot/rss/rss_measured_boot.h``.
+
+.. code-block:: c
+
+    struct rss_mboot_metadata {
+            unsigned int id;
+            uint8_t slot;
+            uint8_t signer_id[SIGNER_ID_MAX_SIZE];
+            size_t  signer_id_size;
+            uint8_t version[VERSION_MAX_SIZE];
+            size_t  version_size;
+            uint8_t sw_type[SW_TYPE_MAX_SIZE];
+            size_t  sw_type_size;
+            bool    lock_measurement;
+    };
+
+Build time config options
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- ``MEASURED_BOOT``: Enable measured boot. It depends on the platform
+  implementation whether RSS or TPM (or both) backend based measured boot is
+  enabled.
+- ``MBOOT_RSS_HASH_ALG``: Determine the hash algorithm to measure the images.
+  The default value is sha-256.
+
+Measured boot flow
+^^^^^^^^^^^^^^^^^^
+
+.. figure:: ../resources/diagrams/rss_measured_boot_flow.svg
+  :align: center
+
+Sample console log
+^^^^^^^^^^^^^^^^^^
+
+.. code-block:: bash
+
+    INFO:    Measured boot extend measurement:
+    INFO:     - slot        : 6
+    INFO:     - signer_id   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:                   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:     - version     :
+    INFO:     - version_size: 0
+    INFO:     - sw_type     : FW_CONFIG
+    INFO:     - sw_type_size: 10
+    INFO:     - algorithm   : 2000009
+    INFO:     - measurement : aa ea d3 a7 a8 e2 ab 7d 13 a6 cb 34 99 10 b9 a1
+    INFO:                   : 1b 9f a0 52 c5 a8 b1 d7 76 f2 c1 c1 ef ca 1a df
+    INFO:     - locking     : true
+    INFO:    FCONF: Config file with image ID:31 loaded at address = 0x4001010
+    INFO:    Loading image id=24 at address 0x4001300
+    INFO:    Image id=24 loaded: 0x4001300 - 0x400153a
+    INFO:    Measured boot extend measurement:
+    INFO:     - slot        : 7
+    INFO:     - signer_id   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:                   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:     - version     :
+    INFO:     - version_size: 0
+    INFO:     - sw_type     : TB_FW_CONFIG
+    INFO:     - sw_type_size: 13
+    INFO:     - algorithm   : 2000009
+    INFO:     - measurement : 05 b9 dc 98 62 26 a7 1c 2d e5 bb af f0 90 52 28
+    INFO:                   : f2 24 15 8a 3a 56 60 95 d6 51 3a 7a 1a 50 9b b7
+    INFO:     - locking     : true
+    INFO:    FCONF: Config file with image ID:24 loaded at address = 0x4001300
+    INFO:    BL1: Loading BL2
+    INFO:    Loading image id=1 at address 0x404d000
+    INFO:    Image id=1 loaded: 0x404d000 - 0x406412a
+    INFO:    Measured boot extend measurement:
+    INFO:     - slot        : 8
+    INFO:     - signer_id   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:                   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:     - version     :
+    INFO:     - version_size: 0
+    INFO:     - sw_type     : BL_2
+    INFO:     - sw_type_size: 5
+    INFO:     - algorithm   : 2000009
+    INFO:     - measurement : 53 a1 51 75 25 90 fb a1 d9 b8 c8 34 32 3a 01 16
+    INFO:                   : c9 9e 74 91 7d 28 02 56 3f 5c 40 94 37 58 50 68
+    INFO:     - locking     : true
+
+Delegated Attestation
+---------------------
+
+Delegated Attestation Service was mainly developed to support the attestation
+flow on the ``ARM Confidential Compute Architecture`` (ARM CCA) [7]_.
+The detailed description of the delegated attestation service can be found in
+the ``Delegated Attestation Service Integration Guide`` [4]_ document.
+
+In the CCA use case, the Realm Management Monitor (RMM) relies on the delegated
+attestation service of the RSS to get a realm attestation key and the CCA
+platform token. BL31 does not use the service for its own purpose, only calls
+it on behalf of RMM. The access to MHU interface and thereby to RSS is
+restricted to BL31 only. Therefore, RMM does not have direct access, all calls
+need to go through BL31. The RMM dispatcher module of the BL31 is responsible
+for delivering the calls between the two parties.
+
+.. Note::
+     Currently the connection between the RMM dispatcher and the PSA/RSS layer
+     is not yet implemented. RMM dispatcher just returns hard coded data.
+
+Delegated Attestation API
+^^^^^^^^^^^^^^^^^^^^^^^^^
+Defined here:
+
+- ``include/lib/psa/delegated_attestation.h``
+
+.. code-block:: c
+
+    psa_status_t
+    rss_delegated_attest_get_delegated_key(uint8_t   ecc_curve,
+                                           uint32_t  key_bits,
+                                           uint8_t  *key_buf,
+                                           size_t    key_buf_size,
+                                           size_t   *key_size,
+                                           uint32_t  hash_algo);
+
+    psa_status_t
+    rss_delegated_attest_get_token(const uint8_t *dak_pub_hash,
+                                   size_t         dak_pub_hash_size,
+                                   uint8_t       *token_buf,
+                                   size_t         token_buf_size,
+                                   size_t        *token_size);
+
+Attestation flow
+^^^^^^^^^^^^^^^^
+
+.. figure:: ../resources/diagrams/rss_attestation_flow.svg
+  :align: center
+
+Sample attestation token
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Binary format:
+
+.. code-block:: bash
+
+    INFO:    DELEGATED ATTEST TEST START
+    INFO:    Get delegated attestation key start
+    INFO:    Get delegated attest key succeeds, len: 48
+    INFO:    Delegated attest key:
+    INFO:            0d 2a 66 61 d4 89 17 e1 70 c6 73 56 df f4 11 fd
+    INFO:            7d 1f 3b 8a a3 30 3d 70 4c d9 06 c3 c7 ef 29 43
+    INFO:            0f ee b5 e7 56 e0 71 74 1b c4 39 39 fd 85 f6 7b
+    INFO:    Get platform token start
+    INFO:    Get platform token succeeds, len: 1086
+    INFO:    Platform attestation token:
+    INFO:            d2 84 44 a1 01 38 22 a0 59 03 d1 a9 0a 58 20 00
+    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 19
+    INFO:            01 00 58 21 01 cb 8c 79 f7 a0 0a 6c ce 12 66 f8
+    INFO:            64 45 48 42 0e c5 10 bf 84 ee 22 18 b9 8f 11 04
+    INFO:            c7 22 31 9d fb 19 09 5c 58 20 aa aa aa aa aa aa
+    INFO:            aa aa bb bb bb bb bb bb bb bb cc cc cc cc cc cc
+    INFO:            cc cc dd dd dd dd dd dd dd dd 19 09 5b 19 30 00
+    INFO:            19 09 5f 89 a4 05 58 20 bf e6 d8 6f 88 26 f4 ff
+    INFO:            97 fb 96 c4 e6 fb c4 99 3e 46 19 fc 56 5d a2 6a
+    INFO:            df 34 c3 29 48 9a dc 38 04 67 31 2e 36 2e 30 2b
+    INFO:            30 01 64 52 54 5f 30 02 58 20 90 27 f2 46 ab 31
+    INFO:            85 36 46 c4 d7 c6 60 ed 31 0d 3c f0 14 de f0 6c
+    INFO:            24 0b de b6 7a 84 fc 3f 5b b7 a4 05 58 20 b3 60
+    INFO:            ca f5 c9 8c 6b 94 2a 48 82 fa 9d 48 23 ef b1 66
+    INFO:            a9 ef 6a 6e 4a a3 7c 19 19 ed 1f cc c0 49 04 67
+    INFO:            30 2e 30 2e 30 2b 30 01 64 52 54 5f 31 02 58 20
+    INFO:            52 13 15 d4 9d b2 cf 54 e4 99 37 44 40 68 f0 70
+    INFO:            7d 73 64 ae f7 08 14 b0 f7 82 ad c6 17 db a3 91
+    INFO:            a4 05 58 20 bf e6 d8 6f 88 26 f4 ff 97 fb 96 c4
+    INFO:            e6 fb c4 99 3e 46 19 fc 56 5d a2 6a df 34 c3 29
+    INFO:            48 9a dc 38 04 67 31 2e 35 2e 30 2b 30 01 64 52
+    INFO:            54 5f 32 02 58 20 8e 5d 64 7e 6f 6c c6 6f d4 4f
+    INFO:            54 b6 06 e5 47 9a cc 1b f3 7f ce 87 38 49 c5 92
+    INFO:            d8 2f 85 2e 85 42 a4 05 58 20 bf e6 d8 6f 88 26
+    INFO:            f4 ff 97 fb 96 c4 e6 fb c4 99 3e 46 19 fc 56 5d
+    INFO:            a2 6a df 34 c3 29 48 9a dc 38 04 67 31 2e 35 2e
+    INFO:            30 2b 30 01 60 02 58 20 b8 01 65 a7 78 8b c6 59
+    INFO:            42 8d 33 10 85 d1 49 0a dc 9e c3 ee df 85 1b d2
+    INFO:            f0 73 73 6a 0c 07 11 b8 a4 05 58 20 00 00 00 00
+    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 04 60 01 6a
+    INFO:            46 57 5f 43 4f 4e 46 49 47 00 02 58 20 21 9e a0
+    INFO:            13 82 e6 d7 97 5a 11 13 a3 5f 45 39 68 b1 d9 a3
+    INFO:            ea 6a ab 84 23 3b 8c 06 16 98 20 ba b9 a4 05 58
+    INFO:            20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:            00 04 60 01 6d 54 42 5f 46 57 5f 43 4f 4e 46 49
+    INFO:            47 00 02 58 20 41 39 f6 c2 10 84 53 c5 17 ae 9a
+    INFO:            e5 be c1 20 7b cc 24 24 f3 9d 20 a8 fb c7 b3 10
+    INFO:            e3 ee af 1b 05 a4 05 58 20 00 00 00 00 00 00 00
+    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:            00 00 00 00 00 00 00 00 00 04 60 01 65 42 4c 5f
+    INFO:            32 00 02 58 20 5c 96 20 e1 e3 3b 0f 2c eb c1 8e
+    INFO:            1a 02 a6 65 86 dd 34 97 a7 4c 98 13 bf 74 14 45
+    INFO:            2d 30 28 05 c3 a4 05 58 20 00 00 00 00 00 00 00
+    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:            00 00 00 00 00 00 00 00 00 04 60 01 6e 53 45 43
+    INFO:            55 52 45 5f 52 54 5f 45 4c 33 00 02 58 20 f6 fb
+    INFO:            62 99 a5 0c df db 02 0b 72 5b 1c 0b 63 6e 94 ee
+    INFO:            66 50 56 3a 29 9c cb 38 f0 ec 59 99 d4 2e a4 05
+    INFO:            58 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:            00 00 04 60 01 6a 48 57 5f 43 4f 4e 46 49 47 00
+    INFO:            02 58 20 98 5d 87 21 84 06 33 9d c3 1f 91 f5 68
+    INFO:            8d a0 5a f0 d7 7e 20 51 ce 3b f2 a5 c3 05 2e 3c
+    INFO:            8b 52 31 19 01 09 78 1c 68 74 74 70 3a 2f 2f 61
+    INFO:            72 6d 2e 63 6f 6d 2f 43 43 41 2d 53 53 44 2f 31
+    INFO:            2e 30 2e 30 19 09 62 71 6e 6f 74 2d 68 61 73 68
+    INFO:            2d 65 78 74 65 6e 64 65 64 19 09 61 44 ef be ad
+    INFO:            de 19 09 60 77 77 77 77 2e 74 72 75 73 74 65 64
+    INFO:            66 69 72 6d 77 61 72 65 2e 6f 72 67 58 60 29 4e
+    INFO:            4a d3 98 1e 3b 70 9f b6 66 ed 47 33 0e 99 f0 b1
+    INFO:            c3 f2 bc b2 1d b0 ae 90 0c c4 82 ff a2 6f ae 45
+    INFO:            f6 87 09 4a 09 21 77 ec 36 1c 53 b8 a7 9b 8e f7
+    INFO:            27 eb 7a 09 da 6f fb bf cb fd b3 e5 e9 36 91 b1
+    INFO:            92 13 c1 30 16 b4 5c 49 5e c0 c1 b9 01 5c 88 2c
+    INFO:            f8 2f 3e a4 a2 6d e4 9d 31 6a 06 f7 a7 73
+    INFO:    DELEGATED ATTEST TEST END
+
+JSON format:
+
+.. code-block:: JSON
+
+    {
+        "CCA_PLATFORM_CHALLENGE": "b'0000000000000000000000000000000000000000000000000000000000000000'",
+        "CCA_PLATFORM_INSTANCE_ID": "b'01CB8C79F7A00A6CCE1266F8644548420EC510BF84EE2218B98F1104C722319DFB'",
+        "CCA_PLATFORM_IMPLEMENTATION_ID": "b'AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDD'",
+        "CCA_PLATFORM_LIFECYCLE": "secured_3000",
+        "CCA_PLATFORM_SW_COMPONENTS": [
+            {
+                "SIGNER_ID": "b'BFE6D86F8826F4FF97FB96C4E6FBC4993E4619FC565DA26ADF34C329489ADC38'",
+                "SW_COMPONENT_VERSION": "1.6.0+0",
+                "SW_COMPONENT_TYPE": "RT_0",
+                "MEASUREMENT_VALUE": "b'9027F246AB31853646C4D7C660ED310D3CF014DEF06C240BDEB67A84FC3F5BB7'"
+            },
+            {
+                "SIGNER_ID": "b'B360CAF5C98C6B942A4882FA9D4823EFB166A9EF6A6E4AA37C1919ED1FCCC049'",
+                "SW_COMPONENT_VERSION": "0.0.0+0",
+                "SW_COMPONENT_TYPE": "RT_1",
+                "MEASUREMENT_VALUE": "b'521315D49DB2CF54E49937444068F0707D7364AEF70814B0F782ADC617DBA391'"
+            },
+            {
+                "SIGNER_ID": "b'BFE6D86F8826F4FF97FB96C4E6FBC4993E4619FC565DA26ADF34C329489ADC38'",
+                "SW_COMPONENT_VERSION": "1.5.0+0",
+                "SW_COMPONENT_TYPE": "RT_2",
+                "MEASUREMENT_VALUE": "b'8E5D647E6F6CC66FD44F54B606E5479ACC1BF37FCE873849C592D82F852E8542'"
+            },
+            {
+                "SIGNER_ID": "b'BFE6D86F8826F4FF97FB96C4E6FBC4993E4619FC565DA26ADF34C329489ADC38'",
+                "SW_COMPONENT_VERSION": "1.5.0+0",
+                "SW_COMPONENT_TYPE": "",
+                "MEASUREMENT_VALUE": "b'B80165A7788BC659428D331085D1490ADC9EC3EEDF851BD2F073736A0C0711B8'"
+            },
+            {
+                "SIGNER_ID": "b'0000000000000000000000000000000000000000000000000000000000000000'",
+                "SW_COMPONENT_VERSION": "",
+                "SW_COMPONENT_TYPE": "FW_CONFIG\u0000",
+                "MEASUREMENT_VALUE": "b'219EA01382E6D7975A1113A35F453968B1D9A3EA6AAB84233B8C06169820BAB9'"
+            },
+            {
+                "SIGNER_ID": "b'0000000000000000000000000000000000000000000000000000000000000000'",
+                "SW_COMPONENT_VERSION": "",
+                "SW_COMPONENT_TYPE": "TB_FW_CONFIG\u0000",
+                "MEASUREMENT_VALUE": "b'4139F6C2108453C517AE9AE5BEC1207BCC2424F39D20A8FBC7B310E3EEAF1B05'"
+            },
+            {
+                "SIGNER_ID": "b'0000000000000000000000000000000000000000000000000000000000000000'",
+                "SW_COMPONENT_VERSION": "",
+                "SW_COMPONENT_TYPE": "BL_2\u0000",
+                "MEASUREMENT_VALUE": "b'5C9620E1E33B0F2CEBC18E1A02A66586DD3497A74C9813BF7414452D302805C3'"
+            },
+            {
+                "SIGNER_ID": "b'0000000000000000000000000000000000000000000000000000000000000000'",
+                "SW_COMPONENT_VERSION": "",
+                "SW_COMPONENT_TYPE": "SECURE_RT_EL3\u0000",
+                "MEASUREMENT_VALUE": "b'F6FB6299A50CDFDB020B725B1C0B636E94EE6650563A299CCB38F0EC5999D42E'"
+            },
+            {
+                "SIGNER_ID": "b'0000000000000000000000000000000000000000000000000000000000000000'",
+                "SW_COMPONENT_VERSION": "",
+                "SW_COMPONENT_TYPE": "HW_CONFIG\u0000",
+                "MEASUREMENT_VALUE": "b'985D87218406339DC31F91F5688DA05AF0D77E2051CE3BF2A5C3052E3C8B5231'"
+            }
+        ],
+        "CCA_ATTESTATION_PROFILE": "http://arm.com/CCA-SSD/1.0.0",
+        "CCA_PLATFORM_HASH_ALGO_ID": "not-hash-extended",
+        "CCA_PLATFORM_CONFIG": "b'EFBEADDE'",
+        "CCA_PLATFORM_VERIFICATION_SERVICE": "www.trustedfirmware.org"
+    }
+
+References
+----------
+
+.. [1] https://tf-m-user-guide.trustedfirmware.org/platform/arm/rss/readme.html
+.. [2] https://tf-m-user-guide.trustedfirmware.org/platform/arm/rss/rss_comms.html
+.. [3] https://git.trustedfirmware.org/TF-M/tf-m-extras.git/tree/partitions/measured_boot/measured_boot_integration_guide.rst
+.. [4] https://git.trustedfirmware.org/TF-M/tf-m-extras.git/tree/partitions/delegated_attestation/delegated_attest_integration_guide.rst
+.. [5] https://tf-m-user-guide.trustedfirmware.org/platform/arm/rss/rss_key_management.html
+.. [6] https://developer.arm.com/-/media/Files/pdf/PlatformSecurityArchitecture/Architect/DEN0063-PSA_Firmware_Framework-1.0.0-2.pdf?revision=2d1429fa-4b5b-461a-a60e-4ef3d8f7f4b4&hash=3BFD6F3E687F324672F18E5BE9F08EDC48087C93
+.. [7] https://developer.arm.com/documentation/DEN0096/A_a/?lang=en
+
+--------------
+
+*Copyright (c) 2023, Arm Limited. All rights reserved.*
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index d5ded5e..1ee07d9 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -52,8 +52,14 @@
 -  ``BL2U``: This is an optional build option which specifies the path to
    BL2U image. In this case, the BL2U in TF-A will not be built.
 
--  ``BL2_AT_EL3``: This is an optional build option that enables the use of
-   BL2 at EL3 execution level.
+-  ``RESET_TO_BL2``: Boolean option to enable BL2 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 BL2 entrypoint).
+   The default value is 0.
+
+-  ``BL2_RUNS_AT_EL3``: This is an implicit flag to denote that BL2 runs at EL3.
+   While it is explicitly set to 1 when RESET_TO_BL2 is set to 1 it can also be
+   true in a 4-world system where RESET_TO_BL2 is 0.
 
 -  ``BL2_ENABLE_SP_LOAD``: Boolean option to enable loading SP packages from the
    FIP. Automatically enabled if ``SP_LAYOUT_FILE`` is provided.
@@ -61,8 +67,8 @@
 -  ``BL2_IN_XIP_MEM``: In some use-cases BL2 will be stored in eXecute In Place
    (XIP) memory, like BL1. In these use-cases, it is necessary to initialize
    the RW sections in RAM, while leaving the RO sections in place. This option
-   enable this use-case. For now, this option is only supported when BL2_AT_EL3
-   is set to '1'.
+   enable this use-case. For now, this option is only supported
+   when RESET_TO_BL2 is set to '1'.
 
 -  ``BL31``: This is an optional build option which specifies the path to
    BL31 image for the ``fip`` target. In this case, the BL31 in TF-A will not
@@ -224,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.
@@ -255,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
@@ -321,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.
@@ -348,6 +347,13 @@
    values 0 to 2, to align  with the ``FEATURE_DETECTION`` mechanism.
    Default value is ``0``.
 
+-  ``ENABLE_FEAT_TCR2``: Numeric value to set the bit SCR_EL3.ENTCR2 in EL3 to
+   allow access to TCR2_EL2 (extended translation control) from EL2 as
+   well as adding TCR2_EL2 to the EL2 context save/restore operations. Its a
+   mandatory architectural feature and is enabled from v8.9 and upwards. This
+   flag can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   mechanism. Default value is ``0``.
+
 -  ``ENABLE_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.
@@ -377,8 +383,8 @@
 
 -  ``ENABLE_PIE``: Boolean option to enable Position Independent Executable(PIE)
    support within generic code in TF-A. This option is currently only supported
-   in BL2_AT_EL3, BL31, and BL32 (TSP) for AARCH64 binaries, and in BL32
-   (SP_min) for AARCH32. Default is 0.
+   in BL2, BL31, and BL32 (TSP) for AARCH64 binaries, and
+   in BL32 (SP_min) for AARCH32. Default is 0.
 
 -  ``ENABLE_PMF``: Boolean option to enable support for optional Performance
    Measurement Framework(PMF). Default is 0.
@@ -400,14 +406,15 @@
    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
    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_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
@@ -415,12 +422,13 @@
    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.
 
--  ``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
@@ -429,9 +437,10 @@
    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.
+   1. This flag can take the values 0 to 2, to align with the ``FEATURE_DETECTION``
+   mechanism. 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.
 
 -  ``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
@@ -670,7 +679,7 @@
    the measurements and recording them as per `PSA DRTM specification`_. For
    platforms which use BL2 to load/authenticate BL31 ``TRUSTED_BOARD_BOOT`` can
    be used and for the platforms which use ``RESET_TO_BL31`` platform owners
-   should have mechanism to authenticate BL31.
+   should have mechanism to authenticate BL31. This is an experimental feature.
 
    This option defaults to 0.
 
@@ -727,6 +736,9 @@
    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
    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
@@ -1065,10 +1077,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),
@@ -1199,7 +1212,7 @@
 
 --------------
 
-*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2023, Arm Limited. All rights reserved.*
 
 .. _DEN0115: https://developer.arm.com/docs/den0115/latest
 .. _PSA FW update specification: https://developer.arm.com/documentation/den0118/a/
diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst
index 80b72e5..8d6a2bf 100644
--- a/docs/getting_started/porting-guide.rst
+++ b/docs/getting_started/porting-guide.rst
@@ -14,10 +14,17 @@
 
 The platform-specific functions and variables are declared in
 ``include/plat/common/platform.h``. The firmware provides a default
-implementation of variables and functions to fulfill the optional requirements.
-These implementations are all weakly defined; they are provided to ease the
-porting effort. Each platform port can override them with its own implementation
-if the default implementation is inadequate.
+implementation of variables and functions to fulfill the optional requirements
+in order to ease the porting effort. Each platform port can use them as is or
+provide their own implementation if the default implementation is inadequate.
+
+   .. note::
+
+      TF-A historically provided default implementations of platform interfaces
+      as *weak* functions. This practice is now discouraged and new platform
+      interfaces as they get introduced in the code base should be *strongly*
+      defined. We intend to convert existing weak functions over time. Until
+      then, you will find references to *weak* functions in this document.
 
 Some modifications are common to all Boot Loader (BL) stages. Section 2
 discusses these in detail. The subsequent sections discuss the remaining
@@ -66,22 +73,22 @@
 If the build option ``USE_COHERENT_MEM`` is enabled, each platform can allocate a
 block of identity mapped secure memory with Device-nGnRE attributes aligned to
 page boundary (4K) for each BL stage. All sections which allocate coherent
-memory are grouped under ``coherent_ram``. For ex: Bakery locks are placed in a
-section identified by name ``bakery_lock`` inside ``coherent_ram`` so that its
+memory are grouped under ``.coherent_ram``. For ex: Bakery locks are placed in a
+section identified by name ``.bakery_lock`` inside ``.coherent_ram`` so that its
 possible for the firmware to place variables in it using the following C code
 directive:
 
 ::
 
-    __section("bakery_lock")
+    __section(".bakery_lock")
 
 Or alternatively the following assembler code directive:
 
 ::
 
-    .section bakery_lock
+    .section .bakery_lock
 
-The ``coherent_ram`` section is a sum of all sections like ``bakery_lock`` which are
+The ``.coherent_ram`` section is a sum of all sections like ``.bakery_lock`` which are
 used to allocate any data structures that are accessed both when a CPU is
 executing with its MMU and caches enabled, and when it's running with its MMU
 and caches disabled. Examples are given below.
@@ -531,6 +538,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:
 
@@ -2411,7 +2427,7 @@
 accommodate all the bakery locks.
 
 If this constant is not defined when ``USE_COHERENT_MEM = 0``, the linker
-calculates the size of the ``bakery_lock`` input section, aligns it to the
+calculates the size of the ``.bakery_lock`` input section, aligns it to the
 nearest ``CACHE_WRITEBACK_GRANULE``, multiplies it with ``PLATFORM_CORE_COUNT``
 and stores the result in a linker symbol. This constant prevents a platform
 from relying on the linker and provide a more efficient mechanism for
@@ -2803,6 +2819,10 @@
 data, for example in DRAM. The Distributor can then be powered down using an
 implementation-defined sequence.
 
+If the build option ``PSCI_OS_INIT_MODE`` is enabled, the generic code expects
+the platform to return PSCI_E_SUCCESS on success, or either PSCI_E_DENIED or
+PSCI_E_INVALID_PARAMS as appropriate for any invalid requests.
+
 plat_psci_ops.pwr_domain_pwr_down_wfi()
 .......................................
 
@@ -3204,9 +3224,20 @@
 
 Common helper functions
 -----------------------
+Function : elx_panic()
+~~~~~~~~~~~~~~~~~~~~~~
 
-Function : do_panic()
-~~~~~~~~~~~~~~~~~~~~~
+::
+
+    Argument : void
+    Return   : void
+
+This API is called from assembly files when reporting a critical failure
+that has occured in lower EL and is been trapped in EL3. This call
+**must not** return.
+
+Function : el3_panic()
+~~~~~~~~~~~~~~~~~~~~~~
 
 ::
 
@@ -3214,9 +3245,8 @@
     Return   : void
 
 This API is called from assembly files when encountering a critical failure that
-cannot be recovered from. It also invokes elx_panic() which allows to report a
-crash from lower exception level. This function assumes that it is invoked from
-a C runtime environment i.e. valid stack exists. This call **must not** return.
+cannot be recovered from. This function assumes that it is invoked from a C
+runtime environment i.e. valid stack exists. This call **must not** return.
 
 Function : panic()
 ~~~~~~~~~~~~~~~~~~
@@ -3228,7 +3258,7 @@
 
 This API called from C files when encountering a critical failure that cannot
 be recovered from. This function in turn prints backtrace (if enabled) and calls
-do_panic(). This call **must not** return.
+el3_panic(). This call **must not** return.
 
 Crash Reporting mechanism (in BL31)
 -----------------------------------
@@ -3540,7 +3570,7 @@
 
 --------------
 
-*Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.*
+*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
 .. _Arm Generic Interrupt Controller version 2.0 (GICv2): http://infocenter.arm.com/help/topic/com.arm.doc.ihi0048b/index.html
diff --git a/docs/getting_started/prerequisites.rst b/docs/getting_started/prerequisites.rst
index 3723294..5b49d2e 100644
--- a/docs/getting_started/prerequisites.rst
+++ b/docs/getting_started/prerequisites.rst
@@ -31,12 +31,18 @@
    You will need the targets ``arm-none-eabi`` and ``aarch64-none-elf`` for
    AArch32 and AArch64 builds respectively.
 
-- Clang >= 14.0.0
-- Arm Compiler >= 6.18
+- Clang == 14.0.0
+- Arm Compiler == 6.18
 
 In addition, a native compiler is required to build the supporting tools.
 
 .. note::
+   Versions greater than the ones specified are likely but not guaranteed to
+   work. This is predominantly because TF-A carries its own copy of compiler-rt,
+   which may be older than the version expected by the compiler. Fixes and bug
+   reports are always welcome.
+
+.. note::
    The software has also been built on Windows 7 Enterprise SP1, using CMD.EXE,
    Cygwin, and Msys (MinGW) shells, using version 5.3.1 of the GNU toolchain.
 
diff --git a/docs/perf/psci-performance-juno.rst b/docs/perf/psci-performance-juno.rst
index eab3e4d..7418669 100644
--- a/docs/perf/psci-performance-juno.rst
+++ b/docs/perf/psci-performance-juno.rst
@@ -286,7 +286,7 @@
 
 --------------
 
-*Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2019-2023, Arm Limited and Contributors. All rights reserved.*
 
-.. _Juno R1 platform: https://static.docs.arm.com/100122/0100/arm_versatile_express_juno_r1_development_platform_(v2m_juno_r1)_technical_reference_manual_100122_0100_05_en.pdf
+.. _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
diff --git a/docs/plat/arm/corstone1000/index.rst b/docs/plat/arm/corstone1000/index.rst
index b889b7f..dc626e1 100644
--- a/docs/plat/arm/corstone1000/index.rst
+++ b/docs/plat/arm/corstone1000/index.rst
@@ -47,7 +47,7 @@
       ARCH=aarch64 \
       TARGET_PLATFORM=<fpga or fvp> \
       ENABLE_PIE=1 \
-      BL2_AT_EL3=1 \
+      RESET_TO_BL2=1 \
       CREATE_KEYS=1 \
       GENERATE_COT=1 \
       TRUSTED_BOARD_BOOT=1 \
@@ -58,4 +58,4 @@
       BL33=<path to u-boot binary> \
       bl2
 
-*Copyright (c) 2021, Arm Limited. All rights reserved.*
+*Copyright (c) 2021-2023, Arm Limited. All rights reserved.*
diff --git a/docs/plat/arm/juno/index.rst b/docs/plat/arm/juno/index.rst
index 91e681f..d741d58 100644
--- a/docs/plat/arm/juno/index.rst
+++ b/docs/plat/arm/juno/index.rst
@@ -241,7 +241,7 @@
 
 --------------
 
-*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2023, Arm Limited. All rights reserved.*
 
 .. _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
@@ -250,4 +250,3 @@
 .. _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
-.. _Juno Arm Development Platform: http://www.arm.com/products/tools/development-boards/versatile-express/juno-arm-development-platform.php
diff --git a/docs/plat/qemu.rst b/docs/plat/qemu.rst
index 6986326..f2a39e9 100644
--- a/docs/plat/qemu.rst
+++ b/docs/plat/qemu.rst
@@ -44,7 +44,7 @@
 Then, you will get ``Build/ArmVirtQemuKernel-AARCH64/DEBUG_GCC5/FV/QEMU_EFI.fd``
 
 Please note you do not need to use GCC 5 in spite of the environment variable
-``GCC5_AARCH64_PREFIX``
+``GCC5_AARCH64_PREFIX``.
 
 The rootfs can be built by using Buildroot as follows:
 
@@ -88,54 +88,73 @@
         -initrd rootfs.cpio.gz -smp 2 -m 1024 -bios bl1.bin   \
         -d unimp -semihosting-config enable,target=native
 
-Booting via flash based firmwares
----------------------------------
+Booting via flash based firmware
+--------------------------------
 
-Boot firmwares are loaded via secure FLASH0 device so ``bl1.bin`` and
-``fip.bin`` should be concatenated to create a ``flash.bin`` that is flashed
-onto secure FLASH0.
+An alternate approach to deploy a full system stack on QEMU is to load the
+firmware via a secure flash device.  This involves concatenating ``bl1.bin`` and
+``fip.bin`` to create a boot ROM that is flashed onto secure FLASH0 with the
+``-bios`` option.
 
--  ``bl32.bin`` -> BL32 (``tee-header_v2.bin``)
--  ``bl32_extra1.bin`` -> BL32 Extra1 (``tee-pager_v2.bin``)
--  ``bl32_extra2.bin`` -> BL32 Extra2 (``tee-pageable_v2.bin``)
--  ``bl33.bin`` -> BL33 (``QEMU_EFI.fd``)
+For example, to test the following firmware stack:
+
+
+-  BL32 - ``bl32.bin`` -> ``tee-header_v2.bin``
+-  BL32 Extra1 - ``bl32_extra1.bin`` -> ``tee-pager_v2.bin``
+-  BL32 Extra2 - ``bl32_extra2.bin`` -> ``tee-pageable_v2.bin``
+-  BL33 - ``bl33.bin`` -> ``QEMU_EFI.fd`` (EDK II)
 -  ``Image`` -> linux/arch/arm64/boot/Image
 
-To build:
 
-.. code:: shell
+1.  Compile TF-A
 
-    make CROSS_COMPILE=aarch64-linux-gnu- PLAT=qemu BL32=bl32.bin \
-        BL32_EXTRA1=bl32_extra1.bin BL32_EXTRA2=bl32_extra2.bin \
-        BL33=bl33.bin BL32_RAM_LOCATION=tdram SPD=opteed all fip
+  .. code:: shell
 
-To build with TBBR enabled, BL31 and BL32 encrypted with test key:
+      make CROSS_COMPILE=aarch64-linux-gnu- PLAT=qemu BL32=bl32.bin \
+          BL32_EXTRA1=bl32_extra1.bin BL32_EXTRA2=bl32_extra2.bin \
+          BL33=bl33.bin BL32_RAM_LOCATION=tdram SPD=opteed all fip
 
-.. code:: shell
+  Or, alternatively, to build with TBBR enabled, as well as, BL31 and BL32 encrypted with
+  test key:
 
-    make CROSS_COMPILE=aarch64-linux-gnu- PLAT=qemu BL32=bl32.bin \
-        BL32_EXTRA1=bl32_extra1.bin BL32_EXTRA2=bl32_extra2.bin \
-        BL33=bl33.bin BL32_RAM_LOCATION=tdram SPD=opteed all fip \
-        MBEDTLS_DIR=<path-to-mbedtls-repo> TRUSTED_BOARD_BOOT=1 \
-        GENERATE_COT=1 DECRYPTION_SUPPORT=aes_gcm FW_ENC_STATUS=0 \
-        ENCRYPT_BL31=1 ENCRYPT_BL32=1
+  .. code:: shell
 
-To build flash.bin:
+      make CROSS_COMPILE=aarch64-linux-gnu- PLAT=qemu BL32=bl32.bin \
+          BL32_EXTRA1=bl32_extra1.bin BL32_EXTRA2=bl32_extra2.bin \
+          BL33=bl33.bin BL32_RAM_LOCATION=tdram SPD=opteed all fip \
+          MBEDTLS_DIR=<path-to-mbedtls-repo> TRUSTED_BOARD_BOOT=1 \
+          GENERATE_COT=1 DECRYPTION_SUPPORT=aes_gcm FW_ENC_STATUS=0 \
+          ENCRYPT_BL31=1 ENCRYPT_BL32=1
 
-.. code:: shell
+2.  Concatenate ``bl1.bin`` and ``fip.bin`` to create the boot ROM
 
-    dd if=build/qemu/release/bl1.bin of=flash.bin bs=4096 conv=notrunc
-    dd if=build/qemu/release/fip.bin of=flash.bin seek=64 bs=4096 conv=notrunc
+  .. code:: shell
 
-To start (QEMU v5.0.0):
+      dd if=build/qemu/release/bl1.bin of=flash.bin bs=4096 conv=notrunc
+      dd if=build/qemu/release/fip.bin of=flash.bin seek=64 bs=4096 conv=notrunc
 
-.. code:: shell
+3.  Launch QEMU
 
-    qemu-system-aarch64 -nographic -machine virt,secure=on -cpu cortex-a57  \
-        -kernel Image -no-acpi                     \
-        -append 'console=ttyAMA0,38400 keep_bootcon'  \
-        -initrd rootfs.cpio.gz -smp 2 -m 1024 -bios flash.bin   \
-        -d unimp
+  .. code:: shell
+
+      qemu-system-aarch64 -nographic -machine virt,secure=on
+          -cpu cortex-a57  -kernel Image   \
+          -append 'console=ttyAMA0,38400 keep_bootcon'  \
+          -initrd rootfs.cpio.gz -smp 2 -m 1024 -bios flash.bin   \
+          -d unimp
+
+The ``-bios`` option abstracts the loading of raw bare metal binaries into flash
+or ROM memory. QEMU loads the binary into the region corresponding to
+the hardware's entrypoint, from which the binary is executed upon a platform
+"reset". In addition to this, it places the information about the kernel
+provided with option ``-kernel``, and the RamDisk provided with ``-initrd``,
+into the firmware configuration ``fw_cfg``. In this setup, EDK II is responsible
+for extracting and launching these from ``fw_cfg``.
+
+.. note::
+    QEMU may be launched with or without ACPI (``-acpi``/``-no-acpi``). In
+    either case, ensure that the kernel build options are aligned with the
+    parameters passed to QEMU.
 
 Running QEMU in OpenCI
 -----------------------
diff --git a/docs/plat/stm32mp1.rst b/docs/plat/stm32mp1.rst
index 23ea25a..a983606 100644
--- a/docs/plat/stm32mp1.rst
+++ b/docs/plat/stm32mp1.rst
@@ -107,11 +107,11 @@
 Boot sequence
 ~~~~~~~~~~~~~
 
-ROM code -> BL2 (compiled with BL2_AT_EL3) -> BL32 (SP_min) -> BL33 (U-Boot)
+ROM code -> BL2(compiled with RESET_TO_BL2) -> BL32(SP_min)-> BL33(U-Boot)
 
 or if Op-TEE is used:
 
-ROM code -> BL2 (compiled with BL2_AT_EL3) -> OP-TEE -> BL33 (U-Boot)
+ROM code -> BL2 (compiled with RESET_TO_BL2) -> OP-TEE -> BL33 (U-Boot)
 
 
 Build Instructions
diff --git a/docs/plat/xilinx-versal-net.rst b/docs/plat/xilinx-versal-net.rst
index 5d2e663..5d04639 100644
--- a/docs/plat/xilinx-versal-net.rst
+++ b/docs/plat/xilinx-versal-net.rst
@@ -14,6 +14,11 @@
 make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal_net bl31
 ```
 
+To build TF-A for JTAG DCC console:
+```bash
+make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal_net VERSAL_NET_CONSOLE=dcc bl31
+```
+
 Xilinx Versal NET platform specific build options
 -------------------------------------------------
 
@@ -23,8 +28,9 @@
 *   `VERSAL_NET_BL32_MEM_SIZE`: Specifies the size of the memory region of the bl32 binary.
 
 *   `VERSAL_NET_CONSOLE`: Select the console driver. Options:
-    -   `pl011`, `pl011_0`: ARM pl011 UART 0
+    -   `pl011`, `pl011_0`: ARM pl011 UART 0 (default)
     -   `pl011_1`         : ARM pl011 UART 1
+    -   `dcc`             : JTAG Debug Communication Channel(DCC)
 
 *   `TFA_NO_PM` : Platform Management support.
     -    0 : Enable Platform Management (Default)
diff --git a/docs/plat/xilinx-zynqmp.rst b/docs/plat/xilinx-zynqmp.rst
index af1cb22..81f4fbe 100644
--- a/docs/plat/xilinx-zynqmp.rst
+++ b/docs/plat/xilinx-zynqmp.rst
@@ -31,6 +31,7 @@
 ZynqMP platform specific build options
 --------------------------------------
 
+-  ``XILINX_OF_BOARD_DTB_ADDR`` : Specifies the base address of Device tree.
 -  ``ZYNQMP_ATF_MEM_BASE``: Specifies the base address of the bl31 binary.
 -  ``ZYNQMP_ATF_MEM_SIZE``: Specifies the size of the memory region of the bl31 binary.
 -  ``ZYNQMP_BL32_MEM_BASE``: Specifies the base address of the bl32 binary.
@@ -41,6 +42,53 @@
    -  ``cadence``, ``cadence0``: Cadence UART 0
    -  ``cadence1`` : Cadence UART 1
 
+ZynqMP Debug behavior
+---------------------
+
+With DEBUG=1, TF-A for ZynqMP uses DDR memory range instead of OCM memory range
+due to size constraints.
+For DEBUG=1 configuration for ZynqMP the BL31_BASE is set to the DDR location
+of 0x1000 and BL31_LIMIT is set to DDR location of 0x7FFFF. By default the
+above memory range will NOT be reserved in device tree.
+
+To reserve the above memory range in device tree, the device tree base address
+must be provided during build as,
+
+make CROSS_COMPILE=aarch64-none-elf- PLAT=zynqmp RESET_TO_BL31=1 DEBUG=1 \
+       XILINX_OF_BOARD_DTB_ADDR=<DTB address> bl31
+
+The default DTB base address for ZynqMP platform is 0x100000. This default value
+is not set in the code and to use this default address, user still needs to
+provide it through the build command as above.
+
+If the user wants to move the bl31 to a different DDR location, user can provide
+the DDR address location using the build time parameters ZYNQMP_ATF_MEM_BASE and
+ZYNQMP_ATF_MEM_SIZE.
+
+The DDR address must be reserved in the DTB by the user, either by manually
+adding the reserved memory node, in the device tree, with the required address
+range OR let TF-A modify the device tree on the run.
+
+To let TF-A access and modify the device tree, the DTB address must be provided
+to the build command as follows,
+
+make CROSS_COMPILE=aarch64-none-elf- PLAT=zynqmp RESET_TO_BL31=1 DEBUG=1 \
+	ZYNQMP_ATF_MEM_BASE=<DDR address> ZYNQMP_ATF_MEM_SIZE=<size> \
+	XILINX_OF_BOARD_DTB_ADDR=<DTB address> bl31
+
+DDR Address Range Usage
+-----------------------
+
+When FSBL runs on RPU and TF-A is to be placed in DDR address range,
+then the user needs to make sure that the DDR address is beyond 256KB.
+In the RPU view, the first 256 KB is TCM memory.
+
+For this use case, with the minimum base address in DDR for TF-A,
+the build command example is;
+
+make CROSS_COMPILE=aarch64-none-elf- PLAT=zynqmp RESET_TO_BL31=1 DEBUG=1 \
+	ZYNQMP_ATF_MEM_BASE=0x40000 ZYNQMP_ATF_MEM_SIZE=<size>
+
 FSBL->TF-A Parameter Passing
 ----------------------------
 
@@ -71,3 +119,40 @@
 
 The 4 leaf power domains represent the individual A53 cores, while resources
 common to the cluster are grouped in the power domain on the top.
+
+CUSTOM SIP service support
+--------------------------
+
+- Dedicated SMC FID ZYNQMP_SIP_SVC_CUSTOM(0x82002000)(32-bit)/
+  (0xC2002000)(64-bit) to be used by a custom package for
+  providing CUSTOM SIP service.
+
+- by default platform provides bare minimum definition for
+  custom_smc_handler in this service.
+
+- to use this service, custom package should implement their
+  smc handler with the name custom_smc_handler. once custom package is
+  included in TF-A build, their definition of custom_smc_handler is
+  enabled.
+
+Custom package makefile fragment inclusion in TF-A build
+--------------------------------------------------------
+
+- custom package is not directly part of TF-A source.
+
+- <CUSTOM_PKG_PATH> is the location at which user clones a
+  custom package locally.
+
+- custom package needs to implement makefile fragment named
+  custom_pkg.mk so as to get included in TF-A build.
+
+- custom_pkg.mk specify all the rules to include custom package
+  specific header files, dependent libs, source files that are
+  supposed to be included in TF-A build.
+
+- when <CUSTOM_PKG_PATH> is specified in TF-A build command,
+  custom_pkg.mk is included from <CUSTOM_PKG_PATH> in TF-A build.
+
+- TF-A build command:
+  make CROSS_COMPILE=aarch64-none-elf- PLAT=zynqmp RESET_TO_BL31=1
+  bl31 CUSTOM_PKG_PATH=<...>
diff --git a/docs/process/coding-guidelines.rst b/docs/process/coding-guidelines.rst
index 26c272d..13fb7cb 100644
--- a/docs/process/coding-guidelines.rst
+++ b/docs/process/coding-guidelines.rst
@@ -461,9 +461,56 @@
   - Low-level code where specific system-level instructions must be used, such
     as cache maintenance operations.
 
+Do not use weak functions
+-------------------------
+
+.. note::
+
+   The following guideline applies more strongly to common, platform-independent
+   code. For plaform code (under ``plat/`` directory), it is up to each platform
+   maintainer to decide whether this should be striclty enforced or not.
+
+The use of weak functions is highly discouraged in the TF-A codebase. Newly
+introduced platform interfaces should be strongly defined, wherever possible. In
+the rare cases where this is not possible or where weak functions appear as the
+best tool to solve the problem at hand, this should be discussed with the
+project's maintainers and justified in the code.
+
+For the purpose of providing a default implementation of a platform interface,
+an alternative to weak functions is to provide a strongly-defined implementation
+under the ``plat/common/`` directory. Then platforms have two options to pull
+in this implementation:
+
+  - They can include the source file through the platform's makefile.  Note that
+    this method is suitable only if the platform wants *all* default
+    implementations defined in this file, else either the file should be
+    refactored or the next approach should be used.
+
+  - They access the platform interface through a **constant** function pointer.
+
+In both cases, what matters is that platforms include the default implementation
+as a conscious decision.
+
+.. rubric:: Rationale
+
+Weak functions may sound useful to simplify the initial porting effort to a
+new platform, such that one can quickly get the firmware to build and link,
+without implementing all platform interfaces from the beginning. For this
+reason, the TF-A project used to make heavy use of weak functions and there
+are still many outstanding usages of them across the code base today. We
+intend to convert them to strongly-defined functions over time.
+
+However, weak functions also have major drawbacks, which we consider
+outweighing their benefits. They can make it hard to identify which
+implementation gets built into the firmware, especially when using multiple
+levels of "weakness". This has resulted in bugs in the past.
+
+Weak functions are also forbidden by MISRA coding guidelines, which TF-A aims to
+comply with.
+
 --------------
 
-*Copyright (c) 2020, 2022, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2020 - 2023, Arm Limited and Contributors. All rights reserved.*
 
 .. _`Linux master tree`: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/
 .. _`Procedure Call Standard for the Arm Architecture`: https://github.com/ARM-software/abi-aa/blob/main/aapcs32/aapcs32.rst
diff --git a/docs/process/coding-style.rst b/docs/process/coding-style.rst
index be13b14..483780b 100644
--- a/docs/process/coding-style.rst
+++ b/docs/process/coding-style.rst
@@ -386,6 +386,27 @@
 
   #include "a_header.h"
 
+The preferred approach for third-party headers is to include them immediately
+following system header files like in the example below, where the
+``version.h`` header from the Mbed TLS library immediately follows the
+``stddef.h`` system header.
+
+.. code:: c
+
+  /* system header files */
+  #include <stddef.h>
+
+  /* Mbed TLS header files */
+  #include <mbedtls/version.h>
+
+  /* project header files */
+  #include <drivers/auth/auth_mod.h>
+  #include <drivers/auth/tbbr_cot_common.h>
+
+  /* platform header files */
+  #include <platform_def.h>
+
+
 Include statement variants
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -463,7 +484,7 @@
 
 --------------
 
-*Copyright (c) 2020, Arm Limited. All rights reserved.*
+*Copyright (c) 2020-2023, Arm Limited. All rights reserved.*
 
 .. _`Linux kernel coding style`: https://www.kernel.org/doc/html/latest/process/coding-style.html
 .. _`MISRA C:2012 Guidelines`: https://www.misra.org.uk/Activities/MISRAC/tabid/160/Default.aspx
diff --git a/docs/process/security.rst b/docs/process/security.rst
index f1e7a9d..c6429ad 100644
--- a/docs/process/security.rst
+++ b/docs/process/security.rst
@@ -67,6 +67,12 @@
 |  |TFV-8|  | Not saving x0 to x3 registers can leak information from one      |
 |           | Normal World SMC client to another                               |
 +-----------+------------------------------------------------------------------+
+|  |TFV-9|  | Trusted Firmware-A exposure to speculative processor             |
+|           | vulnerabilities with branch prediction target reuse              |
++-----------+------------------------------------------------------------------+
+|  |TFV-10| | Incorrect validation of X.509 certificate extensions can result  |
+|           | in an out-of-bounds read                                         |
++-----------+------------------------------------------------------------------+
 
 .. _issue tracker: https://developer.trustedfirmware.org/project/board/1/
 .. _mailing list: https://lists.trustedfirmware.org/mailman3/lists/tf-a.lists.trustedfirmware.org/
@@ -79,6 +85,8 @@
 .. |TFV-6| replace:: :ref:`Advisory TFV-6 (CVE-2017-5753, CVE-2017-5715, CVE-2017-5754)`
 .. |TFV-7| replace:: :ref:`Advisory TFV-7 (CVE-2018-3639)`
 .. |TFV-8| replace:: :ref:`Advisory TFV-8 (CVE-2018-19440)`
+.. |TFV-9| replace:: :ref:`Advisory TFV-9 (CVE-2022-23960)`
+.. |TFV-10| replace:: :ref:`Advisory TFV-10 (CVE-2022-47630)`
 
 .. _TrustedFirmware.org security incident process: https://developer.trustedfirmware.org/w/collaboration/security_center/
 
diff --git a/docs/requirements.in b/docs/requirements.in
index 5d771e5..ae20b7d 100644
--- a/docs/requirements.in
+++ b/docs/requirements.in
@@ -1,5 +1,5 @@
-myst-parser==0.15.2
+myst-parser==0.18.1
 pip-tools==6.4.0
-sphinx==4.2.0
-sphinx-rtd-theme==1.0.0
-sphinxcontrib-plantuml==0.22
+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
index 03b1189..1ed78d0 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -1,71 +1,71 @@
 #
-# This file is autogenerated by pip-compile with python 3.8
-# To update, run:
+# This file is autogenerated by pip-compile with Python 3.8
+# by the following command:
 #
-#    pip-compile
+#    pip-compile docs/requirements.in
 #
 alabaster==0.7.12
     # via sphinx
-attrs==21.2.0
-    # via markdown-it-py
-babel==2.9.1
+babel==2.11.0
     # via sphinx
-certifi==2021.5.30
+certifi==2022.12.7
     # via requests
-charset-normalizer==2.0.4
+charset-normalizer==2.1.1
     # via requests
-click==8.0.1
+click==8.1.3
     # via pip-tools
-docutils==0.16
+docutils==0.17.1
     # via
     #   myst-parser
     #   sphinx
     #   sphinx-rtd-theme
-idna==3.2
+idna==3.4
     # via requests
-imagesize==1.2.0
+imagesize==1.4.1
+    # via sphinx
+importlib-metadata==6.0.0
     # via sphinx
-jinja2==3.0.1
+jinja2==3.1.2
     # via
     #   myst-parser
     #   sphinx
-markdown-it-py==1.1.0
+markdown-it-py==2.1.0
     # via
     #   mdit-py-plugins
     #   myst-parser
-markupsafe==2.0.1
+markupsafe==2.1.1
     # via jinja2
-mdit-py-plugins==0.2.8
+mdit-py-plugins==0.3.3
     # via myst-parser
-myst-parser==0.15.2
-    # via -r requirements.in
-packaging==21.0
+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.11.0
+pep517==0.13.0
     # via pip-tools
 pip-tools==6.4.0
-    # via -r requirements.in
-pygments==2.10.0
+    # via -r docs/requirements.in
+pygments==2.14.0
     # via sphinx
-pyparsing==2.4.7
-    # via packaging
-pytz==2021.1
+pytz==2022.7
     # via babel
 pyyaml==6.0
     # via myst-parser
-requests==2.26.0
+requests==2.28.1
     # via sphinx
-snowballstemmer==2.1.0
+snowballstemmer==2.2.0
     # via sphinx
-sphinx==4.2.0
+sphinx==5.3.0
     # via
-    #   -r requirements.in
+    #   -r docs/requirements.in
     #   myst-parser
     #   sphinx-rtd-theme
     #   sphinxcontrib-plantuml
-sphinx-rtd-theme==1.0.0
-    # via -r requirements.in
-sphinxcontrib-applehelp==1.0.2
+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
@@ -73,18 +73,22 @@
     # via sphinx
 sphinxcontrib-jsmath==1.0.1
     # via sphinx
-sphinxcontrib-plantuml==0.22
-    # via -r requirements.in
+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==1.2.1
+tomli==2.0.1
     # via pep517
-urllib3==1.26.6
+typing-extensions==4.4.0
+    # via myst-parser
+urllib3==1.26.13
     # via requests
-wheel==0.37.0
+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
diff --git a/docs/resources/diagrams/plantuml/rss_attestation_flow.puml b/docs/resources/diagrams/plantuml/rss_attestation_flow.puml
new file mode 100644
index 0000000..aca5c01
--- /dev/null
+++ b/docs/resources/diagrams/plantuml/rss_attestation_flow.puml
@@ -0,0 +1,39 @@
+@startuml
+skinparam ParticipantPadding 10
+skinparam BoxPadding 10
+box AP
+participant RMM
+participant BL31
+endbox
+box RSS
+participant DelegAttest
+participant InitAttest
+participant MeasuredBoot
+participant Crypto
+endbox
+
+== RMM Boot phase ==
+
+RMM -> BL31: get_realm_key(\n\t**hash_algo**, ...)
+BL31 -> DelegAttest: get_delegated_key
+DelegAttest -> MeasuredBoot: read_measurement
+Rnote over DelegAttest: Compute input\n\ for key derivation\n\ (hash of measurements)
+DelegAttest -> Crypto: derive_key
+Rnote over DelegAttest: Compute public key\n\ hash with **hash_algo**.
+Rnote over Crypto: Seed is provisioned\n\ in the factory.
+DelegAttest --> BL31: get_delegated_key
+BL31 --> RMM: get_realm_key
+Rnote over RMM: Only private key\n\ is returned. Public\n\ key and its hash\n\ must be computed.\n\
+Public key is included\n\ in the realm token.\n\ Its hash is the input\n\ for get_platform_token
+RMM -> BL31: get_platform_token(\n\t**pub_key_hash**, ...)
+BL31 -> DelegAttest: get_delegated_token
+Rnote over DelegAttest: Check **pub_key_hash**\n\ against derived key.
+DelegAttest -> InitAttest: get_initial_token
+Rnote over InitAttest: Create the token including\n\ the **pub_key_hash** as the\n\ challenge claim
+InitAttest -> MeasuredBoot: read_measurement
+InitAttest -> Crypto: sign_token
+InitAttest --> DelegAttest:  get_initial_token
+DelegAttest --> BL31: get_delegated_token
+BL31 --> RMM: get_platform_token
+Rnote over RMM: Platform token is\n\ cached. It is not\n\ changing within\n\ a power cycle.
+@enduml
diff --git a/docs/resources/diagrams/plantuml/rss_measured_boot_flow.puml b/docs/resources/diagrams/plantuml/rss_measured_boot_flow.puml
new file mode 100644
index 0000000..1aeb1a9
--- /dev/null
+++ b/docs/resources/diagrams/plantuml/rss_measured_boot_flow.puml
@@ -0,0 +1,79 @@
+@startuml
+skinparam ParticipantPadding 10
+skinparam BoxPadding 10
+box RSS
+participant RSS_BL1_1
+participant RSS_BL1_2
+participant RSS_BL2
+participant RSS_S
+endbox
+box SCP
+participant SCP_BL1
+endbox
+box AP
+participant AP_BL1
+participant AP_BL2
+participant AP_BL31
+endbox
+
+== RSS Boot phase ==
+-> RSS_BL1_1: Reset
+Rnote over RSS_BL1_1: ROM code, XIP
+Rnote over RSS_BL1_2: OTP code, XIP
+Rnote over RSS_BL2, AP_BL31: Stored in flash, loaded and executed in RAM
+activate RSS_BL1_1 #Green
+RSS_BL1_1 -->> RSS_BL1_2: Validate, measure
+Rnote over RSS_BL1_1: BL1_2 measurement\n\ saved to a shared buffer
+RSS_BL1_1 -> RSS_BL1_2: Pass execution
+deactivate RSS_BL1_1
+activate RSS_BL1_2 #Green
+RSS_BL1_2 -->> RSS_BL2: Validate, measure, load
+Rnote over RSS_BL1_2: RSS_BL2 measurement\n\ saved to a shared buffer
+RSS_BL1_2 -> RSS_BL2: Pass execution
+deactivate RSS_BL1_2
+activate RSS_BL2 #Green
+RSS_BL2 -->> RSS_S: Validate, measure, load
+RSS_BL2 -->> SCP_BL1: Validate, measure, load
+Rnote over RSS_BL2: RSS_S and SCP_BL1\n\ measurements saved\n\ to a shared buffer
+RSS_BL2 -> SCP_BL1: Release from reset
+activate SCP_BL1 #Green
+Rnote over RSS_BL2, SCP_BL1: MHU init between RSS and SCP
+Rnote over SCP_BL1: Configure memory
+Rnote over RSS_BL2: Waits for SCP
+SCP_BL1 --> RSS_BL2: Done
+RSS_BL2 -->> AP_BL1: Validate, measure, load
+Rnote over RSS_BL2: AP_BL1 measurement\n\ saved to a shared buffer
+RSS_BL2 -> AP_BL1: Release from reset
+activate AP_BL1 #Green
+RSS_BL2 -> RSS_S: Pass execution
+deactivate RSS_BL2
+activate RSS_S #Green
+Rnote over RSS_S: Measurements read from\n\ shared buffer and saved by\n\
+Measured Boot service to\n\ measurement slots.
+
+== RSS Runtime / AP Boot phase ==
+Rnote over RSS_S, AP_BL1: MHU init between RSS and AP
+Rnote over AP_BL1: Measure and load:\n\ FW_CONFIG\n\ TB_FW_CONFIG
+AP_BL1 -> RSS_S: Extend measurement
+Rnote over RSS_S: Measured Boot:\n\ store measurement
+AP_BL1 -->> AP_BL2: Validate, measure,load
+AP_BL1 -> RSS_S: Extend measurement
+Rnote over RSS_S: Measured Boot:\n\ store measurement
+AP_BL1 -> AP_BL2: Pass execution
+deactivate AP_BL1
+activate AP_BL2 #Green
+Rnote over AP_BL2: Measure and load:\n\ HW_CONFIG
+AP_BL2 -> RSS_S: Extend measurement
+Rnote over RSS_S: Measured Boot:\n\ store measurement
+AP_BL2 -->> AP_BL31: Validate, measure,load
+Rnote over AP_BL2: Measure and load:\n\ BL31
+AP_BL2 -> RSS_S: Extend measurement
+Rnote over RSS_S: Measured Boot:\n\ store measurement
+Rnote over AP_BL2: Measure and load:\n\ RMM
+AP_BL2 -> RSS_S: Extend measurement
+Rnote over RSS_S: Measured Boot:\n\ store measurement
+AP_BL2 -> AP_BL31: Pass execution
+deactivate AP_BL2
+activate AP_BL31 #Green
+== RSS / AP Runtime ==
+@enduml
diff --git a/docs/resources/diagrams/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..d322953
--- /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/resources/diagrams/rmm_el3_manifest_struct.dia b/docs/resources/diagrams/rmm_el3_manifest_struct.dia
deleted file mode 100644
index 7b7a9c2..0000000
--- a/docs/resources/diagrams/rmm_el3_manifest_struct.dia
+++ /dev/null
Binary files differ
diff --git a/docs/resources/diagrams/rmm_el3_manifest_struct.png b/docs/resources/diagrams/rmm_el3_manifest_struct.png
deleted file mode 100644
index 8b5776c..0000000
--- a/docs/resources/diagrams/rmm_el3_manifest_struct.png
+++ /dev/null
Binary files differ
diff --git a/docs/resources/diagrams/rss_attestation_flow.svg b/docs/resources/diagrams/rss_attestation_flow.svg
new file mode 100644
index 0000000..3728c6f
--- /dev/null
+++ b/docs/resources/diagrams/rss_attestation_flow.svg
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" height="1087px" preserveAspectRatio="none" style="width:900px;height:1087px;background:#FFFFFF;" version="1.1" viewBox="0 0 900 1087" width="900px" zoomAndPan="magnify"><defs/><g><rect fill="#DDDDDD" height="1075.1719" style="stroke:#181818;stroke-width:0.5;" width="261.5" x="44" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="20" x="164.75" y="18.0669">AP</text><rect fill="#DDDDDD" height="1075.1719" style="stroke:#181818;stroke-width:0.5;" width="502" x="364" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="28" x="601" y="18.0669">RSS</text><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="82" x2="82" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="266.5" x2="266.5" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="426" x2="426" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="553.5" x2="553.5" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="705" x2="705" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="822" x2="822" y1="56.4297" y2="1046.875"/><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="48" x="58" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="34" x="65" y="45.1279">RMM</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="48" x="58" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="34" x="65" y="1065.8701">RMM</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="49" x="242.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="35" x="249.5" y="45.1279">BL31</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="49" x="242.5" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="35" x="249.5" y="1065.8701">BL31</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="96" x="378" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="82" x="385" y="45.1279">DelegAttest</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="96" x="378" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="82" x="385" y="1065.8701">DelegAttest</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="516.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="523.5" y="45.1279">InitAttest</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="516.5" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="523.5" y="1065.8701">InitAttest</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="116" x="647" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="102" x="654" y="45.1279">MeasuredBoot</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="116" x="647" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="102" x="654" y="1065.8701">MeasuredBoot</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="59" x="793" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="45" x="800" y="45.1279">Crypto</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="59" x="793" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="45" x="800" y="1065.8701">Crypto</text><rect fill="#EEEEEE" height="3" style="stroke:#EEEEEE;stroke-width:1.0;" width="893" x="0" y="86.9961"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="893" y1="86.9961" y2="86.9961"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="893" y1="89.9961" y2="89.9961"/><rect fill="#EEEEEE" height="23.1328" style="stroke:#000000;stroke-width:2.0;" width="144" x="374.5" y="76.4297"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="125" x="380.5" y="92.4966">RMM Boot phase</text><polygon fill="#181818" points="255,141.8281,265,145.8281,255,149.8281,259,145.8281" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="82" x2="261" y1="145.8281" y2="145.8281"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="99" x="89" y="125.6294">get_realm_key(</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="74" x="121" y="140.7622">hash_algo</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="25" x="195" y="140.7622">, ...)</text><polygon fill="#181818" points="414,170.9609,424,174.9609,414,178.9609,418,174.9609" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="267" x2="420" y1="174.9609" y2="174.9609"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="121" x="274" y="169.895">get_delegated_key</text><polygon fill="#181818" points="693,200.0938,703,204.0938,693,208.0938,697,204.0938" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="426" x2="699" y1="204.0938" y2="204.0938"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="127" x="433" y="199.0278">read_measurement</text><rect fill="#FEFFDD" height="53" style="stroke:#181818;stroke-width:0.5;" width="167" x="342" y="217.0938"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="95" x="346" y="233.1606">Compute input</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="110" x="346" y="248.2935">for key derivation</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="159" x="346" y="263.4263">(hash of measurements)</text><polygon fill="#181818" points="810.5,292.625,820.5,296.625,810.5,300.625,814.5,296.625" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="426" x2="816.5" y1="296.625" y2="296.625"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="68" x="433" y="291.5591">derive_key</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="150" x="351" y="309.625"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="126" x="355" y="325.6919">Compute public key</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="60" x="355" y="340.8247">hash with</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="74" x="419" y="340.8247">hash_algo</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="4" x="493" y="340.8247">.</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="132" x="756" y="357.8906"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="124" x="760" y="373.9575">Seed is provisioned</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="88" x="760" y="389.0903">in the factory.</text><polygon fill="#181818" points="278,418.2891,268,422.2891,278,426.2891,274,422.2891" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="272" x2="425" y1="422.2891" y2="422.2891"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="121" x="284" y="417.2231">get_delegated_key</text><polygon fill="#181818" points="93,447.4219,83,451.4219,93,455.4219,89,451.4219" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="87" x2="266" y1="451.4219" y2="451.4219"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="94" x="99" y="446.356">get_realm_key</text><rect fill="#FEFFDD" height="129" style="stroke:#181818;stroke-width:0.5;" width="154" x="5" y="464.4219"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="102" x="9" y="480.4888">Only private key</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="114" x="9" y="495.6216">is returned. Public</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="104" x="9" y="510.7544">key and its hash</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="126" x="9" y="525.8872">must be computed.</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="134" x="9" y="541.02">Public key is included</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="121" x="9" y="556.1528">in the realm token.</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="125" x="9" y="571.2856">Its hash is the input</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="146" x="9" y="586.4185">for get_platform_token</text><polygon fill="#181818" points="255,630.75,265,634.75,255,638.75,259,634.75" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="82" x2="261" y1="634.75" y2="634.75"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="130" x="89" y="614.5513">get_platform_token(</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="104" x="121" y="629.6841">pub_key_hash</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="25" x="225" y="629.6841">, ...)</text><polygon fill="#181818" points="414,659.8828,424,663.8828,414,667.8828,418,663.8828" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="267" x2="420" y1="663.8828" y2="663.8828"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="135" x="274" y="658.8169">get_delegated_token</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="155" x="348" y="676.8828"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="39" x="352" y="692.9497">Check</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="104" x="395" y="692.9497">pub_key_hash</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="352" y="708.0825">against derived key.</text><polygon fill="#181818" points="542,737.2813,552,741.2813,542,745.2813,546,741.2813" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="426" x2="548" y1="741.2813" y2="741.2813"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="104" x="433" y="736.2153">get_initial_token</text><rect fill="#FEFFDD" height="53" style="stroke:#181818;stroke-width:0.5;" width="181" x="463" y="754.2813"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="168" x="467" y="770.3481">Create the token including</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="21" x="467" y="785.481">the</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="104" x="492" y="785.481">pub_key_hash</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="40" x="600" y="785.481">as the</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="99" x="467" y="800.6138">challenge claim</text><polygon fill="#181818" points="693,829.8125,703,833.8125,693,837.8125,697,833.8125" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="554" x2="699" y1="833.8125" y2="833.8125"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="127" x="561" y="828.7466">read_measurement</text><polygon fill="#181818" points="810.5,858.9453,820.5,862.9453,810.5,866.9453,814.5,862.9453" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="554" x2="816.5" y1="862.9453" y2="862.9453"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="69" x="561" y="857.8794">sign_token</text><polygon fill="#181818" points="437,888.0781,427,892.0781,437,896.0781,433,892.0781" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="431" x2="553" y1="892.0781" y2="892.0781"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="104" x="443" y="887.0122">get_initial_token</text><polygon fill="#181818" points="278,917.2109,268,921.2109,278,925.2109,274,921.2109" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="272" x2="425" y1="921.2109" y2="921.2109"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="135" x="284" y="916.145">get_delegated_token</text><polygon fill="#181818" points="93,946.3438,83,950.3438,93,954.3438,89,950.3438" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="87" x2="266" y1="950.3438" y2="950.3438"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="125" x="99" y="945.2778">get_platform_token</text><rect fill="#FEFFDD" height="68" style="stroke:#181818;stroke-width:0.5;" width="116" x="24" y="963.3438"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="108" x="28" y="979.4106">Platform token is</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="28" y="994.5435">cached. It is not</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="98" x="28" y="1009.6763">changing within</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="90" x="28" y="1024.8091">a power cycle.</text><!--MD5=[84fabec568a656165bea957fac178b53]
+@startuml

+skinparam ParticipantPadding 10

+skinparam BoxPadding 10

+box AP

+participant RMM

+participant BL31

+endbox

+box RSS

+participant DelegAttest

+participant InitAttest

+participant MeasuredBoot

+participant Crypto

+endbox

+

+== RMM Boot phase ==

+

+RMM -> BL31: get_realm_key(\n\t**hash_algo**, ...)

+BL31 -> DelegAttest: get_delegated_key

+DelegAttest -> MeasuredBoot: read_measurement

+Rnote over DelegAttest: Compute input\n\ for key derivation\n\ (hash of measurements)

+DelegAttest -> Crypto: derive_key

+Rnote over DelegAttest: Compute public key\n\ hash with **hash_algo**.

+Rnote over Crypto: Seed is provisioned\n\ in the factory.

+DelegAttest - -> BL31: get_delegated_key

+BL31 - -> RMM: get_realm_key

+Rnote over RMM: Only private key\n\ is returned. Public\n\ key and its hash\n\ must be computed.\nPublic key is included\n\ in the realm token.\n\ Its hash is the input\n\ for get_platform_token

+RMM -> BL31: get_platform_token(\n\t**pub_key_hash**, ...)

+BL31 -> DelegAttest: get_delegated_token

+Rnote over DelegAttest: Check **pub_key_hash**\n\ against derived key.

+DelegAttest -> InitAttest: get_initial_token

+Rnote over InitAttest: Create the token including\n\ the **pub_key_hash** as the\n\ challenge claim

+InitAttest -> MeasuredBoot: read_measurement

+InitAttest -> Crypto: sign_token

+InitAttest - -> DelegAttest:  get_initial_token

+DelegAttest - -> BL31: get_delegated_token

+BL31 - -> RMM: get_platform_token

+Rnote over RMM: Platform token is\n\ cached. It is not\n\ changing within\n\ a power cycle.

+@enduml

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

+skinparam ParticipantPadding 10

+skinparam BoxPadding 10

+box RSS

+participant RSS_BL1_1

+participant RSS_BL1_2

+participant RSS_BL2

+participant RSS_S

+endbox

+box SCP

+participant SCP_BL1

+endbox

+box AP

+participant AP_BL1

+participant AP_BL2

+participant AP_BL31

+endbox

+

+== RSS Boot phase ==

+-> RSS_BL1_1: Reset

+Rnote over RSS_BL1_1: ROM code, XIP

+Rnote over RSS_BL1_2: OTP code, XIP

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

+activate RSS_BL1_1 #Green

+RSS_BL1_1 - ->> RSS_BL1_2: Validate, measure

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

+RSS_BL1_1 -> RSS_BL1_2: Pass execution

+deactivate RSS_BL1_1

+activate RSS_BL1_2 #Green

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

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

+RSS_BL1_2 -> RSS_BL2: Pass execution

+deactivate RSS_BL1_2

+activate RSS_BL2 #Green

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

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

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

+RSS_BL2 -> SCP_BL1: Release from reset

+activate SCP_BL1 #Green

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

+Rnote over SCP_BL1: Configure memory

+Rnote over RSS_BL2: Waits for SCP

+SCP_BL1 - -> RSS_BL2: Done

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

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

+RSS_BL2 -> AP_BL1: Release from reset

+activate AP_BL1 #Green

+RSS_BL2 -> RSS_S: Pass execution

+deactivate RSS_BL2

+activate RSS_S #Green

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

+

+== RSS Runtime / AP Boot phase ==

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

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

+AP_BL1 -> RSS_S: Extend measurement

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

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

+AP_BL1 -> RSS_S: Extend measurement

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

+AP_BL1 -> AP_BL2: Pass execution

+deactivate AP_BL1

+activate AP_BL2 #Green

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

+AP_BL2 -> RSS_S: Extend measurement

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

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

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

+AP_BL2 -> RSS_S: Extend measurement

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

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

+AP_BL2 -> RSS_S: Extend measurement

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

+AP_BL2 -> AP_BL31: Pass execution

+deactivate AP_BL2

+activate AP_BL31 #Green

+== RSS / AP Runtime ==

+@enduml

+
+PlantUML version 1.2022.7(Mon Aug 22 19:01:30 CEST 2022)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: hu
+Country: HU
+--></g></svg>
\ No newline at end of file
diff --git a/docs/threat_model/threat_model.rst b/docs/threat_model/threat_model.rst
index 99bbb3a..940cad5 100644
--- a/docs/threat_model/threat_model.rst
+++ b/docs/threat_model/threat_model.rst
@@ -918,9 +918,54 @@
 | Mitigations            | | Yes / Platform specific                           |
 +------------------------+-----------------------------------------------------+
 
++------------------------+-----------------------------------------------------+
+| ID                     | 14                                                  |
++========================+=====================================================+
+| Threat                 | | **Attacker wants to execute an arbitrary or       |
+|                        |   untrusted binary as the secure OS.**              |
+|                        |                                                     |
+|                        | | When the option OPTEE_ALLOW_SMC_LOAD is enabled,  |
+|                        |   this trusts the non-secure world up until the     |
+|                        |   point it issues the SMC call to load the Secure   |
+|                        |   BL32 payload. If a compromise occurs before the   |
+|                        |   SMC call is invoked, then arbitrary code execution|
+|                        |   in S-EL1 can occur or arbitrary memory in EL3 can |
+|                        |   be overwritten.                                   |
++------------------------+-----------------------------------------------------+
+| Diagram Elements       | DF5                                                 |
++------------------------+-----------------------------------------------------+
+| Affected TF-A          | BL31, BL32                                          |
+| Components             |                                                     |
++------------------------+-----------------------------------------------------+
+| Assets                 | Code Execution, Sensitive Data                      |
++------------------------+-----------------------------------------------------+
+| Threat Agent           | NSCode                                              |
++------------------------+-----------------------------------------------------+
+| Threat Type            | Tampering, Information Disclosure,                  |
+|                        | Elevation of privilege                              |
++------------------------+-----------------+-----------------+-----------------+
+| Application            | Server          | IoT             | Mobile          |
++------------------------+-----------------+-----------------+-----------------+
+| Impact                 | Critical (5)    | Critical (5)    | Critical (5)    |
++------------------------+-----------------+-----------------+-----------------+
+| Likelihood             | High (4)        | High (4)        | High (4)        |
++------------------------+-----------------+-----------------+-----------------+
+| Total Risk Rating      | Critical (20)   | Critical (20)   | Critical (20)   |
++------------------------+-----------------+-----------------+-----------------+
+| Mitigations            | When enabling the option OPTEE_ALLOW_SMC_LOAD,      |
+|                        | the non-secure OS must be considered a closed       |
+|                        | platform up until the point the SMC can be invoked  |
+|                        | to load OP-TEE.                                     |
++------------------------+-----------------------------------------------------+
+| Mitigations            | | None in TF-A itself. This option is only used by  |
+| implemented?           |   ChromeOS currently which has other mechanisms to  |
+|                        |   to mitigate this threat which are described in    |
+|                        |   `OP-TEE Dispatcher`_.                             |
++------------------------+-----------------------------------------------------+
+
 --------------
 
-*Copyright (c) 2021-2022, Arm Limited. All rights reserved.*
+*Copyright (c) 2021-2023, Arm Limited. All rights reserved.*
 
 
 .. _STRIDE threat analysis technique: https://docs.microsoft.com/en-us/azure/security/develop/threat-modeling-tool-threats#stride-model
@@ -932,3 +977,4 @@
 .. _TF-A error handling policy: https://trustedfirmware-a.readthedocs.io/en/latest/process/coding-guidelines.html#error-handling-and-robustness
 .. _Secure Development Guidelines: https://trustedfirmware-a.readthedocs.io/en/latest/process/security-hardening.html#secure-development-guidelines
 .. _Trusted Firmware-A Tests: https://git.trustedfirmware.org/TF-A/tf-a-tests.git/about/
+.. _OP-TEE Dispatcher: https://github.com/ARM-software/arm-trusted-firmware/blob/master/docs/components/spd/optee-dispatcher.rst
diff --git a/drivers/allwinner/axp/common.c b/drivers/allwinner/axp/common.c
index f1250b0..79f9089 100644
--- a/drivers/allwinner/axp/common.c
+++ b/drivers/allwinner/axp/common.c
@@ -9,6 +9,7 @@
 #include <libfdt.h>
 
 #include <common/debug.h>
+#include <common/fdt_wrappers.h>
 #include <drivers/allwinner/axp.h>
 
 int axp_check_id(void)
@@ -97,19 +98,9 @@
 	return 0;
 }
 
-static bool is_node_disabled(const void *fdt, int node)
-{
-	const char *cell;
-	cell = fdt_getprop(fdt, node, "status", NULL);
-	if (cell == NULL) {
-		return false;
-	}
-	return strcmp(cell, "okay") != 0;
-}
-
 static bool should_enable_regulator(const void *fdt, int node)
 {
-	if (is_node_disabled(fdt, node)) {
+	if (!fdt_node_is_enabled(fdt, node)) {
 		return false;
 	}
 	if (fdt_getprop(fdt, node, "phandle", NULL) != NULL) {
diff --git a/drivers/arm/css/mhu/css_mhu_doorbell.c b/drivers/arm/css/mhu/css_mhu_doorbell.c
index c51f3b1..479bb21 100644
--- a/drivers/arm/css/mhu/css_mhu_doorbell.c
+++ b/drivers/arm/css/mhu/css_mhu_doorbell.c
@@ -15,7 +15,6 @@
 	MHU_RING_DOORBELL(plat_info->db_reg_addr,
 			plat_info->db_modify_mask,
 			plat_info->db_preserve_mask);
-	return;
 }
 
 void mhuv2_ring_doorbell(struct scmi_channel_plat_info *plat_info)
@@ -35,6 +34,4 @@
 
 	/* clear the access request for the receiver */
 	MHU_V2_CLEAR_REQUEST(mhuv2_base);
-
-	return;
 }
diff --git a/drivers/arm/gic/v3/gic600_multichip.c b/drivers/arm/gic/v3/gic600_multichip.c
index e85dbc1..f26e056 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) 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,11 +209,11 @@
 		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) ||
@@ -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;
@@ -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..f6028ad 100644
--- a/drivers/arm/gic/v3/gic600_multichip_private.h
+++ b/drivers/arm/gic/v3/gic600_multichip_private.h
@@ -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 446d0ad..00bd7a1 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) 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,6 +223,7 @@
 		current_prop = &interrupt_props[i];
 
 		unsigned int intr_num = current_prop->intr_num;
+		uintptr_t multichip_gicd_base = gicv3_get_multichip_base(intr_num, gicd_base);
 
 		/* Skip SGI, (E)PPI and LPI interrupts */
 		if (!IS_SPI(intr_num)) {
@@ -218,42 +231,43 @@
 		}
 
 		/* 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;
 }
 
 /*******************************************************************************
- * Helper function to configure the default attributes of (E)SPIs
+ * Helper function to configure the default attributes of (E)PPIs/SGIs
  ******************************************************************************/
 void gicv3_ppi_sgi_config_defaults(uintptr_t gicr_base)
 {
@@ -292,7 +306,7 @@
 	regs_num = ppi_regs_num << 3;
 	for (i = 0U; i < regs_num; ++i) {
 		/* Setup the default (E)PPI/SGI priorities doing 4 at a time */
-		gicr_write_ipriorityr(gicr_base, i, GICD_IPRIORITYR_DEF_VAL);
+		gicr_write_ipriorityr(gicr_base, i << 2, GICD_IPRIORITYR_DEF_VAL);
 	}
 
 	/* 16 interrupt IDs per GICR_ICFGR register */
diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c
index f6c251d..168d0eb 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>
@@ -430,6 +432,7 @@
 {
 	unsigned int igroup, grpmodr;
 	uintptr_t gicr_base;
+	uintptr_t gicd_base;
 
 	assert(IS_IN_EL3());
 	assert(gicv3_driver_data != NULL);
@@ -453,8 +456,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 +934,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 +949,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 +960,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 +980,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 +992,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 +1015,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 +1033,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 +1047,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 +1062,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 +1102,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 +1183,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 +1193,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 +1216,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 +1235,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 +1249,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 +1269,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/rss/rss_comms_protocol_embed.c b/drivers/arm/rss/rss_comms_protocol_embed.c
index 801b7cc..c453258 100644
--- a/drivers/arm/rss/rss_comms_protocol_embed.c
+++ b/drivers/arm/rss/rss_comms_protocol_embed.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
  *
@@ -54,7 +54,9 @@
 		if (in_vec[i].len > sizeof(msg->trailer) - payload_size) {
 			return PSA_ERROR_INVALID_ARGUMENT;
 		}
-		memcpy(msg->trailer + payload_size, in_vec[i].base, in_vec[i].len);
+		memcpy(msg->trailer + payload_size,
+		       in_vec[i].base,
+		       in_vec[i].len);
 		payload_size += in_vec[i].len;
 	}
 
@@ -77,12 +79,16 @@
 	assert(return_val != NULL);
 
 	for (i = 0U; i < out_len; ++i) {
-		if (sizeof(reply) - sizeof(reply->trailer) + payload_offset > reply_size) {
+		if ((sizeof(*reply) - sizeof(reply->trailer) + payload_offset)
+		    > reply_size) {
 			return PSA_ERROR_INVALID_ARGUMENT;
 		}
 
-		memcpy(out_vec[i].base, reply->trailer + payload_offset, out_vec[i].len);
-		payload_offset += out_vec[i].len;
+		memcpy(out_vec[i].base,
+		       reply->trailer + payload_offset,
+		       reply->out_size[i]);
+		out_vec[i].len = reply->out_size[i];
+		payload_offset += reply->out_size[i];
 	}
 
 	*return_val = reply->return_val;
diff --git a/drivers/auth/cca/cot.c b/drivers/auth/cca/cot.c
index d3f3087..e8f4d9c 100644
--- a/drivers/auth/cca/cot.c
+++ b/drivers/auth/cca/cot.c
@@ -1,13 +1,15 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <stddef.h>
 
+#include <mbedtls/version.h>
+
+#include <common/tbbr/cot_def.h>
 #include <drivers/auth/auth_mod.h>
-#include MBEDTLS_CONFIG_FILE
 #include <tools_share/cca_oid.h>
 
 #include <platform_def.h>
diff --git a/drivers/auth/cryptocell/712/cryptocell_crypto.c b/drivers/auth/cryptocell/712/cryptocell_crypto.c
index c7ee36f..e2b189b 100644
--- a/drivers/auth/cryptocell/712/cryptocell_crypto.c
+++ b/drivers/auth/cryptocell/712/cryptocell_crypto.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,7 +7,8 @@
 #include <stddef.h>
 #include <string.h>
 
-#include <platform_def.h>
+#include <mbedtls/oid.h>
+#include <mbedtls/x509.h>
 
 #include <arch_helpers.h>
 #include <common/debug.h>
@@ -21,8 +22,7 @@
 #include <drivers/auth/mbedtls/mbedtls_common.h>
 #include <lib/utils.h>
 
-#include <mbedtls/oid.h>
-#include <mbedtls/x509.h>
+#include <platform_def.h>
 
 #define LIB_NAME		"CryptoCell 712 SBROM"
 #define RSA_SALT_LEN		32
@@ -95,11 +95,10 @@
 	CCError_t error;
 	CCSbNParams_t pk;
 	CCSbSignature_t signature;
-	int rc, exp;
+	int rc, exp, expected_salt_len;
 	mbedtls_asn1_buf sig_oid, alg_oid, params;
-	mbedtls_md_type_t md_alg;
+	mbedtls_md_type_t md_alg, mgf1_hash_id;
 	mbedtls_pk_type_t pk_alg;
-	mbedtls_pk_rsassa_pss_options pss_opts;
 	size_t len;
 	uint8_t *p, *end;
 	/* Temp buf to store the public key modulo (N) in LE format */
@@ -110,70 +109,85 @@
 	p = sig_alg;
 	end = p + sig_alg_len;
 	rc = mbedtls_asn1_get_alg(&p, end, &sig_oid, &params);
-	if (rc != 0)
+	if (rc != 0) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
 	/* Get the actual signature algorithm (MD + PK) */
 	rc = mbedtls_oid_get_sig_alg(&sig_oid, &md_alg, &pk_alg);
-	if (rc != 0)
+	if (rc != 0) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
 	/* The CryptoCell only supports RSASSA-PSS signature */
-	if (pk_alg != MBEDTLS_PK_RSASSA_PSS || md_alg != MBEDTLS_MD_NONE)
+	if ((pk_alg != MBEDTLS_PK_RSASSA_PSS) || (md_alg != MBEDTLS_MD_NONE)) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
 	/* Verify the RSASSA-PSS params */
 	/* The trailer field is verified to be 0xBC internally by this API */
 	rc = mbedtls_x509_get_rsassa_pss_params(&params, &md_alg,
-			&pss_opts.mgf1_hash_id,
-			&pss_opts.expected_salt_len);
-	if (rc != 0)
+			&mgf1_hash_id,
+			&expected_salt_len);
+	if (rc != 0) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
 	/* The CryptoCell only supports SHA256 as hash algorithm */
-	if (md_alg != MBEDTLS_MD_SHA256 || pss_opts.mgf1_hash_id != MBEDTLS_MD_SHA256)
+	if ((md_alg != MBEDTLS_MD_SHA256) || (mgf1_hash_id != MBEDTLS_MD_SHA256)) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
-	if (pss_opts.expected_salt_len != RSA_SALT_LEN)
+	if (expected_salt_len != RSA_SALT_LEN) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
 	/* Parse the public key */
 	p = pk_ptr;
 	end = p + pk_len;
 	rc = mbedtls_asn1_get_tag(&p, end, &len,
 			MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
-	if (rc != 0)
+	if (rc != 0) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
 	end = p + len;
 	rc = mbedtls_asn1_get_alg_null(&p, end, &alg_oid);
-	if (rc != 0)
+	if (rc != 0) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
-	if (mbedtls_oid_get_pk_alg(&alg_oid, &pk_alg) != 0)
+	if (mbedtls_oid_get_pk_alg(&alg_oid, &pk_alg) != 0) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
-	if (pk_alg != MBEDTLS_PK_RSA)
+	if (pk_alg != MBEDTLS_PK_RSA) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
 	rc = mbedtls_asn1_get_bitstring_null(&p, end, &len);
-	if (rc != 0)
+	if (rc != 0) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
 	rc = mbedtls_asn1_get_tag(&p, end, &len,
 				MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
-	if (rc != 0)
+	if (rc != 0) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
 	rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_INTEGER);
-	if (rc != 0)
+	if (rc != 0) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
 	if (*p == 0) {
 		p++; len--;
 	}
-	if (len != RSA_MOD_SIZE_IN_BYTES || ((p + len) > end))
+
+	if (len != RSA_MOD_SIZE_IN_BYTES || ((p + len) > end)) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
 	/*
 	 * The CCSbVerifySignature() API expects N and Np in BE format and
@@ -184,11 +198,13 @@
 	/* Verify the RSA exponent */
 	p += len;
 	rc = mbedtls_asn1_get_int(&p, end, &exp);
-	if (rc != 0)
+	if (rc != 0) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
-	if (exp != RSA_EXPONENT)
+	if (exp != RSA_EXPONENT) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
 	/*
 	 * Calculate the Np (Barrett n' value). The RSA_CalcNp() API expects
@@ -205,11 +221,13 @@
 	p = sig_ptr;
 	end = p + sig_len;
 	rc = mbedtls_asn1_get_bitstring_null(&p, end, &len);
-	if (rc != 0)
+	if (rc != 0) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
-	if (len != RSA_MOD_SIZE_IN_BYTES || ((p + len) > end))
+	if (len != RSA_MOD_SIZE_IN_BYTES || ((p + len) > end)) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
 	/*
 	 *  The signature is BE format. Convert it to LE before calling
@@ -227,8 +245,9 @@
 	error = CCSbVerifySignature((uintptr_t)PLAT_CRYPTOCELL_BASE,
 			(uint32_t *)data_ptr, &pk, &signature,
 			data_len, RSA_PSS);
-	if (error != CC_OK)
+	if (error != CC_OK) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
 	/* Signature verification success */
 	return CRYPTO_SUCCESS;
@@ -256,29 +275,36 @@
 	end = p + digest_info_len;
 	rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
 				  MBEDTLS_ASN1_SEQUENCE);
-	if (rc != 0)
+	if (rc != 0) {
 		return CRYPTO_ERR_HASH;
+	}
 
 	/* Get the hash algorithm */
 	rc = mbedtls_asn1_get_alg(&p, end, &hash_oid, &params);
-	if (rc != 0)
+	if (rc != 0) {
 		return CRYPTO_ERR_HASH;
+	}
 
 	rc = mbedtls_oid_get_md_alg(&hash_oid, &md_alg);
-	if (rc != 0)
+	if (rc != 0) {
 		return CRYPTO_ERR_HASH;
+	}
+
 	/* Verify that hash algorithm is SHA256 */
-	if (md_alg != MBEDTLS_MD_SHA256)
+	if (md_alg != MBEDTLS_MD_SHA256) {
 		return CRYPTO_ERR_HASH;
+	}
 
 	/* Hash should be octet string type */
 	rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING);
-	if (rc != 0)
+	if (rc != 0) {
 		return CRYPTO_ERR_HASH;
+	}
 
 	/* Length of hash must match the algorithm's size */
-	if (len != HASH_RESULT_SIZE_IN_BYTES)
+	if (len != HASH_RESULT_SIZE_IN_BYTES) {
 		return CRYPTO_ERR_HASH;
+	}
 
 	/*
 	 * CryptoCell utilises DMA internally to transfer data. Flush the data
@@ -289,12 +315,14 @@
 	hash = p;
 	error = SBROM_CryptoHash((uintptr_t)PLAT_CRYPTOCELL_BASE,
 			(uintptr_t)data_ptr, data_len, pubKeyHash);
-	if (error != CC_OK)
+	if (error != CC_OK) {
 		return CRYPTO_ERR_HASH;
+	}
 
 	rc = memcmp(pubKeyHash, hash, HASH_RESULT_SIZE_IN_BYTES);
-	if (rc != 0)
+	if (rc != 0) {
 		return CRYPTO_ERR_HASH;
+	}
 
 	return CRYPTO_SUCCESS;
 }
diff --git a/drivers/auth/cryptocell/713/cryptocell_crypto.c b/drivers/auth/cryptocell/713/cryptocell_crypto.c
index 3ac16af..388264e 100644
--- a/drivers/auth/cryptocell/713/cryptocell_crypto.c
+++ b/drivers/auth/cryptocell/713/cryptocell_crypto.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023 ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,14 +8,14 @@
 #include <stddef.h>
 #include <string.h>
 
-#include <platform_def.h>
+#include <mbedtls/oid.h>
+#include <mbedtls/x509.h>
 
 #include <drivers/arm/cryptocell/713/bsv_api.h>
 #include <drivers/arm/cryptocell/713/bsv_crypto_asym_api.h>
 #include <drivers/auth/crypto_mod.h>
 
-#include <mbedtls/oid.h>
-#include <mbedtls/x509.h>
+#include <platform_def.h>
 
 #define LIB_NAME		"CryptoCell 713 SBROM"
 #define RSA_SALT_LEN		32
@@ -82,11 +82,11 @@
 	CCError_t error;
 	CCBsvNBuff_t NBuff;
 	CCBsvSignature_t signature;
-	int rc, exp;
+	int rc, exp, expected_salt_len;
 	mbedtls_asn1_buf sig_oid, alg_oid, params;
-	mbedtls_md_type_t md_alg;
+	mbedtls_md_type_t md_alg, mgf1_hash_id;
 	mbedtls_pk_type_t pk_alg;
-	mbedtls_pk_rsassa_pss_options pss_opts;
+
 	size_t len;
 	uint8_t *p, *end;
 	CCHashResult_t digest;
@@ -99,72 +99,86 @@
 	p = sig_alg;
 	end = p + sig_alg_len;
 	rc = mbedtls_asn1_get_alg(&p, end, &sig_oid, &params);
-	if (rc != 0)
+	if (rc != 0) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
 	/* Get the actual signature algorithm (MD + PK) */
 	rc = mbedtls_oid_get_sig_alg(&sig_oid, &md_alg, &pk_alg);
-	if (rc != 0)
+	if (rc != 0) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
 	/* The CryptoCell only supports RSASSA-PSS signature */
-	if (pk_alg != MBEDTLS_PK_RSASSA_PSS || md_alg != MBEDTLS_MD_NONE)
+	if (pk_alg != MBEDTLS_PK_RSASSA_PSS || md_alg != MBEDTLS_MD_NONE) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
 	/* Verify the RSASSA-PSS params */
 	/* The trailer field is verified to be 0xBC internally by this API */
 	rc = mbedtls_x509_get_rsassa_pss_params(&params, &md_alg,
-			&pss_opts.mgf1_hash_id,
-			&pss_opts.expected_salt_len);
-	if (rc != 0)
+			&mgf1_hash_id,
+			&expected_salt_len);
+	if (rc != 0) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
 	/* The CryptoCell only supports SHA256 as hash algorithm */
 	if (md_alg != MBEDTLS_MD_SHA256 ||
-	    pss_opts.mgf1_hash_id != MBEDTLS_MD_SHA256)
+	    mgf1_hash_id != MBEDTLS_MD_SHA256) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
-	if (pss_opts.expected_salt_len != RSA_SALT_LEN)
+	if (expected_salt_len != RSA_SALT_LEN) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
 	/* Parse the public key */
 	p = pk_ptr;
 	end = p + pk_len;
 	rc = mbedtls_asn1_get_tag(&p, end, &len,
 			MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
-	if (rc != 0)
+	if (rc != 0) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
 	end = p + len;
 	rc = mbedtls_asn1_get_alg_null(&p, end, &alg_oid);
-	if (rc != 0)
+	if (rc != 0) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
-	if (mbedtls_oid_get_pk_alg(&alg_oid, &pk_alg) != 0)
+	if (mbedtls_oid_get_pk_alg(&alg_oid, &pk_alg) != 0) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
-	if (pk_alg != MBEDTLS_PK_RSA)
+	if (pk_alg != MBEDTLS_PK_RSA) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
 	rc = mbedtls_asn1_get_bitstring_null(&p, end, &len);
-	if (rc != 0)
+	if (rc != 0) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
 	rc = mbedtls_asn1_get_tag(&p, end, &len,
 				MBEDTLS_ASN1_CONSTRUCTED |
 				MBEDTLS_ASN1_SEQUENCE);
-	if (rc != 0)
+	if (rc != 0) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
 	rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_INTEGER);
-	if (rc != 0)
+	if (rc != 0) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
 	if (*p == 0) {
 		p++; len--;
 	}
-	if (len != BSV_CERT_RSA_KEY_SIZE_IN_BYTES || ((p + len) > end))
+	if (len != BSV_CERT_RSA_KEY_SIZE_IN_BYTES || ((p + len) > end)) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
 	/*
 	 * Copy N from certificate.
@@ -174,21 +188,25 @@
 	/* Verify the RSA exponent */
 	p += len;
 	rc = mbedtls_asn1_get_int(&p, end, &exp);
-	if (rc != 0)
+	if (rc != 0) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
-	if (exp != RSA_EXPONENT)
+	if (exp != RSA_EXPONENT) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
 	/* Get the signature (bitstring) */
 	p = sig_ptr;
 	end = p + sig_len;
 	rc = mbedtls_asn1_get_bitstring_null(&p, end, &len);
-	if (rc != 0)
+	if (rc != 0) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
-	if (len != BSV_CERT_RSA_KEY_SIZE_IN_BYTES || ((p + len) > end))
+	if (len != BSV_CERT_RSA_KEY_SIZE_IN_BYTES || ((p + len) > end)) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
 	/*
 	 * Copy the signature (in BE format)
@@ -197,15 +215,17 @@
 
 	error = CC_BsvSha256((uintptr_t)PLAT_CRYPTOCELL_BASE,
 			     data_ptr, data_len, digest);
-	if (error != CC_OK)
+	if (error != CC_OK) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
 	/* Verify the signature */
 	error = CC_BsvRsaPssVerify((uintptr_t)PLAT_CRYPTOCELL_BASE, NBuff,
 				    NULL, signature, digest, workspace,
 				    BSV_RSA_WORKSPACE_MIN_SIZE, &is_verified);
-	if ((error != CC_OK) || (is_verified != CC_TRUE))
+	if ((error != CC_OK) || (is_verified != CC_TRUE)) {
 		return CRYPTO_ERR_SIGNATURE;
+	}
 
 	/* Signature verification success */
 	return CRYPTO_SUCCESS;
@@ -233,39 +253,48 @@
 	end = p + digest_info_len;
 	rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
 				  MBEDTLS_ASN1_SEQUENCE);
-	if (rc != 0)
+	if (rc != 0) {
 		return CRYPTO_ERR_HASH;
+	}
 
 	/* Get the hash algorithm */
 	rc = mbedtls_asn1_get_alg(&p, end, &hash_oid, &params);
-	if (rc != 0)
+	if (rc != 0) {
 		return CRYPTO_ERR_HASH;
+	}
 
 	rc = mbedtls_oid_get_md_alg(&hash_oid, &md_alg);
-	if (rc != 0)
+	if (rc != 0) {
 		return CRYPTO_ERR_HASH;
+	}
+
 	/* Verify that hash algorithm is SHA256 */
-	if (md_alg != MBEDTLS_MD_SHA256)
+	if (md_alg != MBEDTLS_MD_SHA256) {
 		return CRYPTO_ERR_HASH;
+	}
 
 	/* Hash should be octet string type */
 	rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING);
-	if (rc != 0)
+	if (rc != 0) {
 		return CRYPTO_ERR_HASH;
+	}
 
 	/* Length of hash must match the algorithm's size */
-	if (len != HASH_RESULT_SIZE_IN_BYTES)
+	if (len != HASH_RESULT_SIZE_IN_BYTES) {
 		return CRYPTO_ERR_HASH;
+	}
 
 	hash = p;
 	error = CC_BsvSha256((uintptr_t)PLAT_CRYPTOCELL_BASE, data_ptr,
 			     data_len, pubKeyHash);
-	if (error != CC_OK)
+	if (error != CC_OK) {
 		return CRYPTO_ERR_HASH;
+	}
 
 	rc = memcmp(pubKeyHash, hash, HASH_RESULT_SIZE_IN_BYTES);
-	if (rc != 0)
+	if (rc != 0) {
 		return CRYPTO_ERR_HASH;
+	}
 
 	return CRYPTO_SUCCESS;
 }
diff --git a/drivers/auth/dualroot/cot.c b/drivers/auth/dualroot/cot.c
index 8368503..c89930c 100644
--- a/drivers/auth/dualroot/cot.c
+++ b/drivers/auth/dualroot/cot.c
@@ -1,17 +1,20 @@
 /*
- * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <stddef.h>
 
-#include <platform_def.h>
+#include <mbedtls/version.h>
 
-#include MBEDTLS_CONFIG_FILE
+#include <common/tbbr/cot_def.h>
 #include <drivers/auth/auth_mod.h>
+
 #include <tools_share/dualroot_oid.h>
 
+#include <platform_def.h>
+
 /*
  * Allocate static buffers to store the authentication parameters extracted from
  * the certificates.
diff --git a/drivers/auth/mbedtls/mbedtls_common.c b/drivers/auth/mbedtls/mbedtls_common.c
index a12e49c..4f30d82 100644
--- a/drivers/auth/mbedtls/mbedtls_common.c
+++ b/drivers/auth/mbedtls/mbedtls_common.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
  */
@@ -10,10 +10,11 @@
 /* mbed TLS headers */
 #include <mbedtls/memory_buffer_alloc.h>
 #include <mbedtls/platform.h>
+#include <mbedtls/version.h>
 
 #include <common/debug.h>
 #include <drivers/auth/mbedtls/mbedtls_common.h>
-#include MBEDTLS_CONFIG_FILE
+
 #include <plat/common/platform.h>
 
 static void cleanup(void)
diff --git a/drivers/auth/mbedtls/mbedtls_common.mk b/drivers/auth/mbedtls/mbedtls_common.mk
index ae4b067..79c4512 100644
--- a/drivers/auth/mbedtls/mbedtls_common.mk
+++ b/drivers/auth/mbedtls/mbedtls_common.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2022, Arm Limited. All rights reserved.
+# Copyright (c) 2015-2023, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -15,42 +15,68 @@
 
 MBEDTLS_INC		=	-I${MBEDTLS_DIR}/include
 
+MBEDTLS_MAJOR=$(shell grep -hP "define MBEDTLS_VERSION_MAJOR" ${MBEDTLS_DIR}/include/mbedtls/*.h | grep -oe '\([0-9.]*\)')
+MBEDTLS_MINOR=$(shell grep -hP "define MBEDTLS_VERSION_MINOR" ${MBEDTLS_DIR}/include/mbedtls/*.h | grep -oe '\([0-9.]*\)')
+$(info MBEDTLS_VERSION_MAJOR is [${MBEDTLS_MAJOR}] MBEDTLS_VERSION_MINOR is [${MBEDTLS_MINOR}])
+
 # Specify mbed TLS configuration file
-MBEDTLS_CONFIG_FILE	?=	"<drivers/auth/mbedtls/mbedtls_config.h>"
+ifeq (${MBEDTLS_MAJOR}, 2)
+	MBEDTLS_CONFIG_FILE	?=	"<drivers/auth/mbedtls/mbedtls_config-2.h>"
+else ifeq (${MBEDTLS_MAJOR}, 3)
+	MBEDTLS_CONFIG_FILE	?=	"<drivers/auth/mbedtls/mbedtls_config-3.h>"
+endif
+
 $(eval $(call add_define,MBEDTLS_CONFIG_FILE))
 
 MBEDTLS_SOURCES	+=		drivers/auth/mbedtls/mbedtls_common.c
 
-
-LIBMBEDTLS_SRCS		+= $(addprefix ${MBEDTLS_DIR}/library/,	\
-					aes.c 					\
-					asn1parse.c 				\
-					asn1write.c 				\
-					cipher.c 				\
-					cipher_wrap.c 				\
-					memory_buffer_alloc.c			\
-					oid.c 					\
-					platform.c 				\
-					platform_util.c				\
-					bignum.c				\
-					gcm.c 					\
-					md.c					\
-					pk.c 					\
-					pk_wrap.c 				\
-					pkparse.c 				\
-					pkwrite.c 				\
-					sha256.c            			\
-					sha512.c            			\
-					ecdsa.c					\
-					ecp_curves.c				\
-					ecp.c					\
-					rsa.c					\
-					rsa_internal.c				\
-					x509.c 					\
-					x509_crt.c 				\
-					constant_time.c 			\
+LIBMBEDTLS_SRCS		+= $(addprefix ${MBEDTLS_DIR}/library/,		\
+					aes.c 				\
+					asn1parse.c 			\
+					asn1write.c 			\
+					cipher.c 			\
+					cipher_wrap.c 			\
+					constant_time.c			\
+					memory_buffer_alloc.c		\
+					oid.c 				\
+					platform.c 			\
+					platform_util.c			\
+					bignum.c			\
+					gcm.c 				\
+					md.c				\
+					pk.c 				\
+					pk_wrap.c 			\
+					pkparse.c 			\
+					pkwrite.c 			\
+					sha256.c            		\
+					sha512.c            		\
+					ecdsa.c				\
+					ecp_curves.c			\
+					ecp.c				\
+					rsa.c				\
+					x509.c 				\
+					x509_crt.c 			\
 					)
 
+ifeq (${MBEDTLS_MAJOR}, 2)
+	LIBMBEDTLS_SRCS +=  $(addprefix ${MBEDTLS_DIR}/library/,	\
+						rsa_internal.c		\
+						)
+else ifeq (${MBEDTLS_MAJOR}, 3)
+	LIBMBEDTLS_SRCS +=  $(addprefix ${MBEDTLS_DIR}/library/,	\
+						bignum_core.c		\
+						rsa_alt_helpers.c	\
+						hash_info.c		\
+						)
+
+	# Currently on Mbedtls-3 there is outstanding bug due to usage
+	# of redundant declaration[1], So disable redundant-decls
+	# compilation flag to avoid compilation error when compiling with
+	# Mbedtls-3.
+	# [1]: https://github.com/Mbed-TLS/mbedtls/issues/6910
+	LIBMBEDTLS_CFLAGS += -Wno-error=redundant-decls
+endif
+
 # The platform may define the variable 'TF_MBEDTLS_KEY_ALG' to select the key
 # algorithm to use. If the variable is not defined, select it based on
 # algorithm used for key generation `KEY_ALG`. If `KEY_ALG` is not defined,
diff --git a/drivers/auth/mbedtls/mbedtls_crypto.c b/drivers/auth/mbedtls/mbedtls_crypto.c
index 42a0925..4241d21 100644
--- a/drivers/auth/mbedtls/mbedtls_crypto.c
+++ b/drivers/auth/mbedtls/mbedtls_crypto.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
  */
@@ -14,12 +14,13 @@
 #include <mbedtls/memory_buffer_alloc.h>
 #include <mbedtls/oid.h>
 #include <mbedtls/platform.h>
+#include <mbedtls/version.h>
 #include <mbedtls/x509.h>
 
 #include <common/debug.h>
 #include <drivers/auth/crypto_mod.h>
 #include <drivers/auth/mbedtls/mbedtls_common.h>
-#include <drivers/auth/mbedtls/mbedtls_config.h>
+
 #include <plat/common/platform.h>
 
 #define LIB_NAME		"mbed TLS"
@@ -294,6 +295,7 @@
 	unsigned char *pt = data_ptr;
 	size_t dec_len;
 	int diff, i, rc;
+	size_t output_length __unused;
 
 	mbedtls_gcm_init(&ctx);
 
@@ -303,7 +305,11 @@
 		goto exit_gcm;
 	}
 
+#if (MBEDTLS_VERSION_MAJOR < 3)
 	rc = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT, iv, iv_len, NULL, 0);
+#else
+	rc = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT, iv, iv_len);
+#endif
 	if (rc != 0) {
 		rc = CRYPTO_ERR_DECRYPTION;
 		goto exit_gcm;
@@ -312,7 +318,12 @@
 	while (len > 0) {
 		dec_len = MIN(sizeof(buf), len);
 
+#if (MBEDTLS_VERSION_MAJOR < 3)
 		rc = mbedtls_gcm_update(&ctx, dec_len, pt, buf);
+#else
+		rc = mbedtls_gcm_update(&ctx, pt, dec_len, buf, sizeof(buf), &output_length);
+#endif
+
 		if (rc != 0) {
 			rc = CRYPTO_ERR_DECRYPTION;
 			goto exit_gcm;
@@ -323,7 +334,12 @@
 		len -= dec_len;
 	}
 
+#if (MBEDTLS_VERSION_MAJOR < 3)
 	rc = mbedtls_gcm_finish(&ctx, tag_buf, sizeof(tag_buf));
+#else
+	rc = mbedtls_gcm_finish(&ctx, NULL, 0, &output_length, tag_buf, sizeof(tag_buf));
+#endif
+
 	if (rc != 0) {
 		rc = CRYPTO_ERR_DECRYPTION;
 		goto exit_gcm;
diff --git a/drivers/auth/mbedtls/mbedtls_x509_parser.c b/drivers/auth/mbedtls/mbedtls_x509_parser.c
index bbabd9b..fb5b036 100644
--- a/drivers/auth/mbedtls/mbedtls_x509_parser.c
+++ b/drivers/auth/mbedtls/mbedtls_x509_parser.c
@@ -66,46 +66,63 @@
  * Get X509v3 extension
  *
  * Global variable 'v3_ext' must point to the extensions region
- * in the certificate. No need to check for errors since the image has passed
- * the integrity check.
+ * in the certificate.  OID may be NULL to request that get_ext()
+ * is only being called for integrity checking.
  */
 static int get_ext(const char *oid, void **ext, unsigned int *ext_len)
 {
-	int oid_len;
+	int oid_len, ret, is_critical;
 	size_t len;
-	unsigned char *end_ext_data, *end_ext_octet;
 	unsigned char *p;
 	const unsigned char *end;
 	char oid_str[MAX_OID_STR_LEN];
 	mbedtls_asn1_buf extn_oid;
-	int is_critical;
-
-	assert(oid != NULL);
 
 	p = v3_ext.p;
 	end = v3_ext.p + v3_ext.len;
 
-	while (p < end) {
-		zeromem(&extn_oid, sizeof(extn_oid));
-		is_critical = 0; /* DEFAULT FALSE */
+	/*
+	 * Check extensions integrity.  At least one extension is
+	 * required: the ASN.1 specifies a minimum size of 1, and at
+	 * least one extension is needed to authenticate the next stage
+	 * in the boot chain.
+	 */
+	do {
+		unsigned char *end_ext_data;
 
-		mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
-				     MBEDTLS_ASN1_SEQUENCE);
+		ret = mbedtls_asn1_get_tag(&p, end, &len,
+					   MBEDTLS_ASN1_CONSTRUCTED |
+					   MBEDTLS_ASN1_SEQUENCE);
+		if (ret != 0) {
+			return IMG_PARSER_ERR_FORMAT;
+		}
 		end_ext_data = p + len;
 
 		/* Get extension ID */
-		extn_oid.tag = *p;
-		mbedtls_asn1_get_tag(&p, end, &extn_oid.len, MBEDTLS_ASN1_OID);
+		ret = mbedtls_asn1_get_tag(&p, end_ext_data, &extn_oid.len,
+					   MBEDTLS_ASN1_OID);
+		if (ret != 0) {
+			return IMG_PARSER_ERR_FORMAT;
+		}
+		extn_oid.tag = MBEDTLS_ASN1_OID;
 		extn_oid.p = p;
 		p += extn_oid.len;
 
 		/* Get optional critical */
-		mbedtls_asn1_get_bool(&p, end_ext_data, &is_critical);
+		ret = mbedtls_asn1_get_bool(&p, end_ext_data, &is_critical);
+		if ((ret != 0) && (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)) {
+			return IMG_PARSER_ERR_FORMAT;
+		}
 
-		/* Extension data */
-		mbedtls_asn1_get_tag(&p, end_ext_data, &len,
-				     MBEDTLS_ASN1_OCTET_STRING);
-		end_ext_octet = p + len;
+		/*
+		 * Data should be octet string type and must use all bytes in
+		 * the Extension.
+		 */
+		ret = mbedtls_asn1_get_tag(&p, end_ext_data, &len,
+					   MBEDTLS_ASN1_OCTET_STRING);
+		if ((ret != 0) || ((p + len) != end_ext_data)) {
+			return IMG_PARSER_ERR_FORMAT;
+		}
 
 		/* Detect requested extension */
 		oid_len = mbedtls_oid_get_numeric_string(oid_str,
@@ -114,17 +131,20 @@
 		if ((oid_len == MBEDTLS_ERR_OID_BUF_TOO_SMALL) || (oid_len < 0)) {
 			return IMG_PARSER_ERR;
 		}
-		if (((size_t)oid_len == strlen(oid_str)) && !strcmp(oid, oid_str)) {
+
+		if ((oid != NULL) &&
+		    ((size_t)oid_len == strlen(oid_str)) &&
+		    (strcmp(oid, oid_str) == 0)) {
 			*ext = (void *)p;
 			*ext_len = (unsigned int)len;
 			return IMG_PARSER_OK;
 		}
 
 		/* Next */
-		p = end_ext_octet;
-	}
+		p = end_ext_data;
+	} while (p < end);
 
-	return IMG_PARSER_ERR_NOT_FOUND;
+	return (oid == NULL) ? IMG_PARSER_OK : IMG_PARSER_ERR_NOT_FOUND;
 }
 
 
@@ -139,7 +159,7 @@
  */
 static int cert_parse(void *img, unsigned int img_len)
 {
-	int ret, is_critical;
+	int ret;
 	size_t len;
 	unsigned char *p, *end, *crt_end, *pk_end;
 	mbedtls_asn1_buf sig_alg1;
@@ -161,7 +181,8 @@
 
 	p = (unsigned char *)img;
 	len = img_len;
-	end = p + len;
+	crt_end = p + len;
+	end = crt_end;
 
 	/*
 	 * Certificate  ::=  SEQUENCE  {
@@ -171,15 +192,10 @@
 	 */
 	ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
 				   MBEDTLS_ASN1_SEQUENCE);
-	if (ret != 0) {
+	if ((ret != 0) || ((p + len) != end)) {
 		return IMG_PARSER_ERR_FORMAT;
 	}
 
-	if (len != (size_t)(end - p)) {
-		return IMG_PARSER_ERR_FORMAT;
-	}
-	crt_end = p + len;
-
 	/*
 	 * TBSCertificate  ::=  SEQUENCE  {
 	 */
@@ -220,9 +236,6 @@
 	if (ret != 0) {
 		return IMG_PARSER_ERR_FORMAT;
 	}
-	if ((end - p) < 1) {
-		return IMG_PARSER_ERR_FORMAT;
-	}
 	sig_alg1.len = (p + len) - sig_alg1.p;
 	p += len;
 
@@ -288,30 +301,24 @@
 
 	/*
 	 * issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
-	 */
-	ret = mbedtls_asn1_get_tag(&p, end, &len,
-				   MBEDTLS_ASN1_CONTEXT_SPECIFIC |
-				   MBEDTLS_ASN1_CONSTRUCTED | 1);
-	if (ret != 0) {
-		if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
-			return IMG_PARSER_ERR_FORMAT;
-		}
-	} else {
-		p += len;
-	}
-
-	/*
 	 * subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
+	 * -- technically these contain BIT STRINGs but that is not worth
+	 * -- validating
 	 */
-	ret = mbedtls_asn1_get_tag(&p, end, &len,
-				   MBEDTLS_ASN1_CONTEXT_SPECIFIC |
-				   MBEDTLS_ASN1_CONSTRUCTED | 2);
-	if (ret != 0) {
+	for (int i = 1; i < 3; i++) {
+		ret = mbedtls_asn1_get_tag(&p, end, &len,
+					   MBEDTLS_ASN1_CONTEXT_SPECIFIC |
+					   MBEDTLS_ASN1_CONSTRUCTED | i);
+		/*
+		 * Unique IDs are obsolete, so MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+		 * is the common case.
+		 */
 		if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
-			return IMG_PARSER_ERR_FORMAT;
+			if (ret != 0) {
+				return IMG_PARSER_ERR_FORMAT;
+			}
+			p += len;
 		}
-	} else {
-		p += len;
 	}
 
 	/*
@@ -347,51 +354,12 @@
 	}
 	v3_ext.p = p;
 	v3_ext.len = len;
-
-	/*
-	 * Check extensions integrity.  At least one extension is
-	 * required: the ASN.1 specifies a minimum size of 1, and at
-	 * least one extension is needed to authenticate the next stage
-	 * in the boot chain.
-	 */
-	do {
-		unsigned char *end_ext_data;
-
-		ret = mbedtls_asn1_get_tag(&p, end, &len,
-					   MBEDTLS_ASN1_CONSTRUCTED |
-					   MBEDTLS_ASN1_SEQUENCE);
-		if (ret != 0) {
-			return IMG_PARSER_ERR_FORMAT;
-		}
-		end_ext_data = p + len;
-
-		/* Get extension ID */
-		ret = mbedtls_asn1_get_tag(&p, end_ext_data, &len, MBEDTLS_ASN1_OID);
-		if (ret != 0) {
-			return IMG_PARSER_ERR_FORMAT;
-		}
-		p += len;
-
-		/* Get optional critical */
-		ret = mbedtls_asn1_get_bool(&p, end_ext_data, &is_critical);
-		if ((ret != 0) && (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)) {
-			return IMG_PARSER_ERR_FORMAT;
-		}
-
-		/*
-		 * Data should be octet string type and must use all bytes in
-		 * the Extension.
-		 */
-		ret = mbedtls_asn1_get_tag(&p, end_ext_data, &len,
-					   MBEDTLS_ASN1_OCTET_STRING);
-		if ((ret != 0) || ((p + len) != end_ext_data)) {
-			return IMG_PARSER_ERR_FORMAT;
-		}
-		p = end_ext_data;
-	} while (p < end);
+	p += len;
 
-	if (p != end) {
-		return IMG_PARSER_ERR_FORMAT;
+	/* Check extensions integrity */
+	ret = get_ext(NULL, NULL, NULL);
+	if (ret != IMG_PARSER_OK) {
+		return ret;
 	}
 
 	end = crt_end;
@@ -414,19 +382,14 @@
 
 	/*
 	 * signatureValue       BIT STRING
+	 * } -- must consume all bytes
 	 */
 	signature.p = p;
 	ret = mbedtls_asn1_get_bitstring_null(&p, end, &len);
-	if (ret != 0) {
-		return IMG_PARSER_ERR_FORMAT;
-	}
-	signature.len = (p + len) - signature.p;
-	p += len;
-
-	/* Check certificate length */
-	if (p != end) {
+	if ((ret != 0) || ((p + len) != end)) {
 		return IMG_PARSER_ERR_FORMAT;
 	}
+	signature.len = end - signature.p;
 
 	return IMG_PARSER_OK;
 }
@@ -511,5 +474,5 @@
 	return rc;
 }
 
-REGISTER_IMG_PARSER_LIB(IMG_CERT, LIB_NAME, init, \
+REGISTER_IMG_PARSER_LIB(IMG_CERT, LIB_NAME, init,
 		       check_integrity, get_auth_param);
diff --git a/drivers/auth/tbbr/tbbr_cot_bl1.c b/drivers/auth/tbbr/tbbr_cot_bl1.c
index 44f8638..21942b4 100644
--- a/drivers/auth/tbbr/tbbr_cot_bl1.c
+++ b/drivers/auth/tbbr/tbbr_cot_bl1.c
@@ -1,22 +1,24 @@
 /*
- * 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
  */
 
 #include <stddef.h>
 
-#include <platform_def.h>
-#include MBEDTLS_CONFIG_FILE
+#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 auth_param_type_desc_t scp_bl2u_hash = AUTH_PARAM_TYPE_DESC(
 		AUTH_PARAM_HASH, SCP_FWU_CFG_HASH_OID);
 static auth_param_type_desc_t bl2u_hash = AUTH_PARAM_TYPE_DESC(
diff --git a/drivers/auth/tbbr/tbbr_cot_bl1_r64.c b/drivers/auth/tbbr/tbbr_cot_bl1_r64.c
index 78e38f6..236823a 100644
--- a/drivers/auth/tbbr/tbbr_cot_bl1_r64.c
+++ b/drivers/auth/tbbr/tbbr_cot_bl1_r64.c
@@ -1,13 +1,14 @@
 /*
- * 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 <stddef.h>
 
+#include <mbedtls/version.h>
+
 #include <drivers/auth/auth_mod.h>
-#include MBEDTLS_CONFIG_FILE
 #include <drivers/auth/tbbr_cot_common.h>
 
 #if USE_TBBR_DEFS
@@ -15,8 +16,8 @@
 #else
 #include <platform_oid.h>
 #endif
-#include <platform_def.h>
 
+#include <platform_def.h>
 
 static unsigned char trusted_world_pk_buf[PK_DER_LEN];
 static unsigned char non_trusted_world_pk_buf[PK_DER_LEN];
diff --git a/drivers/auth/tbbr/tbbr_cot_bl2.c b/drivers/auth/tbbr/tbbr_cot_bl2.c
index 11e2f46..ce2aa7e 100644
--- a/drivers/auth/tbbr/tbbr_cot_bl2.c
+++ b/drivers/auth/tbbr/tbbr_cot_bl2.c
@@ -1,22 +1,24 @@
 /*
- * 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
  */
 
 #include <stddef.h>
 
-#include <platform_def.h>
-#include MBEDTLS_CONFIG_FILE
+#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];
diff --git a/drivers/auth/tbbr/tbbr_cot_common.c b/drivers/auth/tbbr/tbbr_cot_common.c
index 0983d42..8c37248 100644
--- a/drivers/auth/tbbr/tbbr_cot_common.c
+++ b/drivers/auth/tbbr/tbbr_cot_common.c
@@ -1,22 +1,23 @@
 /*
- * 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
  */
 
 #include <stddef.h>
 
-#include <platform_def.h>
-#include MBEDTLS_CONFIG_FILE
+#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>
 /*
  * The platform must allocate buffers to store the authentication parameters
  * extracted from the certificates. In this case, because of the way the CoT is
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/nxp/auth/tbbr/tbbr_cot.c b/drivers/nxp/auth/tbbr/tbbr_cot.c
index bb21fa0..ac4595f 100644
--- a/drivers/nxp/auth/tbbr/tbbr_cot.c
+++ b/drivers/nxp/auth/tbbr/tbbr_cot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
  *
  * Copyright 2020 NXP
  *
@@ -8,6 +8,7 @@
 
 #include <stddef.h>
 
+#include <common/tbbr/cot_def.h>
 #include <drivers/auth/auth_mod.h>
 
 #if USE_TBBR_DEFS
diff --git a/drivers/nxp/timer/nxp_timer.c b/drivers/nxp/timer/nxp_timer.c
index 8eecd2e..448c0ba 100644
--- a/drivers/nxp/timer/nxp_timer.c
+++ b/drivers/nxp/timer/nxp_timer.c
@@ -59,7 +59,7 @@
 
 static void delay_timer_init_args(uint32_t mult, uint32_t div)
 {
-	ops.get_timer_value	= timer_get_value,
+	ops.get_timer_value	= timer_get_value;
 	ops.clk_mult		= mult;
 	ops.clk_div		= div;
 
diff --git a/drivers/ufs/ufs.c b/drivers/ufs/ufs.c
index d8c0a14..ea82d02 100644
--- a/drivers/ufs/ufs.c
+++ b/drivers/ufs/ufs.c
@@ -30,9 +30,138 @@
 static ufs_params_t ufs_params;
 static int nutrs;	/* Number of UTP Transfer Request Slots */
 
+/*
+ * ufs_uic_error_handler - UIC error interrupts handler
+ * @ignore_linereset: set to ignore PA_LAYER_GEN_ERR (UIC error)
+ *
+ * Returns
+ * 0 - ignore error
+ * -EIO - fatal error, needs re-init
+ * -EAGAIN - non-fatal error, retries are sufficient
+ */
+static int ufs_uic_error_handler(bool ignore_linereset)
+{
+	uint32_t data;
+	int result = 0;
+
+	data = mmio_read_32(ufs_params.reg_base + UECPA);
+	if (data & UFS_UIC_PA_ERROR_MASK) {
+		if (data & PA_LAYER_GEN_ERR) {
+			if (!ignore_linereset) {
+				return -EIO;
+			}
+		} else {
+			result = -EAGAIN;
+		}
+	}
+
+	data = mmio_read_32(ufs_params.reg_base + UECDL);
+	if (data & UFS_UIC_DL_ERROR_MASK) {
+		if (data & PA_INIT_ERR) {
+			return -EIO;
+		}
+		result = -EAGAIN;
+	}
+
+	/* NL/TL/DME error requires retries */
+	data = mmio_read_32(ufs_params.reg_base + UECN);
+	if (data & UFS_UIC_NL_ERROR_MASK) {
+		result = -EAGAIN;
+	}
+
+	data = mmio_read_32(ufs_params.reg_base + UECT);
+	if (data & UFS_UIC_TL_ERROR_MASK) {
+		result = -EAGAIN;
+	}
+
+	data = mmio_read_32(ufs_params.reg_base + UECDME);
+	if (data & UFS_UIC_DME_ERROR_MASK) {
+		result = -EAGAIN;
+	}
+
+	return result;
+}
+
+/*
+ * ufs_error_handler - error interrupts handler
+ * @status: interrupt status
+ * @ignore_linereset: set to ignore PA_LAYER_GEN_ERR (UIC error)
+ *
+ * Returns
+ * 0 - ignore error
+ * -EIO - fatal error, needs re-init
+ * -EAGAIN - non-fatal error, retries are sufficient
+ */
+static int ufs_error_handler(uint32_t status, bool ignore_linereset)
+{
+	int result;
+
+	if (status & UFS_INT_UE) {
+		result = ufs_uic_error_handler(ignore_linereset);
+		if (result != 0) {
+			return result;
+		}
+	}
+
+	/* Return I/O error on fatal error, it is upto the caller to re-init UFS */
+	if (status & UFS_INT_FATAL) {
+		return -EIO;
+	}
+
+	/* retry for non-fatal errors */
+	return -EAGAIN;
+}
+
+/*
+ * ufs_wait_for_int_status - wait for expected interrupt status
+ * @expected: expected interrupt status bit
+ * @timeout_ms: timeout in milliseconds to poll for
+ * @ignore_linereset: set to ignore PA_LAYER_GEN_ERR (UIC error)
+ *
+ * Returns
+ * 0 - received expected interrupt and cleared it
+ * -EIO - fatal error, needs re-init
+ * -EAGAIN - non-fatal error, caller can retry
+ * -ETIMEDOUT - timed out waiting for interrupt status
+ */
+static int ufs_wait_for_int_status(const uint32_t expected_status,
+				   unsigned int timeout_ms,
+				   bool ignore_linereset)
+{
+	uint32_t interrupt_status, interrupts_enabled;
+	int result = 0;
+
+	interrupts_enabled = mmio_read_32(ufs_params.reg_base + IE);
+	do {
+		interrupt_status = mmio_read_32(ufs_params.reg_base + IS) & interrupts_enabled;
+		if (interrupt_status & UFS_INT_ERR) {
+			mmio_write_32(ufs_params.reg_base + IS, interrupt_status & UFS_INT_ERR);
+			result = ufs_error_handler(interrupt_status, ignore_linereset);
+			if (result != 0) {
+				return result;
+			}
+		}
+
+		if (interrupt_status & expected_status) {
+			break;
+		}
+		mdelay(1);
+	} while (timeout_ms-- > 0);
+
+	if (!(interrupt_status & expected_status)) {
+		return -ETIMEDOUT;
+	}
+
+	mmio_write_32(ufs_params.reg_base + IS, expected_status);
+
+	return result;
+}
+
+
 int ufshc_send_uic_cmd(uintptr_t base, uic_cmd_t *cmd)
 {
 	unsigned int data;
+	int result;
 
 	if (base == 0 || cmd == NULL)
 		return -EINVAL;
@@ -46,10 +175,12 @@
 	mmio_write_32(base + UCMDARG3, cmd->arg3);
 	mmio_write_32(base + UICCMD, cmd->op);
 
-	do {
-		data = mmio_read_32(base + IS);
-	} while ((data & UFS_INT_UCCS) == 0);
-	mmio_write_32(base + IS, UFS_INT_UCCS);
+	result = ufs_wait_for_int_status(UFS_INT_UCCS, UIC_CMD_TIMEOUT_MS,
+					 cmd->op == DME_SET);
+	if (result != 0) {
+		return result;
+	}
+
 	return mmio_read_32(base + UCMDARG2) & CONFIG_RESULT_CODE_MASK;
 }
 
@@ -83,9 +214,10 @@
 		result = ufshc_send_uic_cmd(base, &cmd);
 		if (result == 0)
 			break;
-		data = mmio_read_32(base + IS);
-		if (data & UFS_INT_UE)
-			return -EINVAL;
+		/* -EIO requires UFS re-init */
+		if (result == -EIO) {
+			return result;
+		}
 	}
 	if (retries >= UFS_UIC_COMMAND_RETRIES)
 		return -EIO;
@@ -97,7 +229,6 @@
 int ufshc_dme_set(unsigned int attr, unsigned int idx, unsigned int val)
 {
 	uintptr_t base;
-	unsigned int data;
 	int result, retries;
 	uic_cmd_t cmd;
 
@@ -113,9 +244,10 @@
 		result = ufshc_send_uic_cmd(base, &cmd);
 		if (result == 0)
 			break;
-		data = mmio_read_32(base + IS);
-		if (data & UFS_INT_UE)
-			return -EINVAL;
+		/* -EIO requires UFS re-init */
+		if (result == -EIO) {
+			return result;
+		}
 	}
 	if (retries >= UFS_UIC_COMMAND_RETRIES)
 		return -EIO;
@@ -193,9 +325,10 @@
 		return -EIO;
 	}
 
-	/* Enable Interrupts */
-	data = UFS_INT_UCCS | UFS_INT_ULSS | UFS_INT_UE | UFS_INT_UTPES |
-	       UFS_INT_DFES | UFS_INT_HCFES | UFS_INT_SBFES;
+	/* Enable UIC Interrupts alone. We can ignore other interrupts until
+	 * link is up as there might be spurious error interrupts during link-up
+	 */
+	data = UFS_INT_UCCS | UFS_INT_UHES | UFS_INT_UHXS | UFS_INT_UPMS;
 	mmio_write_32(base + IE, data);
 
 	return 0;
@@ -225,51 +358,49 @@
 			}
 			continue;
 		}
-		assert((mmio_read_32(base + HCS) & HCS_DP) == 0);
+		assert(mmio_read_32(base + HCS) & HCS_DP);
 		data = mmio_read_32(base + IS);
 		if (data & UFS_INT_ULSS)
 			mmio_write_32(base + IS, UFS_INT_ULSS);
+
+		/* clear UE set due to line-reset */
+		if (data & UFS_INT_UE) {
+			mmio_write_32(base + IS, UFS_INT_UE);
+		}
+		/* clearing line-reset, UECPA is cleared on read */
+		mmio_read_32(base + UECPA);
 		return 0;
 	}
 	return -EIO;
 }
 
-/* Check Door Bell register to get an empty slot */
-static int get_empty_slot(int *slot)
+/* Read Door Bell register to check if slot zero is available */
+static int is_slot_available(void)
 {
-	unsigned int data;
-	int i;
-
-	data = mmio_read_32(ufs_params.reg_base + UTRLDBR);
-	for (i = 0; i < nutrs; i++) {
-		if ((data & 1) == 0)
-			break;
-		data = data >> 1;
-	}
-	if (i >= nutrs)
+	if (mmio_read_32(ufs_params.reg_base + UTRLDBR) & 0x1) {
 		return -EBUSY;
-	*slot = i;
+	}
 	return 0;
 }
 
 static void get_utrd(utp_utrd_t *utrd)
 {
 	uintptr_t base;
-	int slot = 0, result;
+	int result;
 	utrd_header_t *hd;
 
 	assert(utrd != NULL);
-	result = get_empty_slot(&slot);
+	result = is_slot_available();
 	assert(result == 0);
 
 	/* clear utrd */
 	memset((void *)utrd, 0, sizeof(utp_utrd_t));
-	base = ufs_params.desc_base + (slot * sizeof(utrd_header_t));
+	base = ufs_params.desc_base;
 	/* clear the descriptor */
 	memset((void *)base, 0, UFS_DESC_SIZE);
 
 	utrd->header = base;
-	utrd->task_tag = slot + 1;
+	utrd->task_tag = 1; /* We always use the first slot */
 	/* CDB address should be aligned with 128 bytes */
 	utrd->upiu = ALIGN_CDB(utrd->header + sizeof(utrd_header_t));
 	utrd->resp_upiu = ALIGN_8(utrd->upiu + sizeof(cmd_upiu_t));
@@ -297,7 +428,8 @@
 	prdt_t *prdt;
 	unsigned int ulba;
 	unsigned int lba_cnt;
-	int prdt_size;
+	uintptr_t desc_limit;
+	uintptr_t prdt_end;
 
 	hd = (utrd_header_t *)utrd->header;
 	upiu = (cmd_upiu_t *)utrd->upiu;
@@ -351,17 +483,24 @@
 		assert(0);
 		break;
 	}
-	if (hd->dd == DD_IN)
+	if (hd->dd == DD_IN) {
 		flush_dcache_range(buf, length);
-	else if (hd->dd == DD_OUT)
+	} else if (hd->dd == DD_OUT) {
 		inv_dcache_range(buf, length);
+	}
+
+	utrd->prdt_length = 0;
 	if (length) {
 		upiu->exp_data_trans_len = htobe32(length);
 		assert(lba_cnt <= UINT16_MAX);
 		prdt = (prdt_t *)utrd->prdt;
 
-		prdt_size = 0;
+		desc_limit = ufs_params.desc_base + ufs_params.desc_size;
 		while (length > 0) {
+			if ((uintptr_t)prdt + sizeof(prdt_t) > desc_limit) {
+				ERROR("UFS: Exceeded descriptor limit. Image is too large\n");
+				panic();
+			}
 			prdt->dba = (unsigned int)(buf & UINT32_MAX);
 			prdt->dbau = (unsigned int)((buf >> 32) & UINT32_MAX);
 			/* prdt->dbc counts from 0 */
@@ -374,14 +513,14 @@
 			}
 			buf += MAX_PRDT_SIZE;
 			prdt++;
-			prdt_size += sizeof(prdt_t);
+			utrd->prdt_length++;
 		}
-		utrd->size_prdt = ALIGN_8(prdt_size);
-		hd->prdtl = utrd->size_prdt >> 2;
+		hd->prdtl = utrd->prdt_length;
 		hd->prdto = (utrd->size_upiu + utrd->size_resp_upiu) >> 2;
 	}
 
-	flush_dcache_range((uintptr_t)utrd->header, UFS_DESC_SIZE);
+	prdt_end = utrd->prdt + utrd->prdt_length * sizeof(prdt_t);
+	flush_dcache_range(utrd->header, prdt_end - utrd->header);
 	return 0;
 }
 
@@ -473,21 +612,22 @@
 	mmio_setbits_32(ufs_params.reg_base + UTRLDBR, 1 << slot);
 }
 
-static int ufs_check_resp(utp_utrd_t *utrd, int trans_type)
+static int ufs_check_resp(utp_utrd_t *utrd, int trans_type, unsigned int timeout_ms)
 {
 	utrd_header_t *hd;
 	resp_upiu_t *resp;
 	sense_data_t *sense;
 	unsigned int data;
-	int slot;
+	int slot, result;
 
 	hd = (utrd_header_t *)utrd->header;
 	resp = (resp_upiu_t *)utrd->resp_upiu;
-	do {
-		data = mmio_read_32(ufs_params.reg_base + IS);
-		if ((data & ~(UFS_INT_UCCS | UFS_INT_UTRCS)) != 0)
-			return -EIO;
-	} while ((data & UFS_INT_UTRCS) == 0);
+
+	result = ufs_wait_for_int_status(UFS_INT_UTRCS, timeout_ms, false);
+	if (result != 0) {
+		return result;
+	}
+
 	slot = utrd->task_tag - 1;
 
 	data = mmio_read_32(ufs_params.reg_base + UTRLDBR);
@@ -511,6 +651,7 @@
 
 	(void)resp;
 	(void)slot;
+	(void)data;
 	return 0;
 }
 
@@ -524,7 +665,7 @@
 		result = ufs_prepare_cmd(utrd, cmd_op, lun, lba, buf, length);
 		assert(result == 0);
 		ufs_send_request(utrd->task_tag);
-		result = ufs_check_resp(utrd, RESPONSE_UPIU);
+		result = ufs_check_resp(utrd, RESPONSE_UPIU, CMD_TIMEOUT_MS);
 		if (result == 0 || result == -EIO) {
 			break;
 		}
@@ -575,7 +716,7 @@
 	get_utrd(&utrd);
 	ufs_prepare_nop_out(&utrd);
 	ufs_send_request(utrd.task_tag);
-	result = ufs_check_resp(&utrd, NOP_IN_UPIU);
+	result = ufs_check_resp(&utrd, NOP_IN_UPIU, NOP_OUT_TIMEOUT_MS);
 	assert(result == 0);
 	(void)result;
 }
@@ -608,7 +749,7 @@
 	get_utrd(&utrd);
 	ufs_prepare_query(&utrd, op, idn, index, sel, buf, size);
 	ufs_send_request(utrd.task_tag);
-	result = ufs_check_resp(&utrd, QUERY_RESPONSE_UPIU);
+	result = ufs_check_resp(&utrd, QUERY_RESPONSE_UPIU, QUERY_REQ_TIMEOUT_MS);
 	assert(result == 0);
 	resp = (query_resp_upiu_t *)utrd.resp_upiu;
 #ifdef UFS_RESP_DEBUG
@@ -896,6 +1037,11 @@
 		result = ufshc_link_startup(ufs_params.reg_base);
 		assert(result == 0);
 
+		/* enable all interrupts */
+		data = UFS_INT_UCCS | UFS_INT_UHES | UFS_INT_UHXS | UFS_INT_UPMS;
+		data |= UFS_INT_UTRCS | UFS_INT_ERR;
+		mmio_write_32(ufs_params.reg_base + IE, data);
+
 		ufs_enum();
 
 		ufs_get_device_info(&card);
diff --git a/fdts/fvp-base-psci-common.dtsi b/fdts/fvp-base-psci-common.dtsi
index 7838fde..79cf37d 100644
--- a/fdts/fvp-base-psci-common.dtsi
+++ b/fdts/fvp-base-psci-common.dtsi
@@ -186,10 +186,7 @@
 
 	pmu {
 		compatible = "arm,armv8-pmuv3";
-		interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
 	};
 
 	panel {
diff --git a/fdts/morello-soc.dts b/fdts/morello-soc.dts
index 5f147b7..e87b617 100644
--- a/fdts/morello-soc.dts
+++ b/fdts/morello-soc.dts
@@ -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
  */
@@ -213,6 +213,29 @@
 		clock-output-names = "aclk";
 	};
 
+	gpu@2d000000 {
+		compatible = "arm,mali-bifrost";
+		reg = <0x0 0x2d000000 0x0 0x4000>;
+		interrupts =
+			<GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
+			<GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
+			<GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names =
+			"gpu",
+			"job",
+			"mmu";
+		clocks = <&clk_gpu>;
+		clock-names = "clk_mali";
+		status = "okay";
+	};
+
+	clk_gpu: clk_gpu {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <650000000>;
+		clock-output-names = "clk_mali";
+	};
+
 	firmware {
 		scmi {
 			compatible = "arm,scmi";
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/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/fdts/tc.dts b/fdts/tc.dts
index 192f407..4f27589 100644
--- a/fdts/tc.dts
+++ b/fdts/tc.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
  */
@@ -456,13 +456,25 @@
 		clock-names = "mclk", "apb_pclk";
 	};
 
+	gpu_clk: gpu_clk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <1000000000>;
+	};
+
+	gpu_core_clk: gpu_core_clk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <1000000000>;
+	};
+
 	gpu: gpu@2d000000 {
 		compatible = "arm,mali-midgard";
 		reg = <0x0 0x2d000000 0x0 0x200000>;
 		interrupts = <0 66 4>, <0 67 4>, <0 65 4>;
 		interrupt-names = "JOB", "MMU", "GPU";
-		clocks = <&soc_refclk100mhz>;
-		clock-names = "clk_mali";
+		clocks = <&gpu_clk>, <&gpu_core_clk>;
+		clock-names = "clk_mali", "shadercores";
 		iommus = <&smmu_700 0x200>;
 		operating-points = <
 			/* KHz uV */
@@ -470,6 +482,18 @@
 		>;
 	};
 
+	power_model@simple {
+		/*
+		 * Numbers used are irrelevant to Titan,
+		 * it helps suppressing the kernel warnings.
+		 */
+		compatible = "arm,mali-simple-power-model";
+		static-coefficient = <2427750>;
+		dynamic-coefficient = <4687>;
+		ts = <20000 2000 (-20) 2>;
+		thermal-zone = "";
+	};
+
 	smmu_700: smmu_700@3f000000 {
 		#iommu-cells = <1>;
 		compatible = "arm,smmu-v3";
@@ -519,6 +543,15 @@
 		};
 	};
 
+	/*
+	 * L3 cache in the DSU is the Memory System Component (MSC)
+	 * The MPAM registers are accessed through utility bus in the DSU
+	 */
+	msc0 {
+		compatible = "arm,mpam-msc";
+		reg = <0x1 0x00010000 0x0 0x2000>;
+	};
+
 	ete0 {
 		compatible = "arm,embedded-trace-extension";
 		cpu = <&CPU0>;
diff --git a/include/arch/aarch32/arch_features.h b/include/arch/aarch32/arch_features.h
index ddf0968..7c25b99 100644
--- a/include/arch/aarch32/arch_features.h
+++ b/include/arch/aarch32/arch_features.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
  */
@@ -10,17 +10,92 @@
 #include <stdbool.h>
 
 #include <arch_helpers.h>
+#include <common/feat_detect.h>
+
+#define ISOLATE_FIELD(reg, feat)					\
+	((unsigned int)(((reg) >> (feat ## _SHIFT)) & (feat ## _MASK)))
 
 static inline bool is_armv7_gentimer_present(void)
 {
-	return ((read_id_pfr1() >> ID_PFR1_GENTIMER_SHIFT) &
-		ID_PFR1_GENTIMER_MASK) != 0U;
+	return ISOLATE_FIELD(read_id_pfr1(), ID_PFR1_GENTIMER) != 0U;
 }
 
 static inline bool is_armv8_2_ttcnp_present(void)
 {
+	return ISOLATE_FIELD(read_id_mmfr4(), ID_MMFR4_CNP) != 0U;
+}
+
+static unsigned int read_feat_amu_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_pfr0(), ID_PFR0_AMU);
+}
+
+static inline bool is_feat_amu_supported(void)
+{
+	if (ENABLE_FEAT_AMU == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_AMU == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_amu_id_field() >= ID_PFR0_AMU_V1;
+}
+
+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);
+}
+
+static inline bool is_feat_trf_supported(void)
+{
+	if (ENABLE_TRF_FOR_NS == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_TRF_FOR_NS == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_trf_id_field() != 0U;
+}
+
+static inline unsigned int read_feat_coptrc_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_dfr0(), ID_DFR0_COPTRC);
+}
+
+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 bool is_feat_spe_supported(void)
+{
-	return ((read_id_mmfr4() >> ID_MMFR4_CNP_SHIFT) &
-		ID_MMFR4_CNP_MASK) != 0U;
+	/* FEAT_SPE is AArch64 only */
+	return false;
 }
 
 #endif /* ARCH_FEATURES_H */
diff --git a/include/arch/aarch32/el3_common_macros.S b/include/arch/aarch32/el3_common_macros.S
index 8b6765a..585a9ae 100644
--- a/include/arch/aarch32/el3_common_macros.S
+++ b/include/arch/aarch32/el3_common_macros.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -374,7 +374,7 @@
 	 * ---------------------------------------------------------------------
 	 */
 	.if \_init_c_runtime
-#if defined(IMAGE_BL32) || (defined(IMAGE_BL2) && BL2_AT_EL3)
+#if defined(IMAGE_BL32) || (defined(IMAGE_BL2) && RESET_TO_BL2)
 		/* -----------------------------------------------------------------
 		 * Invalidate the RW memory used by the image. This
 		 * includes the data and NOBITS sections. This is done to
@@ -426,7 +426,8 @@
 		/* Restore r12 */
 		mov	r12, r7
 
-#if defined(IMAGE_BL1) || (defined(IMAGE_BL2) && BL2_AT_EL3 && BL2_IN_XIP_MEM)
+#if defined(IMAGE_BL1) || \
+	(defined(IMAGE_BL2) && RESET_TO_BL2 && BL2_IN_XIP_MEM)
 		/* -----------------------------------------------------
 		 * Copy data from ROM to RAM.
 		 * -----------------------------------------------------
diff --git a/include/arch/aarch32/smccc_helpers.h b/include/arch/aarch32/smccc_helpers.h
index 2ce7874..8876da9 100644
--- a/include/arch/aarch32/smccc_helpers.h
+++ b/include/arch/aarch32/smccc_helpers.h
@@ -90,21 +90,21 @@
  * ensure that the assembler and the compiler view of the offsets of
  * the structure members is the same.
  */
-CASSERT(SMC_CTX_GPREG_R0 == __builtin_offsetof(smc_ctx_t, r0), \
+CASSERT(SMC_CTX_GPREG_R0 == __builtin_offsetof(smc_ctx_t, r0),
 	assert_smc_ctx_greg_r0_offset_mismatch);
-CASSERT(SMC_CTX_GPREG_R1 == __builtin_offsetof(smc_ctx_t, r1), \
+CASSERT(SMC_CTX_GPREG_R1 == __builtin_offsetof(smc_ctx_t, r1),
 	assert_smc_ctx_greg_r1_offset_mismatch);
-CASSERT(SMC_CTX_GPREG_R2 == __builtin_offsetof(smc_ctx_t, r2), \
+CASSERT(SMC_CTX_GPREG_R2 == __builtin_offsetof(smc_ctx_t, r2),
 	assert_smc_ctx_greg_r2_offset_mismatch);
-CASSERT(SMC_CTX_GPREG_R3 == __builtin_offsetof(smc_ctx_t, r3), \
+CASSERT(SMC_CTX_GPREG_R3 == __builtin_offsetof(smc_ctx_t, r3),
 	assert_smc_ctx_greg_r3_offset_mismatch);
-CASSERT(SMC_CTX_GPREG_R4 == __builtin_offsetof(smc_ctx_t, r4), \
+CASSERT(SMC_CTX_GPREG_R4 == __builtin_offsetof(smc_ctx_t, r4),
 	assert_smc_ctx_greg_r4_offset_mismatch);
-CASSERT(SMC_CTX_SP_USR == __builtin_offsetof(smc_ctx_t, sp_usr), \
+CASSERT(SMC_CTX_SP_USR == __builtin_offsetof(smc_ctx_t, sp_usr),
 	assert_smc_ctx_sp_usr_offset_mismatch);
-CASSERT(SMC_CTX_LR_MON == __builtin_offsetof(smc_ctx_t, lr_mon), \
+CASSERT(SMC_CTX_LR_MON == __builtin_offsetof(smc_ctx_t, lr_mon),
 	assert_smc_ctx_lr_mon_offset_mismatch);
-CASSERT(SMC_CTX_SPSR_MON == __builtin_offsetof(smc_ctx_t, spsr_mon), \
+CASSERT(SMC_CTX_SPSR_MON == __builtin_offsetof(smc_ctx_t, spsr_mon),
 	assert_smc_ctx_spsr_mon_offset_mismatch);
 
 CASSERT((sizeof(smc_ctx_t) & 0x7U) == 0U, assert_smc_ctx_not_aligned);
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 9e13c3d..2ce1be8 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2020-2022, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -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
@@ -349,6 +352,12 @@
 #define ID_AA64MMFR2_EL1_NV_SUPPORTED		ULL(0x1)
 #define ID_AA64MMFR2_EL1_NV2_SUPPORTED		ULL(0x2)
 
+/* ID_AA64MMFR3_EL1 definitions */
+#define ID_AA64MMFR3_EL1			S3_0_C0_C7_3
+
+#define ID_AA64MMFR3_EL1_TCRX_SHIFT		U(0)
+#define ID_AA64MMFR3_EL1_TCRX_MASK		ULL(0xf)
+
 /* ID_AA64PFR1_EL1 definitions */
 #define ID_AA64PFR1_EL1_SSBS_SHIFT	U(4)
 #define ID_AA64PFR1_EL1_SSBS_MASK	ULL(0xf)
@@ -384,8 +393,10 @@
 #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)
 
 /* ID_PFR1_EL1 definitions */
 #define ID_PFR1_VIRTEXT_SHIFT	U(12)
@@ -501,6 +512,7 @@
 #define SCR_GPF_BIT		(UL(1) << 48)
 #define SCR_TWEDEL_SHIFT	U(30)
 #define SCR_TWEDEL_MASK		ULL(0xf)
+#define SCR_TCR2EN_BIT		(UL(1) << 43)
 #define SCR_TRNDR_BIT		(UL(1) << 40)
 #define SCR_HXEn_BIT		(UL(1) << 38)
 #define SCR_ENTP2_SHIFT		U(41)
@@ -994,7 +1006,9 @@
 #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)
 
 /* SMCR_ELx definitions */
 #define SMCR_ELX_LEN_SHIFT		U(0)
@@ -1063,13 +1077,15 @@
 #define PMBLIMITR_EL1		S3_0_C9_C10_0
 
 /*******************************************************************************
- * Definitions for system register interface to MPAM
+ * Definitions for system register interface, shifts and masks for MPAM
  ******************************************************************************/
 #define MPAMIDR_EL1		S3_0_C10_C4_4
 #define MPAM2_EL2		S3_4_C10_C5_0
 #define MPAMHCR_EL2		S3_4_C10_C4_0
 #define MPAM3_EL3		S3_6_C10_C5_0
 
+#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
  ******************************************************************************/
@@ -1298,6 +1314,11 @@
 #define HCRX_EL2_EnAS0_BIT	(UL(1) << 0)
 
 /*******************************************************************************
+ * FEAT_TCR2 - Extended Translation Control Register
+ ******************************************************************************/
+#define TCR2_EL2		S3_4_C2_C0_3
+
+/*******************************************************************************
  * Definitions for DynamicIQ Shared Unit registers
  ******************************************************************************/
 #define CLUSTERPWRDN_EL1	S3_0_c15_c3_6
@@ -1319,4 +1340,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 2b801ac..3ea08a6 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.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
  */
@@ -12,24 +12,51 @@
 #include <arch_helpers.h>
 #include <common/feat_detect.h>
 
+#define ISOLATE_FIELD(reg, feat)					\
+	((unsigned int)(((reg) >> (feat ## _SHIFT)) & (feat ## _MASK)))
+
 static inline bool is_armv7_gentimer_present(void)
 {
 	/* The Generic Timer is always present in an ARMv8-A implementation */
 	return true;
 }
 
+static inline unsigned int read_feat_pan_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr1_el1(), ID_AA64MMFR1_EL1_PAN);
+}
+
-static inline bool is_armv8_1_pan_present(void)
+static inline bool is_feat_pan_supported(void)
 {
-	return ((read_id_aa64mmfr1_el1() >> ID_AA64MMFR1_EL1_PAN_SHIFT) &
-		ID_AA64MMFR1_EL1_PAN_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 bool is_armv8_1_vhe_present(void)
+static inline unsigned int read_feat_vhe_id_field(void)
 {
-	return ((read_id_aa64mmfr1_el1() >> ID_AA64MMFR1_EL1_VHE_SHIFT) &
-		ID_AA64MMFR1_EL1_VHE_MASK) != 0U;
+	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)
 {
 	return ((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_CNP_SHIFT) &
@@ -86,22 +113,45 @@
 		ID_AA64PFR1_EL1_MTE_MASK);
 }
 
+static inline unsigned int read_feat_sel2_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_SEL2);
+}
+
+static inline bool is_feat_sel2_supported(void)
+{
+	if (ENABLE_FEAT_SEL2 == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_SEL2 == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_sel2_id_field() != 0U;
+}
+
-static inline bool is_armv8_4_sel2_present(void)
+static inline unsigned int read_feat_twed_id_field(void)
 {
-	return ((read_id_aa64pfr0_el1() >> ID_AA64PFR0_SEL2_SHIFT) &
-		ID_AA64PFR0_SEL2_MASK) == 1ULL;
+	return ISOLATE_FIELD(read_id_aa64mmfr1_el1(), ID_AA64MMFR1_EL1_TWED);
 }
 
-static inline bool is_armv8_6_twed_present(void)
+static inline bool is_feat_twed_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_TWED == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_TWED == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_twed_id_field() != 0U;
 }
 
 static unsigned int read_feat_fgt_id_field(void)
 {
-	return (read_id_aa64mmfr0_el1() >> ID_AA64MMFR0_EL1_FGT_SHIFT) &
-		ID_AA64MMFR0_EL1_FGT_MASK;
+	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(), ID_AA64MMFR0_EL1_FGT);
 }
 
 static inline bool is_feat_fgt_supported(void)
@@ -117,16 +167,71 @@
 	return read_feat_fgt_id_field() != 0U;
 }
 
+static unsigned int read_feat_ecv_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(), ID_AA64MMFR0_EL1_ECV);
+}
+
+static inline bool is_feat_ecv_supported(void)
+{
+	if (ENABLE_FEAT_ECV == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_ECV == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_ecv_id_field() != 0U;
+}
+
+static inline bool is_feat_ecv_v2_supported(void)
+{
+	if (ENABLE_FEAT_ECV == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_ECV == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_ecv_id_field() >= ID_AA64MMFR0_EL1_ECV_SELF_SYNCH;
+}
+
+static unsigned int read_feat_rng_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64isar0_el1(), ID_AA64ISAR0_RNDR);
+}
+
+static inline bool is_feat_rng_supported(void)
+{
+	if (ENABLE_FEAT_RNG == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_RNG == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_rng_id_field() != 0U;
+}
+
-static inline unsigned long int get_armv8_6_ecv_support(void)
+static unsigned int read_feat_tcrx_id_field(void)
 {
-	return ((read_id_aa64mmfr0_el1() >> ID_AA64MMFR0_EL1_ECV_SHIFT) &
-		ID_AA64MMFR0_EL1_ECV_MASK);
+	return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_TCRX);
 }
 
-static inline bool is_armv8_5_rng_present(void)
+static inline bool is_feat_tcr2_supported(void)
 {
-	return ((read_id_aa64isar0_el1() >> ID_AA64ISAR0_RNDR_SHIFT) &
-		ID_AA64ISAR0_RNDR_MASK);
+	if (ENABLE_FEAT_TCR2 == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_TCR2 == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_tcrx_id_field() != 0U;
 }
 
 /*******************************************************************************
@@ -134,25 +239,32 @@
  ******************************************************************************/
 static unsigned int read_feat_amu_id_field(void)
 {
-	return (read_id_aa64pfr0_el1() >> ID_AA64PFR0_AMU_SHIFT) &
-		ID_AA64PFR0_AMU_MASK;
+	return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_AMU);
 }
 
 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;
 }
 
@@ -165,7 +277,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) |
@@ -173,10 +285,22 @@
 		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 (read_id_aa64mmfr1_el1() >> ID_AA64MMFR1_EL1_HCX_SHIFT) &
-		ID_AA64MMFR1_EL1_HCX_MASK;
+	return ISOLATE_FIELD(read_id_aa64mmfr1_el1(), ID_AA64MMFR1_EL1_HCX);
 }
 
 static inline bool is_feat_hcx_supported(void)
@@ -213,37 +337,72 @@
 /*********************************************************************************
  * 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 (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_CSV2_SHIFT) &
-		ID_AA64PFR0_CSV2_MASK) == ID_AA64PFR0_CSV2_2_SUPPORTED);
+	return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_CSV2);
 }
 
+static inline bool is_feat_csv2_2_supported(void)
+{
+	if (ENABLE_FEAT_CSV2_2 == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_CSV2_2 == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_csv2_id_field() >= ID_AA64PFR0_CSV2_2_SUPPORTED;
+}
+
 /**********************************************************************************
  * Function to identify the presence of FEAT_SPE (Statistical Profiling Extension)
  *********************************************************************************/
-static inline 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);
+}
+
+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;
 }
 
 /*******************************************************************************
@@ -265,42 +424,134 @@
 		ID_AA64PFR0_DIT_MASK) == ID_AA64PFR0_DIT_SUPPORTED);
 }
 
+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)
  ************************************************************************/
-static inline bool is_arm8_4_feat_trf_present(void)
+static inline unsigned int read_feat_trf_id_field(void)
 {
-	return (((read_id_aa64dfr0_el1() >> ID_AA64DFR0_TRACEFILT_SHIFT) &
-		ID_AA64DFR0_TRACEFILT_MASK) == ID_AA64DFR0_TRACEFILT_SUPPORTED);
+	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_TRACEFILT);
 }
 
+static inline bool is_feat_trf_supported(void)
+{
+	if (ENABLE_TRF_FOR_NS == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_TRF_FOR_NS == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_trf_id_field() != 0U;
+}
+
 /********************************************************************************
  * 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 ISOLATE_FIELD(read_id_aa64mmfr2_el1(), ID_AA64MMFR2_EL1_NV);
+}
+
+static inline bool is_feat_nv2_supported(void)
 {
-	return (((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_NV_SHIFT) &
-		ID_AA64MMFR2_EL1_NV_MASK));
+	if (CTX_INCLUDE_NEVE_REGS == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (CTX_INCLUDE_NEVE_REGS == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_nv_id_field() >= ID_AA64MMFR2_EL1_NV2_SUPPORTED;
 }
 
 /*******************************************************************************
  * Function to identify the presence of FEAT_BRBE (Branch Record Buffer
  * Extension)
  ******************************************************************************/
-static inline bool is_feat_brbe_present(void)
+static inline unsigned int read_feat_brbe_id_field(void)
 {
-	return (((read_id_aa64dfr0_el1() >> ID_AA64DFR0_BRBE_SHIFT) &
-		ID_AA64DFR0_BRBE_MASK) == ID_AA64DFR0_BRBE_SUPPORTED);
+	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_BRBE);
 }
 
+static inline bool is_feat_brbe_supported(void)
+{
+	if (ENABLE_BRBE_FOR_NS == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_BRBE_FOR_NS == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_brbe_id_field() != 0U;
+}
+
 /*******************************************************************************
  * Function to identify the presence of FEAT_TRBE (Trace Buffer Extension)
  ******************************************************************************/
-static inline bool is_feat_trbe_present(void)
+static inline unsigned int read_feat_trbe_id_field(void)
 {
-	return (((read_id_aa64dfr0_el1() >> ID_AA64DFR0_TRACEBUFFER_SHIFT) &
-		ID_AA64DFR0_TRACEBUFFER_MASK) == ID_AA64DFR0_TRACEBUFFER_SUPPORTED);
+	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_TRACEBUFFER);
+}
+
+static inline bool is_feat_trbe_supported(void)
+{
+	if (ENABLE_TRBE_FOR_NS == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_TRBE_FOR_NS == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_trbe_id_field() != 0U;
+
+}
+/*******************************************************************************
+ * Function to identify the presence of FEAT_SMEx (Scalar Matrix Extension)
+ ******************************************************************************/
+static inline unsigned int read_feat_sme_fa64_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64smfr0_el1(), ID_AA64SMFR0_EL1_SME_FA64);
+}
+
+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;
 }
 
 #endif /* ARCH_FEATURES_H */
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index 86c1dbe..04b64be 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,30 @@
 DEFINE_RENAME_SYSREG_READ_FUNC(erxmisc0_el1, ERXMISC0_EL1)
 DEFINE_RENAME_SYSREG_READ_FUNC(erxmisc1_el1, ERXMISC1_EL1)
 
+DEFINE_RENAME_SYSREG_RW_FUNCS(scxtnum_el2, SCXTNUM_EL2)
+
-/* Armv8.2 Registers */
+/* 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 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)
@@ -555,6 +571,10 @@
 /* Armv8.4 Data Independent Timing Register */
 DEFINE_RENAME_SYSREG_RW_FUNCS(dit, DIT)
 
+/* 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)
 DEFINE_RENAME_SYSREG_RW_FUNCS(tfsr_el1, TFSR_EL1)
@@ -573,9 +593,18 @@
 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)
 
+/* Armv8.9 system registers */
+DEFINE_RENAME_IDREG_READ_FUNC(id_aa64mmfr3_el1, ID_AA64MMFR3_EL1)
+
+/* FEAT_TCR2 Register */
+DEFINE_RENAME_SYSREG_RW_FUNCS(tcr2_el2, TCR2_EL2)
+
 /* DynamIQ Shared Unit power management */
 DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpwrdn_el1, CLUSTERPWRDN_EL1)
 
@@ -689,7 +718,7 @@
 	isb();	\
 }
 #else
-#define AT(_at_inst, _va)	_at_inst(_va);
+#define AT(_at_inst, _va)	_at_inst(_va)
 #endif
 
 #endif /* ARCH_HELPERS_H */
diff --git a/include/arch/aarch64/asm_macros.S b/include/arch/aarch64/asm_macros.S
index 66c39e5..b4dab08 100644
--- a/include/arch/aarch64/asm_macros.S
+++ b/include/arch/aarch64/asm_macros.S
@@ -215,12 +215,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 +246,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 7bf4806..dcaea3d 100644
--- a/include/arch/aarch64/el2_common_macros.S
+++ b/include/arch/aarch64/el2_common_macros.S
@@ -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
  */
@@ -347,7 +347,8 @@
 		sub	x1, x1, x0
 		bl	zeromem
 
-#if defined(IMAGE_BL1) || (defined(IMAGE_BL2) && BL2_AT_EL3 && BL2_IN_XIP_MEM)
+#if defined(IMAGE_BL1) || (defined(IMAGE_BL2) && \
+	RESET_TO_BL2 && BL2_IN_XIP_MEM)
 		adrp	x0, __DATA_RAM_START__
 		add	x0, x0, :lo12:__DATA_RAM_START__
 		adrp	x1, __DATA_ROM_START__
@@ -384,13 +385,12 @@
 	.macro	apply_at_speculative_wa
 #if ERRATA_SPECULATIVE_AT
 	/*
-	 * Explicitly save x30 so as to free up a register and to enable
-	 * branching and also, save x29 which will be used in the called
-	 * function
+	 * This function expects x30 has been saved.
+	 * Also, save x29 which will be used in the called function.
 	 */
-	stp	x29, x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X29]
+	str	x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X29]
 	bl	save_and_update_ptw_el1_sys_regs
-	ldp	x29, x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X29]
+	ldr	x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X29]
 #endif
 	.endm
 
diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S
index de2b931..45a86c1 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -433,7 +433,7 @@
 	 */
 	.if \_init_c_runtime
 #if defined(IMAGE_BL31) || (defined(IMAGE_BL2) && \
-	((BL2_AT_EL3 && BL2_INV_DCACHE) || ENABLE_RME))
+	((RESET_TO_BL2 && BL2_INV_DCACHE) || ENABLE_RME))
 		/* -------------------------------------------------------------
 		 * Invalidate the RW memory used by the BL31 image. This
 		 * includes the data and NOBITS sections. This is done to
@@ -495,7 +495,8 @@
 		bl	zeromem
 #endif
 
-#if defined(IMAGE_BL1) || (defined(IMAGE_BL2) && BL2_AT_EL3 && BL2_IN_XIP_MEM)
+#if defined(IMAGE_BL1) ||	\
+	(defined(IMAGE_BL2) && RESET_TO_BL2 && BL2_IN_XIP_MEM)
 		adrp	x0, __DATA_RAM_START__
 		add	x0, x0, :lo12:__DATA_RAM_START__
 		adrp	x1, __DATA_ROM_START__
@@ -532,13 +533,12 @@
 	.macro	apply_at_speculative_wa
 #if ERRATA_SPECULATIVE_AT
 	/*
-	 * Explicitly save x30 so as to free up a register and to enable
-	 * branching and also, save x29 which will be used in the called
-	 * function
+	 * This function expects x30 has been saved.
+	 * Also, save x29 which will be used in the called function.
 	 */
-	stp	x29, x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X29]
+	str	x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X29]
 	bl	save_and_update_ptw_el1_sys_regs
-	ldp	x29, x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X29]
+	ldr	x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X29]
 #endif
 	.endm
 
diff --git a/include/arch/aarch64/smccc_helpers.h b/include/arch/aarch64/smccc_helpers.h
index 920f294..950a811 100644
--- a/include/arch/aarch64/smccc_helpers.h
+++ b/include/arch/aarch64/smccc_helpers.h
@@ -75,6 +75,24 @@
 #define SMC_SET_GP(_h, _g, _v)					\
 	write_ctx_reg((get_gpregs_ctx(_h)), (_g), (_v))
 
+
+/* Useful for SMCCCv1.2 */
+#define SMC_RET18(_h, _x0, _x1, _x2, _x3, _x4, _x5, _x6, _x7, _x8, _x9, \
+		_x10, _x11, _x12, _x13, _x14, _x15, _x16, _x17) {	\
+	SMC_SET_GP(_h, CTX_GPREG_X8, _x8);				\
+	SMC_SET_GP(_h, CTX_GPREG_X9, _x9);				\
+	SMC_SET_GP(_h, CTX_GPREG_X10, _x10);				\
+	SMC_SET_GP(_h, CTX_GPREG_X11, _x11);				\
+	SMC_SET_GP(_h, CTX_GPREG_X12, _x12);				\
+	SMC_SET_GP(_h, CTX_GPREG_X13, _x13);				\
+	SMC_SET_GP(_h, CTX_GPREG_X14, _x14);				\
+	SMC_SET_GP(_h, CTX_GPREG_X15, _x15);				\
+	SMC_SET_GP(_h, CTX_GPREG_X16, _x16);				\
+	SMC_SET_GP(_h, CTX_GPREG_X17, _x17);				\
+	SMC_RET8(_h, (_x0), (_x1), (_x2), (_x3), (_x4), (_x5), (_x6),	\
+		(_x7));							\
+}
+
 /*
  * Convenience macros to access EL3 context registers using handle provided to
  * SMC handler. These take the offset values defined in context.h
diff --git a/include/bl1/bl1.h b/include/bl1/bl1.h
index 21d3ae7..7cd7e72 100644
--- a/include/bl1/bl1.h
+++ b/include/bl1/bl1.h
@@ -90,8 +90,8 @@
 /*
  * Check if the total number of FWU SMC calls are as expected.
  */
-CASSERT(FWU_NUM_SMC_CALLS == 	\
-		(FWU_SMC_FID_END - FWU_SMC_FID_START + 1),\
+CASSERT(FWU_NUM_SMC_CALLS ==
+		(FWU_SMC_FID_END - FWU_SMC_FID_START + 1),
 		assert_FWU_NUM_SMC_CALLS_mismatch);
 
 /* Utility functions */
diff --git a/include/common/bl_common.ld.h b/include/common/bl_common.ld.h
index 080e331..c9bed1a 100644
--- a/include/common/bl_common.ld.h
+++ b/include/common/bl_common.ld.h
@@ -24,7 +24,7 @@
 #define CPU_OPS						\
 	. = ALIGN(STRUCT_ALIGN);			\
 	__CPU_OPS_START__ = .;				\
-	KEEP(*(cpu_ops))				\
+	KEEP(*(.cpu_ops))				\
 	__CPU_OPS_END__ = .;
 
 #define PARSER_LIB_DESCS				\
@@ -36,14 +36,14 @@
 #define RT_SVC_DESCS					\
 	. = ALIGN(STRUCT_ALIGN);			\
 	__RT_SVC_DESCS_START__ = .;			\
-	KEEP(*(rt_svc_descs))				\
+	KEEP(*(.rt_svc_descs))				\
 	__RT_SVC_DESCS_END__ = .;
 
 #if SPMC_AT_EL3
 #define EL3_LP_DESCS					\
 	. = ALIGN(STRUCT_ALIGN);			\
 	__EL3_LP_DESCS_START__ = .;			\
-	KEEP(*(el3_lp_descs))				\
+	KEEP(*(.el3_lp_descs))				\
 	__EL3_LP_DESCS_END__ = .;
 #else
 #define EL3_LP_DESCS
@@ -52,7 +52,7 @@
 #define PMF_SVC_DESCS					\
 	. = ALIGN(STRUCT_ALIGN);			\
 	__PMF_SVC_DESCS_START__ = .;			\
-	KEEP(*(pmf_svc_descs))				\
+	KEEP(*(.pmf_svc_descs))				\
 	__PMF_SVC_DESCS_END__ = .;
 
 #define FCONF_POPULATOR					\
@@ -81,7 +81,7 @@
 #define BASE_XLAT_TABLE					\
 	. = ALIGN(16);					\
 	__BASE_XLAT_TABLE_START__ = .;			\
-	*(base_xlat_table)				\
+	*(.base_xlat_table)				\
 	__BASE_XLAT_TABLE_END__ = .;
 
 #if PLAT_RO_XLAT_TABLES
@@ -135,9 +135,9 @@
 
 #if !(defined(IMAGE_BL31) && RECLAIM_INIT_CODE)
 #define STACK_SECTION					\
-	stacks (NOLOAD) : {				\
+	.stacks (NOLOAD) : {				\
 		__STACKS_START__ = .;			\
-		*(tzfw_normal_stacks)			\
+		*(.tzfw_normal_stacks)			\
 		__STACKS_END__ = .;			\
 	}
 #endif
@@ -170,7 +170,7 @@
 	. = ALIGN(CACHE_WRITEBACK_GRANULE);		\
 	__BAKERY_LOCK_START__ = .;			\
 	__PERCPU_BAKERY_LOCK_START__ = .;		\
-	*(bakery_lock)					\
+	*(.bakery_lock)					\
 	. = ALIGN(CACHE_WRITEBACK_GRANULE);		\
 	__PERCPU_BAKERY_LOCK_END__ = .;			\
 	__PERCPU_BAKERY_LOCK_SIZE__ = ABSOLUTE(__PERCPU_BAKERY_LOCK_END__ - __PERCPU_BAKERY_LOCK_START__); \
@@ -191,7 +191,7 @@
 #define PMF_TIMESTAMP					\
 	. = ALIGN(CACHE_WRITEBACK_GRANULE);		\
 	__PMF_TIMESTAMP_START__ = .;			\
-	KEEP(*(pmf_timestamp_array))			\
+	KEEP(*(.pmf_timestamp_array))			\
 	. = ALIGN(CACHE_WRITEBACK_GRANULE);		\
 	__PMF_PERCPU_TIMESTAMP_END__ = .;		\
 	__PERCPU_TIMESTAMP_SIZE__ = ABSOLUTE(. - __PMF_TIMESTAMP_START__); \
@@ -216,15 +216,15 @@
 	}
 
 /*
- * The xlat_table section is for full, aligned page tables (4K).
+ * The .xlat_table section is for full, aligned page tables (4K).
  * Removing them from .bss avoids forcing 4K alignment on
  * the .bss section. The tables are initialized to zero by the translation
  * tables library.
  */
 #define XLAT_TABLE_SECTION				\
-	xlat_table (NOLOAD) : {				\
+	.xlat_table (NOLOAD) : {				\
 		__XLAT_TABLE_START__ = .;		\
-		*(xlat_table)				\
+		*(.xlat_table)				\
 		__XLAT_TABLE_END__ = .;			\
 	}
 
diff --git a/include/common/debug.h b/include/common/debug.h
index af47999..5ea541d 100644
--- a/include/common/debug.h
+++ b/include/common/debug.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -99,15 +99,31 @@
 #define backtrace(x)
 #endif
 
-void __dead2 do_panic(void);
+void __dead2 el3_panic(void);
+void __dead2 elx_panic(void);
 
 #define panic()				\
 	do {				\
 		backtrace(__func__);	\
 		console_flush();	\
-		do_panic();		\
+		el3_panic();		\
 	} while (false)
 
+#if CRASH_REPORTING
+/* --------------------------------------------------------------------
+ * do_lower_el_panic assumes it's called due to a panic from a lower EL
+ * This call will not return.
+ * --------------------------------------------------------------------
+ */
+#define	lower_el_panic()		\
+	do {				\
+		console_flush();	\
+		elx_panic();		\
+	} while (false)
+#else
+#define	lower_el_panic()
+#endif
+
 /* Function called when stack protection check code detects a corrupted stack */
 void __dead2 __stack_chk_fail(void);
 
diff --git a/include/common/fdt_wrappers.h b/include/common/fdt_wrappers.h
index 2929fc2..b16510f 100644
--- a/include/common/fdt_wrappers.h
+++ b/include/common/fdt_wrappers.h
@@ -10,6 +10,7 @@
 #define FDT_WRAPPERS_H
 
 #include <libfdt_env.h>
+#include <libfdt.h>
 
 /* Number of cells, given total length in bytes. Each cell is 4 bytes long */
 #define NCELLS(len) ((len) / 4U)
@@ -53,6 +54,15 @@
 	return fdt32_to_cpu(dtb_header[1]);
 }
 
+static inline bool fdt_node_is_enabled(const void *fdt, int node)
+{
+	int len;
+	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);
+}
+
 #define fdt_for_each_compatible_node(dtb, node, compatible_str)       \
 for (node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);   \
      node >= 0;                                                       \
diff --git a/include/common/interrupt_props.h b/include/common/interrupt_props.h
index 07bafaa..681c896 100644
--- a/include/common/interrupt_props.h
+++ b/include/common/interrupt_props.h
@@ -19,7 +19,7 @@
 	}
 
 typedef struct interrupt_prop {
-	unsigned int intr_num:10;
+	unsigned int intr_num:13;
 	unsigned int intr_pri:8;
 	unsigned int intr_grp:2;
 	unsigned int intr_cfg:2;
diff --git a/include/common/runtime_svc.h b/include/common/runtime_svc.h
index 472a32a..26e8d6f 100644
--- a/include/common/runtime_svc.h
+++ b/include/common/runtime_svc.h
@@ -72,7 +72,7 @@
  */
 #define DECLARE_RT_SVC(_name, _start, _end, _type, _setup, _smch)	\
 	static const rt_svc_desc_t __svc_desc_ ## _name			\
-		__section("rt_svc_descs") __used = {			\
+		__section(".rt_svc_descs") __used = {			\
 			.start_oen = (_start),				\
 			.end_oen = (_end),				\
 			.call_type = (_type),				\
@@ -90,11 +90,11 @@
  * 3. ensure that the assembler and the compiler see the handler
  *    routine at the same offset.
  */
-CASSERT((sizeof(rt_svc_desc_t) == SIZEOF_RT_SVC_DESC), \
+CASSERT((sizeof(rt_svc_desc_t) == SIZEOF_RT_SVC_DESC),
 	assert_sizeof_rt_svc_desc_mismatch);
-CASSERT(RT_SVC_DESC_INIT == __builtin_offsetof(rt_svc_desc_t, init), \
+CASSERT(RT_SVC_DESC_INIT == __builtin_offsetof(rt_svc_desc_t, init),
 	assert_rt_svc_desc_init_offset_mismatch);
-CASSERT(RT_SVC_DESC_HANDLE == __builtin_offsetof(rt_svc_desc_t, handle), \
+CASSERT(RT_SVC_DESC_HANDLE == __builtin_offsetof(rt_svc_desc_t, handle),
 	assert_rt_svc_desc_handle_offset_mismatch);
 
 
diff --git a/include/common/tbbr/cot_def.h b/include/common/tbbr/cot_def.h
index 60dfb8a..822c474 100644
--- a/include/common/tbbr/cot_def.h
+++ b/include/common/tbbr/cot_def.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
  */
@@ -7,8 +7,13 @@
 #ifndef COT_DEF_H
 #define COT_DEF_H
 
+/*
+ * Guard here with availability of mbedtls config since PLAT=lx2162aqds
+ * uses custom tbbr from 'drivers/nxp/auth/tbbr/tbbr_cot.c'  and also may
+ * build without mbedtls folder only with TRUSTED_BOOT enabled.
+ */
 #ifdef MBEDTLS_CONFIG_FILE
-#include MBEDTLS_CONFIG_FILE
+#include <mbedtls/version.h>
 #endif
 
 /* TBBR CoT definitions */
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/auth/auth_mod.h b/include/drivers/auth/auth_mod.h
index 94537f6..28aa407 100644
--- a/include/drivers/auth/auth_mod.h
+++ b/include/drivers/auth/auth_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
  */
@@ -7,7 +7,6 @@
 #ifndef AUTH_MOD_H
 #define AUTH_MOD_H
 
-#include <common/tbbr/cot_def.h>
 #include <common/tbbr/tbbr_img_def.h>
 #include <drivers/auth/auth_common.h>
 #include <drivers/auth/img_parser_mod.h>
diff --git a/include/drivers/auth/mbedtls/mbedtls_config.h b/include/drivers/auth/mbedtls/mbedtls_config-2.h
similarity index 100%
rename from include/drivers/auth/mbedtls/mbedtls_config.h
rename to include/drivers/auth/mbedtls/mbedtls_config-2.h
diff --git a/include/drivers/auth/mbedtls/mbedtls_config-3.h b/include/drivers/auth/mbedtls/mbedtls_config-3.h
new file mode 100644
index 0000000..ba936a3
--- /dev/null
+++ b/include/drivers/auth/mbedtls/mbedtls_config-3.h
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ *  This set of compile-time options may be used to enable
+ *  or disable features selectively, and reduce the global
+ *  memory footprint.
+ */
+
+/*
+ * Key algorithms currently supported on mbed TLS libraries
+ */
+#define TF_MBEDTLS_RSA			1
+#define TF_MBEDTLS_ECDSA		2
+#define TF_MBEDTLS_RSA_AND_ECDSA	3
+
+#define TF_MBEDTLS_USE_RSA (TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA \
+		|| TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA)
+#define TF_MBEDTLS_USE_ECDSA (TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA \
+		|| TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA)
+
+/*
+ * Hash algorithms currently supported on mbed TLS libraries
+ */
+#define TF_MBEDTLS_SHA256		1
+#define TF_MBEDTLS_SHA384		2
+#define TF_MBEDTLS_SHA512		3
+
+/*
+ * Configuration file to build mbed TLS with the required features for
+ * Trusted Boot
+ */
+
+#define MBEDTLS_PLATFORM_MEMORY
+#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
+/* Prevent mbed TLS from using snprintf so that it can use tf_snprintf. */
+#define MBEDTLS_PLATFORM_SNPRINTF_ALT
+
+#define MBEDTLS_PKCS1_V21
+
+#define MBEDTLS_ASN1_PARSE_C
+#define MBEDTLS_ASN1_WRITE_C
+
+#define MBEDTLS_BASE64_C
+#define MBEDTLS_BIGNUM_C
+
+#define MBEDTLS_ERROR_C
+#define MBEDTLS_MD_C
+
+#define MBEDTLS_MEMORY_BUFFER_ALLOC_C
+#define MBEDTLS_OID_C
+
+#define MBEDTLS_PK_C
+#define MBEDTLS_PK_PARSE_C
+#define MBEDTLS_PK_WRITE_C
+
+#define MBEDTLS_PLATFORM_C
+
+#if TF_MBEDTLS_USE_ECDSA
+#define MBEDTLS_ECDSA_C
+#define MBEDTLS_ECP_C
+#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
+#endif
+#if TF_MBEDTLS_USE_RSA
+#define MBEDTLS_RSA_C
+#define MBEDTLS_X509_RSASSA_PSS_SUPPORT
+#endif
+
+/* The library does not currently support enabling SHA-256 without SHA-224. */
+#define MBEDTLS_SHA224_C
+#define MBEDTLS_SHA256_C
+/*
+ * If either Trusted Boot or Measured Boot require a stronger algorithm than
+ * SHA-256, pull in SHA-512 support. Library currently needs to have SHA_384
+ * support when enabling SHA-512.
+ */
+#if (TF_MBEDTLS_HASH_ALG_ID != TF_MBEDTLS_SHA256) /* TBB hash algo */
+#define MBEDTLS_SHA384_C
+#define	MBEDTLS_SHA512_C
+#else
+   /* TBB uses SHA-256, what about measured boot? */
+#if defined(TF_MBEDTLS_MBOOT_USE_SHA512)
+#define MBEDTLS_SHA384_C
+#define MBEDTLS_SHA512_C
+#endif
+#endif
+
+#define MBEDTLS_VERSION_C
+
+#define MBEDTLS_X509_USE_C
+#define MBEDTLS_X509_CRT_PARSE_C
+
+#if TF_MBEDTLS_USE_AES_GCM
+#define MBEDTLS_AES_C
+#define MBEDTLS_CIPHER_C
+#define MBEDTLS_GCM_C
+#endif
+
+/* MPI / BIGNUM options */
+#define MBEDTLS_MPI_WINDOW_SIZE			2
+
+#if TF_MBEDTLS_USE_RSA
+#if TF_MBEDTLS_KEY_SIZE <= 2048
+#define MBEDTLS_MPI_MAX_SIZE			256
+#else
+#define MBEDTLS_MPI_MAX_SIZE			512
+#endif
+#else
+#define MBEDTLS_MPI_MAX_SIZE			256
+#endif
+
+/* Memory buffer allocator options */
+#define MBEDTLS_MEMORY_ALIGN_MULTIPLE		8
+
+/*
+ * Prevent the use of 128-bit division which
+ * creates dependency on external libraries.
+ */
+#define MBEDTLS_NO_UDBL_DIVISION
+
+#ifndef __ASSEMBLER__
+/* System headers required to build mbed TLS with the current configuration */
+#include <stdlib.h>
+#include <mbedtls/check_config.h>
+#endif
+
+/*
+ * Determine Mbed TLS heap size
+ * 13312 = 13*1024
+ * 11264 = 11*1024
+ * 7168  = 7*1024
+ */
+#if TF_MBEDTLS_USE_ECDSA
+#define TF_MBEDTLS_HEAP_SIZE		U(13312)
+#elif TF_MBEDTLS_USE_RSA
+#if TF_MBEDTLS_KEY_SIZE <= 2048
+#define TF_MBEDTLS_HEAP_SIZE		U(7168)
+#else
+#define TF_MBEDTLS_HEAP_SIZE		U(11264)
+#endif
+#endif
+
+/*
+ * Warn if errors from certain functions are ignored.
+ *
+ * The warnings are always enabled (where supported) for critical functions
+ * where ignoring the return value is almost always a bug. This macro extends
+ * the warnings to more functions.
+ */
+#define MBEDTLS_CHECK_RETURN_WARNING
diff --git a/include/drivers/auth/tbbr_cot_common.h b/include/drivers/auth/tbbr_cot_common.h
index a51faee..b4f2d22 100644
--- a/include/drivers/auth/tbbr_cot_common.h
+++ b/include/drivers/auth/tbbr_cot_common.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020,2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,7 @@
 #ifndef TBBR_COT_COMMON_H
 #define TBBR_COT_COMMON_H
 
+#include <common/tbbr/cot_def.h>
 #include <drivers/auth/auth_mod.h>
 
 extern unsigned char tb_fw_hash_buf[HASH_DER_LEN];
diff --git a/include/drivers/nxp/dcfg/dcfg.h b/include/drivers/nxp/dcfg/dcfg.h
index cf29b12..ee8f866 100644
--- a/include/drivers/nxp/dcfg/dcfg.h
+++ b/include/drivers/nxp/dcfg/dcfg.h
@@ -93,8 +93,8 @@
  ******************************************************************************/
 bool check_boot_mode_secure(uint32_t *mode);
 
-const soc_info_t *get_soc_info();
-const devdisr5_info_t *get_devdisr5_info();
+const soc_info_t *get_soc_info(void);
+const devdisr5_info_t *get_devdisr5_info(void);
 
 void dcfg_init(dcfg_init_info_t *dcfg_init_data);
 bool is_sec_enabled(void);
diff --git a/include/drivers/ufs.h b/include/drivers/ufs.h
index 1cd1bee..2a63fd4 100644
--- a/include/drivers/ufs.h
+++ b/include/drivers/ufs.h
@@ -57,6 +57,21 @@
 /* UTP Transfer Request Completion Status */
 #define UFS_INT_UTRCS			(1 << 0)
 
+#define UFS_INT_FATAL			(UFS_INT_DFES |\
+					 UFS_INT_HCFES |\
+					 UFS_INT_SBFES)
+#define UFS_INT_ERR			(UFS_INT_FATAL |\
+					 UFS_INT_UE)
+
+#define UFS_UIC_PA_ERROR_MASK		0x8000001F
+#define UFS_UIC_DL_ERROR_MASK		0x8000FFFF
+#define UFS_UIC_NL_ERROR_MASK		0x80000007
+#define UFS_UIC_TL_ERROR_MASK		0x8000007F
+#define UFS_UIC_DME_ERROR_MASK		0x80000001
+
+#define PA_INIT_ERR			(1 << 13)
+#define PA_LAYER_GEN_ERR		(1 << 4)
+
 /* Host Controller Status */
 #define HCS				0x30
 #define HCS_UPMCRS_MASK			(7 << 8)
@@ -275,6 +290,11 @@
 
 #define FDEVICEINIT_TIMEOUT_MS	        1500
 
+#define UIC_CMD_TIMEOUT_MS		500
+#define QUERY_REQ_TIMEOUT_MS		1500
+#define NOP_OUT_TIMEOUT_MS		50
+#define CMD_TIMEOUT_MS		        5000
+
 /**
  * ufs_dev_desc - ufs device details from the device descriptor
  * @wmanufacturerid: card details
@@ -519,7 +539,7 @@
 	uintptr_t	prdt;
 	size_t		size_upiu;
 	size_t		size_resp_upiu;
-	size_t		size_prdt;
+	size_t		prdt_length;
 	int		task_tag;
 } utp_utrd_t;
 
diff --git a/include/lib/bakery_lock.h b/include/lib/bakery_lock.h
index 1fece01..2cf2b44 100644
--- a/include/lib/bakery_lock.h
+++ b/include/lib/bakery_lock.h
@@ -96,7 +96,7 @@
 void bakery_lock_get(bakery_lock_t *bakery);
 void bakery_lock_release(bakery_lock_t *bakery);
 
-#define DEFINE_BAKERY_LOCK(_name) bakery_lock_t _name __section("bakery_lock")
+#define DEFINE_BAKERY_LOCK(_name) bakery_lock_t _name __section(".bakery_lock")
 
 #define DECLARE_BAKERY_LOCK(_name) extern bakery_lock_t _name
 
diff --git a/include/lib/cpus/aarch32/cpu_macros.S b/include/lib/cpus/aarch32/cpu_macros.S
index a5ae6a4..ab2f2c6 100644
--- a/include/lib/cpus/aarch32/cpu_macros.S
+++ b/include/lib/cpus/aarch32/cpu_macros.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
  */
@@ -9,7 +9,8 @@
 #include <arch.h>
 #include <lib/cpus/errata_report.h>
 
-#if defined(IMAGE_BL1) || defined(IMAGE_BL32)  || (defined(IMAGE_BL2) && BL2_AT_EL3)
+#if defined(IMAGE_BL1) || defined(IMAGE_BL32)  \
+	|| (defined(IMAGE_BL2) && RESET_TO_BL2)
 #define IMAGE_AT_EL3
 #endif
 
@@ -129,7 +130,7 @@
 	 */
 	.macro declare_cpu_ops _name:req, _midr:req, _resetfunc:req, \
 		_power_down_ops:vararg
-	.section cpu_ops, "a"
+	.section .cpu_ops, "a"
 	.align 2
 	.type cpu_ops_\_name, %object
 	.word \_midr
diff --git a/include/lib/cpus/aarch64/cortex_a78.h b/include/lib/cpus/aarch64/cortex_a78.h
index fb325b6..66f565d 100644
--- a/include/lib/cpus/aarch64/cortex_a78.h
+++ b/include/lib/cpus/aarch64/cortex_a78.h
@@ -20,8 +20,8 @@
 #define CORTEX_A78_CPUECTLR_EL1				S3_0_C15_C1_4
 #define CORTEX_A78_CPUECTLR_EL1_BIT_8			(ULL(1) << 8)
 #define CORTEX_A78_CPUECTLR_EL1_PF_MODE_CNSRV		ULL(3)
-#define CPUECTLR_EL1_PF_MODE_LSB				U(6)
-#define CPUECTLR_EL1_PF_MODE_WIDTH				U(2)
+#define CPUECTLR_EL1_PF_MODE_LSB			U(6)
+#define CPUECTLR_EL1_PF_MODE_WIDTH			U(2)
 
 /*******************************************************************************
  * CPU Power Control register specific definitions
@@ -42,6 +42,8 @@
 
 #define CORTEX_A78_ACTLR3_EL1				S3_0_C15_C1_2
 
+#define CORTEX_A78_ACTLR5_EL1				S3_0_C15_C9_0
+
 /*******************************************************************************
  * CPU Activity Monitor Unit register specific definitions.
  ******************************************************************************/
diff --git a/include/lib/cpus/aarch64/cortex_a78c.h b/include/lib/cpus/aarch64/cortex_a78c.h
index 35e543c..301be69 100644
--- a/include/lib/cpus/aarch64/cortex_a78c.h
+++ b/include/lib/cpus/aarch64/cortex_a78c.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
  */
@@ -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
@@ -34,6 +35,11 @@
 #define CORTEX_A78C_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT	U(1)
 
 /*******************************************************************************
+ * CPU Auxiliary Control register 3 specific definitions.
+ ******************************************************************************/
+#define CORTEX_A78C_ACTLR3_EL1				S3_0_C15_C1_2
+
+/*******************************************************************************
  * CPU Implementation Specific Selected Instruction registers
  ******************************************************************************/
 #define CORTEX_A78C_IMP_CPUPSELR_EL3			S3_6_C15_C8_0
diff --git a/include/lib/cpus/aarch64/cpu_macros.S b/include/lib/cpus/aarch64/cpu_macros.S
index 92e65ae..041be51 100644
--- a/include/lib/cpus/aarch64/cpu_macros.S
+++ b/include/lib/cpus/aarch64/cpu_macros.S
@@ -157,7 +157,7 @@
 	 */
 	.macro declare_cpu_ops_base _name:req, _midr:req, _resetfunc:req, \
 		_extra1:req, _extra2:req, _extra3:req, _e_handler:req, _power_down_ops:vararg
-	.section cpu_ops, "a"
+	.section .cpu_ops, "a"
 	.align 3
 	.type cpu_ops_\_name, %object
 	.quad \_midr
diff --git a/include/lib/cpus/aarch64/neoverse_v1.h b/include/lib/cpus/aarch64/neoverse_v1.h
index 4c10484..3d48623 100644
--- a/include/lib/cpus/aarch64/neoverse_v1.h
+++ b/include/lib/cpus/aarch64/neoverse_v1.h
@@ -43,4 +43,6 @@
 
 #define NEOVERSE_V1_ACTLR3_EL1					S3_0_C15_C1_2
 
+#define NEOVERSE_V1_ACTLR5_EL1					S3_0_C15_C9_0
+
 #endif /* NEOVERSE_V1_H */
diff --git a/include/lib/el3_runtime/aarch32/context.h b/include/lib/el3_runtime/aarch32/context.h
index 5604c8e..df77c0f 100644
--- a/include/lib/el3_runtime/aarch32/context.h
+++ b/include/lib/el3_runtime/aarch32/context.h
@@ -62,7 +62,7 @@
  * ensure that the assembler and the compiler view of the offsets of
  * the structure members is the same.
  */
-CASSERT(CTX_REGS_OFFSET == __builtin_offsetof(cpu_context_t, regs_ctx), \
+CASSERT(CTX_REGS_OFFSET == __builtin_offsetof(cpu_context_t, regs_ctx),
 	assert_core_context_regs_offset_mismatch);
 
 #endif /* __ASSEMBLER__ */
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index 6986e0e..e5e7e74 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)
@@ -229,6 +228,9 @@
 // Register for FEAT_HCX
 #define CTX_HCRX_EL2            U(0x1d0)
 
+// Starting with Armv8.9
+#define CTX_TCR2_EL2            U(0x1d8)
+
 /* Align to the next 16 byte boundary */
 #define CTX_EL2_SYSREGS_END	U(0x1e0)
 
@@ -445,24 +447,24 @@
  * ensure that the assembler and the compiler view of the offsets of
  * the structure members is the same.
  */
-CASSERT(CTX_GPREGS_OFFSET == __builtin_offsetof(cpu_context_t, gpregs_ctx), \
+CASSERT(CTX_GPREGS_OFFSET == __builtin_offsetof(cpu_context_t, gpregs_ctx),
 	assert_core_context_gp_offset_mismatch);
-CASSERT(CTX_EL1_SYSREGS_OFFSET == __builtin_offsetof(cpu_context_t, el1_sysregs_ctx), \
+CASSERT(CTX_EL1_SYSREGS_OFFSET == __builtin_offsetof(cpu_context_t, el1_sysregs_ctx),
 	assert_core_context_el1_sys_offset_mismatch);
 #if CTX_INCLUDE_EL2_REGS
-CASSERT(CTX_EL2_SYSREGS_OFFSET == __builtin_offsetof(cpu_context_t, el2_sysregs_ctx), \
+CASSERT(CTX_EL2_SYSREGS_OFFSET == __builtin_offsetof(cpu_context_t, el2_sysregs_ctx),
 	assert_core_context_el2_sys_offset_mismatch);
 #endif
 #if CTX_INCLUDE_FPREGS
-CASSERT(CTX_FPREGS_OFFSET == __builtin_offsetof(cpu_context_t, fpregs_ctx), \
+CASSERT(CTX_FPREGS_OFFSET == __builtin_offsetof(cpu_context_t, fpregs_ctx),
 	assert_core_context_fp_offset_mismatch);
 #endif
-CASSERT(CTX_EL3STATE_OFFSET == __builtin_offsetof(cpu_context_t, el3state_ctx), \
+CASSERT(CTX_EL3STATE_OFFSET == __builtin_offsetof(cpu_context_t, el3state_ctx),
 	assert_core_context_el3state_offset_mismatch);
-CASSERT(CTX_CVE_2018_3639_OFFSET == __builtin_offsetof(cpu_context_t, cve_2018_3639_ctx), \
+CASSERT(CTX_CVE_2018_3639_OFFSET == __builtin_offsetof(cpu_context_t, cve_2018_3639_ctx),
 	assert_core_context_cve_2018_3639_offset_mismatch);
 #if CTX_INCLUDE_PAUTH_REGS
-CASSERT(CTX_PAUTH_REGS_OFFSET == __builtin_offsetof(cpu_context_t, pauth_ctx), \
+CASSERT(CTX_PAUTH_REGS_OFFSET == __builtin_offsetof(cpu_context_t, pauth_ctx),
 	assert_core_context_pauth_offset_mismatch);
 #endif
 
@@ -511,42 +513,14 @@
 #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_TRF_FOR_NS
-void el2_sysregs_context_save_trf(el2_sysregs_t *regs);
-void el2_sysregs_context_restore_trf(el2_sysregs_t *regs);
-#endif /* ENABLE_TRF_FOR_NS */
-#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/pubsub.h b/include/lib/el3_runtime/pubsub.h
index 64fe5cc..cbd8ecc 100644
--- a/include/lib/el3_runtime/pubsub.h
+++ b/include/lib/el3_runtime/pubsub.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,7 +12,7 @@
 /* For the linker ... */
 #define __pubsub_start_sym(event)	__pubsub_##event##_start
 #define __pubsub_end_sym(event)		__pubsub_##event##_end
-#define __pubsub_section(event)		__pubsub_##event
+#define __pubsub_section(event)		.__pubsub_##event
 
 /*
  * REGISTER_PUBSUB_EVENT has a different definition between linker and compiler
@@ -54,7 +54,7 @@
 #define __pubsub_end_sym(event)		__pubsub_##event##_end
 #endif
 
-#define __pubsub_section(event)		__section("__pubsub_" #event)
+#define __pubsub_section(event)		__section(".__pubsub_" #event)
 
 /*
  * In compiler context, REGISTER_PUBSUB_EVENT declares the per-event symbols
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 aac1ace..9ee2444 100644
--- a/include/lib/extensions/brbe.h
+++ b/include/lib/extensions/brbe.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
  */
@@ -7,6 +7,12 @@
 #ifndef BRBE_H
 #define BRBE_H
 
+#if ENABLE_BRBE_FOR_NS
 void brbe_enable(void);
+#else
+static inline void brbe_enable(void)
+{
+}
+#endif /* ENABLE_BRBE_FOR_NS */
 
 #endif /* BRBE_H */
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/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 1753ab6..861a4ad 100644
--- a/include/lib/extensions/trbe.h
+++ b/include/lib/extensions/trbe.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,12 @@
 #ifndef TRBE_H
 #define TRBE_H
 
+#if ENABLE_TRBE_FOR_NS
 void trbe_enable(void);
+#else
+static inline void trbe_enable(void)
+{
+}
+#endif /* ENABLE_TRBE_FOR_NS */
 
 #endif /* TRBE_H */
diff --git a/include/lib/extensions/trf.h b/include/lib/extensions/trf.h
index 18f17f3..91a9615 100644
--- a/include/lib/extensions/trf.h
+++ b/include/lib/extensions/trf.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,12 @@
 #ifndef TRF_H
 #define TRF_H
 
+#if ENABLE_TRF_FOR_NS
 void trf_enable(void);
+#else
+static inline void trf_enable(void)
+{
+}
+#endif /* ENABLE_TRF_FOR_NS */
 
 #endif /* TRF_H */
diff --git a/include/lib/fconf/fconf_dyn_cfg_getter.h b/include/lib/fconf/fconf_dyn_cfg_getter.h
index 43f298e..3554673 100644
--- a/include/lib/fconf/fconf_dyn_cfg_getter.h
+++ b/include/lib/fconf/fconf_dyn_cfg_getter.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
  */
@@ -19,12 +19,11 @@
 	uint32_t config_max_size;
 	unsigned int config_id;
 	/*
-	 * Load address in non-secure memory. Only needed by those
-	 * configuration files which require being loaded in secure
-	 * memory (at config_addr) as well as in non-secure memory
+	 * A platform uses this address to copy the configuration
+	 * to another location during the boot-flow.
 	 * - e.g. HW_CONFIG
 	 */
-	uintptr_t ns_config_addr;
+	uintptr_t secondary_config_addr;
 };
 
 unsigned int dyn_cfg_dtb_info_get_index(unsigned int config_id);
@@ -32,7 +31,7 @@
 int fconf_populate_dtb_registry(uintptr_t config);
 
 /* Set config information in global DTB array */
-void set_config_info(uintptr_t config_addr, uintptr_t ns_config_addr,
+void set_config_info(uintptr_t config_addr, uintptr_t secondary_config_addr,
 		     uint32_t config_max_size,
 		     unsigned int config_id);
 
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/optee_utils.h b/include/lib/optee_utils.h
index 06378eb..8224d50 100644
--- a/include/lib/optee_utils.h
+++ b/include/lib/optee_utils.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
  */
@@ -17,4 +17,40 @@
 	image_info_t *pager_image_info,
 	image_info_t *paged_image_info);
 
+/*
+ * load_addr_hi and load_addr_lo: image load address.
+ * image_id: 0 - pager, 1 - paged
+ * size: image size in bytes.
+ */
+typedef struct optee_image {
+	uint32_t load_addr_hi;
+	uint32_t load_addr_lo;
+	uint32_t image_id;
+	uint32_t size;
+} optee_image_t;
+
+#define OPTEE_PAGER_IMAGE_ID		0
+#define OPTEE_PAGED_IMAGE_ID		1
+
+#define OPTEE_MAX_NUM_IMAGES		2u
+
+#define TEE_MAGIC_NUM_OPTEE		0x4554504f
+/*
+ * magic: header magic number.
+ * version: OPTEE header version:
+ *		1 - not supported
+ *		2 - supported
+ * arch: OPTEE os architecture type: 0 - AARCH32, 1 - AARCH64.
+ * flags: unused currently.
+ * nb_images: number of images.
+ */
+typedef struct optee_header {
+	uint32_t magic;
+	uint8_t version;
+	uint8_t arch;
+	uint16_t flags;
+	uint32_t nb_images;
+	optee_image_t optee_image_list[];
+} optee_header_t;
+
 #endif /* OPTEE_UTILS_H */
diff --git a/include/lib/pmf/pmf_helpers.h b/include/lib/pmf/pmf_helpers.h
index b49c6da..01cc179 100644
--- a/include/lib/pmf/pmf_helpers.h
+++ b/include/lib/pmf/pmf_helpers.h
@@ -154,7 +154,7 @@
 	extern unsigned long long pmf_ts_mem_ ## _name[_total_id];	\
 	unsigned long long pmf_ts_mem_ ## _name[_total_id]	\
 	__aligned(CACHE_WRITEBACK_GRANULE)			\
-	__section("pmf_timestamp_array")			\
+	__section(".pmf_timestamp_array")			\
 	__used;
 
 /*
@@ -225,7 +225,7 @@
 #define PMF_DEFINE_SERVICE_DESC(_name, _implid, _svcid, _totalid,	\
 		_init, _getts_by_mpidr) 				\
 	static const pmf_svc_desc_t __pmf_desc_ ## _name 		\
-	__section("pmf_svc_descs") __used = {		 		\
+	__section(".pmf_svc_descs") __used = {		 		\
 		.h.type = PARAM_EP, 					\
 		.h.version = VERSION_1, 				\
 		.h.size = sizeof(pmf_svc_desc_t),			\
diff --git a/include/lib/psa/psa_manifest/sid.h b/include/lib/psa/psa_manifest/sid.h
index 0bdeed4..be78bae 100644
--- a/include/lib/psa/psa_manifest/sid.h
+++ b/include/lib/psa/psa_manifest/sid.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
  *
@@ -8,6 +8,9 @@
 #ifndef PSA_MANIFEST_SID_H
 #define PSA_MANIFEST_SID_H
 
+/******** RSS_SP_PLATFORM ********/
+#define RSS_PLATFORM_SERVICE_HANDLE			(0x40000105U)
+
 /******** PSA_SP_MEASURED_BOOT ********/
 #define RSS_MEASURED_BOOT_HANDLE			(0x40000110U)
 
diff --git a/include/lib/psa/rss_platform_api.h b/include/lib/psa/rss_platform_api.h
new file mode 100644
index 0000000..1dd7d05
--- /dev/null
+++ b/include/lib/psa/rss_platform_api.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef RSS_PLATFORM_API_H
+#define RSS_PLATFORM_API_H
+
+#include <stdint.h>
+
+#include "psa/error.h"
+
+#define RSS_PLATFORM_API_ID_NV_READ       (1010)
+#define RSS_PLATFORM_API_ID_NV_INCREMENT  (1011)
+
+/*
+ * Increments the given non-volatile (NV) counter by one
+ *
+ * counter_id	NV counter ID.
+ *
+ * PSA_SUCCESS if the value is read correctly. Otherwise,
+ *	it returns a PSA_ERROR.
+ */
+psa_status_t
+rss_platform_nv_counter_increment(uint32_t counter_id);
+
+/*
+ * Reads the given non-volatile (NV) counter
+ *
+ * counter_id	NV counter ID.
+ * size		Size of the buffer to store NV counter value
+ *			in bytes.
+ * val		Pointer to store the current NV counter value.
+ *
+ * PSA_SUCCESS if the value is read correctly. Otherwise,
+ *	it returns a PSA_ERROR.
+ */
+psa_status_t
+rss_platform_nv_counter_read(uint32_t counter_id,
+		uint32_t size, uint8_t *val);
+
+#endif /* RSS_PLATFORM_API_H */
diff --git a/include/lib/psci/psci.h b/include/lib/psci/psci.h
index b56e98b..6d27b7b 100644
--- a/include/lib/psci/psci.h
+++ b/include/lib/psci/psci.h
@@ -59,6 +59,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 +74,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 +143,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 +281,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;
 
 /*******************************************************************************
@@ -299,7 +319,11 @@
 	void (*pwr_domain_off)(const psci_power_state_t *target_state);
 	void (*pwr_domain_suspend_pwrdown_early)(
 				const psci_power_state_t *target_state);
+#if PSCI_OS_INIT_MODE
+	int (*pwr_domain_suspend)(const psci_power_state_t *target_state);
+#else
 	void (*pwr_domain_suspend)(const psci_power_state_t *target_state);
+#endif
 	void (*pwr_domain_on_finish)(const psci_power_state_t *target_state);
 	void (*pwr_domain_on_finish_late)(
 				const psci_power_state_t *target_state);
@@ -347,6 +371,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..63637d5 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
  */
@@ -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/lib/xlat_tables/xlat_tables_v2.h b/include/lib/xlat_tables/xlat_tables_v2.h
index 69ad027..4d16ced 100644
--- a/include/lib/xlat_tables/xlat_tables_v2.h
+++ b/include/lib/xlat_tables/xlat_tables_v2.h
@@ -203,7 +203,7 @@
 					 (_virt_addr_space_size),	\
 					 (_phy_addr_space_size),	\
 					 EL_REGIME_INVALID,		\
-					 "xlat_table", "base_xlat_table")
+					 ".xlat_table", ".base_xlat_table")
 
 /*
  * Same as REGISTER_XLAT_CONTEXT plus the additional parameters:
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index 36b1bdb..925ff21 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.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
  */
@@ -82,6 +82,7 @@
  *   - L1 GPT DRAM: Reserved for L1 GPT if RME is enabled
  *   - REALM DRAM: Reserved for Realm world if RME is enabled
  *   - TF-A <-> RMM SHARED: Area shared for communication between TF-A and RMM
+ *   - Event Log: Area for Event Log if MEASURED_BOOT feature is enabled
  *   - AP TZC DRAM: The remaining TZC secured DRAM reserved for AP use
  *
  *              RME enabled(64MB)                RME not enabled(16MB)
@@ -89,13 +90,15 @@
  *              |                  |             |                 |
  *              |  AP TZC (~28MB)  |             |  AP TZC (~14MB) |
  *              --------------------             -------------------
+ *              |     Event Log    |             |     Event Log   |
+ *              |      (4KB)       |             |      (4KB)      |
+ *              --------------------             -------------------
+ *              |   REALM (RMM)    |             |                 |
+ *              |   (32MB - 4KB)   |             |  EL3 TZC (2MB)  |
+ *              --------------------             -------------------
  *              |                  |             |                 |
- *              |   REALM (RMM)    |             |  EL3 TZC (2MB)  |
- *              |   (32MB - 4KB)   |             -------------------
- *              --------------------             |                 |
- *              |                  |             |    SCP TZC      |
- *              |   TF-A <-> RMM   |  0xFFFF_FFFF-------------------
- *              |   SHARED (4KB)   |
+ *              |   TF-A <-> RMM   |             |    SCP TZC      |
+ *              |   SHARED (4KB)   |  0xFFFF_FFFF-------------------
  *              --------------------
  *              |                  |
  *              |  EL3 TZC (3MB)   |
@@ -109,12 +112,11 @@
 /*
  * Define a region within the TZC secured DRAM for use by EL3 runtime
  * firmware. This region is meant to be NOLOAD and will not be zero
- * initialized. Data sections with the attribute `arm_el3_tzc_dram` will be
+ * initialized. Data sections with the attribute `.arm_el3_tzc_dram` will be
  * placed here. 3MB region is reserved if RME is enabled, 2MB otherwise.
  */
 #define ARM_EL3_TZC_DRAM1_SIZE		UL(0x00300000) /* 3MB */
 #define ARM_L1_GPT_SIZE			UL(0x00100000) /* 1MB */
-
 /* 32MB - ARM_EL3_RMM_SHARED_SIZE */
 #define ARM_REALM_SIZE			(UL(0x02000000) -		\
 						ARM_EL3_RMM_SHARED_SIZE)
@@ -134,6 +136,25 @@
 #define ARM_SCP_TZC_DRAM1_SIZE		PLAT_ARM_SCP_TZC_DRAM1_SIZE
 #define ARM_SCP_TZC_DRAM1_END		(ARM_SCP_TZC_DRAM1_BASE +	\
 					ARM_SCP_TZC_DRAM1_SIZE - 1U)
+
+# if (defined(SPD_tspd) || defined(SPD_opteed) || defined(SPD_spmd)) && \
+MEASURED_BOOT
+#define ARM_EVENT_LOG_DRAM1_SIZE	UL(0x00001000)	/* 4KB */
+
+#if ENABLE_RME
+#define ARM_EVENT_LOG_DRAM1_BASE	(ARM_REALM_BASE -		\
+					 ARM_EVENT_LOG_DRAM1_SIZE)
+#else
+#define ARM_EVENT_LOG_DRAM1_BASE	(ARM_EL3_TZC_DRAM1_BASE -	\
+					 ARM_EVENT_LOG_DRAM1_SIZE)
+#endif /* ENABLE_RME */
+#define ARM_EVENT_LOG_DRAM1_END		(ARM_EVENT_LOG_DRAM1_BASE +	\
+					 ARM_EVENT_LOG_DRAM1_SIZE -	\
+					 1U)
+#else
+#define ARM_EVENT_LOG_DRAM1_SIZE	UL(0)
+#endif /* (SPD_tspd || SPD_opteed || SPD_spmd) && MEASURED_BOOT */
+
 #if ENABLE_RME
 #define ARM_L1_GPT_ADDR_BASE		(ARM_DRAM1_BASE +		\
 					ARM_DRAM1_SIZE -		\
@@ -170,7 +191,9 @@
 					ARM_EL3_TZC_DRAM1_SIZE +	\
 					ARM_EL3_RMM_SHARED_SIZE +	\
 					ARM_REALM_SIZE +		\
-					ARM_L1_GPT_SIZE))
+					ARM_L1_GPT_SIZE +		\
+					ARM_EVENT_LOG_DRAM1_SIZE))
+
 #define ARM_AP_TZC_DRAM1_END		(ARM_AP_TZC_DRAM1_BASE +	\
 					ARM_AP_TZC_DRAM1_SIZE - 1U)
 
@@ -235,6 +258,8 @@
 #define ARM_DRAM2_SIZE			PLAT_ARM_DRAM2_SIZE
 #define ARM_DRAM2_END			(ARM_DRAM2_BASE +		\
 					 ARM_DRAM2_SIZE - 1U)
+/* Number of DRAM banks */
+#define ARM_DRAM_NUM_BANKS		2UL
 
 #define ARM_IRQ_SEC_PHY_TIMER		29
 
@@ -310,6 +335,15 @@
 					PLAT_ARM_TRUSTED_DRAM_BASE,	\
 					PLAT_ARM_TRUSTED_DRAM_SIZE,	\
 					MT_MEMORY | MT_RW | MT_SECURE)
+
+# if (defined(SPD_tspd) || defined(SPD_opteed) || defined(SPD_spmd)) && \
+MEASURED_BOOT
+#define ARM_MAP_EVENT_LOG_DRAM1						\
+				MAP_REGION_FLAT(			\
+					ARM_EVENT_LOG_DRAM1_BASE,	\
+					ARM_EVENT_LOG_DRAM1_SIZE,	\
+					MT_MEMORY | MT_RW | MT_SECURE)
+#endif /* (SPD_tspd || SPD_opteed || SPD_spmd) && MEASURED_BOOT */
 
 #if ENABLE_RME
 /*
@@ -552,7 +586,7 @@
 /*******************************************************************************
  * BL2 specific defines.
  ******************************************************************************/
-#if BL2_AT_EL3
+#if RESET_TO_BL2
 #if ENABLE_PIE
 /*
  * As the BL31 image size appears to be increased when built with the ENABLE_PIE
@@ -612,10 +646,11 @@
 						- PLAT_ARM_MAX_BL31_SIZE)
 #define BL31_PROGBITS_LIMIT		BL2_BASE
 /*
- * For BL2_AT_EL3 make sure the BL31 can grow up until BL2_BASE. This is
- * because in the BL2_AT_EL3 configuration, BL2 is always resident.
+ * For RESET_TO_BL2 make sure the BL31 can grow up until BL2_BASE.
+ * This is because in the RESET_TO_BL2 configuration,
+ * BL2 is always resident.
  */
-#if BL2_AT_EL3
+#if RESET_TO_BL2
 #define BL31_LIMIT			BL2_BASE
 #else
 #define BL31_LIMIT			(ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)
diff --git a/include/plat/arm/common/arm_reclaim_init.ld.S b/include/plat/arm/common/arm_reclaim_init.ld.S
index 788e9ff..a77c964 100644
--- a/include/plat/arm/common/arm_reclaim_init.ld.S
+++ b/include/plat/arm/common/arm_reclaim_init.ld.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
  */
@@ -26,9 +26,9 @@
 #define	ABS		ABSOLUTE
 
 #define STACK_SECTION							\
-	stacks (NOLOAD) : {						\
+	.stacks (NOLOAD) : {						\
 		__STACKS_START__ = .;					\
-		*(tzfw_normal_stacks)					\
+		*(.tzfw_normal_stacks)					\
 		__STACKS_END__ = .;					\
 		/* Allow room for the init section where necessary. */	\
 		OFFSET = ABS(SIZEOF(.init) - (. - __STACKS_START__));	\
diff --git a/include/plat/arm/common/arm_tzc_dram.ld.S b/include/plat/arm/common/arm_tzc_dram.ld.S
index 6dcea0b..c790bb9 100644
--- a/include/plat/arm/common/arm_tzc_dram.ld.S
+++ b/include/plat/arm/common/arm_tzc_dram.ld.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,9 +17,9 @@
 	. = ARM_EL3_TZC_DRAM1_BASE;
 	ASSERT(. == ALIGN(PAGE_SIZE),
 	"ARM_EL3_TZC_DRAM_BASE address is not aligned on a page boundary.")
-	el3_tzc_dram (NOLOAD) : ALIGN(PAGE_SIZE) {
+	.el3_tzc_dram (NOLOAD) : ALIGN(PAGE_SIZE) {
 	__EL3_SEC_DRAM_START__ = .;
-	*(arm_el3_tzc_dram)
+	*(.arm_el3_tzc_dram)
 	__EL3_SEC_DRAM_UNALIGNED_END__ = .;
 
 	. = ALIGN(PAGE_SIZE);
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 494e470..34f913b 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -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 */
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index 3351036..a14d775 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,7 +11,7 @@
 
 #include <lib/psci/psci.h>
 #if defined(SPD_spmd)
- #include <services/spm_core_manifest.h>
+#include <services/spm_core_manifest.h>
 #endif
 #if ENABLE_RME
 #include <services/rmm_core_manifest.h>
@@ -37,6 +37,7 @@
 struct mmap_region;
 struct spm_mm_boot_info;
 struct sp_res_desc;
+struct rmm_manifest;
 enum fw_enc_status_t;
 
 /*******************************************************************************
@@ -255,8 +256,8 @@
 #endif /* MEASURED_BOOT */
 
 /*******************************************************************************
- * Mandatory BL2 at EL3 functions: Must be implemented if BL2_AT_EL3 image is
- * supported
+ * Mandatory BL2 at EL3 functions: Must be implemented
+ * if RESET_TO_BL2 image is supported
  ******************************************************************************/
 void bl2_el3_early_platform_setup(u_register_t arg0, u_register_t arg1,
 				  u_register_t arg2, u_register_t arg3);
@@ -322,7 +323,7 @@
 int plat_rmmd_get_cca_realm_attest_key(uintptr_t buf, size_t *len,
 				       unsigned int type);
 size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared);
-int plat_rmmd_load_manifest(rmm_manifest_t *manifest);
+int plat_rmmd_load_manifest(struct rmm_manifest *manifest);
 #endif
 
 /*******************************************************************************
diff --git a/include/services/el3_spmc_logical_sp.h b/include/services/el3_spmc_logical_sp.h
index 7ec9958..5ce33ed 100644
--- a/include/services/el3_spmc_logical_sp.h
+++ b/include/services/el3_spmc_logical_sp.h
@@ -35,7 +35,7 @@
 #define DECLARE_LOGICAL_PARTITION(_name, _init, _sp_id, _uuid, _properties, \
 				  _direct_req)				    \
 	static const struct el3_lp_desc __partition_desc_ ## _name	    \
-		__section("el3_lp_descs") __used = {			    \
+		__section(".el3_lp_descs") __used = {			    \
 			.debug_name = #_name,				    \
 			.init = (_init),				    \
 			.sp_id = (_sp_id),				    \
diff --git a/include/services/ffa_svc.h b/include/services/ffa_svc.h
index da016fd..8bc911a 100644
--- a/include/services/ffa_svc.h
+++ b/include/services/ffa_svc.h
@@ -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(0x87)
+#define FFA_FNUM_MAX_VALUE	U(0x8B)
 #define is_ffa_fid(fid) __extension__ ({		\
 	__typeof__(fid) _fid = (fid);			\
 	((GET_SMC_NUM(_fid) >= FFA_FNUM_MIN_VALUE) &&	\
@@ -117,6 +117,7 @@
 #define FFA_FNUM_SPM_ID_GET			U(0x85)
 #define FFA_FNUM_MSG_SEND2			U(0x86)
 #define FFA_FNUM_SECONDARY_EP_REGISTER		U(0x87)
+#define FFA_FNUM_PARTITION_INFO_GET_REGS	U(0x8B)
 
 /* FFA SMC32 FIDs */
 #define FFA_ERROR		FFA_FID(SMC_32, FFA_FNUM_ERROR)
@@ -180,6 +181,8 @@
 	FFA_FID(SMC_64, FFA_FNUM_SECONDARY_EP_REGISTER)
 #define FFA_NOTIFICATION_INFO_GET_SMC64 \
 	FFA_FID(SMC_64, FFA_FNUM_NOTIFICATION_INFO_GET)
+#define FFA_PARTITION_INFO_GET_REGS_SMC64 \
+	FFA_FID(SMC_64, FFA_FNUM_PARTITION_INFO_GET_REGS)
 
 /*
  * FF-A partition properties values.
diff --git a/include/services/rmm_core_manifest.h b/include/services/rmm_core_manifest.h
index 7edef46..b89de9f 100644
--- a/include/services/rmm_core_manifest.h
+++ b/include/services/rmm_core_manifest.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,7 +14,7 @@
 #include <lib/cassert.h>
 
 #define RMMD_MANIFEST_VERSION_MAJOR		U(0)
-#define RMMD_MANIFEST_VERSION_MINOR		U(1)
+#define RMMD_MANIFEST_VERSION_MINOR		U(2)
 
 /*
  * Manifest version encoding:
@@ -22,29 +22,57 @@
  *	- Bits [30:16] Major version
  *	- Bits [15:0] Minor version
  */
-#define _RMMD_MANIFEST_VERSION(_major, _minor)				\
+#define SET_RMMD_MANIFEST_VERSION(_major, _minor)		\
 	((((_major) & 0x7FFF) << 16) | ((_minor) & 0xFFFF))
 
-#define RMMD_MANIFEST_VERSION _RMMD_MANIFEST_VERSION(			\
-				RMMD_MANIFEST_VERSION_MAJOR,		\
+#define RMMD_MANIFEST_VERSION	SET_RMMD_MANIFEST_VERSION(	\
+				RMMD_MANIFEST_VERSION_MAJOR,	\
 				RMMD_MANIFEST_VERSION_MINOR)
 
-#define RMMD_GET_MANIFEST_VERSION_MAJOR(_version)			\
+#define RMMD_GET_MANIFEST_VERSION_MAJOR(_version)		\
 	((_version >> 16) & 0x7FFF)
 
-#define RMMD_GET_MANIFEST_VERSION_MINOR(_version)			\
+#define RMMD_GET_MANIFEST_VERSION_MINOR(_version)		\
 	(_version & 0xFFFF)
 
-/* Boot manifest core structure as per v0.1 */
-typedef struct rmm_manifest {
-	uint32_t version;	/* Manifest version */
-	uint32_t padding;	/* RES0 */
-	uintptr_t plat_data;	/* Manifest platform data */
-} rmm_manifest_t;
+/* NS DRAM bank structure */
+struct ns_dram_bank {
+	uintptr_t base;			/* Base address */
+	uint64_t size;			/* Size of bank */
+};
+
+CASSERT(offsetof(struct ns_dram_bank, base) == 0UL,
+			rmm_manifest_base_unaligned);
+CASSERT(offsetof(struct ns_dram_bank, size) == 8UL,
+			rmm_manifest_size_unaligned);
+
+/* NS DRAM layout info structure */
+struct ns_dram_info {
+	uint64_t num_banks;		/* Number of NS DRAM banks */
+	struct ns_dram_bank *banks;	/* Pointer to ns_dram_bank[] */
+	uint64_t checksum;		/* Checksum of ns_dram_info data */
+};
+
+CASSERT(offsetof(struct ns_dram_info, num_banks) == 0UL,
+			rmm_manifest_num_banks_unaligned);
+CASSERT(offsetof(struct ns_dram_info, banks) == 8UL,
+			rmm_manifest_dram_data_unaligned);
+CASSERT(offsetof(struct ns_dram_info, checksum) == 16UL,
+			rmm_manifest_checksum_unaligned);
+
+/* Boot manifest core structure as per v0.2 */
+struct rmm_manifest {
+	uint32_t version;		/* Manifest version */
+	uint32_t padding;		/* RES0 */
+	uintptr_t plat_data;		/* Manifest platform data */
+	struct ns_dram_info plat_dram;	/* Platform NS DRAM data */
+};
 
-CASSERT(offsetof(rmm_manifest_t, version) == 0,
-				rmm_manifest_t_version_unaligned);
-CASSERT(offsetof(rmm_manifest_t, plat_data) == 8,
-				rmm_manifest_t_plat_data_unaligned);
+CASSERT(offsetof(struct rmm_manifest, version) == 0UL,
+			rmm_manifest_version_unaligned);
+CASSERT(offsetof(struct rmm_manifest, plat_data) == 8UL,
+			rmm_manifest_plat_data_unaligned);
+CASSERT(offsetof(struct rmm_manifest, plat_dram) == 16UL,
+			rmm_manifest_plat_dram_unaligned);
 
 #endif /* RMM_CORE_MANIFEST_H */
diff --git a/include/services/trp/platform_trp.h b/include/services/trp/platform_trp.h
index 1c963c8..756e9db 100644
--- a/include/services/trp/platform_trp.h
+++ b/include/services/trp/platform_trp.h
@@ -9,9 +9,11 @@
 
 #include <services/rmm_core_manifest.h>
 
+struct rmm_manifest;
+
 /*******************************************************************************
  * Mandatory TRP functions (only if platform contains a TRP)
  ******************************************************************************/
-void trp_early_platform_setup(rmm_manifest_t *manifest);
+void trp_early_platform_setup(struct rmm_manifest *manifest);
 
 #endif /* PLATFORM_TRP_H */
diff --git a/lib/aarch64/misc_helpers.S b/lib/aarch64/misc_helpers.S
index e8110b0..f9c4baf 100644
--- a/lib/aarch64/misc_helpers.S
+++ b/lib/aarch64/misc_helpers.S
@@ -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
  */
@@ -164,7 +164,7 @@
 	 * register value and panic if the MMU is disabled.
 	 */
 #if defined(IMAGE_BL1) || defined(IMAGE_BL31) || (defined(IMAGE_BL2) && \
-	(BL2_AT_EL3 || ENABLE_RME))
+	BL2_RUNS_AT_EL3)
 	mrs	tmp1, sctlr_el3
 #else
 	mrs	tmp1, sctlr_el1
diff --git a/lib/compiler-rt/builtins/arm/aeabi_memset.S b/lib/compiler-rt/builtins/arm/aeabi_memset.S
new file mode 100644
index 0000000..2aa8ec0
--- /dev/null
+++ b/lib/compiler-rt/builtins/arm/aeabi_memset.S
@@ -0,0 +1,49 @@
+//===-- aeabi_memset.S - EABI memset implementation -----------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//  void __aeabi_memset(void *dest, size_t n, int c) { memset(dest, c, n); }
+//  void __aeabi_memclr(void *dest, size_t n) { __aeabi_memset(dest, n, 0); }
+
+        .syntax unified
+        .p2align 2
+DEFINE_COMPILERRT_FUNCTION(__aeabi_memset)
+        mov     r3, r1
+        mov     r1, r2
+        mov     r2, r3
+#ifdef USE_THUMB_1
+        push    {r7, lr}
+        bl      memset
+        pop     {r7, pc}
+#else
+        b       memset
+#endif
+END_COMPILERRT_FUNCTION(__aeabi_memset)
+
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memset4, __aeabi_memset)
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memset8, __aeabi_memset)
+
+        .p2align 2
+DEFINE_COMPILERRT_FUNCTION(__aeabi_memclr)
+        mov     r2, r1
+        movs    r1, #0
+#ifdef USE_THUMB_1
+        push    {r7, lr}
+        bl      memset
+        pop     {r7, pc}
+#else
+        b       memset
+#endif
+END_COMPILERRT_FUNCTION(__aeabi_memclr)
+
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memclr4, __aeabi_memclr)
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memclr8, __aeabi_memclr)
+
+NO_EXEC_STACK_DIRECTIVE
+
diff --git a/lib/compiler-rt/compiler-rt.mk b/lib/compiler-rt/compiler-rt.mk
index 2338908..b41c4d0 100644
--- a/lib/compiler-rt/compiler-rt.mk
+++ b/lib/compiler-rt/compiler-rt.mk
@@ -35,6 +35,7 @@
 COMPILER_RT_SRCS	+=	lib/compiler-rt/builtins/arm/aeabi_ldivmod.S	\
 				lib/compiler-rt/builtins/arm/aeabi_uldivmod.S	\
 				lib/compiler-rt/builtins/arm/aeabi_memcpy.S	\
+				lib/compiler-rt/builtins/arm/aeabi_memset.S	\
 				lib/compiler-rt/builtins/ctzdi2.c		\
 				lib/compiler-rt/builtins/divdi3.c		\
 				lib/compiler-rt/builtins/divmoddi4.c		\
diff --git a/lib/cpus/aarch32/cpu_helpers.S b/lib/cpus/aarch32/cpu_helpers.S
index 6ed800c..e25ce2a 100644
--- a/lib/cpus/aarch32/cpu_helpers.S
+++ b/lib/cpus/aarch32/cpu_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,7 +11,8 @@
 #include <common/bl_common.h>
 #include <lib/el3_runtime/cpu_data.h>
 
-#if defined(IMAGE_BL1) || defined(IMAGE_BL32) || (defined(IMAGE_BL2) && BL2_AT_EL3)
+#if defined(IMAGE_BL1) || defined(IMAGE_BL32) || \
+	(defined(IMAGE_BL2) && RESET_TO_BL2)
 	/*
 	 * The reset handler common to all platforms.  After a matching
 	 * cpu_ops structure entry is found, the correponding reset_handler
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 a3932e8..69d7ab0 100644
--- a/lib/cpus/aarch64/cortex_a78.S
+++ b/lib/cpus/aarch64/cortex_a78.S
@@ -327,6 +327,36 @@
 endfunc check_errata_2395406
 
 /* ----------------------------------------------------
+ * Errata Workaround for Cortex A78 Errata 2742426.
+ * This applies to revisions r0p0, r1p0, r1p1 and r1p2.
+ * It is still open.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x1, x17
+ * ----------------------------------------------------
+ */
+func errata_a78_2742426_wa
+	/* Check revision. */
+	mov	x17, x30
+	bl	check_errata_2742426
+	cbz	x0, 1f
+
+	/* Apply the workaround */
+	mrs	x1, CORTEX_A78_ACTLR5_EL1
+	bic	x1, x1, #BIT(56)
+	orr	x1, x1, #BIT(55)
+	msr	CORTEX_A78_ACTLR5_EL1, x1
+
+1:
+	ret	x17
+endfunc errata_a78_2742426_wa
+
+func check_errata_2742426
+	/* Applies to r0p0, r1p0, r1p1, r1p2 */
+	mov	x1, #CPU_REV(1, 2)
+	b	cpu_rev_var_ls
+endfunc check_errata_2742426
+
+/* ----------------------------------------------------
  * Errata Workaround for Cortex-A78 Errata 2772019
  * This applies to revisions <= r1p2 and is still open.
  * x0: variant[4:7] and revision[0:3] of current cpu.
@@ -443,12 +473,17 @@
 	bl	errata_a78_2395406_wa
 #endif
 
+#if ERRATA_A78_2742426
+	mov	x0, x18
+	bl	errata_a78_2742426_wa
+#endif
+
 #if ERRATA_A78_2779479
 	mov	x0, x18
 	bl	errata_a78_2779479_wa
 #endif
 
-#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
@@ -526,6 +561,7 @@
 	report_errata ERRATA_A78_2242635, cortex_a78, 2242635
 	report_errata ERRATA_A78_2376745, cortex_a78, 2376745
 	report_errata ERRATA_A78_2395406, cortex_a78, 2395406
+	report_errata ERRATA_A78_2742426, cortex_a78, 2742426
 	report_errata ERRATA_A78_2772019, cortex_a78, 2772019
 	report_errata ERRATA_A78_2779479, cortex_a78, 2779479
 	report_errata WORKAROUND_CVE_2022_23960, cortex_a78, cve_2022_23960
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 49cebfe..fddd24f 100644
--- a/lib/cpus/aarch64/cortex_a78c.S
+++ b/lib/cpus/aarch64/cortex_a78c.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
  */
@@ -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.
@@ -117,13 +171,13 @@
 	b	cpu_rev_var_range
 endfunc check_errata_2132064
 
-/* --------------------------------------------------------------------
+/* ----------------------------------------------------------
  * Errata Workaround for A78C Erratum 2242638.
  * This applies to revisions r0p1 and r0p2 of the Cortex A78C
  * processor and is still open.
  * x0: variant[4:7] and revision[0:3] of current cpu.
  * Shall clobber: x0-x17
- * --------------------------------------------------------------------
+ * ----------------------------------------------------------
  */
 func errata_a78c_2242638_wa
 	/* Compare x0 against revisions r0p1 - r0p2 */
@@ -152,6 +206,61 @@
 	b	cpu_rev_var_range
 endfunc check_errata_2242638
 
+/* ----------------------------------------------------------------
+ * Errata Workaround for A78C Erratum 2772121.
+ * This applies to revisions r0p0, r0p1 and r0p2 of the Cortex A78C
+ * processor and is still open.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * ----------------------------------------------------------------
+ */
+func errata_a78c_2772121_wa
+	mov	x17, x30
+	bl	check_errata_2772121
+	cbz	x0, 1f
+
+	/* dsb before isb of power down sequence */
+	dsb	sy
+1:
+	ret	x17
+endfunc errata_a78c_2772121_wa
+
+func check_errata_2772121
+	/* Applies to all revisions <= r0p2 */
+	mov	x1, #0x02
+	b	cpu_rev_var_ls
+endfunc check_errata_2772121
+
+/* --------------------------------------------------
+ * Errata Workaround for Cortex A78C Errata 2779484.
+ * This applies to revisions r0p1 and r0p2.
+ * It is still open.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x1, x17
+ * --------------------------------------------------
+ */
+func errata_a78c_2779484_wa
+	/* Check revision. */
+	mov	x17, x30
+	bl	check_errata_2779484
+	cbz	x0, 1f
+
+	/* Apply the workaround */
+	mrs	x1, CORTEX_A78C_ACTLR3_EL1
+	orr	x1, x1, #BIT(47)
+	msr	CORTEX_A78C_ACTLR3_EL1, x1
+
+1:
+	ret	x17
+endfunc errata_a78c_2779484_wa
+
+func check_errata_2779484
+	/* Applies to r0p1 and r0p2*/
+	mov	x1, #0x01
+	mov	x2, #0x02
+	b	cpu_rev_var_range
+endfunc check_errata_2779484
+
 func check_errata_cve_2022_23960
 #if WORKAROUND_CVE_2022_23960
 	mov	x0, #ERRATA_APPLIES
@@ -170,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
@@ -190,6 +309,11 @@
 	bl	errata_a78c_2395411_wa
 #endif
 
+#if ERRATA_A78C_2779484
+	mov	x0, x18
+	bl	errata_a78c_2779484_wa
+#endif
+
 #if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
 	/*
 	 * The Cortex-A78c generic vectors are overridden to apply errata
@@ -215,6 +339,12 @@
 	mrs	x0, CORTEX_A78C_CPUPWRCTLR_EL1
 	orr	x0, x0, #CORTEX_A78C_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
 	msr	CORTEX_A78C_CPUPWRCTLR_EL1, x0
+#if ERRATA_A78C_2772121
+	mov	x15, x30
+	bl	cpu_get_rev_var
+	bl	errata_a78c_2772121_wa
+	mov	x30, x15
+#endif /* ERRATA_A78C_2772121 */
 	isb
 	ret
 endfunc cortex_a78c_core_pwr_dwn
@@ -233,10 +363,14 @@
 	 * Report all errata. The revision-variant information is passed to
 	 * checking functions of each errata.
 	 */
+	report_errata ERRATA_A78C_1827430, cortex_a78c, 1827430
+	report_errata ERRATA_A78C_1827440, cortex_a78c, 1827440
 	report_errata ERRATA_A78C_2132064, cortex_a78c, 2132064
 	report_errata ERRATA_A78C_2242638, cortex_a78c, 2242638
 	report_errata ERRATA_A78C_2376749, cortex_a78c, 2376749
 	report_errata ERRATA_A78C_2395411, cortex_a78c, 2395411
+	report_errata ERRATA_A78C_2772121, cortex_a78c, 2772121
+	report_errata ERRATA_A78C_2779484, cortex_a78c, 2779484
 	report_errata WORKAROUND_CVE_2022_23960, cortex_a78c, cve_2022_23960
 
 	ldp	x8, x30, [sp], #16
diff --git a/lib/cpus/aarch64/cpu_helpers.S b/lib/cpus/aarch64/cpu_helpers.S
index 2385627..0a03e38 100644
--- a/lib/cpus/aarch64/cpu_helpers.S
+++ b/lib/cpus/aarch64/cpu_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,7 +14,8 @@
 #include <lib/el3_runtime/cpu_data.h>
 
  /* Reset fn is needed in BL at reset vector */
-#if defined(IMAGE_BL1) || defined(IMAGE_BL31) || (defined(IMAGE_BL2) && BL2_AT_EL3)
+#if defined(IMAGE_BL1) || defined(IMAGE_BL31) ||	\
+	(defined(IMAGE_BL2) && RESET_TO_BL2)
 	/*
 	 * The reset handler common to all platforms.  After a matching
 	 * cpu_ops structure entry is found, the correponding reset_handler
@@ -30,10 +31,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]
@@ -99,10 +96,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:
diff --git a/lib/cpus/aarch64/neoverse_n1.S b/lib/cpus/aarch64/neoverse_n1.S
index ec62519..827c0b0 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
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/neoverse_v1.S b/lib/cpus/aarch64/neoverse_v1.S
index f9a5789..363c2e6 100644
--- a/lib/cpus/aarch64/neoverse_v1.S
+++ b/lib/cpus/aarch64/neoverse_v1.S
@@ -486,6 +486,37 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_2743093
 
+	/* ---------------------------------------------------
+	 * Errata Workaround for Neoverse V1 Errata #2743233.
+	 * This applies to revisions r0p0, r1p0, r1p1 and r1p2.
+	 * It is still open.
+	 * x0: variant[4:7] and revisions[0:3] of current cpu.
+	 * Shall clobber: x0-x1, x17
+	 * ---------------------------------------------------
+	 */
+func errata_neoverse_v1_2743233_wa
+	/* Check revision. */
+	mov 	x17, x30
+	bl	check_errata_2743233
+	cbz	x0, 1f
+
+	/* Apply the workaround */
+	mrs	x1, NEOVERSE_V1_ACTLR5_EL1
+	bic	x1, x1, #BIT(56)
+	orr	x1, x1, #BIT(55)
+	msr	NEOVERSE_V1_ACTLR5_EL1, x1
+
+1:
+	ret 	x17
+endfunc errata_neoverse_v1_2743233_wa
+
+func check_errata_2743233
+	/* Applies to r0p0, r1p0, r1p1 and r1p2 */
+	mov	x1, #CPU_REV(1,2)
+	b	cpu_rev_var_ls
+endfunc check_errata_2743233
+
+
 	/* ----------------------------------------------------
  	 * Errata Workaround for Neoverse V1 Errata #2779461.
 	 * This applies to revisions r0p0, r1p0, r1p1, and r1p2.
@@ -573,6 +604,7 @@
 	report_errata ERRATA_V1_2294912, neoverse_v1, 2294912
 	report_errata ERRATA_V1_2372203, neoverse_v1, 2372203
 	report_errata ERRATA_V1_2743093, neoverse_v1, 2743093
+	report_errata ERRATA_V1_2743233, neoverse_v1, 2743233
 	report_errata ERRATA_V1_2779461, neoverse_v1, 2779461
 	report_errata WORKAROUND_CVE_2022_23960, neoverse_v1, cve_2022_23960
 
@@ -652,6 +684,11 @@
 	bl	errata_neoverse_v1_2372203_wa
 #endif
 
+#if ERRATA_V1_2743233
+	mov	x0, x18
+	bl	errata_neoverse_v1_2743233_wa
+#endif
+
 #if ERRATA_V1_2779461
 	mov	x0, x18
 	bl	errata_neoverse_v1_2779461_wa
diff --git a/lib/cpus/aarch64/rainier.S b/lib/cpus/aarch64/rainier.S
index 584ab97..3b7b8b2 100644
--- a/lib/cpus/aarch64/rainier.S
+++ b/lib/cpus/aarch64/rainier.S
@@ -94,7 +94,7 @@
 	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
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 1dc9419..82a4890 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -5,1428 +5,768 @@
 # 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 2742426 workaround during reset. This erratum
+# applies to revisions r0p0, r1p0, r1p1 and r1p2 of the A78 cpu. It is still
+# open.
+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 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 2772121 workaround during powerdown. This erratum
+# applies to revisions r0p0, r0p1 and r0p2 of the A78C cpu. It is still open.
+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.
+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 2743093 workaround during powerdown. This erratum
 # applies to revisions r0p0, r1p0, r1p1 and r1p2  of the Neoverse V1 cpu and is
 # still open.
+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_2743093	?=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 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 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 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 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_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_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_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 93b2744..5f41aee 100644
--- a/lib/cpus/errata_report.c
+++ b/lib/cpus/errata_report.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
  */
@@ -21,7 +21,7 @@
 # define BL_STRING	"BL31"
 #elif !defined(__aarch64__) && defined(IMAGE_BL32)
 # define BL_STRING	"BL32"
-#elif defined(IMAGE_BL2) && BL2_AT_EL3
+#elif defined(IMAGE_BL2) && RESET_TO_BL2
 # define BL_STRING "BL2"
 #else
 # error This image should not be printing errata status
diff --git a/lib/el3_runtime/aarch32/context_mgmt.c b/lib/el3_runtime/aarch32/context_mgmt.c
index af8edf5..62e30fc 100644
--- a/lib/el3_runtime/aarch32/context_mgmt.c
+++ b/lib/el3_runtime/aarch32/context_mgmt.c
@@ -11,6 +11,7 @@
 #include <platform_def.h>
 
 #include <arch.h>
+#include <arch_features.h>
 #include <arch_helpers.h>
 #include <common/bl_common.h>
 #include <context.h>
@@ -135,17 +136,17 @@
 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 ENABLE_TRF_FOR_NS
-	trf_enable();
-#endif /* ENABLE_TRF_FOR_NS */
+	if (is_feat_trf_supported()) {
+		trf_enable();
+	}
 #endif
 }
 
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index b5d61ff..013a505 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -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
  */
@@ -13,42 +13,14 @@
 #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_TRF_FOR_NS
-	.global	el2_sysregs_context_save_trf
-	.global	el2_sysregs_context_restore_trf
-#endif /* ENABLE_TRF_FOR_NS */
-#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
@@ -224,20 +196,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
@@ -252,98 +210,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	x11, MPAMHCR_EL2
-	mrs	x12, MPAMVPM0_EL2
-	stp	x11, x12, [x0, #CTX_MPAMHCR_EL2]
-
-	mrs	x13, MPAMVPM1_EL2
-	mrs	x14, MPAMVPM2_EL2
-	stp	x13, x14, [x0, #CTX_MPAMVPM1_EL2]
-
-	mrs	x15, MPAMVPM3_EL2
-	mrs	x16, MPAMVPM4_EL2
-	stp	x15, x16, [x0, #CTX_MPAMVPM3_EL2]
-
-	mrs	x9, MPAMVPM5_EL2
-	mrs	x10, MPAMVPM6_EL2
-	stp	x9, x10, [x0, #CTX_MPAMVPM5_EL2]
-
-	mrs	x11, MPAMVPM7_EL2
-	mrs	x12, MPAMVPMV_EL2
-	stp	x11, x12, [x0, #CTX_MPAMVPM7_EL2]
-	ret
-endfunc el2_sysregs_context_save_mpam
-
-func el2_sysregs_context_restore_mpam
-	ldr	x10, [x0, #CTX_MPAM2_EL2]
-	msr	MPAM2_EL2, x10
-
-	ldp	x11, x12, [x0, #CTX_MPAMHCR_EL2]
-	msr	MPAMHCR_EL2, x11
-	msr	MPAMVPM0_EL2, x12
-
-	ldp	x13, x14, [x0, #CTX_MPAMVPM1_EL2]
-	msr	MPAMVPM1_EL2, x13
-	msr	MPAMVPM2_EL2, x14
-
-	ldp	x15, x16, [x0, #CTX_MPAMVPM3_EL2]
-	msr	MPAMVPM3_EL2, x15
-	msr	MPAMVPM4_EL2, x16
-
-	ldp	x9, x10, [x0, #CTX_MPAMVPM5_EL2]
-	msr	MPAMVPM5_EL2, x9
-	msr	MPAMVPM6_EL2, x10
-
-	ldp	x11, x12, [x0, #CTX_MPAMVPM7_EL2]
-	msr	MPAMVPM7_EL2, x11
-	msr	MPAMVPMV_EL2, x12
-	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
 	/*
@@ -368,66 +234,6 @@
 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_TRF_FOR_NS
-func el2_sysregs_context_save_trf
-	/*
-	 * TRFCR_EL2 register is saved only when FEAT_TRF is supported.
-	 */
-	mrs	x12, TRFCR_EL2
-	str	x12, [x0, #CTX_TRFCR_EL2]
-	ret
-endfunc el2_sysregs_context_save_trf
-
-func el2_sysregs_context_restore_trf
-	/*
-	 * TRFCR_EL2 register is restored only when FEAT_TRF is supported.
-	 */
-	ldr	x12, [x0, #CTX_TRFCR_EL2]
-	msr	TRFCR_EL2, x12
-	ret
-endfunc el2_sysregs_context_restore_trf
-#endif /* ENABLE_TRF_FOR_NS */
-
-#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 */
 
 /* ------------------------------------------------------------------
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 3bcefdb..42166eb 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2022, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -134,7 +134,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();
@@ -169,7 +169,12 @@
 	state = get_el3state_ctx(ctx);
 	scr_el3 = read_ctx_reg(state, CTX_SCR_EL3);
 
-	scr_el3 |= SCR_NS_BIT | SCR_NSE_BIT | SCR_EnSCXT_BIT;
+	scr_el3 |= SCR_NS_BIT | SCR_NSE_BIT;
+
+	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);
 }
@@ -222,6 +227,11 @@
 	scr_el3 |= SCR_TERR_BIT;
 #endif
 
+	if (is_feat_csv2_2_supported()) {
+		/* Enable access to the SCXTNUM_ELx registers. */
+		scr_el3 |= SCR_EnSCXT_BIT;
+	}
+
 #ifdef IMAGE_BL31
 	/*
 	 * SCR_EL3.IRQ, SCR_EL3.FIQ: Enable the physical FIQ and IRQ routing as
@@ -338,6 +348,13 @@
 #endif
 
 	/*
+	 * SCR_EL3.TCR2EN: Enable access to TCR2_ELx for AArch64 if present.
+	 */
+	if (is_feat_tcr2_supported() && (GET_RW(ep->spsr) == MODE_RW_64)) {
+		scr_el3 |= SCR_TCR2EN_BIT;
+	}
+
+	/*
 	 * CPTR_EL3 was initialized out of reset, copy that value to the
 	 * context register.
 	 */
@@ -363,22 +380,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
@@ -465,41 +481,41 @@
 static void manage_extensions_nonsecure(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
+	if (is_feat_sme_supported()) {
+		sme_enable(ctx);
+	} else if (is_feat_sve_supported()) {
+		/* Enable SVE and FPU/SIMD for non-secure world. */
+		sve_enable(ctx);
+	}
 
-#if ENABLE_MPAM_FOR_LOWER_ELS
-	mpam_enable(el2_unused);
-#endif
+	if (is_feat_mpam_supported()) {
+		mpam_enable(el2_unused);
+	}
 
-#if ENABLE_TRBE_FOR_NS
-	trbe_enable();
-#endif /* ENABLE_TRBE_FOR_NS */
+	if (is_feat_trbe_supported()) {
+		trbe_enable();
+	}
 
-#if ENABLE_BRBE_FOR_NS
-	brbe_enable();
-#endif /* ENABLE_BRBE_FOR_NS */
+	if (is_feat_brbe_supported()) {
+		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 ENABLE_TRF_FOR_NS
-	trf_enable();
-#endif /* ENABLE_TRF_FOR_NS */
+	if (is_feat_trf_supported()) {
+		trf_enable();
+	}
 #endif
 }
 
@@ -509,35 +525,38 @@
 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_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);
+		}
+	} else 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);
+		}
+	}
+
 #endif /* IMAGE_BL31 */
 }
 
@@ -795,32 +814,118 @@
 
 static void el2_sysregs_context_save_fgt(el2_sysregs_t *ctx)
 {
-	if (is_feat_fgt_supported()) {
-		write_ctx_reg(ctx, CTX_HDFGRTR_EL2, read_hdfgrtr_el2());
-		if (is_feat_amu_supported()) {
-			write_ctx_reg(ctx, CTX_HAFGRTR_EL2, read_hafgrtr_el2());
-		}
-		write_ctx_reg(ctx, CTX_HDFGWTR_EL2, read_hdfgwtr_el2());
-		write_ctx_reg(ctx, CTX_HFGITR_EL2, read_hfgitr_el2());
-		write_ctx_reg(ctx, CTX_HFGRTR_EL2, read_hfgrtr_el2());
-		write_ctx_reg(ctx, CTX_HFGWTR_EL2, read_hfgwtr_el2());
+	write_ctx_reg(ctx, CTX_HDFGRTR_EL2, read_hdfgrtr_el2());
+	if (is_feat_amu_supported()) {
+		write_ctx_reg(ctx, CTX_HAFGRTR_EL2, read_hafgrtr_el2());
 	}
+	write_ctx_reg(ctx, CTX_HDFGWTR_EL2, read_hdfgwtr_el2());
+	write_ctx_reg(ctx, CTX_HFGITR_EL2, read_hfgitr_el2());
+	write_ctx_reg(ctx, CTX_HFGRTR_EL2, read_hfgrtr_el2());
+	write_ctx_reg(ctx, CTX_HFGWTR_EL2, read_hfgwtr_el2());
 }
 
 static void el2_sysregs_context_restore_fgt(el2_sysregs_t *ctx)
 {
-	if (is_feat_fgt_supported()) {
-		write_hdfgrtr_el2(read_ctx_reg(ctx, CTX_HDFGRTR_EL2));
-		if (is_feat_amu_supported()) {
-			write_hafgrtr_el2(read_ctx_reg(ctx, CTX_HAFGRTR_EL2));
-		}
-		write_hdfgwtr_el2(read_ctx_reg(ctx, CTX_HDFGWTR_EL2));
-		write_hfgitr_el2(read_ctx_reg(ctx, CTX_HFGITR_EL2));
-		write_hfgrtr_el2(read_ctx_reg(ctx, CTX_HFGRTR_EL2));
-		write_hfgwtr_el2(read_ctx_reg(ctx, CTX_HFGWTR_EL2));
+	write_hdfgrtr_el2(read_ctx_reg(ctx, CTX_HDFGRTR_EL2));
+	if (is_feat_amu_supported()) {
+		write_hafgrtr_el2(read_ctx_reg(ctx, CTX_HAFGRTR_EL2));
 	}
+	write_hdfgwtr_el2(read_ctx_reg(ctx, CTX_HDFGWTR_EL2));
+	write_hfgitr_el2(read_ctx_reg(ctx, CTX_HFGITR_EL2));
+	write_hfgrtr_el2(read_ctx_reg(ctx, CTX_HFGRTR_EL2));
+	write_hfgwtr_el2(read_ctx_reg(ctx, CTX_HFGWTR_EL2));
 }
 
+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
  ******************************************************************************/
@@ -843,39 +948,52 @@
 		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);
+		}
 
-		el2_sysregs_context_save_fgt(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 (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 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 ENABLE_TRF_FOR_NS
-		el2_sysregs_context_save_trf(el2_sysregs_ctx);
-#endif
-#if ENABLE_FEAT_CSV2_2
-		el2_sysregs_context_save_csv2(el2_sysregs_ctx);
-#endif
+
+		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 (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());
+		}
 	}
 }
 
@@ -901,39 +1019,48 @@
 		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);
+		}
 
-		el2_sysregs_context_restore_fgt(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 (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 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 ENABLE_TRF_FOR_NS
-		el2_sysregs_context_restore_trf(el2_sysregs_ctx);
-#endif
-#if ENABLE_FEAT_CSV2_2
-		el2_sysregs_context_restore_csv2(el2_sysregs_ctx);
-#endif
+
+		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 (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));
+		}
 	}
 }
 #endif /* CTX_INCLUDE_EL2_REGS */
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/brbe/brbe.c b/lib/extensions/brbe/brbe.c
index 1982619..329cf98 100644
--- a/lib/extensions/brbe/brbe.c
+++ b/lib/extensions/brbe/brbe.c
@@ -12,16 +12,14 @@
 {
 	uint64_t val;
 
-	if (is_feat_brbe_present()) {
-		/*
-		 * MDCR_EL3.SBRBE = 0b01
-		 *
-		 * Allows BRBE usage in non-secure world and prohibited in
-		 * secure world.
-		 */
-		val = read_mdcr_el3();
-		val &= ~(MDCR_SBRBE_MASK << MDCR_SBRBE_SHIFT);
-		val |= (0x1UL << MDCR_SBRBE_SHIFT);
-		write_mdcr_el3(val);
-	}
+	/*
+	 * MDCR_EL3.SBRBE = 0b01
+	 *
+	 * Allows BRBE usage in non-secure world and prohibited in
+	 * secure world.
+	 */
+	val = read_mdcr_el3();
+	val &= ~(MDCR_SBRBE_MASK << MDCR_SBRBE_SHIFT);
+	val |= (0x1UL << MDCR_SBRBE_SHIFT);
+	write_mdcr_el3(val);
 }
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/sme/sme.c b/lib/extensions/sme/sme.c
index ec8cca8..29034fd 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);
 
@@ -66,7 +44,7 @@
 	 * using SMCR_EL2 and SMCR_EL1.
 	 */
 	reg = SMCR_ELX_LEN_MASK;
-	if (feat_sme_fa64_supported()) {
+	if (read_feat_sme_fa64_id_field() != 0U) {
 		VERBOSE("[SME] FA64 enabled\n");
 		reg |= SMCR_ELX_FA64_BIT;
 	}
@@ -85,13 +63,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/extensions/trbe/trbe.c b/lib/extensions/trbe/trbe.c
index b346387..fa139ca 100644
--- a/lib/extensions/trbe/trbe.c
+++ b/lib/extensions/trbe/trbe.c
@@ -23,22 +23,20 @@
 {
 	uint64_t val;
 
-	if (is_feat_trbe_present()) {
-		/*
-		 * MDCR_EL3.NSTB = 0b11
-		 * Allow access of trace buffer control registers from NS-EL1
-		 * and NS-EL2, tracing is prohibited in Secure and Realm state
-		 * (if implemented).
-		 */
-		val = read_mdcr_el3();
-		val |= MDCR_NSTB(MDCR_NSTB_EL1);
-		write_mdcr_el3(val);
-	}
+	/*
+	 * MDCR_EL3.NSTB = 0b11
+	 * Allow access of trace buffer control registers from NS-EL1
+	 * and NS-EL2, tracing is prohibited in Secure and Realm state
+	 * (if implemented).
+	 */
+	val = read_mdcr_el3();
+	val |= MDCR_NSTB(MDCR_NSTB_EL1);
+	write_mdcr_el3(val);
 }
 
 static void *trbe_drain_trace_buffers_hook(const void *arg __unused)
 {
-	if (is_feat_trbe_present()) {
+	if (is_feat_trbe_supported()) {
 		/*
 		 * Before switching from normal world to secure world
 		 * the trace buffers need to be drained out to memory. This is
diff --git a/lib/extensions/trf/aarch32/trf.c b/lib/extensions/trf/aarch32/trf.c
index 834092d..0c63efa 100644
--- a/lib/extensions/trf/aarch32/trf.c
+++ b/lib/extensions/trf/aarch32/trf.c
@@ -10,26 +10,15 @@
 #include <arch_helpers.h>
 #include <lib/extensions/trf.h>
 
-static bool trf_supported(void)
-{
-	uint32_t features;
-
-	features = read_id_dfr0() >> ID_DFR0_TRACEFILT_SHIFT;
-	return ((features & ID_DFR0_TRACEFILT_MASK) ==
-		ID_DFR0_TRACEFILT_SUPPORTED);
-}
-
 void trf_enable(void)
 {
 	uint32_t val;
 
-	if (trf_supported()) {
-		/*
-		 * Allow access of trace filter control registers from
-		 * non-monitor mode
-		 */
-		val = read_sdcr();
-		val &= ~SDCR_TTRF_BIT;
-		write_sdcr(val);
-	}
+	/*
+	 * Allow access of trace filter control registers from
+	 * non-monitor mode
+	 */
+	val = read_sdcr();
+	val &= ~SDCR_TTRF_BIT;
+	write_sdcr(val);
 }
diff --git a/lib/extensions/trf/aarch64/trf.c b/lib/extensions/trf/aarch64/trf.c
index 1da5dce..941692b 100644
--- a/lib/extensions/trf/aarch64/trf.c
+++ b/lib/extensions/trf/aarch64/trf.c
@@ -4,33 +4,21 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <stdbool.h>
-
 #include <arch.h>
+#include <arch_features.h>
 #include <arch_helpers.h>
 #include <lib/extensions/trf.h>
 
-static bool trf_supported(void)
-{
-	uint64_t features;
-
-	features = read_id_aa64dfr0_el1() >> ID_AA64DFR0_TRACEFILT_SHIFT;
-	return ((features & ID_AA64DFR0_TRACEFILT_MASK) ==
-		ID_AA64DFR0_TRACEFILT_SUPPORTED);
-}
-
 void trf_enable(void)
 {
 	uint64_t val;
 
-	if (trf_supported()) {
-		/*
-		 * MDCR_EL3.TTRF = b0
-		 * Allow access of trace filter control registers from NS-EL2
-		 * and NS-EL1 when NS-EL2 is implemented but not used
-		 */
-		val = read_mdcr_el3();
-		val &= ~MDCR_TTRF_BIT;
-		write_mdcr_el3(val);
-	}
+	/*
+	 * MDCR_EL3.TTRF = b0
+	 * Allow access of trace filter control registers from NS-EL2
+	 * and NS-EL1 when NS-EL2 is implemented but not used
+	 */
+	val = read_mdcr_el3();
+	val &= ~MDCR_TTRF_BIT;
+	write_mdcr_el3(val);
 }
diff --git a/lib/fconf/fconf_cot_getter.c b/lib/fconf/fconf_cot_getter.c
index ae59d8c..1033018 100644
--- a/lib/fconf/fconf_cot_getter.c
+++ b/lib/fconf/fconf_cot_getter.c
@@ -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
  */
@@ -7,8 +7,10 @@
 #include <assert.h>
 #include <stddef.h>
 
+#include <mbedtls/version.h>
+
 #include <common/fdt_wrappers.h>
-#include MBEDTLS_CONFIG_FILE
+#include <common/tbbr/cot_def.h>
 #include <drivers/auth/auth_mod.h>
 #include <lib/fconf/fconf.h>
 #include <lib/object_pool.h>
diff --git a/lib/fconf/fconf_dyn_cfg_getter.c b/lib/fconf/fconf_dyn_cfg_getter.c
index 351772e..13081b0 100644
--- a/lib/fconf/fconf_dyn_cfg_getter.c
+++ b/lib/fconf/fconf_dyn_cfg_getter.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
  */
@@ -31,7 +31,7 @@
  * This function is used to alloc memory for config information from
  * global pool and set the configuration information.
  */
-void set_config_info(uintptr_t config_addr, uintptr_t ns_config_addr,
+void set_config_info(uintptr_t config_addr, uintptr_t secondary_config_addr,
 		     uint32_t config_max_size,
 		     unsigned int config_id)
 {
@@ -39,7 +39,7 @@
 
 	dtb_info = pool_alloc(&dtb_info_pool);
 	dtb_info->config_addr = config_addr;
-	dtb_info->ns_config_addr = ns_config_addr;
+	dtb_info->secondary_config_addr = secondary_config_addr;
 	dtb_info->config_max_size = config_max_size;
 	dtb_info->config_id = config_id;
 }
@@ -106,7 +106,7 @@
 	fdt_for_each_subnode(child, dtb, node) {
 		uint32_t config_max_size, config_id;
 		uintptr_t config_addr;
-		uintptr_t ns_config_addr = ~0UL;
+		uintptr_t secondary_config_addr = ~0UL;
 		uint64_t val64;
 
 		/* Read configuration dtb information */
@@ -134,14 +134,16 @@
 		VERBOSE("\tmax-size = 0x%x\n", config_max_size);
 		VERBOSE("\tconfig-id = %u\n", config_id);
 
-		rc = fdt_read_uint64(dtb, child, "ns-load-address", &val64);
+		rc = fdt_read_uint64(dtb, child, "secondary-load-address",
+				     &val64);
 		if (rc == 0) {
-			ns_config_addr = (uintptr_t)val64;
-			VERBOSE("\tns-load-address = %lx\n", ns_config_addr);
+			secondary_config_addr = (uintptr_t)val64;
+			VERBOSE("\tsecondary-load-address = %lx\n",
+				secondary_config_addr);
 		}
 
-		set_config_info(config_addr, ns_config_addr, config_max_size,
-				config_id);
+		set_config_info(config_addr, secondary_config_addr,
+				config_max_size, config_id);
 	}
 
 	if ((child < 0) && (child != -FDT_ERR_NOTFOUND)) {
diff --git a/lib/locks/bakery/bakery_lock_normal.c b/lib/locks/bakery/bakery_lock_normal.c
index faea6c5..3c03ae6 100644
--- a/lib/locks/bakery/bakery_lock_normal.c
+++ b/lib/locks/bakery/bakery_lock_normal.c
@@ -44,7 +44,7 @@
  * Using this value, if provided, rather than the linker generated value results in
  * more efficient code
  */
-CASSERT((PLAT_PERCPU_BAKERY_LOCK_SIZE & (CACHE_WRITEBACK_GRANULE - 1)) == 0, \
+CASSERT((PLAT_PERCPU_BAKERY_LOCK_SIZE & (CACHE_WRITEBACK_GRANULE - 1)) == 0,
 	PLAT_PERCPU_BAKERY_LOCK_SIZE_not_cacheline_multiple);
 #define PERCPU_BAKERY_LOCK_SIZE (PLAT_PERCPU_BAKERY_LOCK_SIZE)
 #else
diff --git a/lib/optee/optee_utils.c b/lib/optee/optee_utils.c
index 6c87b0d..25272fc 100644
--- a/lib/optee/optee_utils.c
+++ b/lib/optee/optee_utils.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
  */
@@ -11,42 +11,6 @@
 
 #include <platform_def.h>
 
-/*
- * load_addr_hi and load_addr_lo: image load address.
- * image_id: 0 - pager, 1 - paged
- * size: image size in bytes.
- */
-typedef struct optee_image {
-	uint32_t load_addr_hi;
-	uint32_t load_addr_lo;
-	uint32_t image_id;
-	uint32_t size;
-} optee_image_t;
-
-#define OPTEE_PAGER_IMAGE_ID		0
-#define OPTEE_PAGED_IMAGE_ID		1
-
-#define OPTEE_MAX_NUM_IMAGES		2u
-
-#define TEE_MAGIC_NUM_OPTEE		0x4554504f
-/*
- * magic: header magic number.
- * version: OPTEE header version:
- *		1 - not supported
- *		2 - supported
- * arch: OPTEE os architecture type: 0 - AARCH32, 1 - AARCH64.
- * flags: unused currently.
- * nb_images: number of images.
- */
-typedef struct optee_header {
-	uint32_t magic;
-	uint8_t version;
-	uint8_t arch;
-	uint16_t flags;
-	uint32_t nb_images;
-	optee_image_t optee_image_list[];
-} optee_header_t;
-
 /*******************************************************************************
  * Check if it is a valid tee header
  * Return true if valid
diff --git a/lib/pmf/pmf_main.c b/lib/pmf/pmf_main.c
index 131a055..ce2f0d9 100644
--- a/lib/pmf/pmf_main.c
+++ b/lib/pmf/pmf_main.c
@@ -17,7 +17,7 @@
 
 /*******************************************************************************
  * The 'pmf_svc_descs' array holds the PMF service descriptors exported by
- * services by placing them in the 'pmf_svc_descs' linker section.
+ * services by placing them in the '.pmf_svc_descs' linker section.
  * The 'pmf_svc_descs_indices' array holds the index of a descriptor in the
  * 'pmf_svc_descs' array. The TIF[15:10] bits in the time-stamp id are used
  * to get an index into the 'pmf_svc_descs_indices' array. This gives the
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/rss_platform.c b/lib/psa/rss_platform.c
new file mode 100644
index 0000000..359f894
--- /dev/null
+++ b/lib/psa/rss_platform.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stdint.h>
+
+#include <psa/client.h>
+#include <psa_manifest/sid.h>
+#include <rss_platform_api.h>
+
+psa_status_t
+rss_platform_nv_counter_increment(uint32_t counter_id)
+{
+	struct psa_invec in_vec[1];
+
+	in_vec[0].base = &counter_id;
+	in_vec[0].len = sizeof(counter_id);
+
+	return psa_call(RSS_PLATFORM_SERVICE_HANDLE,
+			RSS_PLATFORM_API_ID_NV_INCREMENT,
+			in_vec, 1, NULL, 0);
+}
+
+psa_status_t
+rss_platform_nv_counter_read(uint32_t counter_id,
+		uint32_t size, uint8_t *val)
+{
+	struct psa_invec in_vec[1];
+	struct psa_outvec out_vec[1];
+
+	in_vec[0].base = &counter_id;
+	in_vec[0].len = sizeof(counter_id);
+
+	out_vec[0].base = val;
+	out_vec[0].len = size;
+
+	return psa_call(RSS_PLATFORM_SERVICE_HANDLE,
+			RSS_PLATFORM_API_ID_NV_READ,
+			in_vec, 1, out_vec, 1);
+}
diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c
index 8d736cc..ebeb10b 100644
--- a/lib/psci/psci_common.c
+++ b/lib/psci/psci_common.c
@@ -55,7 +55,7 @@
  ******************************************************************************/
 non_cpu_pd_node_t psci_non_cpu_pd_nodes[PSCI_NUM_NON_CPU_PWR_DOMAINS]
 #if USE_COHERENT_MEM
-__section("tzfw_coherent_mem")
+__section(".tzfw_coherent_mem")
 #endif
 ;
 
@@ -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
@@ -399,6 +521,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
@@ -476,6 +600,97 @@
 	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;
+	}
+
+	/* Update the target state in the power domain nodes */
+	psci_set_target_local_pwr_states(end_pwrlvl, state_info);
+
+	return rc;
+}
+#endif
+
 /******************************************************************************
  * This function validates a suspend request by making sure that if a standby
  * state is requested then no power level is turned off and the highest power
@@ -1050,3 +1265,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_main.c b/lib/psci/psci_main.c
index a631f3f..276c3a5 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.
  ******************************************************************************/
@@ -453,6 +508,12 @@
 			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:
 			ret = psci_stat_residency(r1, r2);
@@ -506,6 +567,10 @@
 			ret = psci_migrate_info_up_cpu();
 			break;
 
+		case PSCI_FEATURES:
+			ret = (u_register_t)psci_features(x1);
+			break;
+
 		case PSCI_NODE_HW_STATE_AARCH64:
 			ret = (u_register_t)psci_node_hw_state(
 					x1, (unsigned int) x2);
@@ -515,6 +580,12 @@
 			ret = (u_register_t)psci_system_suspend(x1, x2);
 			break;
 
+#if PSCI_OS_INIT_MODE
+		case PSCI_SET_SUSPEND_MODE:
+			ret = (u_register_t)psci_set_suspend_mode(x1);
+			break;
+#endif
+
 #if ENABLE_PSCI_STAT
 		case PSCI_STAT_RESIDENCY_AARCH64:
 			ret = psci_stat_residency(x1, (unsigned int) x2);
diff --git a/lib/psci/psci_private.h b/lib/psci/psci_private.h
index 6ca9ef6..b9987fe 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,6 +288,14 @@
 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);
 int psci_validate_entry_point(entry_point_info_t *ep,
@@ -284,6 +305,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 +342,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..16d6e45 100644
--- a/lib/psci/psci_setup.c
+++ b/lib/psci/psci_setup.c
@@ -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..861b875 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,32 @@
 	 * 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 ENABLE_PSCI_STAT
 	/* Update the last cpu for each level till end_pwrlvl */
@@ -208,7 +233,16 @@
 	 * platform defined mailbox with the psci entrypoint,
 	 * program the power controller etc.
 	 */
+
+#if PSCI_OS_INIT_MODE
+	rc = psci_plat_pm_ops->pwr_domain_suspend(state_info);
+	if (rc != PSCI_E_SUCCESS) {
+		skip_wfi = true;
+		goto exit;
+	}
+#else
 	psci_plat_pm_ops->pwr_domain_suspend(state_info);
+#endif
 
 #if ENABLE_PSCI_STAT
 	plat_psci_stat_accounting_start(state_info);
@@ -221,8 +255,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 +304,8 @@
 	 * context retaining suspend finisher.
 	 */
 	psci_suspend_to_standby_finisher(idx, end_pwrlvl);
+
+	return rc;
 }
 
 /*******************************************************************************
diff --git a/lib/romlib/romlib.ld.S b/lib/romlib/romlib.ld.S
index 2aac4ad..d54a684 100644
--- a/lib/romlib/romlib.ld.S
+++ b/lib/romlib/romlib.ld.S
@@ -8,37 +8,42 @@
 #include <platform_def.h>
 
 MEMORY {
-	ROM (rx): ORIGIN = ROMLIB_RO_BASE, LENGTH = ROMLIB_RO_LIMIT - ROMLIB_RO_BASE
-	RAM (rwx): ORIGIN = ROMLIB_RW_BASE, LENGTH = ROMLIB_RW_END - ROMLIB_RW_BASE
+    ROM (rx): ORIGIN = ROMLIB_RO_BASE, LENGTH = ROMLIB_RO_LIMIT - ROMLIB_RO_BASE
+    RAM (rwx): ORIGIN = ROMLIB_RW_BASE, LENGTH = ROMLIB_RW_END - ROMLIB_RW_BASE
 }
 
 OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
 OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
 ENTRY(jmptbl)
 
-SECTIONS
-{
-	. = ROMLIB_RO_BASE;
-	.text : {
-		*jmptbl.o(.text)
-		*(.text*)
-		*(.rodata*)
-	} >ROM
+SECTIONS {
+    . = ROMLIB_RO_BASE;
 
-	__DATA_ROM_START__ = LOADADDR(.data);
+    .text : {
+        *jmptbl.o(.text)
+        *(.text*)
+        *(.rodata*)
+    } >ROM
 
-	.data : {
-		__DATA_RAM_START__ = .;
-		*(.data*)
-		__DATA_RAM_END__ = .;
-	} >RAM AT>ROM
+    __DATA_ROM_START__ = LOADADDR(.data);
 
-	__DATA_SIZE__ = SIZEOF(.data);
+    .data : {
+        __DATA_RAM_START__ = .;
+
+        *(.data*)
+
+        __DATA_RAM_END__ = .;
+    } >RAM AT>ROM
+
+    __DATA_SIZE__ = SIZEOF(.data);
+
+    .bss : {
+        __BSS_START__ = .;
+
+        *(.bss*)
+
+        __BSS_END__ = .;
+     } >RAM
 
-	.bss : {
-		__BSS_START__ = .;
-		*(.bss*)
-		__BSS_END__ = .;
-	 } >RAM
-	__BSS_SIZE__ = SIZEOF(.bss);
+    __BSS_SIZE__ = SIZEOF(.bss);
 }
diff --git a/lib/xlat_tables/aarch32/nonlpae_tables.c b/lib/xlat_tables/aarch32/nonlpae_tables.c
index 7cd509d..5646f34 100644
--- a/lib/xlat_tables/aarch32/nonlpae_tables.c
+++ b/lib/xlat_tables/aarch32/nonlpae_tables.c
@@ -138,10 +138,10 @@
 static uintptr_t xlat_max_va;
 
 static uint32_t mmu_l1_base[NUM_1MB_IN_4GB]
-	__aligned(MMU32B_L1_TABLE_ALIGN) __attribute__((section("xlat_table")));
+	__aligned(MMU32B_L1_TABLE_ALIGN) __attribute__((section(".xlat_table")));
 
 static uint32_t mmu_l2_base[MAX_XLAT_TABLES][NUM_4K_IN_1MB]
-	__aligned(MMU32B_L2_TABLE_ALIGN) __attribute__((section("xlat_table")));
+	__aligned(MMU32B_L2_TABLE_ALIGN) __attribute__((section(".xlat_table")));
 
 /*
  * Array of all memory regions stored in order of ascending base address.
@@ -518,9 +518,9 @@
 	/* Enable Access flag (simplified access permissions) and TEX remap */
 	write_sctlr(read_sctlr() | SCTLR_AFE_BIT | SCTLR_TRE_BIT);
 
-	prrr = MMU32B_PRRR_IDX(MMU32B_ATTR_DEVICE_INDEX, 1, 0) \
+	prrr = MMU32B_PRRR_IDX(MMU32B_ATTR_DEVICE_INDEX, 1, 0)
 			| MMU32B_PRRR_IDX(MMU32B_ATTR_IWBWA_OWBWA_INDEX, 2, 1);
-	nmrr = MMU32B_NMRR_IDX(MMU32B_ATTR_DEVICE_INDEX, 0, 0) \
+	nmrr = MMU32B_NMRR_IDX(MMU32B_ATTR_DEVICE_INDEX, 0, 0)
 			| MMU32B_NMRR_IDX(MMU32B_ATTR_IWBWA_OWBWA_INDEX, 1, 1);
 
 	prrr |= MMU32B_PRRR_NS1 | MMU32B_PRRR_DS1;
diff --git a/lib/xlat_tables/xlat_tables_common.c b/lib/xlat_tables/xlat_tables_common.c
index 23fe3f0..71273cb 100644
--- a/lib/xlat_tables/xlat_tables_common.c
+++ b/lib/xlat_tables/xlat_tables_common.c
@@ -39,7 +39,7 @@
 #define MT_UNKNOWN	~0U
 
 static uint64_t xlat_tables[MAX_XLAT_TABLES][XLAT_TABLE_ENTRIES]
-			__aligned(XLAT_TABLE_SIZE) __section("xlat_table");
+			__aligned(XLAT_TABLE_SIZE) __section(".xlat_table");
 
 static unsigned int next_xlat;
 static unsigned long long xlat_max_pa;
diff --git a/lib/zlib/crc32.c b/lib/zlib/crc32.c
index f8357b0..21a69a8 100644
--- a/lib/zlib/crc32.c
+++ b/lib/zlib/crc32.c
@@ -279,7 +279,7 @@
   combinations of CRC register values and incoming bytes.
  */
 
-local void make_crc_table()
+local void make_crc_table(void)
 {
     unsigned i, j, n;
     z_crc_t p;
@@ -498,7 +498,7 @@
 }
 
 /* Actually do the deed. */
-int main()
+int main(void)
 {
     make_crc_table();
     return 0;
diff --git a/lib/zlib/inflate.c b/lib/zlib/inflate.c
index 8acbef4..aa25e61 100644
--- a/lib/zlib/inflate.c
+++ b/lib/zlib/inflate.c
@@ -342,7 +342,7 @@
 
     a.out > inffixed.h
  */
-void makefixed()
+void makefixed(void)
 {
     unsigned low, size;
     struct inflate_state state;
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index 426e344..9ca6bdf 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.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
 #
@@ -13,6 +13,7 @@
 # Some utility macros for manipulating awkward (whitespace) characters.
 blank			:=
 space			:=${blank} ${blank}
+comma			:= ,
 
 # A user defined function to recursively search for a filename below a directory
 #    $1 is the directory root of the recursive search (blank for current directory).
@@ -37,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
@@ -44,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
@@ -86,6 +98,12 @@
     $(foreach num,$1,$(eval $(call assert_numeric,$(num))))
 endef
 
+# Convenience function to check for a given linker option. An call to
+# $(call ld_option, --no-XYZ) will return --no-XYZ if supported by the linker
+define ld_option
+	$(shell if $(LD) $(1) -v >/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
@@ -97,12 +115,6 @@
 )
 endef
 
-# IMG_LINKERFILE defines the linker script corresponding to a BL stage
-#   $(1) = BL stage
-define IMG_LINKERFILE
-    ${BUILD_DIR}/$(1).ld
-endef
-
 # IMG_MAPFILE defines the output file describing the memory map corresponding
 # to a BL stage
 #   $(1) = BL stage
@@ -279,10 +291,11 @@
 define MAKE_C_LIB
 $(eval OBJ := $(1)/$(patsubst %.c,%.o,$(notdir $(2))))
 $(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
+$(eval LIB := $(call uppercase, $(notdir $(1))))
 
 $(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | lib$(3)_dirs
 	$$(ECHO) "  CC      $$<"
-	$$(Q)$$(CC) $$(TF_CFLAGS) $$(CFLAGS) $(MAKE_DEP) -c $$< -o $$@
+	$$(Q)$$(CC) $$($(LIB)_CFLAGS) $$(TF_CFLAGS) $$(CFLAGS) $(MAKE_DEP) -c $$< -o $$@
 
 -include $(DEP)
 
@@ -457,6 +470,15 @@
 	$$(Q)$$(AR) cr $$@ $$?
 endef
 
+# Generate the path to one or more preprocessed linker scripts given the paths
+# of their sources.
+#
+# Arguments:
+#   $(1) = path to one or more linker script sources
+define linker_script_path
+        $(patsubst %.S,$(BUILD_DIR)/%,$(1))
+endef
+
 # MAKE_BL macro defines the targets and options to build each BL image.
 # Arguments:
 #   $(1) = BL stage
@@ -468,17 +490,22 @@
         $(eval BL_SOURCES := $($(call uppercase,$(1))_SOURCES))
         $(eval SOURCES    := $(BL_SOURCES) $(BL_COMMON_SOURCES) $(PLAT_BL_COMMON_SOURCES))
         $(eval OBJS       := $(addprefix $(BUILD_DIR)/,$(call SOURCES_TO_OBJS,$(SOURCES))))
-        $(eval LINKERFILE := $(call IMG_LINKERFILE,$(1)))
         $(eval MAPFILE    := $(call IMG_MAPFILE,$(1)))
         $(eval ELF        := $(call IMG_ELF,$(1)))
         $(eval DUMP       := $(call IMG_DUMP,$(1)))
         $(eval BIN        := $(call IMG_BIN,$(1)))
         $(eval ENC_BIN    := $(call IMG_ENC_BIN,$(1)))
-        $(eval BL_LINKERFILE := $($(call uppercase,$(1))_LINKERFILE))
         $(eval BL_LIBS    := $($(call uppercase,$(1))_LIBS))
+
+        $(eval DEFAULT_LINKER_SCRIPT_SOURCE := $($(call uppercase,$(1))_DEFAULT_LINKER_SCRIPT_SOURCE))
+        $(eval DEFAULT_LINKER_SCRIPT := $(call linker_script_path,$(DEFAULT_LINKER_SCRIPT_SOURCE)))
+
+        $(eval LINKER_SCRIPT_SOURCES := $($(call uppercase,$(1))_LINKER_SCRIPT_SOURCES))
+        $(eval LINKER_SCRIPTS := $(call linker_script_path,$(LINKER_SCRIPT_SOURCES)))
+
         # We use sort only to get a list of unique object directory names.
         # ordering is not relevant but sort removes duplicates.
-        $(eval TEMP_OBJ_DIRS := $(sort $(dir ${OBJS} ${LINKERFILE})))
+        $(eval TEMP_OBJ_DIRS := $(sort $(dir ${OBJS} ${DEFAULT_LINKER_SCRIPT} ${LINKER_SCRIPTS})))
         # The $(dir ) function leaves a trailing / on the directory names
         # Rip off the / to match directory names with make rule targets.
         $(eval OBJ_DIRS   := $(patsubst %/,%,$(TEMP_OBJ_DIRS)))
@@ -487,7 +514,8 @@
 
 $(eval $(call MAKE_PREREQ_DIR,${BUILD_DIR},${BUILD_PLAT}))
 
-$(eval $(foreach objd,${OBJ_DIRS},$(call MAKE_PREREQ_DIR,${objd},${BUILD_DIR})))
+$(eval $(foreach objd,${OBJ_DIRS},
+        $(call MAKE_PREREQ_DIR,${objd},${BUILD_DIR})))
 
 .PHONY : ${1}_dirs
 
@@ -496,7 +524,11 @@
 ${1}_dirs: | ${OBJ_DIRS}
 
 $(eval $(call MAKE_OBJS,$(BUILD_DIR),$(SOURCES),$(1)))
-$(eval $(call MAKE_LD,$(LINKERFILE),$(BL_LINKERFILE),$(1)))
+
+# Generate targets to preprocess each required linker script
+$(eval $(foreach source,$(DEFAULT_LINKER_SCRIPT_SOURCE) $(LINKER_SCRIPT_SOURCES), \
+        $(call MAKE_LD,$(call linker_script_path,$(source)),$(source),$(1))))
+
 $(eval BL_LDFLAGS := $($(call uppercase,$(1))_LDFLAGS))
 
 ifeq ($(USE_ROMLIB),1)
@@ -507,7 +539,7 @@
 # object file path, and prebuilt object file path.
 $(eval OBJS += $(MODULE_OBJS))
 
-$(ELF): $(OBJS) $(LINKERFILE) | $(1)_dirs libraries $(BL_LIBS)
+$(ELF): $(OBJS) $(DEFAULT_LINKER_SCRIPT) $(LINKER_SCRIPTS) | $(1)_dirs libraries $(BL_LIBS)
 	$$(ECHO) "  LD      $$@"
 ifdef MAKE_BUILD_STRINGS
 	$(call MAKE_BUILD_STRINGS, $(BUILD_DIR)/build_message.o)
@@ -526,11 +558,13 @@
 		$(BUILD_DIR)/build_message.o $(OBJS)
 else ifneq ($(findstring gcc,$(notdir $(LD))),)
 	$$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) -Wl,-Map=$(MAPFILE) \
-		-Wl,-dT $(LINKERFILE) $(EXTRA_LINKERFILE) $(BUILD_DIR)/build_message.o \
+		$(addprefix -Wl$(comma)--script$(comma),$(LINKER_SCRIPTS)) -Wl,--script,$(DEFAULT_LINKER_SCRIPT) \
+		$(BUILD_DIR)/build_message.o \
 		$(OBJS) $(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS)
 else
 	$$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) -Map=$(MAPFILE) \
-		--script $(LINKERFILE) $(BUILD_DIR)/build_message.o \
+		$(addprefix -T ,$(LINKER_SCRIPTS)) --script $(DEFAULT_LINKER_SCRIPT) \
+		$(BUILD_DIR)/build_message.o \
 		$(OBJS) $(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS)
 endif
 ifeq ($(DISABLE_BIN_GENERATION),1)
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index a66123a..63617b2 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016-2022, Arm Limited. All rights reserved.
+# Copyright (c) 2016-2023, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -30,13 +30,13 @@
 BASE_COMMIT			:= origin/master
 
 # Execute BL2 at EL3
-BL2_AT_EL3			:= 0
+RESET_TO_BL2			:= 0
 
 # Only use SP packages if SP layout JSON is defined
 BL2_ENABLE_SP_LOAD		:= 0
 
 # BL2 image is stored in XIP memory, for now, this option is only supported
-# when BL2_AT_EL3 is 1.
+# when RESET_TO_BL2 is 1.
 BL2_IN_XIP_MEM			:= 0
 
 # Do dcache invalidate upon BL2 entry at EL3
@@ -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
 
@@ -176,6 +173,9 @@
 # Flag to enable delayed trapping of WFE instruction (FEAT_TWED)
 ENABLE_FEAT_TWED		:= 0
 
+# Flag to enable access to TCR2 (FEAT_TCR2)
+ENABLE_FEAT_TCR2		:= 0
+
 # By default BL31 encryption disabled
 ENCRYPT_BL31			:= 0
 
@@ -255,6 +255,9 @@
 # Flag used to choose the power state format: Extended State-ID or Original
 PSCI_EXTENDED_STATE_ID		:= 0
 
+# Enable PSCI OS-initiated mode support
+PSCI_OS_INIT_MODE		:= 0
+
 # Enable RAS support
 RAS_EXTENSION			:= 0
 
@@ -352,11 +355,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
@@ -364,13 +367,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
@@ -385,7 +388,7 @@
 ENABLE_SME_FOR_SWD		:= 0
 
 # If SME is enabled then force SVE off
-ifeq (${ENABLE_SME_FOR_NS},1)
+ifneq (${ENABLE_SME_FOR_NS},0)
 	override ENABLE_SVE_FOR_NS	:= 0
 	override ENABLE_SVE_FOR_SWD	:= 0
 endif
diff --git a/make_helpers/tbbr/tbbr_tools.mk b/make_helpers/tbbr/tbbr_tools.mk
index 5ef2d85..8605bae 100644
--- a/make_helpers/tbbr/tbbr_tools.mk
+++ b/make_helpers/tbbr/tbbr_tools.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
 #
@@ -83,7 +83,7 @@
 
 # Add the BL2 CoT (image cert)
 ifeq (${NEED_BL2},yes)
-ifeq (${BL2_AT_EL3}, 0)
+ifeq (${RESET_TO_BL2}, 0)
 ifneq (${COT},cca)
 $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/tb_fw.crt,--tb-fw-cert))
 endif
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/sun50i_h6/sunxi_power.c b/plat/allwinner/sun50i_h6/sunxi_power.c
index d298e6b..1257076 100644
--- a/plat/allwinner/sun50i_h6/sunxi_power.c
+++ b/plat/allwinner/sun50i_h6/sunxi_power.c
@@ -8,8 +8,10 @@
 #include <errno.h>
 
 #include <common/debug.h>
+#include <common/fdt_wrappers.h>
 #include <drivers/allwinner/axp.h>
 #include <drivers/allwinner/sunxi_rsb.h>
+#include <libfdt.h>
 #include <lib/mmio.h>
 
 #include <sunxi_cpucfg.h>
@@ -63,7 +65,12 @@
 
 int sunxi_pmic_setup(uint16_t socid, const void *fdt)
 {
-	int ret;
+	int node, ret;
+
+	node = fdt_node_offset_by_compatible(fdt, 0, "allwinner,sun8i-a23-rsb");
+	if ((node < 0) || !fdt_node_is_enabled(fdt, node)) {
+		return -ENODEV;
+	}
 
 	INFO("PMIC: Probing AXP805 on RSB\n");
 
diff --git a/plat/arm/board/arm_fpga/build_axf.ld.S b/plat/arm/board/arm_fpga/build_axf.ld.S
index d8254e5..bd3d163 100644
--- a/plat/arm/board/arm_fpga/build_axf.ld.S
+++ b/plat/arm/board/arm_fpga/build_axf.ld.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited. All rights reserved.
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -46,7 +46,7 @@
 		KEEP(*(.kern_tramp))
 	}
 
-	/DISCARD/ : { *(stacks) }
+	/DISCARD/ : { *(.stacks) }
 	/DISCARD/ : { *(.debug_*) }
 	/DISCARD/ : { *(.note*) }
 	/DISCARD/ : { *(.comment*) }
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..109bfbe 100644
--- a/plat/arm/board/arm_fpga/platform.mk
+++ b/plat/arm/board/arm_fpga/platform.mk
@@ -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
diff --git a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
index 45e3b7e..43dc17b 100644
--- a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
+++ b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
@@ -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
  */
@@ -18,6 +18,15 @@
 struct hw_topology_t soc_topology;
 struct uart_serial_config_t uart_serial_config;
 struct cpu_timer_t cpu_timer;
+struct ns_dram_layout dram_layout;
+
+/*
+ * Each NS DRAM bank entry is 'reg' node property which is
+ * a sequence of (address, length) pairs of 32-bit values.
+ */
+#define DRAM_ENTRY_SIZE		(4UL * sizeof(uint32_t))
+
+CASSERT(ARM_DRAM_NUM_BANKS == 2UL, ARM_DRAM_NUM_BANKS_mismatch);
 
 #define ILLEGAL_ADDR	ULL(~0)
 
@@ -293,7 +302,58 @@
 	return 0;
 }
 
+int fconf_populate_dram_layout(uintptr_t config)
+{
+	int node, len;
+	const uint32_t *reg;
+
+	/* Necessary to work with libfdt APIs */
+	const void *hw_config_dtb = (const void *)config;
+
+	/* Find 'memory' node */
+	node = fdt_node_offset_by_prop_value(hw_config_dtb, -1, "device_type",
+					     "memory", sizeof("memory"));
+	if (node < 0) {
+		WARN("FCONF: Unable to locate 'memory' node\n");
+		return node;
+	}
+
+	reg = fdt_getprop(hw_config_dtb, node, "reg", &len);
+	if (reg == NULL) {
+		ERROR("FCONF failed to read 'reg' property\n");
+		return len;
+	}
+
+	switch (len) {
+	case DRAM_ENTRY_SIZE:
+		/* 1 DRAM bank */
+		dram_layout.num_banks = 1UL;
+		break;
+	case 2UL * DRAM_ENTRY_SIZE:
+		/* 2 DRAM banks */
+		dram_layout.num_banks = 2UL;
+		break;
+	default:
+		ERROR("FCONF: Invalid 'memory' node\n");
+		return -FDT_ERR_BADLAYOUT;
+	}
+
+	for (unsigned long i = 0UL; i < dram_layout.num_banks; i++) {
+		int err = fdt_get_reg_props_by_index(
+				hw_config_dtb, node, (int)i,
+				&dram_layout.dram_bank[i].base,
+				(size_t *)&dram_layout.dram_bank[i].size);
+		if (err < 0) {
+			ERROR("FCONF: Failed to read 'reg' property #%lu of 'memory' node\n", i);
+			return err;
+		}
+	}
+
+	return 0;
+}
+
 FCONF_REGISTER_POPULATOR(HW_CONFIG, gicv3_config, fconf_populate_gicv3_config);
 FCONF_REGISTER_POPULATOR(HW_CONFIG, topology, fconf_populate_topology);
 FCONF_REGISTER_POPULATOR(HW_CONFIG, uart_config, fconf_populate_uart_config);
 FCONF_REGISTER_POPULATOR(HW_CONFIG, cpu_timer, fconf_populate_cpu_timer);
+FCONF_REGISTER_POPULATOR(HW_CONFIG, dram_layout, fconf_populate_dram_layout);
diff --git a/plat/arm/board/fvp/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts
index 577ac74..4adf5d5 100644
--- a/plat/arm/board/fvp/fdts/fvp_fw_config.dts
+++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts
@@ -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
  */
@@ -22,7 +22,7 @@
 			load-address = <0x0 0x07f00000>;
 			max-size = <0x00100000>;
 			id = <HW_CONFIG_ID>;
-			ns-load-address = <0x0 0x82000000>;
+			secondary-load-address = <0x0 0x82000000>;
 		};
 
 		/*
@@ -40,7 +40,11 @@
 /* If required, SPD should enable loading of trusted OS fw config */
 #if defined(SPD_tspd) || defined(SPD_spmd)
 		tos_fw-config {
+
 			load-address = <0x0 0x04001500>;
+#if ENABLE_RME
+			secondary-load-address = <0x0 0x7e00000>;
+#endif /* ENABLE_RME */
 			max-size = <0xB00>;
 			id = <TOS_FW_CONFIG_ID>;
 		};
diff --git a/plat/arm/board/fvp/fvp_bl2_measured_boot.c b/plat/arm/board/fvp/fvp_bl2_measured_boot.c
index 29b6619..7b0673a 100644
--- a/plat/arm/board/fvp/fvp_bl2_measured_boot.c
+++ b/plat/arm/board/fvp/fvp_bl2_measured_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,6 +15,11 @@
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/common_def.h>
 
+#if defined(SPD_tspd) || defined(SPD_opteed) || defined(SPD_spmd)
+CASSERT(ARM_EVENT_LOG_DRAM1_SIZE >= PLAT_ARM_EVENT_LOG_MAX_SIZE, \
+	assert_res_eventlog_mem_insufficient);
+#endif /* defined(SPD_tspd) || defined(SPD_opteed) || defined(SPD_spmd) */
+
 /* Event Log data */
 static uint64_t event_log_base;
 
@@ -195,9 +200,19 @@
 
 	event_log_cur_size = event_log_get_cur_size((uint8_t *)event_log_base);
 
+#if defined(SPD_tspd) || defined(SPD_opteed) || defined(SPD_spmd)
+	/* Copy Event Log to TZC secured DRAM memory */
+	(void)memcpy((void *)ARM_EVENT_LOG_DRAM1_BASE,
+		     (const void *)event_log_base,
+		     event_log_cur_size);
+
+	/* Ensure that the Event Log is visible in TZC secured DRAM memory */
+	flush_dcache_range(ARM_EVENT_LOG_DRAM1_BASE, event_log_cur_size);
+#endif /* defined(SPD_tspd) || defined(SPD_opteed) || defined(SPD_spmd) */
+
 	rc = arm_set_nt_fw_info(
 #ifdef SPD_opteed
-			    (uintptr_t)event_log_base,
+			    (uintptr_t)ARM_EVENT_LOG_DRAM1_BASE,
 #endif
 			    event_log_cur_size, &ns_log_addr);
 	if (rc != 0) {
@@ -222,7 +237,7 @@
 
 #if defined(SPD_tspd) || defined(SPD_spmd)
 	/* Set Event Log data in TOS_FW_CONFIG */
-	rc = arm_set_tos_fw_info((uintptr_t)event_log_base,
+	rc = arm_set_tos_fw_info((uintptr_t)ARM_EVENT_LOG_DRAM1_BASE,
 				 event_log_cur_size);
 	if (rc != 0) {
 		ERROR("%s(): Unable to update %s_FW_CONFIG\n",
diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c
index 74e5d72..b93922a 100644
--- a/plat/arm/board/fvp/fvp_bl2_setup.c
+++ b/plat/arm/board/fvp/fvp_bl2_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -45,7 +45,7 @@
 
 	arm_bl_params = arm_get_next_bl_params();
 
-#if !BL2_AT_EL3 && !EL3_PAYLOAD_BASE
+#if !RESET_TO_BL2 && !EL3_PAYLOAD_BASE
 	const struct dyn_cfg_dtb_info_t *fw_config_info;
 	uintptr_t fw_config_base = 0UL;
 	entry_point_info_t *ep_info;
@@ -82,7 +82,7 @@
 	assert(param_node != NULL);
 
 	/* Copy HW config from Secure address to NS address */
-	memcpy((void *)hw_config_info->ns_config_addr,
+	memcpy((void *)hw_config_info->secondary_config_addr,
 	       (void *)hw_config_info->config_addr,
 	       (size_t)param_node->image_info.image_size);
 
@@ -91,15 +91,15 @@
 	 * a possibility to use HW-config without cache and MMU enabled
 	 * at BL33
 	 */
-	flush_dcache_range(hw_config_info->ns_config_addr,
+	flush_dcache_range(hw_config_info->secondary_config_addr,
 			   param_node->image_info.image_size);
 
 	param_node = get_bl_mem_params_node(BL33_IMAGE_ID);
 	assert(param_node != NULL);
 
 	/* Update BL33's ep info with NS HW config address  */
-	param_node->ep_info.args.arg1 = hw_config_info->ns_config_addr;
-#endif /* !BL2_AT_EL3 && !EL3_PAYLOAD_BASE */
+	param_node->ep_info.args.arg1 = hw_config_info->secondary_config_addr;
+#endif /* !RESET_TO_BL2 && !EL3_PAYLOAD_BASE */
 
 	return arm_bl_params;
 }
diff --git a/plat/arm/board/fvp/fvp_bl31_setup.c b/plat/arm/board/fvp/fvp_bl31_setup.c
index dd90965..e46dbc9 100644
--- a/plat/arm/board/fvp/fvp_bl31_setup.c
+++ b/plat/arm/board/fvp/fvp_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -25,7 +25,7 @@
 	/* Initialize the console to provide early debug support */
 	arm_console_boot_init();
 
-#if !RESET_TO_BL31 && !BL2_AT_EL3
+#if !RESET_TO_BL31 && !RESET_TO_BL2
 	const struct dyn_cfg_dtb_info_t *soc_fw_config_info;
 
 	INFO("BL31 FCONF: FW_CONFIG address = %lx\n", (uintptr_t)arg1);
@@ -45,9 +45,9 @@
 	 */
 	hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID);
 	assert(hw_config_info != NULL);
-	assert(hw_config_info->ns_config_addr != 0UL);
-	arg2 = hw_config_info->ns_config_addr;
-#endif /* !RESET_TO_BL31 && !BL2_AT_EL3 */
+	assert(hw_config_info->secondary_config_addr != 0UL);
+	arg2 = hw_config_info->secondary_config_addr;
+#endif /* !RESET_TO_BL31 && !RESET_TO_BL2 */
 
 	arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
 
@@ -93,7 +93,7 @@
 	 * TODO: remove the ARM_XLAT_TABLES_LIB_V1 check when its support
 	 * gets deprecated.
 	 */
-#if !RESET_TO_BL31 && !BL2_AT_EL3 && !ARM_XLAT_TABLES_LIB_V1
+#if !RESET_TO_BL31 && !RESET_TO_BL2 && !ARM_XLAT_TABLES_LIB_V1
 	assert(hw_config_info != NULL);
 	assert(hw_config_info->config_addr != 0UL);
 
@@ -129,14 +129,14 @@
 		      rc);
 		panic();
 	}
-#endif /* !RESET_TO_BL31 && !BL2_AT_EL3 && !ARM_XLAT_TABLES_LIB_V1 */
+#endif /* !RESET_TO_BL31 && !RESET_TO_BL2 && !ARM_XLAT_TABLES_LIB_V1 */
 }
 
 unsigned int plat_get_syscnt_freq2(void)
 {
 	unsigned int counter_base_frequency;
 
-#if !RESET_TO_BL31 && !BL2_AT_EL3
+#if !RESET_TO_BL31 && !RESET_TO_BL2
 	/* Get the frequency through FCONF API for HW_CONFIG */
 	counter_base_frequency = FCONF_GET_PROPERTY(hw_config, cpu_timer, clock_freq);
 	if (counter_base_frequency > 0U) {
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index f5d9940..283918b 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,19 +12,19 @@
 #include <drivers/arm/gicv2.h>
 #include <drivers/arm/sp804_delay_timer.h>
 #include <drivers/generic_delay_timer.h>
+#include <fconf_hw_config_getter.h>
 #include <lib/mmio.h>
 #include <lib/smccc.h>
 #include <lib/xlat_tables/xlat_tables_compat.h>
 #include <platform_def.h>
 #include <services/arm_arch_svc.h>
-#if ENABLE_RME
 #include <services/rmm_core_manifest.h>
-#endif
 #if SPM_MM
 #include <services/spm_mm_partition.h>
 #endif
 
 #include <plat/arm/common/arm_config.h>
+#include <plat/arm/common/arm_pas_def.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
@@ -111,6 +111,15 @@
 	 * Required to load HW_CONFIG, SPMC and SPs to trusted DRAM.
 	 */
 	ARM_MAP_TRUSTED_DRAM,
+
+	/*
+	 * Required to load Event Log in TZC secured memory
+	 */
+#if MEASURED_BOOT && (defined(SPD_tspd) || defined(SPD_opteed) || \
+defined(SPD_spmd))
+	ARM_MAP_EVENT_LOG_DRAM1,
+#endif /* MEASURED_BOOT && (SPD_tspd || SPD_opteed || SPD_spmd) */
+
 #if ENABLE_RME
 	ARM_MAP_RMM_DRAM,
 	ARM_MAP_GPT_L1_DRAM,
@@ -123,13 +132,13 @@
 	MAP_DEVICE2,
 #endif /* TRUSTED_BOARD_BOOT */
 
-#if CRYPTO_SUPPORT && !BL2_AT_EL3
+#if CRYPTO_SUPPORT && !RESET_TO_BL2
 	/*
 	 * To access shared the Mbed TLS heap while booting the
 	 * system with Crypto support
 	 */
 	ARM_MAP_BL1_RW,
-#endif /* CRYPTO_SUPPORT && !BL2_AT_EL3 */
+#endif /* CRYPTO_SUPPORT && !RESET_TO_BL2 */
 #if SPM_MM || SPMC_AT_EL3
 	ARM_SP_IMAGE_MMAP,
 #endif
@@ -180,8 +189,8 @@
 #if defined(IMAGE_BL31) && SPM_MM
 const mmap_region_t plat_arm_secure_partition_mmap[] = {
 	V2M_MAP_IOFPGA_EL0, /* for the UART */
-	MAP_REGION_FLAT(DEVICE0_BASE,				\
-			DEVICE0_SIZE,				\
+	MAP_REGION_FLAT(DEVICE0_BASE,
+			DEVICE0_SIZE,
 			MT_DEVICE | MT_RO | MT_SECURE | MT_USER),
 	ARM_SP_IMAGE_MMAP,
 	ARM_SP_IMAGE_NS_BUF_MMAP,
@@ -531,15 +540,73 @@
 	return (size_t)RMM_SHARED_SIZE;
 }
 
-int plat_rmmd_load_manifest(rmm_manifest_t *manifest)
+int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
 {
+	uint64_t checksum, num_banks;
+	struct ns_dram_bank *bank_ptr;
+
 	assert(manifest != NULL);
 
+	/* Get number of DRAM banks */
+	num_banks = FCONF_GET_PROPERTY(hw_config, dram_layout, num_banks);
+	assert(num_banks <= ARM_DRAM_NUM_BANKS);
+
 	manifest->version = RMMD_MANIFEST_VERSION;
 	manifest->padding = 0U; /* RES0 */
 	manifest->plat_data = (uintptr_t)NULL;
+	manifest->plat_dram.num_banks = num_banks;
+
+	/*
+	 * Array ns_dram_banks[] follows ns_dram_info structure:
+	 *
+	 * +-----------------------------------+
+	 * |  offset  |   field   |  comment   |
+	 * +----------+-----------+------------+
+	 * |    0     |  version  | 0x00000002 |
+	 * +----------+-----------+------------+
+	 * |    4     |  padding  | 0x00000000 |
+	 * +----------+-----------+------------+
+	 * |    8     | plat_data |    NULL    |
+	 * +----------+-----------+------------+
+	 * |    16    | num_banks |            |
+	 * +----------+-----------+            |
+	 * |    24    |   banks   | plat_dram  |
+	 * +----------+-----------+            |
+	 * |    32    | checksum  |            |
+	 * +----------+-----------+------------+
+	 * |    40    |  base 0   |            |
+	 * +----------+-----------+   bank[0]  |
+	 * |    48    |  size 0   |            |
+	 * +----------+-----------+------------+
+	 * |    56    |  base 1   |            |
+	 * +----------+-----------+   bank[1]  |
+	 * |    64    |  size 1   |            |
+	 * +----------+-----------+------------+
+	 */
+	bank_ptr = (struct ns_dram_bank *)
+			((uintptr_t)&manifest->plat_dram.checksum +
+			sizeof(manifest->plat_dram.checksum));
+
+	manifest->plat_dram.banks = bank_ptr;
+
+	/* Calculate checksum of plat_dram structure */
+	checksum = num_banks + (uint64_t)bank_ptr;
+
+	/* Store FVP DRAM banks data in Boot Manifest */
+	for (unsigned long i = 0UL; i < num_banks; i++) {
+		uintptr_t base = FCONF_GET_PROPERTY(hw_config, dram_layout, dram_bank[i].base);
+		uint64_t size = FCONF_GET_PROPERTY(hw_config, dram_layout, dram_bank[i].size);
+
+		bank_ptr[i].base = base;
+		bank_ptr[i].size = size;
+
+		/* Update checksum */
+		checksum += base + size;
+	}
+
+	/* Checksum must be 0 */
+	manifest->plat_dram.checksum = ~checksum + 1UL;
 
 	return 0;
 }
-
-#endif
+#endif	/* ENABLE_RME */
diff --git a/plat/arm/board/fvp/fvp_console.c b/plat/arm/board/fvp/fvp_console.c
index 1a6cd42..3aa454b 100644
--- a/plat/arm/board/fvp/fvp_console.c
+++ b/plat/arm/board/fvp/fvp_console.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,9 +24,9 @@
 
 	/*
 	 * fconf APIs are not supported for RESET_TO_SP_MIN, RESET_TO_BL31 and
-	 * BL2_AT_EL3 systems.
+	 * RESET_TO_BL2 systems.
 	 */
-#if RESET_TO_SP_MIN || RESET_TO_BL31 || BL2_AT_EL3
+#if RESET_TO_SP_MIN || RESET_TO_BL31 || RESET_TO_BL2
 	uart_base = PLAT_ARM_RUN_UART_BASE;
 	uart_clk = PLAT_ARM_RUN_UART_CLK_IN_HZ;
 #else
diff --git a/plat/arm/board/fvp/fvp_el3_spmc.c b/plat/arm/board/fvp/fvp_el3_spmc.c
index 2b347ed..6b44f63 100644
--- a/plat/arm/board/fvp/fvp_el3_spmc.c
+++ b/plat/arm/board/fvp/fvp_el3_spmc.c
@@ -18,7 +18,7 @@
 
 #define PLAT_SPMC_SHMEM_DATASTORE_SIZE 512 * 1024
 
-__section("arm_el3_tzc_dram") static uint8_t
+__section(".arm_el3_tzc_dram") static uint8_t
 plat_spmc_shmem_datastore[PLAT_SPMC_SHMEM_DATASTORE_SIZE];
 
 int plat_spmc_shmem_datastore_get(uint8_t **datastore, size_t *size)
diff --git a/plat/arm/board/fvp/fvp_plat_attest_token.c b/plat/arm/board/fvp/fvp_plat_attest_token.c
index 4dd37a4..5af2405 100644
--- a/plat/arm/board/fvp/fvp_plat_attest_token.c
+++ b/plat/arm/board/fvp/fvp_plat_attest_token.c
@@ -1,111 +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, 0x40, 0xA0, 0x59, 0x02, 0x46, 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, 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, 0x5C, 0x58,
-	0x40, 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, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0xA0, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x38,
-	0x00, 0x09, 0x00, 0x40, 0x00, 0x1C, 0x00, 0x1B,
-	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, 0x67, 0x73, 0x68,
-	0x61, 0x2D, 0x32, 0x35, 0x36, 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, 0x40, 0x84,
-	0x32, 0x12, 0x5B, 0x92, 0x6B, 0x20, 0xD8, 0x14,
-	0xC1, 0xC1, 0x8C, 0x3C, 0x73, 0xB8, 0x29, 0x0F,
-	0x42, 0xBC, 0x0B, 0x25, 0x87, 0x5C, 0x4F, 0xA4,
-	0xFA, 0xD9, 0xDE, 0xC1, 0x2B, 0x20, 0xED, 0xDF,
-	0x1C, 0xDD, 0x1A, 0x09, 0xBD, 0xA0, 0x25, 0x48,
-	0xC6, 0xBB, 0x99, 0xA1, 0x30, 0x4F, 0x2C, 0xDC,
-	0x89, 0xE8, 0xB7, 0xFF, 0x32, 0xE9, 0x3F, 0xBB,
-	0xC6, 0xBF, 0x9D, 0x38, 0x68, 0xE1, 0xB2,
-};
-
+/*
+ * 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..a3289b6 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();
@@ -227,7 +228,11 @@
  * FVP handler called when a power domain is about to be suspended. The
  * target_state encodes the power state that each level should transition to.
  ******************************************************************************/
+#if PSCI_OS_INIT_MODE
+static int fvp_pwr_domain_suspend(const psci_power_state_t *target_state)
+#else
 static void fvp_pwr_domain_suspend(const psci_power_state_t *target_state)
+#endif
 {
 	unsigned long mpidr;
 
@@ -237,7 +242,11 @@
 	 */
 	if (target_state->pwr_domain_state[ARM_PWR_LVL0] ==
 					ARM_LOCAL_STATE_RET)
+#if PSCI_OS_INIT_MODE
+		return PSCI_E_SUCCESS;
+#else
 		return;
+#endif
 
 	assert(target_state->pwr_domain_state[ARM_PWR_LVL0] ==
 					ARM_LOCAL_STATE_OFF);
@@ -269,6 +278,12 @@
 
 	/* Program the power controller to power off this cpu. */
 	fvp_pwrc_write_ppoffr(read_mpidr_el1());
+
+#if PSCI_OS_INIT_MODE
+	return PSCI_E_SUCCESS;
+#else
+	return;
+#endif
 }
 
 /*******************************************************************************
diff --git a/plat/arm/board/fvp/fvp_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_topology.c b/plat/arm/board/fvp/fvp_topology.c
index 80cfbd5..971e35b 100644
--- a/plat/arm/board/fvp/fvp_topology.c
+++ b/plat/arm/board/fvp/fvp_topology.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -34,9 +34,9 @@
 
 	/*
 	 * fconf APIs are not supported for RESET_TO_SP_MIN, RESET_TO_BL31 and
-	 * BL2_AT_EL3 systems.
+	 * RESET_TO_BL2 systems.
 	 */
-#if RESET_TO_SP_MIN || RESET_TO_BL31 || BL2_AT_EL3
+#if RESET_TO_SP_MIN || RESET_TO_BL31 || RESET_TO_BL2
 	cluster_count = FVP_CLUSTER_COUNT;
 	cpus_per_cluster = FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU;
 #else
diff --git a/plat/arm/board/fvp/include/fconf_hw_config_getter.h b/plat/arm/board/fvp/include/fconf_hw_config_getter.h
index ca85f7a..b7a1247 100644
--- a/plat/arm/board/fvp/include/fconf_hw_config_getter.h
+++ b/plat/arm/board/fvp/include/fconf_hw_config_getter.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,12 +8,16 @@
 #define FCONF_HW_CONFIG_GETTER_H
 
 #include <lib/fconf/fconf.h>
+#include <services/rmm_core_manifest.h>
+
+#include <plat/arm/common/arm_def.h>
 
 /* Hardware Config related getter */
 #define hw_config__gicv3_config_getter(prop) gicv3_config.prop
 #define hw_config__topology_getter(prop) soc_topology.prop
 #define hw_config__uart_serial_config_getter(prop) uart_serial_config.prop
 #define hw_config__cpu_timer_getter(prop) cpu_timer.prop
+#define hw_config__dram_layout_getter(prop) dram_layout.prop
 
 struct gicv3_config_t {
 	uint64_t gicd_base;
@@ -36,13 +40,21 @@
 	uint32_t clock_freq;
 };
 
+struct ns_dram_layout {
+	uint64_t num_banks;
+	struct ns_dram_bank dram_bank[ARM_DRAM_NUM_BANKS];
+};
+
 int fconf_populate_gicv3_config(uintptr_t config);
 int fconf_populate_topology(uintptr_t config);
 int fconf_populate_uart_config(uintptr_t config);
 int fconf_populate_cpu_timer(uintptr_t config);
+int fconf_populate_dram_layout(uintptr_t config);
 
 extern struct gicv3_config_t gicv3_config;
 extern struct hw_topology_t soc_topology;
 extern struct uart_serial_config_t uart_serial_config;
 extern struct cpu_timer_t cpu_timer;
+extern struct ns_dram_layout dram_layout;
+
 #endif /* FCONF_HW_CONFIG_GETTER_H */
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index 1ef6c87..84e2e82 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -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
  */
@@ -16,6 +16,10 @@
 
 #include "../fvp_def.h"
 
+#if TRUSTED_BOARD_BOOT
+#include MBEDTLS_CONFIG_FILE
+#endif
+
 /* Required platform porting definitions */
 #define PLATFORM_CORE_COUNT  (U(FVP_CLUSTER_COUNT) * \
 			      U(FVP_MAX_CPUS_PER_CLUSTER) * \
@@ -26,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
  */
@@ -164,14 +172,23 @@
 # define MAX_XLAT_TABLES		5
 #else
 # define PLAT_ARM_MMAP_ENTRIES		12
-# define MAX_XLAT_TABLES		6
+# if (defined(SPD_tspd) || defined(SPD_opteed) || defined(SPD_spmd)) && \
+defined(IMAGE_BL2) && MEASURED_BOOT
+#  define MAX_XLAT_TABLES		7
+# else
+#  define MAX_XLAT_TABLES		6
+# endif /* (SPD_tspd || SPD_opteed || SPD_spmd) && IMAGE_BL2 && MEASURED_BOOT */
 #endif
 
 /*
  * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size
  * plus a little space for growth.
  */
+#if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA
+#define PLAT_ARM_MAX_BL1_RW_SIZE	UL(0xC000)
+#else
 #define PLAT_ARM_MAX_BL1_RW_SIZE	UL(0xB000)
+#endif
 
 /*
  * PLAT_ARM_MAX_ROMLIB_RW_SIZE is define to use a full page
@@ -191,10 +208,12 @@
  * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a
  * little space for growth.
  */
-#if TRUSTED_BOARD_BOOT && COT_DESC_IN_DTB
+#if CRYPTO_SUPPORT
+#if (TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA) || COT_DESC_IN_DTB
 # define PLAT_ARM_MAX_BL2_SIZE	(UL(0x1E000) - FVP_BL2_ROMLIB_OPTIMIZATION)
-#elif CRYPTO_SUPPORT
+#else
 # define PLAT_ARM_MAX_BL2_SIZE	(UL(0x1D000) - FVP_BL2_ROMLIB_OPTIMIZATION)
+#endif
 #elif ARM_BL31_IN_DRAM
 /* When ARM_BL31_IN_DRAM is set, BL2 can use almost all of Trusted SRAM. */
 # define PLAT_ARM_MAX_BL2_SIZE	(UL(0x1F000) - FVP_BL2_ROMLIB_OPTIMIZATION)
diff --git a/plat/arm/board/fvp/jmptbl.i b/plat/arm/board/fvp/jmptbl.i
index 85e6e3a..927ffef 100644
--- a/plat/arm/board/fvp/jmptbl.i
+++ b/plat/arm/board/fvp/jmptbl.i
@@ -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
 #
@@ -21,6 +21,7 @@
 fdt     fdt_setprop_inplace
 fdt     fdt_check_header
 fdt     fdt_node_offset_by_compatible
+fdt     fdt_node_offset_by_prop_value
 fdt     fdt_setprop_inplace_namelen_partial
 fdt     fdt_first_subnode
 fdt     fdt_next_subnode
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index efbf68f..caac8d4 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/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
 #
@@ -65,7 +65,8 @@
 				plat/common/plat_gicv3.c		\
 				plat/arm/common/arm_gicv3.c
 
-	ifeq ($(filter 1,${BL2_AT_EL3} ${RESET_TO_BL31} ${RESET_TO_SP_MIN}),)
+	ifeq ($(filter 1,${RESET_TO_BL2} \
+		${RESET_TO_BL31} ${RESET_TO_SP_MIN}),)
 		FVP_GIC_SOURCES += plat/arm/board/fvp/fvp_gicv3.c
 	endif
 
@@ -101,7 +102,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
@@ -153,7 +155,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			\
@@ -194,15 +197,21 @@
 
 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)
 BL31_SOURCES		+=	plat/arm/board/fvp/fvp_sync_traps.c
 endif
 
-ifeq (${BL2_AT_EL3},1)
+ifeq (${RESET_TO_BL2},1)
 BL2_SOURCES		+=	plat/arm/board/fvp/${ARCH}/fvp_helpers.S	\
 				plat/arm/board/fvp/fvp_bl2_el3_setup.c		\
 				${FVP_CPU_LIBS}					\
@@ -238,7 +247,7 @@
 
 # Support for fconf in BL31
 # Added separately from the above list for better readability
-ifeq ($(filter 1,${BL2_AT_EL3} ${RESET_TO_BL31}),)
+ifeq ($(filter 1,${RESET_TO_BL2} ${RESET_TO_BL31}),)
 BL31_SOURCES		+=	lib/fconf/fconf.c				\
 				lib/fconf/fconf_dyn_cfg_getter.c		\
 				plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
@@ -310,12 +319,13 @@
 endif
 
 # Enable Activity Monitor Unit extensions by default
-ENABLE_AMU			:=	1
+ENABLE_FEAT_AMU			:=	2
+ENABLE_FEAT_AMUv1p1		:=	2
 
 # 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
 
@@ -338,7 +348,7 @@
 endif
 
 # Enable the dynamic translation tables library.
-ifeq ($(filter 1,${BL2_AT_EL3} ${ARM_XLAT_TABLES_LIB_V1}),)
+ifeq ($(filter 1,${RESET_TO_BL2} ${ARM_XLAT_TABLES_LIB_V1}),)
     ifeq (${ARCH},aarch32)
         BL32_CPPFLAGS	+=	-DPLAT_XLAT_TABLES_DYNAMIC
     else # AArch64
@@ -364,10 +374,14 @@
 # Add support for platform supplied linker script for BL31 build
 $(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
 
-ifneq (${BL2_AT_EL3}, 0)
+ifneq (${RESET_TO_BL2}, 0)
     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.
@@ -396,17 +410,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
@@ -416,8 +419,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,27 +448,50 @@
 endif
 
 # enable trace buffer control registers access to NS by default
-ENABLE_TRBE_FOR_NS		:= 1
+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		:= 1
+	ENABLE_BRBE_FOR_NS		:= 2
 endif
 endif
 
 # enable trace system registers access to NS by default
-ENABLE_SYS_REG_TRACE_FOR_NS	:= 1
+ENABLE_SYS_REG_TRACE_FOR_NS	:= 2
 
 # enable trace filter control registers access to NS by default
-ENABLE_TRF_FOR_NS		:= 1
+ENABLE_TRF_FOR_NS		:= 2
 
 # Linux relies on EL3 enablement if those features are present
 ENABLE_FEAT_FGT			:= 2
 ENABLE_FEAT_HCX			:= 2
+ENABLE_FEAT_TCR2		:= 2
+
+CTX_INCLUDE_NEVE_REGS		:= 2
+ENABLE_FEAT_CSV2_2		:= 2
+ENABLE_FEAT_ECV			:= 2
+ENABLE_FEAT_PAN			:= 2
+ENABLE_FEAT_SEL2		:= 2
+ENABLE_FEAT_TWED		:= 2
+ENABLE_FEAT_VHE			:= 2
+ENABLE_MPAM_FOR_LOWER_ELS	:= 2
+
+# Enable SME access to NS by default
+ifeq (${ARCH},aarch64)
+ifeq (${SPM_MM}, 0)
+ifeq (${ENABLE_RME}, 0)
+ifeq (${CTX_INCLUDE_FPREGS}, 0)
+	ENABLE_SME_FOR_NS		:= 2
+endif
+endif
+endif
+endif
 
 ifeq (${SPMC_AT_EL3}, 1)
 PLAT_BL_COMMON_SOURCES	+=	plat/arm/board/fvp/fvp_el3_spmc.c
 endif
+
+PSCI_OS_INIT_MODE	:=	1
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 9ab36a6..b961da9 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
@@ -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
  */
@@ -22,7 +22,7 @@
 	/* Initialize the console to provide early debug support */
 	arm_console_boot_init();
 
-#if !RESET_TO_SP_MIN && !BL2_AT_EL3
+#if !RESET_TO_SP_MIN && !RESET_TO_BL2
 
 	INFO("SP_MIN FCONF: FW_CONFIG address = %lx\n", (uintptr_t)arg1);
 	/* Fill the properties struct with the info from the config dtb */
@@ -32,7 +32,7 @@
 	if (tos_fw_config_info != NULL) {
 		arg1 = tos_fw_config_info->config_addr;
 	}
-#endif /* !RESET_TO_SP_MIN && !BL2_AT_EL3 */
+#endif /* !RESET_TO_SP_MIN && !RESET_TO_BL2 */
 
 	arm_sp_min_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
 
@@ -68,13 +68,14 @@
 	 * For RESET_TO_SP_MIN systems, SP_MIN(BL32) is the first bootloader
 	 * to run. So there is no BL2 to load the HW_CONFIG dtb into memory
 	 * before control is passed to SP_MIN.
-	 * Also, BL2 skips loading HW_CONFIG dtb for BL2_AT_EL3 builds.
-	 * The code below relies on dynamic mapping capability, which is not
-	 * supported by xlat tables lib V1.
+	 * Also, BL2 skips loading HW_CONFIG dtb for
+	 * RESET_TO_BL2 builds.
+	 * The code below relies on dynamic mapping capability,
+	 * which is not supported by xlat tables lib V1.
 	 * TODO: remove the ARM_XLAT_TABLES_LIB_V1 check when its support
 	 * gets deprecated.
 	 */
-#if !RESET_TO_SP_MIN && !BL2_AT_EL3 && !ARM_XLAT_TABLES_LIB_V1
+#if !RESET_TO_SP_MIN && !RESET_TO_BL2 && !ARM_XLAT_TABLES_LIB_V1
 	hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID);
 	assert(hw_config_info != NULL);
 	assert(hw_config_info->config_addr != 0UL);
@@ -117,5 +118,5 @@
 		      rc);
 		panic();
 	}
-#endif /* !RESET_TO_SP_MIN && !BL2_AT_EL3 && !ARM_XLAT_TABLES_LIB_V1 */
+#endif /*!RESET_TO_SP_MIN && !RESET_TO_BL2 && !ARM_XLAT_TABLES_LIB_V1*/
 }
diff --git a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
index 183d802..4ddba6f 100644
--- a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
+++ b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
@@ -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
 #
@@ -23,7 +23,7 @@
 
 # Support for fconf in SP_MIN(BL32)
 # Added separately from the above list for better readability
-ifeq ($(filter 1,${BL2_AT_EL3} ${RESET_TO_SP_MIN}),)
+ifeq ($(filter 1,${RESET_TO_BL2} ${RESET_TO_SP_MIN}),)
 BL32_SOURCES		+=	lib/fconf/fconf.c				\
 				lib/fconf/fconf_dyn_cfg_getter.c		\
 				plat/arm/board/fvp/fconf/fconf_hw_config_getter.c \
diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_setup.c b/plat/arm/board/fvp_r/fvp_r_bl1_setup.c
index 1ac0a9c..a642929 100644
--- a/plat/arm/board/fvp_r/fvp_r_bl1_setup.c
+++ b/plat/arm/board/fvp_r/fvp_r_bl1_setup.c
@@ -109,10 +109,10 @@
 		ARM_MAP_BL_COHERENT_RAM,
 #endif
 		/* DRAM1_region: */
-		MAP_REGION_FLAT(					\
-			PLAT_ARM_DRAM1_BASE,				\
-			PLAT_ARM_DRAM1_SIZE,				\
-			MT_MEMORY | MT_SECURE | MT_EXECUTE		\
+		MAP_REGION_FLAT(
+			PLAT_ARM_DRAM1_BASE,
+			PLAT_ARM_DRAM1_SIZE,
+			MT_MEMORY | MT_SECURE | MT_EXECUTE
 			| MT_RW | MT_NON_CACHEABLE),
 		/* NULL terminator: */
 		{0}
diff --git a/plat/arm/board/fvp_r/fvp_r_debug.S b/plat/arm/board/fvp_r/fvp_r_debug.S
index 88f0a29..cc5ffc0 100644
--- a/plat/arm/board/fvp_r/fvp_r_debug.S
+++ b/plat/arm/board/fvp_r/fvp_r_debug.S
@@ -11,7 +11,7 @@
 	.globl el2_panic
 
 	/***********************************************************
-	 * The common implementation of do_panic for all BL stages
+	 * The common implementation of el3_panic for all BL stages
 	 ***********************************************************/
 
 .section .rodata.panic_str, "aS"
diff --git a/plat/arm/board/fvp_r/platform.mk b/plat/arm/board/fvp_r/platform.mk
index 93b5cf2..5dd28b9 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
diff --git a/plat/arm/board/juno/juno_common.c b/plat/arm/board/juno/juno_common.c
index 038f604..451c7df 100644
--- a/plat/arm/board/juno/juno_common.c
+++ b/plat/arm/board/juno/juno_common.c
@@ -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
  */
@@ -50,7 +50,7 @@
 	ARM_MAP_OPTEE_CORE_MEM,
 	ARM_OPTEE_PAGEABLE_LOAD_MEM,
 #endif
-#if TRUSTED_BOARD_BOOT && !BL2_AT_EL3
+#if TRUSTED_BOARD_BOOT && !RESET_TO_BL2
 	ARM_MAP_BL1_RW,
 #endif
 	{0}
diff --git a/plat/arm/board/morello/fdts/morello_fw_config.dts b/plat/arm/board/morello/fdts/morello_fw_config.dts
index c47bae5..a63d7eb 100644
--- a/plat/arm/board/morello/fdts/morello_fw_config.dts
+++ b/plat/arm/board/morello/fdts/morello_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,8 +19,14 @@
 
 		nt_fw-config {
 			load-address = <0x0 0xFEF00000>;
-			max-size = <0x0100000>;
+			max-size = <0xF8000>;
 			id = <NT_FW_CONFIG_ID>;
 		};
+
+		hw-config {
+			load-address = <0x0 0xFEFF8000>;
+			max-size = <0x8000>;
+			id = <HW_CONFIG_ID>;
+		};
 	};
 };
diff --git a/plat/arm/board/morello/include/platform_def.h b/plat/arm/board/morello/include/platform_def.h
index 08e2d60..76e63aa 100644
--- a/plat/arm/board/morello/include/platform_def.h
+++ b/plat/arm/board/morello/include/platform_def.h
@@ -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
  */
@@ -191,4 +191,7 @@
 /* Number of SCMI channels on the platform */
 #define PLAT_ARM_SCMI_CHANNEL_COUNT		U(1)
 
+/* Platform ID address */
+#define SSC_VERSION				(SSC_REG_BASE + SSC_VERSION_OFFSET)
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/morello/morello_bl2_setup.c b/plat/arm/board/morello/morello_bl2_setup.c
index da1f7ae..ec87a8e 100644
--- a/plat/arm/board/morello/morello_bl2_setup.c
+++ b/plat/arm/board/morello/morello_bl2_setup.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
  */
@@ -33,6 +33,7 @@
  *	- remote_chip_count
  *	- multichip mode
  *	- scc configuration
+ *	- silicon revision
  */
 struct morello_plat_info {
 	uint64_t local_ddr_size;
@@ -40,6 +41,7 @@
 	uint8_t remote_chip_count;
 	bool multichip_mode;
 	uint32_t scc_config;
+	uint32_t silicon_revision;
 } __packed;
 #endif
 
diff --git a/plat/arm/board/morello/morello_bl31_setup.c b/plat/arm/board/morello/morello_bl31_setup.c
index e04587d..8f01592 100644
--- a/plat/arm/board/morello/morello_bl31_setup.c
+++ b/plat/arm/board/morello/morello_bl31_setup.c
@@ -1,16 +1,57 @@
 /*
- * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <drivers/arm/css/css_mhu_doorbell.h>
 #include <drivers/arm/css/scmi.h>
+#include <drivers/arm/css/sds.h>
+#include <lib/smccc.h>
 #include <plat/arm/common/plat_arm.h>
+#include <services/arm_arch_svc.h>
 
 #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;
+
+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,
@@ -31,5 +72,63 @@
 
 void bl31_platform_setup(void)
 {
+#ifdef TARGET_PLATFORM_SOC
+	int ret;
+
+	ret = sds_init();
+	if (ret != SDS_OK) {
+		ERROR("SDS initialization failed. ret:%d\n", ret);
+		panic();
+	}
+
+	ret = sds_struct_read(MORELLO_SDS_PLATFORM_INFO_STRUCT_ID,
+				MORELLO_SDS_PLATFORM_INFO_OFFSET,
+				&plat_info,
+				MORELLO_SDS_PLATFORM_INFO_SIZE,
+				SDS_ACCESS_MODE_NON_CACHED);
+	if (ret != SDS_OK) {
+		ERROR("Error getting platform info from SDS. ret:%d\n", ret);
+		panic();
+	}
+#endif
 	arm_bl31_platform_setup();
 }
+
+#ifdef TARGET_PLATFORM_SOC
+/*****************************************************************************
+ * 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 and
+ * 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;
+	}
+}
+
+/* Get SOC version */
+int32_t plat_get_soc_version(void)
+{
+	int ssc_version;
+
+	ssc_version = mmio_read_32(SSC_VERSION);
+
+	return (int32_t)
+		(SOC_ID_SET_JEP_106(ARM_SOC_CONTINUATION_CODE,
+					ARM_SOC_IDENTIFICATION_CODE) |
+		(GET_SSC_VERSION_PART_NUM(ssc_version) & SOC_ID_IMPL_DEF_MASK));
+}
+
+/* Get SOC revision */
+int32_t plat_get_soc_revision(void)
+{
+	return (int32_t)plat_info.silicon_revision;
+}
+#endif
diff --git a/plat/arm/board/morello/morello_def.h b/plat/arm/board/morello/morello_def.h
index f154924..2898774 100644
--- a/plat/arm/board/morello/morello_def.h
+++ b/plat/arm/board/morello/morello_def.h
@@ -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
  */
@@ -21,7 +21,7 @@
 #ifdef TARGET_PLATFORM_FVP
 # define MORELLO_SDS_PLATFORM_INFO_SIZE		U(8)
 #else
-# define MORELLO_SDS_PLATFORM_INFO_SIZE		U(22)
+# define MORELLO_SDS_PLATFORM_INFO_SIZE		U(26)
 #endif
 #define MORELLO_MAX_DDR_CAPACITY		U(0x1000000000)
 #define MORELLO_MAX_REMOTE_CHIP_COUNT		U(16)
diff --git a/plat/arm/board/morello/morello_image_load.c b/plat/arm/board/morello/morello_image_load.c
index 52d46f3..5fc87a0 100644
--- a/plat/arm/board/morello/morello_image_load.c
+++ b/plat/arm/board/morello/morello_image_load.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -34,6 +34,7 @@
  *	- remote_chip_count
  *	- multichip mode
  *	- scc configuration
+ *	- silicon revision
  */
 struct morello_plat_info {
 	uint64_t local_ddr_size;
@@ -41,6 +42,7 @@
 	uint8_t remote_chip_count;
 	bool multichip_mode;
 	uint32_t scc_config;
+	uint32_t silicon_revision;
 } __packed;
 #endif
 
diff --git a/plat/arm/board/morello/morello_plat.c b/plat/arm/board/morello/morello_plat.c
index 1da0ff9..2ca3d08 100644
--- a/plat/arm/board/morello/morello_plat.c
+++ b/plat/arm/board/morello/morello_plat.c
@@ -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
  */
@@ -42,7 +42,7 @@
 	MORELLO_MAP_NS_SRAM,
 	ARM_MAP_DRAM1,
 	ARM_MAP_DRAM2,
-#if TRUSTED_BOARD_BOOT && !BL2_AT_EL3
+#if TRUSTED_BOARD_BOOT && !RESET_TO_BL2
 	ARM_MAP_BL1_RW,
 #endif
 	{0}
diff --git a/plat/arm/board/morello/platform.mk b/plat/arm/board/morello/platform.mk
index 156b7ea..0f0cabb 100644
--- a/plat/arm/board/morello/platform.mk
+++ b/plat/arm/board/morello/platform.mk
@@ -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,11 +59,14 @@
 				${MORELLO_BASE}/fdts/morello_nt_fw_config.dts
 
 FW_CONFIG		:=	${BUILD_PLAT}/fdts/morello_fw_config.dtb
+HW_CONFIG		:=	${BUILD_PLAT}/fdts/morello-${TARGET_PLATFORM}.dtb
 TB_FW_CONFIG		:=	${BUILD_PLAT}/fdts/morello_tb_fw_config.dtb
 NT_FW_CONFIG		:=	${BUILD_PLAT}/fdts/morello_nt_fw_config.dtb
 
 # Add the FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
+# Add the HW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${HW_CONFIG},--hw-config,${HW_CONFIG}))
 # Add the TB_FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
 # Add the NT_FW_CONFIG to FIP and specify the same to certtool
diff --git a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
index ad6c1f8..4941a4b 100644
--- a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
+++ b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
@@ -51,8 +51,8 @@
 		PLAT_ARM_GICD_BASE >> 16
 	},
 	.spi_ids = {
-		{32, 479},
-		{512, 959}
+		{PLAT_ARM_GICD_BASE, 32, 479},
+		{PLAT_ARM_GICD_BASE, 512, 959}
 	}
 };
 
diff --git a/plat/arm/board/n1sdp/n1sdp_plat.c b/plat/arm/board/n1sdp/n1sdp_plat.c
index 502268c..747ff06 100644
--- a/plat/arm/board/n1sdp/n1sdp_plat.c
+++ b/plat/arm/board/n1sdp/n1sdp_plat.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
  */
@@ -33,7 +33,7 @@
 	N1SDP_MAP_NS_SRAM,
 	ARM_MAP_DRAM1,
 	ARM_MAP_DRAM2,
-#if TRUSTED_BOARD_BOOT && !BL2_AT_EL3
+#if TRUSTED_BOARD_BOOT && !RESET_TO_BL2
 	ARM_MAP_BL1_RW,
 #endif
 	{0}
diff --git a/plat/arm/board/rde1edge/rde1edge_topology.c b/plat/arm/board/rde1edge/rde1edge_topology.c
index a16283e..91cc37e 100644
--- a/plat/arm/board/rde1edge/rde1edge_topology.c
+++ b/plat/arm/board/rde1edge/rde1edge_topology.c
@@ -31,6 +31,6 @@
  * to the SCMI power domain ID implemented by SCP.
  ******************************************************************************/
 const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = {
-	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,		\
+	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
 	16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
 };
diff --git a/plat/arm/board/rdn1edge/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/platform.mk b/plat/arm/board/rdn2/platform.mk
index b30e3fc..ca55036 100644
--- a/plat/arm/board/rdn2/platform.mk
+++ b/plat/arm/board/rdn2/platform.mk
@@ -87,4 +87,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..a5564ce 100644
--- a/plat/arm/board/rdn2/rdn2_plat.c
+++ b/plat/arm/board/rdn2/rdn2_plat.c
@@ -47,15 +47,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
 	}
 };
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/include/platform_def.h b/plat/arm/board/tc/include/platform_def.h
index a3b7839..eea1be6 100644
--- a/plat/arm/board/tc/include/platform_def.h
+++ b/plat/arm/board/tc/include/platform_def.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
  */
@@ -200,11 +200,7 @@
 
 #define PLAT_ARM_NSTIMER_FRAME_ID	0
 
-#if (TARGET_PLATFORM >= 2)
-#define PLAT_ARM_TRUSTED_ROM_BASE	0x1000
-#else
 #define PLAT_ARM_TRUSTED_ROM_BASE	0x0
-#endif
 
 /* PLAT_ARM_TRUSTED_ROM_SIZE 512KB minus ROM base. */
 #define PLAT_ARM_TRUSTED_ROM_SIZE	(0x00080000 - PLAT_ARM_TRUSTED_ROM_BASE)
@@ -308,4 +304,17 @@
 /* virtual address used by dynamic mem_protect for chunk_base */
 #define PLAT_ARM_MEM_PROTEC_VA_FRAME	UL(0xc0000000)
 
+#if ARM_GPT_SUPPORT
+/*
+ * This overrides the default PLAT_ARM_FIP_OFFSET_IN_GPT in board_css_def.h.
+ * Offset of the FIP in the GPT image. BL1 component uses this option
+ * as it does not load the partition table to get the FIP base
+ * address. At sector 48 for TC to align with ATU page size boundaries (8KiB)
+ * (i.e. after reserved sectors 0-47).
+ * Offset = 48 * 512 = 0x6000
+ */
+#undef PLAT_ARM_FIP_OFFSET_IN_GPT
+#define PLAT_ARM_FIP_OFFSET_IN_GPT		0x6000
+#endif /* ARM_GPT_SUPPORT */
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/tc/include/tc_plat.h b/plat/arm/board/tc/include/tc_plat.h
index f7ce2fe..ba1831f 100644
--- a/plat/arm/board/tc/include/tc_plat.h
+++ b/plat/arm/board/tc/include/tc_plat.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,6 +11,7 @@
 
 #ifdef PLATFORM_TEST
 void run_platform_tests(void);
+void 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
new file mode 100644
index 0000000..76c9915
--- /dev/null
+++ b/plat/arm/board/tc/nv_counter_test.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2023, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include <drivers/arm/rss_comms.h>
+#include <plat/common/platform.h>
+#include "rss_platform_api.h"
+
+#include <platform_def.h>
+
+void nv_counter_test(void)
+{
+	psa_status_t status;
+	uint32_t old_val;
+	uint32_t new_val;
+	uint32_t id;
+
+	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);
+	}
+
+	for (id = 0; id < 3; id++) {
+		status = rss_platform_nv_counter_read(id, sizeof(old_val), (uint8_t *)&old_val);
+		if (status != PSA_SUCCESS) {
+			printf("Failed during first id=(%d) rss_platform_nv_counter_read\n",
+				       id);
+			plat_error_handler(-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);
+		}
+
+		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);
+		}
+
+		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);
+		}
+	}
+	printf("Passed nv_counter_test\n");
+}
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index 2182477..c6a82de 100644
--- a/plat/arm/board/tc/platform.mk
+++ b/plat/arm/board/tc/platform.mk
@@ -1,4 +1,4 @@
-# Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+# Copyright (c) 2021-2023, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -161,9 +161,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,10 +196,30 @@
 
 endif
 
-# Add this include as first, before arm_common.mk. This is necessary because
-# arm_common.mk builds Mbed TLS, and platform_test.mk can change the list of
-# Mbed TLS files that are to be compiled (LIBMBEDTLS_SRCS).
-include plat/arm/board/tc/platform_test.mk
+ifeq (${PLATFORM_TEST},rss-nv-counters)
+    include drivers/arm/rss/rss_comms.mk
+
+    # Test code.
+    BL31_SOURCES	+=	plat/arm/board/tc/nv_counter_test.c
+
+    # Code under testing.
+    BL31_SOURCES	+=	lib/psa/rss_platform.c \
+				drivers/arm/rss/rss_comms.c \
+				${RSS_COMMS_SOURCES}
+
+    PLAT_INCLUDES	+=	-Iinclude/lib/psa
+
+    $(eval $(call add_define,PLATFORM_TEST))
+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")
+endif
+
 
 include plat/arm/common/arm_common.mk
 include plat/arm/css/common/css_common.mk
diff --git a/plat/arm/board/tc/platform_test.mk b/plat/arm/board/tc/platform_test.mk
index c2ee69e..5cdbb86 100644
--- a/plat/arm/board/tc/platform_test.mk
+++ b/plat/arm/board/tc/platform_test.mk
@@ -1,9 +1,9 @@
-# Copyright (c) 2022, Arm Limited. All rights reserved.
+# Copyright (c) 2022-2023, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-ifeq (${PLATFORM_TEST},1)
+ifeq (${PLATFORM_TEST},tfm-testsuite)
 
     # The variables need to be set to compile the platform test:
     ifeq (${TF_M_TESTS_PATH},)
diff --git a/plat/arm/board/tc/tc_bl31_setup.c b/plat/arm/board/tc/tc_bl31_setup.c
index c79558d..1c1e2fb 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-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -52,9 +52,13 @@
 void tc_bl31_common_platform_setup(void)
 {
 	arm_bl31_platform_setup();
-#ifdef PLATFORM_TEST
-	run_platform_tests();
 
+#ifdef PLATFORM_TEST
+#if PLATFORM_TEST == rss-nv-counters
+	nv_counter_test();
+#elif PLATFORM_TEST == tfm-testsuite
+	run_platform_tests()
+#endif
 	/* Suspend booting */
 	plat_error_handler(-1);
 #endif
diff --git a/plat/arm/board/tc/tc_plat.c b/plat/arm/board/tc/tc_plat.c
index 77db023..228f2fa 100644
--- a/plat/arm/board/tc/tc_plat.c
+++ b/plat/arm/board/tc/tc_plat.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -48,7 +48,7 @@
 #if SPM_MM
 	ARM_SP_IMAGE_MMAP,
 #endif
-#if TRUSTED_BOARD_BOOT && !BL2_AT_EL3
+#if TRUSTED_BOARD_BOOT && !RESET_TO_BL2
 	ARM_MAP_BL1_RW,
 #endif
 #ifdef SPD_opteed
diff --git a/plat/arm/common/aarch64/arm_helpers.S b/plat/arm/common/aarch64/arm_helpers.S
index b470781..ed85ea1 100644
--- a/plat/arm/common/aarch64/arm_helpers.S
+++ b/plat/arm/common/aarch64/arm_helpers.S
@@ -129,7 +129,7 @@
 	 * Single cpu stack in coherent memory.
 	 * ----------------------------------------------------
 	 */
-declare_stack platform_coherent_stacks, tzfw_coherent_mem, \
+declare_stack platform_coherent_stacks, .tzfw_coherent_mem, \
 		PLATFORM_STACK_SIZE, 1, CACHE_WRITEBACK_GRANULE
 
 #endif	/* defined(IMAGE_BL1) || defined(IMAGE_BL2) */
diff --git a/plat/arm/common/aarch64/arm_sdei.c b/plat/arm/common/aarch64/arm_sdei.c
index 3c74a46..2e76118 100644
--- a/plat/arm/common/aarch64/arm_sdei.c
+++ b/plat/arm/common/aarch64/arm_sdei.c
@@ -38,7 +38,7 @@
 	}
 
 	for (i = 0; i < FCONF_GET_PROPERTY(sdei, dyn_config, shared_ev_cnt); i++) {
-		arm_sdei_shared[i] = (sdei_ev_map_t)SDEI_SHARED_EVENT( \
+		arm_sdei_shared[i] = (sdei_ev_map_t)SDEI_SHARED_EVENT(
 			FCONF_GET_PROPERTY(sdei, dyn_config, shared_ev_nums[i]),
 			FCONF_GET_PROPERTY(sdei, dyn_config, shared_ev_intrs[i]),
 			FCONF_GET_PROPERTY(sdei, dyn_config, shared_ev_flags[i]));
diff --git a/plat/arm/common/arm_bl2_el3_setup.c b/plat/arm/common/arm_bl2_el3_setup.c
index 97b5a88..b598c59 100644
--- a/plat/arm/common/arm_bl2_el3_setup.c
+++ b/plat/arm/common/arm_bl2_el3_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -34,7 +34,7 @@
 	/*
 	 * Allow BL2 to see the whole Trusted RAM. This is determined
 	 * statically since we cannot rely on BL1 passing this information
-	 * in the BL2_AT_EL3 case.
+	 * in the RESET_TO_BL2 case.
 	 */
 	bl2_el3_tzram_layout.total_base = ARM_BL_RAM_BASE;
 	bl2_el3_tzram_layout.total_size = ARM_BL_RAM_SIZE;
@@ -71,7 +71,9 @@
 {
 
 #if USE_COHERENT_MEM
-	/* Ensure ARM platforms dont use coherent memory in BL2_AT_EL3 */
+	/* Ensure ARM platforms dont use coherent memory
+	 * in RESET_TO_BL2
+	 */
 	assert(BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE == 0U);
 #endif
 
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index 02e419a..b142b62 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -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
  */
@@ -18,16 +18,14 @@
 #include <drivers/partition/partition.h>
 #include <lib/fconf/fconf.h>
 #include <lib/fconf/fconf_dyn_cfg_getter.h>
-#if ENABLE_RME
 #include <lib/gpt_rme/gpt_rme.h>
-#endif /* ENABLE_RME */
 #ifdef SPD_opteed
 #include <lib/optee_utils.h>
 #endif
 #include <lib/utils.h>
 #if ENABLE_RME
 #include <plat/arm/common/arm_pas_def.h>
-#endif /* ENABLE_RME */
+#endif
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
@@ -131,7 +129,6 @@
 }
 
 #if ENABLE_RME
-
 static void arm_bl2_plat_gpt_setup(void)
 {
 	/*
@@ -171,7 +168,6 @@
 		panic();
 	}
 }
-
 #endif /* ENABLE_RME */
 
 /*******************************************************************************
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index cf403b1..19efdd3 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -13,9 +13,7 @@
 #include <drivers/console.h>
 #include <lib/debugfs.h>
 #include <lib/extensions/ras.h>
-#if ENABLE_RME
 #include <lib/gpt_rme/gpt_rme.h>
-#endif
 #include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_tables_compat.h>
 #include <plat/arm/common/plat_arm.h>
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 7162ce9..de2c4f8 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_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
 #
@@ -283,7 +283,7 @@
 BL1_SOURCES		+=	${DYN_CFG_SOURCES}
 BL2_SOURCES		+=	${DYN_CFG_SOURCES}
 
-ifeq (${BL2_AT_EL3},1)
+ifeq (${RESET_TO_BL2},1)
 BL2_SOURCES		+=	plat/arm/common/arm_bl2_el3_setup.c
 endif
 
@@ -353,8 +353,7 @@
 
 # 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)
diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c
index c88621e..99e2809 100644
--- a/plat/arm/common/arm_dyn_cfg.c
+++ b/plat/arm/common/arm_dyn_cfg.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,20 +8,20 @@
 #include <string.h>
 #include <libfdt.h>
 
-#include <platform_def.h>
+#if CRYPTO_SUPPORT
+#include <mbedtls/version.h>
+#endif /* CRYPTO_SUPPORT */
 
 #include <common/debug.h>
 #include <common/desc_image_load.h>
 #include <common/tbbr/tbbr_img_def.h>
-#if CRYPTO_SUPPORT
-#include MBEDTLS_CONFIG_FILE
-#endif /* CRYPTO_SUPPORT */
 #include <lib/fconf/fconf.h>
 #include <lib/fconf/fconf_dyn_cfg_getter.h>
 #include <lib/fconf/fconf_tbbr_getter.h>
 
 #include <plat/arm/common/arm_dyn_cfg_helpers.h>
 #include <plat/arm/common/plat_arm.h>
+#include <platform_def.h>
 
 #if CRYPTO_SUPPORT
 
@@ -45,9 +45,9 @@
 	assert(heap_addr != NULL);
 	assert(heap_size != NULL);
 
-#if defined(IMAGE_BL1) || BL2_AT_EL3 || defined(IMAGE_BL31)
+#if defined(IMAGE_BL1) || RESET_TO_BL2 || defined(IMAGE_BL31)
 
-	/* If in BL1 or BL2_AT_EL3 define a heap */
+	/* If in BL1 or RESET_TO_BL2 define a heap */
 	static unsigned char heap[TF_MBEDTLS_HEAP_SIZE];
 
 	*heap_addr = heap;
diff --git a/plat/arm/common/arm_gicv3.c b/plat/arm/common/arm_gicv3.c
index 469e22a..1c95afb 100644
--- a/plat/arm/common/arm_gicv3.c
+++ b/plat/arm/common/arm_gicv3.c
@@ -48,8 +48,8 @@
  * data in the designated EL3 Secure carve-out memory. The `used` attribute
  * is used to prevent the compiler from removing the gicv3 contexts.
  */
-static gicv3_redist_ctx_t rdist_ctx __section("arm_el3_tzc_dram") __used;
-static gicv3_dist_ctx_t dist_ctx __section("arm_el3_tzc_dram") __used;
+static gicv3_redist_ctx_t rdist_ctx __section(".arm_el3_tzc_dram") __used;
+static gicv3_dist_ctx_t dist_ctx __section(".arm_el3_tzc_dram") __used;
 
 /* Define accessor function to get reference to the GICv3 context */
 DEFINE_LOAD_SYM_ADDR(rdist_ctx)
diff --git a/plat/arm/common/arm_pm.c b/plat/arm/common/arm_pm.c
index 5434c94..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;
 }
@@ -191,7 +199,7 @@
 	 * ARM_SHARED_RAM region.
 	 */
 	assert((PLAT_ARM_TRUSTED_MAILBOX_BASE >= ARM_SHARED_RAM_BASE) &&
-		((PLAT_ARM_TRUSTED_MAILBOX_BASE + sizeof(*mailbox)) <= \
+		((PLAT_ARM_TRUSTED_MAILBOX_BASE + sizeof(*mailbox)) <=
 				(ARM_SHARED_RAM_BASE + ARM_SHARED_RAM_SIZE)));
 }
 
diff --git a/plat/arm/common/fconf/fconf_ethosn_getter.c b/plat/arm/common/fconf/fconf_ethosn_getter.c
index 0b48a98..251471e 100644
--- a/plat/arm/common/fconf/fconf_ethosn_getter.c
+++ b/plat/arm/common/fconf/fconf_ethosn_getter.c
@@ -20,21 +20,6 @@
 	uint32_t stream_id;
 };
 
-static bool fdt_node_is_enabled(const void *fdt, int node)
-{
-	int len;
-	const char *node_status;
-
-	node_status = fdt_getprop(fdt, node, "status", &len);
-	if (node_status == NULL ||
-	    (len == 5 && /* Includes null character */
-	     strncmp(node_status, "okay", 4U) == 0)) {
-		return true;
-	}
-
-	return false;
-}
-
 static bool fdt_node_has_reserved_memory(const void *fdt, int dev_node)
 {
 	return fdt_get_property(fdt, dev_node, "memory-region", NULL) != NULL;
diff --git a/plat/arm/common/trp/arm_trp_setup.c b/plat/arm/common/trp/arm_trp_setup.c
index aeacd10..0406321 100644
--- a/plat/arm/common/trp/arm_trp_setup.c
+++ b/plat/arm/common/trp/arm_trp_setup.c
@@ -26,7 +26,7 @@
  ******************************************************************************/
 static console_t arm_trp_runtime_console;
 
-static int arm_trp_process_manifest(rmm_manifest_t *manifest)
+static int arm_trp_process_manifest(struct rmm_manifest *manifest)
 {
 	/* padding field on the manifest must be RES0 */
 	assert(manifest->padding == 0U);
@@ -38,12 +38,12 @@
 	}
 
 	trp_boot_manifest_version = manifest->version;
-	flush_dcache_range((uintptr_t)manifest, sizeof(rmm_manifest_t));
+	flush_dcache_range((uintptr_t)manifest, sizeof(struct rmm_manifest));
 
 	return 0;
 }
 
-void arm_trp_early_platform_setup(rmm_manifest_t *manifest)
+void arm_trp_early_platform_setup(struct rmm_manifest *manifest)
 {
 	int rc;
 
@@ -66,10 +66,9 @@
 
 	console_set_scope(&arm_trp_runtime_console,
 			  CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME);
-
 }
 
-void trp_early_platform_setup(rmm_manifest_t *manifest)
+void trp_early_platform_setup(struct rmm_manifest *manifest)
 {
 	arm_trp_early_platform_setup(manifest);
 }
diff --git a/plat/arm/css/sgi/sgi_plat.c b/plat/arm/css/sgi/sgi_plat.c
index a0199c3..b8ba49f 100644
--- a/plat/arm/css/sgi/sgi_plat.c
+++ b/plat/arm/css/sgi/sgi_plat.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -64,7 +64,7 @@
 #if SPM_MM
 	ARM_SP_IMAGE_MMAP,
 #endif
-#if TRUSTED_BOARD_BOOT && !BL2_AT_EL3
+#if TRUSTED_BOARD_BOOT && !RESET_TO_BL2
 	ARM_MAP_BL1_RW,
 #endif
 	{0}
diff --git a/plat/arm/css/sgi/sgi_plat_v2.c b/plat/arm/css/sgi/sgi_plat_v2.c
index cef5345..8d38108 100644
--- a/plat/arm/css/sgi/sgi_plat_v2.c
+++ b/plat/arm/css/sgi/sgi_plat_v2.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
  */
@@ -57,7 +57,7 @@
 #if SPM_MM
 	ARM_SP_IMAGE_MMAP,
 #endif
-#if TRUSTED_BOARD_BOOT && !BL2_AT_EL3
+#if TRUSTED_BOARD_BOOT && !RESET_TO_BL2
 	ARM_MAP_BL1_RW,
 #endif
 	{0}
diff --git a/plat/common/aarch32/platform_mp_stack.S b/plat/common/aarch32/platform_mp_stack.S
index 6c3d08d..314e87a 100644
--- a/plat/common/aarch32/platform_mp_stack.S
+++ b/plat/common/aarch32/platform_mp_stack.S
@@ -43,5 +43,5 @@
 	 * stack of PLATFORM_STACK_SIZE bytes.
 	 * -----------------------------------------------------
 	 */
-declare_stack platform_normal_stacks, tzfw_normal_stacks, \
+declare_stack platform_normal_stacks, .tzfw_normal_stacks, \
 		PLATFORM_STACK_SIZE, PLATFORM_CORE_COUNT
diff --git a/plat/common/aarch32/platform_up_stack.S b/plat/common/aarch32/platform_up_stack.S
index 836c13a..69e112f 100644
--- a/plat/common/aarch32/platform_up_stack.S
+++ b/plat/common/aarch32/platform_up_stack.S
@@ -43,5 +43,5 @@
 	 * stack of PLATFORM_STACK_SIZE bytes.
 	 * -----------------------------------------------------
 	 */
-declare_stack platform_normal_stacks, tzfw_normal_stacks, \
+declare_stack platform_normal_stacks, .tzfw_normal_stacks, \
 		PLATFORM_STACK_SIZE, 1, CACHE_WRITEBACK_GRANULE
diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c
index 8ce1d6c..042916a 100644
--- a/plat/common/aarch64/plat_common.c
+++ b/plat/common/aarch64/plat_common.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
  */
@@ -77,7 +77,7 @@
 	return "EL1";
 }
 
-/* RAS functions common to AArch64 ARM platforms */
+/* Handler for External Aborts from lower EL including RAS errors */
 void plat_default_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
 		void *handle, uint64_t flags)
 {
@@ -93,12 +93,9 @@
 	ERROR("Unhandled External Abort received on 0x%lx from %s\n",
 		read_mpidr_el1(), get_el_str(level));
 	ERROR("exception reason=%u syndrome=0x%" PRIx64 "\n", ea_reason, syndrome);
-#if HANDLE_EA_EL3_FIRST_NS
-	/* Skip backtrace for lower EL */
-	if (level != MODE_EL3) {
-		console_flush();
-		do_panic();
-	}
-#endif
-	panic();
+
+	/* We reached here due to a panic from a lower EL and assuming this is the default
+	 * platform registered handler that we could call on a lower EL panic.
+	 */
+	lower_el_panic();
 }
diff --git a/plat/common/aarch64/platform_mp_stack.S b/plat/common/aarch64/platform_mp_stack.S
index c0668ea..fa1ca22 100644
--- a/plat/common/aarch64/platform_mp_stack.S
+++ b/plat/common/aarch64/platform_mp_stack.S
@@ -56,6 +56,6 @@
 	 * stack of PLATFORM_STACK_SIZE bytes.
 	 * -----------------------------------------------------
 	 */
-declare_stack platform_normal_stacks, tzfw_normal_stacks, \
+declare_stack platform_normal_stacks, .tzfw_normal_stacks, \
 		PLATFORM_STACK_SIZE, PLATFORM_CORE_COUNT, \
 		CACHE_WRITEBACK_GRANULE
diff --git a/plat/common/aarch64/platform_up_stack.S b/plat/common/aarch64/platform_up_stack.S
index c6e5e2d..2c87219 100644
--- a/plat/common/aarch64/platform_up_stack.S
+++ b/plat/common/aarch64/platform_up_stack.S
@@ -46,5 +46,5 @@
 	 * are allocated
 	 * -----------------------------------------------------
 	 */
-declare_stack platform_normal_stacks, tzfw_normal_stacks, \
+declare_stack platform_normal_stacks, .tzfw_normal_stacks, \
 		PLATFORM_STACK_SIZE, 1, CACHE_WRITEBACK_GRANULE
diff --git a/plat/common/plat_spmd_manifest.c b/plat/common/plat_spmd_manifest.c
index b1fc13c..5f7d142 100644
--- a/plat/common/plat_spmd_manifest.c
+++ b/plat/common/plat_spmd_manifest.c
@@ -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
  */
@@ -150,7 +150,7 @@
 	rc = mmap_add_dynamic_region((unsigned long long)pm_base_align,
 				     pm_base_align,
 				     PAGE_SIZE,
-				     MT_RO_DATA);
+				     MT_RO_DATA | EL3_PAS);
 	if (rc != 0) {
 		ERROR("Error while mapping SPM Core manifest (%d).\n", rc);
 		return rc;
diff --git a/plat/hisilicon/hikey/platform.mk b/plat/hisilicon/hikey/platform.mk
index 2bfc582..807a915 100644
--- a/plat/hisilicon/hikey/platform.mk
+++ b/plat/hisilicon/hikey/platform.mk
@@ -1,11 +1,11 @@
 #
-# 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
 #
 
 # Non-TF Boot ROM
-BL2_AT_EL3	:=	1
+RESET_TO_BL2	:=	1
 
 # On Hikey, the TSP can execute from TZC secure area in DRAM (default)
 # or SRAM.
diff --git a/plat/hisilicon/hikey960/hikey960_bl31_setup.c b/plat/hisilicon/hikey960/hikey960_bl31_setup.c
index 0debe1e..50751ee 100644
--- a/plat/hisilicon/hikey960/hikey960_bl31_setup.c
+++ b/plat/hisilicon/hikey960/hikey960_bl31_setup.c
@@ -183,7 +183,7 @@
 
 #define SPMC_SHARED_MEMORY_OBJ_SIZE (512 * 1024)
 
-__section("ram2_region") uint8_t plat_spmc_shmem_datastore[SPMC_SHARED_MEMORY_OBJ_SIZE];
+__section(".ram2_region") uint8_t plat_spmc_shmem_datastore[SPMC_SHARED_MEMORY_OBJ_SIZE];
 
 int plat_spmc_shmem_datastore_get(uint8_t **datastore, size_t *size)
 {
diff --git a/plat/hisilicon/hikey960/include/plat.ld.S b/plat/hisilicon/hikey960/include/plat.ld.S
index 0cc25cd..f8bd376 100644
--- a/plat/hisilicon/hikey960/include/plat.ld.S
+++ b/plat/hisilicon/hikey960/include/plat.ld.S
@@ -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
  */
@@ -14,8 +14,8 @@
 
 SECTIONS
 {
-	ram2_region (NOLOAD) : {
-	*(ram2_region)
+	.ram2_region (NOLOAD) : {
+	*(.ram2_region)
 	}>RAM2
 }
 
diff --git a/plat/hisilicon/hikey960/platform.mk b/plat/hisilicon/hikey960/platform.mk
index 4c3c817..fd11a4d 100644
--- a/plat/hisilicon/hikey960/platform.mk
+++ b/plat/hisilicon/hikey960/platform.mk
@@ -1,11 +1,11 @@
 #
-# 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
 #
 
 # Non-TF Boot ROM
-BL2_AT_EL3	:=	1
+RESET_TO_BL2	:=	1
 
 # On Hikey960, the TSP can execute from TZC secure area in DRAM.
 HIKEY960_TSP_RAM_LOCATION	?=	dram
diff --git a/plat/imx/common/imx_sip_svc.c b/plat/imx/common/imx_sip_svc.c
index 11d02f3..6d6633c 100644
--- a/plat/imx/common/imx_sip_svc.c
+++ b/plat/imx/common/imx_sip_svc.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
  */
@@ -33,6 +33,11 @@
 	case IMX_SIP_GET_SOC_INFO:
 		SMC_RET1(handle, imx_soc_info_handler(smc_fid, x1, x2, x3));
 		break;
+	case IMX_SIP_GPC:
+		SMC_RET1(handle, imx_gpc_handler(smc_fid, x1, x2, x3));
+		break;
+	case IMX_SIP_DDR_DVFS:
+		return dram_dvfs_handler(smc_fid, handle, x1, x2, x3);
 #endif
 #if defined(PLAT_imx8mm) || defined(PLAT_imx8mn) || defined(PLAT_imx8mp)
 	case IMX_SIP_DDR_DVFS:
diff --git a/plat/imx/common/imx_uart_console.S b/plat/imx/common/imx_uart_console.S
index ceeb3a7..4d17288 100644
--- a/plat/imx/common/imx_uart_console.S
+++ b/plat/imx/common/imx_uart_console.S
@@ -12,6 +12,7 @@
 
 #define URXD  0x0  /* Receiver Register */
 #define UTXD  0x40 /* Transmitter Register */
+#define USR2  0x98 /* UART Status Register 2 */
 #define UTS   0xb4 /* UART Test Register (mx31) */
 #define  URXD_RX_DATA    (0xFF)
 
@@ -53,13 +54,13 @@
 1:
 	/* Check if the transmit FIFO is full */
 	ldr	w2, [x1, #UTS]
-	tbz	w2, #6, 1b
+	tbnz	w2, #4, 1b
 	mov	w2, #0xD
 	str	w2, [x1, #UTXD]
 2:
 	/* Check if the transmit FIFO is full */
 	ldr	w2, [x1, #UTS]
-	tbz	w2, #6, 2b
+	tbnz	w2, #4, 2b
 	str	w0, [x1, #UTXD]
 	ret
 putc_error:
@@ -84,5 +85,13 @@
 endfunc console_imx_uart_getc
 
 func console_imx_uart_flush
+	ldr	x0, [x0, #CONSOLE_T_BASE]
+	cbz	x0, flush_exit
+1:
+	/* Wait for the transmit complete bit */
+	ldr	w1, [x0, #USR2]
+	tbz	w1, #3, 1b
+
+flush_exit:
 	ret
 endfunc console_imx_uart_flush
diff --git a/plat/imx/common/include/imx_sip_svc.h b/plat/imx/common/include/imx_sip_svc.h
index 1f45985..0e91c71 100644
--- a/plat/imx/common/include/imx_sip_svc.h
+++ b/plat/imx/common/include/imx_sip_svc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-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
  */
@@ -55,6 +55,10 @@
 #if defined(PLAT_imx8mq)
 int imx_soc_info_handler(uint32_t smc_fid, u_register_t x1,
 			 u_register_t x2, u_register_t x3);
+int imx_gpc_handler(uint32_t smc_fid, u_register_t x1,
+		    u_register_t x2, u_register_t x3);
+int dram_dvfs_handler(uint32_t smc_fid, void *handle,
+	u_register_t x1, u_register_t x2, u_register_t x3);
 #endif
 #if defined(PLAT_imx8mm) || defined(PLAT_imx8mn) || defined(PLAT_imx8mp)
 int dram_dvfs_handler(uint32_t smc_fid, void *handle,
diff --git a/plat/imx/common/sci/svc/pm/pm_rpc_clnt.c b/plat/imx/common/sci/svc/pm/pm_rpc_clnt.c
index 66a57a1..228cff8 100644
--- a/plat/imx/common/sci/svc/pm/pm_rpc_clnt.c
+++ b/plat/imx/common/sci/svc/pm/pm_rpc_clnt.c
@@ -412,8 +412,6 @@
 	RPC_SIZE(&msg) = 2U;
 
 	sc_call_rpc(ipc, &msg, SC_TRUE);
-
-	return;
 }
 
 sc_err_t sc_pm_reboot_partition(sc_ipc_t ipc, sc_rm_pt_t pt,
diff --git a/plat/imx/common/sci/svc/rm/rm_rpc_clnt.c b/plat/imx/common/sci/svc/rm/rm_rpc_clnt.c
index 16771a5..2cea01f 100644
--- a/plat/imx/common/sci/svc/rm/rm_rpc_clnt.c
+++ b/plat/imx/common/sci/svc/rm/rm_rpc_clnt.c
@@ -632,8 +632,6 @@
 	RPC_SIZE(&msg) = 1U;
 
 	sc_call_rpc(ipc, &msg, SC_FALSE);
-
-	return;
 }
 
 /**@}*/
diff --git a/plat/imx/imx7/picopi/platform.mk b/plat/imx/imx7/picopi/platform.mk
index 5901001..0267a8b 100644
--- a/plat/imx/imx7/picopi/platform.mk
+++ b/plat/imx/imx7/picopi/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -22,7 +22,7 @@
 RESET_TO_BL31			:= 0
 
 # Non-TF Boot ROM
-BL2_AT_EL3			:= 1
+RESET_TO_BL2		:= 1
 
 # Indicate single-core
 COLD_BOOT_SINGLE_CPU		:= 1
diff --git a/plat/imx/imx7/warp7/platform.mk b/plat/imx/imx7/warp7/platform.mk
index ea0f001..bd3d8d3 100644
--- a/plat/imx/imx7/warp7/platform.mk
+++ b/plat/imx/imx7/warp7/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -22,7 +22,7 @@
 RESET_TO_BL31			:= 0
 
 # Non-TF Boot ROM
-BL2_AT_EL3			:= 1
+RESET_TO_BL2		:= 1
 
 # Indicate single-core
 COLD_BOOT_SINGLE_CPU		:= 1
diff --git a/plat/imx/imx8m/ddr/clock.c b/plat/imx/imx8m/ddr/clock.c
index 7fb5730..8b132d2 100644
--- a/plat/imx/imx8m/ddr/clock.c
+++ b/plat/imx/imx8m/ddr/clock.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018-2022 NXP
+ * Copyright 2018-2023 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -76,7 +76,7 @@
 
 	/* unbypass the PLL */
 	mmio_clrbits_32(HW_DRAM_PLL_CFG0, 0x30);
-	while (!(mmio_read_32(HW_DRAM_PLL_CFG0) & (1 << 31))) {
+	while (!(mmio_read_32(HW_DRAM_PLL_CFG0) & BIT(31))) {
 		;
 	}
 }
@@ -88,6 +88,12 @@
 	mmio_clrbits_32(DRAM_PLL_CTRL, (1 << 9));
 
 	switch (drate) {
+	case 4000:
+		mmio_write_32(DRAM_PLL_CTRL + 0x4, (250 << 12) | (3 << 4) | 1);
+		break;
+	case 3200:
+		mmio_write_32(DRAM_PLL_CTRL + 0x4, (200 << 12) | (3 << 4) | 1);
+		break;
 	case 2400:
 		mmio_write_32(DRAM_PLL_CTRL + 0x4, (300 << 12) | (3 << 4) | 2);
 		break;
diff --git a/plat/imx/imx8m/ddr/ddr4_dvfs.c b/plat/imx/imx8m/ddr/ddr4_dvfs.c
index cdc7dc2..94bfaba 100644
--- a/plat/imx/imx8m/ddr/ddr4_dvfs.c
+++ b/plat/imx/imx8m/ddr/ddr4_dvfs.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018-2022 NXP
+ * Copyright 2018-2023 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,7 +9,8 @@
 
 #include <dram.h>
 
-void ddr4_mr_write(uint32_t mr, uint32_t data, uint32_t mr_type, uint32_t rank)
+void ddr4_mr_write(uint32_t mr, uint32_t data, uint32_t mr_type,
+	uint32_t rank, uint32_t dram_type)
 {
 	uint32_t val, mr_mirror, data_mirror;
 
@@ -17,20 +18,40 @@
 	 * 1. Poll MRSTAT.mr_wr_busy until it is 0 to make sure
 	 * that there is no outstanding MR transAction.
 	 */
-	while (mmio_read_32(DDRC_MRSTAT(0)) & 0x1) {
-		;
-	}
 
 	/*
+	 * ERR050712:
+	 * When performing a software driven MR access, the following sequence
+	 * must be done automatically before performing other APB register accesses.
+	 * 1. Set MRCTRL0.mr_wr=1
+	 * 2. Check for MRSTAT.mr_wr_busy=0. If not, go to step (2)
+	 * 3. Check for MRSTAT.mr_wr_busy=0 again (for the second time). If not, go to step (2)
+	 */
+	mmio_setbits_32(DDRC_MRCTRL0(0), BIT(31));
+
+	do {
+		while (mmio_read_32(DDRC_MRSTAT(0)) & 0x1) {
+			;
+		}
+
+	} while (mmio_read_32(DDRC_MRSTAT(0)) & 0x1);
+
+	/*
 	 * 2. Write the MRCTRL0.mr_type, MRCTRL0.mr_addr, MRCTRL0.mr_rank
 	 * and (for MRWs) MRCTRL1.mr_data to define the MR transaction.
 	 */
 	val = mmio_read_32(DDRC_DIMMCTL(0));
 	if ((val & 0x2) && (rank == 0x2)) {
 		mr_mirror = (mr & 0x4) | ((mr & 0x1) << 1) | ((mr & 0x2) >> 1); /* BA0, BA1 swap */
-		data_mirror = (data & 0x1607) | ((data & 0x8) << 1) | ((data & 0x10) >> 1) |
+		if (dram_type == DDRC_DDR4) {
+			data_mirror = (data & 0x1607) | ((data & 0x8) << 1) | ((data & 0x10) >> 1) |
 				((data & 0x20) << 1) | ((data & 0x40) >> 1) | ((data & 0x80) << 1) |
-				 ((data & 0x100) >> 1) | ((data & 0x800) << 2) | ((data & 0x2000) >> 2) ;
+				((data & 0x100) >> 1) | ((data & 0x800) << 2) | ((data & 0x2000) >> 2) ;
+		} else {
+			data_mirror = (data & 0xfe07) | ((data & 0x8) << 1) | ((data & 0x10) >> 1) |
+				 ((data & 0x20) << 1) | ((data & 0x40) >> 1) | ((data & 0x80) << 1) |
+				 ((data & 0x100) >> 1);
+		}
 	} else {
 		mr_mirror = mr;
 		data_mirror = data;
@@ -56,6 +77,7 @@
 void dram_cfg_all_mr(struct dram_info *info, uint32_t pstate)
 {
 	uint32_t num_rank = info->num_rank;
+	uint32_t dram_type = info->dram_type;
 	/*
 	 * 15. Perform MRS commands as required to re-program
 	 * timing registers in the SDRAM for the new frequency
@@ -64,9 +86,9 @@
 
 	for (int i = 1; i <= num_rank; i++) {
 		for (int j = 0; j < 6; j++) {
-			ddr4_mr_write(j, info->mr_table[pstate][j], 0, i);
+			ddr4_mr_write(j, info->mr_table[pstate][j], 0, i, dram_type);
 		}
-		ddr4_mr_write(6, info->mr_table[pstate][7], 0, i);
+		ddr4_mr_write(6, info->mr_table[pstate][7], 0, i, dram_type);
 	}
 }
 
@@ -189,8 +211,8 @@
 	 * 12. Wait until STAT.operating_mode[1:0]!=11 indicating that the
 	 * controller is not in self-refresh mode.
 	 */
-	while ((mmio_read_32(DDRC_STAT(0)) & 0x3) == 0x3) {
-		;
+	if ((mmio_read_32(DDRC_STAT(0)) & 0x3) == 0x3) {
+		VERBOSE("DRAM is in Self Refresh\n");
 	}
 
 	/*
diff --git a/plat/imx/imx8m/ddr/dram.c b/plat/imx/imx8m/ddr/dram.c
index 8ea9ba1..b5f6973 100644
--- a/plat/imx/imx8m/ddr/dram.c
+++ b/plat/imx/imx8m/ddr/dram.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-2022 NXP
+ * Copyright 2019-2023 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,6 +11,7 @@
 #include <plat/common/platform.h>
 
 #include <dram.h>
+#include <gpc.h>
 
 #define IMX_SIP_DDR_DVFS_GET_FREQ_COUNT		0x10
 #define IMX_SIP_DDR_DVFS_GET_FREQ_INFO		0x11
@@ -20,6 +21,11 @@
 /* lock used for DDR DVFS */
 spinlock_t dfs_lock;
 
+#if defined(PLAT_imx8mq)
+/* ocram used to dram timing */
+static uint8_t dram_timing_saved[13 * 1024] __aligned(8);
+#endif
+
 static volatile uint32_t wfe_done;
 static volatile bool wait_ddrc_hwffc_done = true;
 static unsigned int dev_fsp = 0x1;
@@ -30,6 +36,64 @@
 	{ DDRC_FREQ2_INIT3(0), DDRC_FREQ2_INIT4(0), DDRC_FREQ2_INIT6(0), DDRC_FREQ2_INIT7(0) },
 };
 
+#if defined(PLAT_imx8mq)
+static inline struct dram_cfg_param *get_cfg_ptr(void *ptr,
+		void *old_base, void *new_base)
+{
+	uintptr_t offset = (uintptr_t)ptr & ~((uintptr_t)old_base);
+
+	return (struct dram_cfg_param *)(offset + new_base);
+}
+
+/* copy the dram timing info from DRAM to OCRAM */
+void imx8mq_dram_timing_copy(struct dram_timing_info *from)
+{
+	struct dram_timing_info *info = (struct dram_timing_info *)dram_timing_saved;
+
+	/* copy the whole 13KB content used for dram timing info */
+	memcpy(dram_timing_saved, from, sizeof(dram_timing_saved));
+
+	/* correct the header after copied into ocram */
+	info->ddrc_cfg = get_cfg_ptr(info->ddrc_cfg, from, dram_timing_saved);
+	info->ddrphy_cfg = get_cfg_ptr(info->ddrphy_cfg, from, dram_timing_saved);
+	info->ddrphy_trained_csr = get_cfg_ptr(info->ddrphy_trained_csr, from, dram_timing_saved);
+	info->ddrphy_pie = get_cfg_ptr(info->ddrphy_pie, from, dram_timing_saved);
+}
+#endif
+
+#if defined(PLAT_imx8mp)
+static uint32_t lpddr4_mr_read(unsigned int mr_rank, unsigned int mr_addr)
+{
+	unsigned int tmp, drate_byte;
+
+	tmp = mmio_read_32(DRC_PERF_MON_MRR0_DAT(0));
+	mmio_write_32(DRC_PERF_MON_MRR0_DAT(0), tmp | 0x1);
+	do {
+		tmp = mmio_read_32(DDRC_MRSTAT(0));
+	} while (tmp & 0x1);
+
+	mmio_write_32(DDRC_MRCTRL0(0), (mr_rank << 4) | 0x1);
+	mmio_write_32(DDRC_MRCTRL1(0), (mr_addr << 8));
+	mmio_write_32(DDRC_MRCTRL0(0), (mr_rank << 4) | BIT(31) | 0x1);
+
+	/* Workaround for SNPS STAR 9001549457 */
+	do {
+		tmp = mmio_read_32(DDRC_MRSTAT(0));
+	} while (tmp & 0x1);
+
+	do {
+		tmp = mmio_read_32(DRC_PERF_MON_MRR0_DAT(0));
+	} while (!(tmp & 0x8));
+	tmp = mmio_read_32(DRC_PERF_MON_MRR1_DAT(0));
+
+	drate_byte = (mmio_read_32(DDRC_DERATEEN(0)) >> 4) & 0xff;
+	tmp = (tmp >> (drate_byte * 8)) & 0xff;
+	mmio_write_32(DRC_PERF_MON_MRR0_DAT(0), 0x4);
+
+	return tmp;
+}
+#endif
+
 static void get_mr_values(uint32_t (*mr_value)[8])
 {
 	uint32_t init_val;
@@ -41,9 +105,38 @@
 			mr_value[fsp_index][2*i] = init_val >> 16;
 			mr_value[fsp_index][2*i + 1] = init_val & 0xFFFF;
 		}
+
+#if defined(PLAT_imx8mp)
+		if (dram_info.dram_type == DDRC_LPDDR4) {
+			mr_value[fsp_index][5] = lpddr4_mr_read(1, MR12); /* read MR12 from DRAM */
+			mr_value[fsp_index][7] = lpddr4_mr_read(1, MR14); /* read MR14 from DRAM */
+		}
+#endif
 	}
 }
 
+static void save_rank_setting(void)
+{
+	uint32_t i, offset;
+	uint32_t pstate_num = dram_info.num_fsp;
+
+	/* only support maximum 3 setpoints */
+	pstate_num = (pstate_num > MAX_FSP_NUM) ? MAX_FSP_NUM : pstate_num;
+
+	for (i = 0U; i < pstate_num; i++) {
+		offset = i ? (i + 1) * 0x1000 : 0U;
+		dram_info.rank_setting[i][0] = mmio_read_32(DDRC_DRAMTMG2(0) + offset);
+		if (dram_info.dram_type != DDRC_LPDDR4) {
+			dram_info.rank_setting[i][1] = mmio_read_32(DDRC_DRAMTMG9(0) + offset);
+		}
+#if !defined(PLAT_imx8mq)
+		dram_info.rank_setting[i][2] = mmio_read_32(DDRC_RANKCTL(0) + offset);
+#endif
+	}
+#if defined(PLAT_imx8mq)
+	dram_info.rank_setting[0][2] = mmio_read_32(DDRC_RANKCTL(0));
+#endif
+}
 /* Restore the ddrc configs */
 void dram_umctl2_init(struct dram_timing_info *timing)
 {
@@ -129,13 +222,19 @@
 	ddrc_mstr = mmio_read_32(DDRC_MSTR(0));
 
 	dram_info.dram_type = ddrc_mstr & DDR_TYPE_MASK;
-	dram_info.num_rank = (ddrc_mstr >> 24) & ACTIVE_RANK_MASK;
+	dram_info.num_rank = ((ddrc_mstr >> 24) & ACTIVE_RANK_MASK) == 0x3 ?
+		DDRC_ACTIVE_TWO_RANK : DDRC_ACTIVE_ONE_RANK;
 
 	/* Get current fsp info */
-	current_fsp = mmio_read_32(DDRC_DFIMISC(0)) & 0xf;
+	current_fsp = mmio_read_32(DDRC_DFIMISC(0));
+	current_fsp = (current_fsp >> 8) & 0xf;
 	dram_info.boot_fsp = current_fsp;
 	dram_info.current_fsp = current_fsp;
 
+#if defined(PLAT_imx8mq)
+	imx8mq_dram_timing_copy((struct dram_timing_info *)dram_timing_base);
+	dram_timing_base = (unsigned long) dram_timing_saved;
+#endif
 	get_mr_values(dram_info.mr_table);
 
 	dram_info.timing_info = (struct dram_timing_info *)dram_timing_base;
@@ -147,7 +246,17 @@
 		}
 		idx = i;
 	}
-	dram_info.num_fsp = i;
+
+	/* only support maximum 3 setpoints */
+	dram_info.num_fsp = (i > MAX_FSP_NUM) ? MAX_FSP_NUM : i;
+
+	/* no valid fsp table, return directly */
+	if (i == 0U) {
+		return;
+	}
+
+	/* save the DRAMTMG2/9 for rank to rank workaround */
+	save_rank_setting();
 
 	/* check if has bypass mode support */
 	if (dram_info.timing_info->fsp_table[idx] < 666) {
@@ -162,8 +271,18 @@
 	if (rc != 0) {
 		panic();
 	}
-}
 
+	if (dram_info.dram_type == DDRC_LPDDR4 && current_fsp != 0x0) {
+		/* flush the L1/L2 cache */
+		dcsw_op_all(DCCSW);
+		lpddr4_swffc(&dram_info, dev_fsp, 0x0);
+		dev_fsp = (~dev_fsp) & 0x1;
+	} else if (current_fsp != 0x0) {
+		/* flush the L1/L2 cache */
+		dcsw_op_all(DCCSW);
+		ddr4_swffc(&dram_info, 0x0);
+	}
+}
 
 /*
  * For each freq return the following info:
@@ -222,7 +341,7 @@
 		SMC_RET1(handle, dram_info.num_fsp);
 	} else if (x1 == IMX_SIP_DDR_DVFS_GET_FREQ_INFO) {
 		return dram_dvfs_get_freq_info(handle, x2);
-	} else if (x1 < 4) {
+	} else if (x1 < 3U) {
 		wait_ddrc_hwffc_done = true;
 		dsb();
 
@@ -232,7 +351,13 @@
 				plat_ic_raise_el3_sgi(0x8, i);
 			}
 		}
-
+#if defined(PLAT_imx8mq)
+		for (unsigned int i = 0; i < PLATFORM_CORE_COUNT; i++) {
+			if (i != cpu_id && online_cores & (1 << (i * 8))) {
+				imx_gpc_core_wake(1 << i);
+			}
+		}
+#endif
 		/* make sure all the core in WFE */
 		online_cores &= ~(0x1 << (cpu_id * 8));
 		while (1) {
@@ -247,7 +372,7 @@
 		if (dram_info.dram_type == DDRC_LPDDR4) {
 			lpddr4_swffc(&dram_info, dev_fsp, fsp_index);
 			dev_fsp = (~dev_fsp) & 0x1;
-		} else if (dram_info.dram_type == DDRC_DDR4) {
+		} else {
 			ddr4_swffc(&dram_info, fsp_index);
 		}
 
diff --git a/plat/imx/imx8m/ddr/dram_retention.c b/plat/imx/imx8m/ddr/dram_retention.c
index 7d4f823..983f6e2 100644
--- a/plat/imx/imx8m/ddr/dram_retention.c
+++ b/plat/imx/imx8m/ddr/dram_retention.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018-2022 NXP
+ * Copyright 2018-2023 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,13 +18,38 @@
 #define GPC_PU_PWRHSK		(IMX_GPC_BASE + 0x01FC)
 #define CCM_SRC_CTRL_OFFSET     (IMX_CCM_BASE + 0x800)
 #define CCM_CCGR_OFFSET         (IMX_CCM_BASE + 0x4000)
+#define CCM_TARGET_ROOT_OFFSET	(IMX_CCM_BASE + 0x8000)
 #define CCM_SRC_CTRL(n)		(CCM_SRC_CTRL_OFFSET + 0x10 * (n))
 #define CCM_CCGR(n)		(CCM_CCGR_OFFSET + 0x10 * (n))
-
-#define DRAM_PLL_CTRL		(IMX_ANAMIX_BASE + 0x50)
+#define CCM_TARGET_ROOT(n)	(CCM_TARGET_ROOT_OFFSET + 0x80 * (n))
 
 #define DBGCAM_EMPTY		0x36000000
 
+static void rank_setting_update(void)
+{
+	uint32_t i, offset;
+	uint32_t pstate_num = dram_info.num_fsp;
+
+	/* only support maximum 3 setpoints */
+	pstate_num = (pstate_num > MAX_FSP_NUM) ? MAX_FSP_NUM : pstate_num;
+
+	for (i = 0U; i < pstate_num; i++) {
+		offset = i ? (i + 1) * 0x1000 : 0U;
+		mmio_write_32(DDRC_DRAMTMG2(0) + offset, dram_info.rank_setting[i][0]);
+		if (dram_info.dram_type != DDRC_LPDDR4) {
+			mmio_write_32(DDRC_DRAMTMG9(0) + offset, dram_info.rank_setting[i][1]);
+		}
+
+#if !defined(PLAT_imx8mq)
+		mmio_write_32(DDRC_RANKCTL(0) + offset,
+			dram_info.rank_setting[i][2]);
+#endif
+	}
+#if defined(PLAT_imx8mq)
+		mmio_write_32(DDRC_RANKCTL(0), dram_info.rank_setting[0][2]);
+#endif
+}
+
 void dram_enter_retention(void)
 {
 	/* Wait DBGCAM to be empty */
@@ -120,6 +145,10 @@
 	mmio_write_32(CCM_CCGR(5), 2);
 	mmio_write_32(CCM_SRC_CTRL(15), 2);
 
+	/* change the clock source of dram_apb_clk_root */
+	mmio_write_32(CCM_TARGET_ROOT(65) + 0x8, (0x7 << 24) | (0x7 << 16));
+	mmio_write_32(CCM_TARGET_ROOT(65) + 0x4, (0x4 << 24) | (0x3 << 16));
+
 	/* disable iso */
 	mmio_setbits_32(IMX_GPC_BASE + PU_PGC_UP_TRG, BIT(5));
 	mmio_write_32(SRC_DDR1_RCR, 0x8F000006);
@@ -157,6 +186,9 @@
 	/* dram phy re-init */
 	dram_phy_init(dram_info.timing_info);
 
+	/* workaround for rank-to-rank issue */
+	rank_setting_update();
+
 	/* DWC_DDRPHYA_APBONLY0_MicroContMuxSel */
 	dwc_ddrphy_apb_wr(0xd0000, 0x0);
 	while (dwc_ddrphy_apb_rd(0x20097)) {
diff --git a/plat/imx/imx8m/ddr/lpddr4_dvfs.c b/plat/imx/imx8m/ddr/lpddr4_dvfs.c
index 2b4f300..2f5f7b5 100644
--- a/plat/imx/imx8m/ddr/lpddr4_dvfs.c
+++ b/plat/imx/imx8m/ddr/lpddr4_dvfs.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018-2022 NXP
+ * Copyright 2018-2023 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -37,6 +37,7 @@
 	uint32_t val;
 	uint32_t derate_backup[3];
 	uint32_t (*mr_data)[8];
+	uint32_t phy_master;
 
 	/* 1. program targetd UMCTL2_REGS_FREQ1/2/3,already done, skip it. */
 
@@ -57,6 +58,8 @@
 	/* 12. set PWRCTL.selfref_en=0 */
 	mmio_clrbits_32(DDRC_PWRCTL(0), 0xf);
 
+	phy_master = mmio_read_32(DDRC_DFIPHYMSTR(0));
+
 	/* It is more safe to config it here */
 	mmio_clrbits_32(DDRC_DFIPHYMSTR(0), 0x1);
 
@@ -225,8 +228,8 @@
 	emr3 = (emr3 & 0x00f7) | 0x0d00;
 	lpddr4_mr_write(3, 13, emr3);
 
-	/* enable PHY master */
-	mmio_write_32(DDRC_DFIPHYMSTR(0), 0x1);
+	/* restore the PHY master */
+	mmio_write_32(DDRC_DFIPHYMSTR(0), phy_master);
 
 	/* 32. issue ZQ if required: zq_calib_short, bit 4 */
 	/* polling zq_calib_short_busy */
diff --git a/plat/imx/imx8m/gpc_common.c b/plat/imx/imx8m/gpc_common.c
index e674d7a..32a35ef 100644
--- a/plat/imx/imx8m/gpc_common.c
+++ b/plat/imx/imx8m/gpc_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -29,6 +29,10 @@
 #pragma weak imx_set_cpu_pwr_on
 #pragma weak imx_set_cpu_lpm
 #pragma weak imx_set_cluster_powerdown
+#pragma weak imx_set_sys_wakeup
+#pragma weak imx_noc_slot_config
+#pragma weak imx_gpc_handler
+#pragma weak imx_anamix_override
 
 void imx_set_cpu_secure_entry(unsigned int core_id, uintptr_t sec_entrypoint)
 {
@@ -211,7 +215,6 @@
 	}
 }
 
-#pragma weak imx_noc_slot_config
 /*
  * this function only need to be override by platform
  * that support noc power down, for example: imx8mm.
@@ -233,7 +236,7 @@
 
 	if (retention)
 		val |= (SLPCR_EN_DSM | SLPCR_VSTBY | SLPCR_SBYOS |
-			SLPCR_BYPASS_PMIC_READY | SLPCR_A53_FASTWUP_STOP_MODE);
+			SLPCR_BYPASS_PMIC_READY);
 
 	mmio_write_32(IMX_GPC_BASE + SLPCR, val);
 
@@ -256,11 +259,6 @@
 		(0x3f << SLPCR_RBC_COUNT_SHIFT));
 }
 
-struct pll_override {
-	uint32_t reg;
-	uint32_t override_mask;
-};
-
 struct pll_override pll[MAX_PLL_NUM] = {
 	{.reg = 0x0, .override_mask = (1 << 12) | (1 << 8), },
 	{.reg = 0x14, .override_mask = (1 << 12) | (1 << 8), },
diff --git a/plat/imx/imx8m/imx8m_psci_common.c b/plat/imx/imx8m/imx8m_psci_common.c
index 8f545d6..48eb8a6 100644
--- a/plat/imx/imx8m/imx8m_psci_common.c
+++ b/plat/imx/imx8m/imx8m_psci_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,6 +24,7 @@
  * reuse below ones.
  */
 #pragma weak imx_validate_power_state
+#pragma weak imx_pwr_domain_off
 #pragma weak imx_domain_suspend
 #pragma weak imx_domain_suspend_finish
 #pragma weak imx_get_sys_suspend_power_state
diff --git a/plat/imx/imx8m/imx8mm/platform.mk b/plat/imx/imx8m/imx8mm/platform.mk
index 7a42554..24582f8 100644
--- a/plat/imx/imx8m/imx8mm/platform.mk
+++ b/plat/imx/imx8m/imx8mm/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2019-2023, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -101,7 +101,7 @@
 $(eval $(call add_define,NEED_BL2))
 LOAD_IMAGE_V2		:=	1
 # Non-TF Boot ROM
-BL2_AT_EL3		:=	1
+RESET_TO_BL2	:=	1
 endif
 
 ifneq (${TRUSTED_BOARD_BOOT},0)
diff --git a/plat/imx/imx8m/imx8mp/include/platform_def.h b/plat/imx/imx8m/imx8mp/include/platform_def.h
index 14cb709..1281270 100644
--- a/plat/imx/imx8m/imx8mp/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mp/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020-2022 NXP
+ * Copyright 2020-2023 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -112,7 +112,7 @@
 #define IMX_DDRC_BASE			U(0x3d400000)
 #define IMX_DDRPHY_BASE			U(0x3c000000)
 #define IMX_DDR_IPS_BASE		U(0x3d000000)
-#define IMX_DDR_IPS_SIZE		U(0x1800000)
+#define IMX_DDR_IPS_SIZE		U(0x1900000)
 #define IMX_ROM_BASE			U(0x0)
 #define IMX_ROM_SIZE			U(0x40000)
 #define IMX_NS_OCRAM_BASE		U(0x900000)
diff --git a/plat/imx/imx8m/imx8mp/platform.mk b/plat/imx/imx8m/imx8mp/platform.mk
index 5414c0a..1102316 100644
--- a/plat/imx/imx8m/imx8mp/platform.mk
+++ b/plat/imx/imx8m/imx8mp/platform.mk
@@ -98,7 +98,7 @@
 $(eval $(call add_define,NEED_BL2))
 LOAD_IMAGE_V2		:=	1
 # Non-TF Boot ROM
-BL2_AT_EL3		:=	1
+RESET_TO_BL2		:=	1
 endif
 
 ifneq (${TRUSTED_BOARD_BOOT},0)
diff --git a/plat/imx/imx8m/imx8mq/gpc.c b/plat/imx/imx8m/imx8mq/gpc.c
index fa83324..0a029d6 100644
--- a/plat/imx/imx8m/imx8mq/gpc.c
+++ b/plat/imx/imx8m/imx8mq/gpc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,14 +8,210 @@
 #include <stdint.h>
 #include <stdbool.h>
 
+#include <arch_helpers.h>
 #include <common/debug.h>
 #include <drivers/delay_timer.h>
 #include <lib/mmio.h>
 #include <lib/psci/psci.h>
-#include <platform_def.h>
+#include <lib/smccc.h>
+#include <lib/spinlock.h>
+#include <plat/common/platform.h>
 #include <services/std_svc.h>
 
 #include <gpc.h>
+#include <platform_def.h>
+
+#define FSL_SIP_CONFIG_GPC_MASK		U(0x00)
+#define FSL_SIP_CONFIG_GPC_UNMASK	U(0x01)
+#define FSL_SIP_CONFIG_GPC_SET_WAKE	U(0x02)
+#define FSL_SIP_CONFIG_GPC_PM_DOMAIN	U(0x03)
+#define FSL_SIP_CONFIG_GPC_SET_AFF	U(0x04)
+#define FSL_SIP_CONFIG_GPC_CORE_WAKE	U(0x05)
+
+#define MAX_HW_IRQ_NUM		U(128)
+#define MAX_IMR_NUM		U(4)
+
+static uint32_t gpc_saved_imrs[16];
+static uint32_t gpc_wake_irqs[4];
+static uint32_t gpc_imr_offset[] = {
+	IMX_GPC_BASE + IMR1_CORE0_A53,
+	IMX_GPC_BASE + IMR1_CORE1_A53,
+	IMX_GPC_BASE + IMR1_CORE2_A53,
+	IMX_GPC_BASE + IMR1_CORE3_A53,
+	IMX_GPC_BASE + IMR1_CORE0_M4,
+};
+
+spinlock_t gpc_imr_lock[4];
+
+static void gpc_imr_core_spin_lock(unsigned int core_id)
+{
+	spin_lock(&gpc_imr_lock[core_id]);
+}
+
+static void gpc_imr_core_spin_unlock(unsigned int core_id)
+{
+	spin_unlock(&gpc_imr_lock[core_id]);
+}
+
+static void gpc_save_imr_lpm(unsigned int core_id, unsigned int imr_idx)
+{
+	uint32_t reg = gpc_imr_offset[core_id] + imr_idx * 4;
+
+	gpc_imr_core_spin_lock(core_id);
+
+	gpc_saved_imrs[core_id + imr_idx * 4] = mmio_read_32(reg);
+	mmio_write_32(reg, ~gpc_wake_irqs[imr_idx]);
+
+	gpc_imr_core_spin_unlock(core_id);
+}
+
+static void gpc_restore_imr_lpm(unsigned int core_id, unsigned int imr_idx)
+{
+	uint32_t reg = gpc_imr_offset[core_id] + imr_idx * 4;
+	uint32_t val = gpc_saved_imrs[core_id + imr_idx * 4];
+
+	gpc_imr_core_spin_lock(core_id);
+
+	mmio_write_32(reg, val);
+
+	gpc_imr_core_spin_unlock(core_id);
+}
+
+/*
+ * On i.MX8MQ, only in system suspend mode, the A53 cluster can
+ * enter LPM mode and shutdown the A53 PLAT power domain. So LPM
+ * wakeup only used for system suspend. when system enter suspend,
+ * any A53 CORE can be the last core to suspend the system, But
+ * the LPM wakeup can only use the C0's IMR to wakeup A53 cluster
+ * from LPM, so save C0's IMRs before suspend, restore back after
+ * resume.
+ */
+void imx_set_sys_wakeup(unsigned int last_core, bool pdn)
+{
+	unsigned int imr, core;
+
+	if (pdn) {
+		for (imr = 0U; imr < MAX_IMR_NUM; imr++) {
+			for (core = 0U; core < PLATFORM_CORE_COUNT; core++) {
+				gpc_save_imr_lpm(core, imr);
+			}
+		}
+	} else {
+		for (imr = 0U; imr < MAX_IMR_NUM; imr++) {
+			for (core = 0U; core < PLATFORM_CORE_COUNT; core++) {
+				gpc_restore_imr_lpm(core, imr);
+			}
+		}
+	}
+}
+
+static void imx_gpc_hwirq_mask(unsigned int hwirq)
+{
+	uintptr_t reg;
+	unsigned int val;
+
+	if (hwirq >= MAX_HW_IRQ_NUM) {
+		return;
+	}
+
+	gpc_imr_core_spin_lock(0);
+	reg = gpc_imr_offset[0] + (hwirq / 32) * 4;
+	val = mmio_read_32(reg);
+	val |= 1 << hwirq % 32;
+	mmio_write_32(reg, val);
+	gpc_imr_core_spin_unlock(0);
+}
+
+static void imx_gpc_hwirq_unmask(unsigned int hwirq)
+{
+	uintptr_t reg;
+	unsigned int val;
+
+	if (hwirq >= MAX_HW_IRQ_NUM) {
+		return;
+	}
+
+	gpc_imr_core_spin_lock(0);
+	reg = gpc_imr_offset[0] + (hwirq / 32) * 4;
+	val = mmio_read_32(reg);
+	val &= ~(1 << hwirq % 32);
+	mmio_write_32(reg, val);
+	gpc_imr_core_spin_unlock(0);
+}
+
+static void imx_gpc_set_wake(uint32_t hwirq, bool on)
+{
+	uint32_t mask, idx;
+
+	if (hwirq >= MAX_HW_IRQ_NUM) {
+		return;
+	}
+
+	mask = 1 << hwirq % 32;
+	idx = hwirq / 32;
+	gpc_wake_irqs[idx] = on ? gpc_wake_irqs[idx] | mask :
+				 gpc_wake_irqs[idx] & ~mask;
+}
+
+static void imx_gpc_mask_irq0(uint32_t core_id, uint32_t mask)
+{
+	gpc_imr_core_spin_lock(core_id);
+	if (mask) {
+		mmio_setbits_32(gpc_imr_offset[core_id], 1);
+	} else {
+		mmio_clrbits_32(gpc_imr_offset[core_id], 1);
+	}
+
+	dsb();
+	gpc_imr_core_spin_unlock(core_id);
+}
+
+void imx_gpc_core_wake(uint32_t cpumask)
+{
+	for (int i = 0; i < PLATFORM_CORE_COUNT; i++) {
+		if (cpumask & (1 << i)) {
+			imx_gpc_mask_irq0(i, false);
+		}
+	}
+}
+
+void imx_gpc_set_a53_core_awake(uint32_t core_id)
+{
+	imx_gpc_mask_irq0(core_id, true);
+}
+
+static void imx_gpc_set_affinity(uint32_t hwirq, unsigned int cpu_idx)
+{
+	uintptr_t reg;
+	unsigned int val;
+
+	if (hwirq >= MAX_HW_IRQ_NUM || cpu_idx >= 4) {
+		return;
+	}
+
+	/*
+	 * using the mask/unmask bit as affinity function.unmask the
+	 * IMR bit to enable IRQ wakeup for this core.
+	 */
+	gpc_imr_core_spin_lock(cpu_idx);
+	reg = gpc_imr_offset[cpu_idx] + (hwirq / 32) * 4;
+	val = mmio_read_32(reg);
+	val &= ~(1 << hwirq % 32);
+	mmio_write_32(reg, val);
+	gpc_imr_core_spin_unlock(cpu_idx);
+
+	/* clear affinity of other core */
+	for (int i = 0; i < PLATFORM_CORE_COUNT; i++) {
+		if (cpu_idx != i) {
+			gpc_imr_core_spin_lock(i);
+			reg = gpc_imr_offset[i] + (hwirq / 32) * 4;
+			val = mmio_read_32(reg);
+			val |= (1 << hwirq % 32);
+			mmio_write_32(reg, val);
+			gpc_imr_core_spin_unlock(i);
+		}
+	}
+}
 
 /* use wfi power down the core */
 void imx_set_cpu_pwr_off(unsigned int core_id)
@@ -65,7 +261,7 @@
 		mmio_setbits_32(IMX_GPC_BASE + SLTx_CFG(2), SLT_COREx_PUP(last_core));
 		/* ACK setting: PLAT ACK for PDN, CORE ACK for PUP */
 		mmio_clrsetbits_32(IMX_GPC_BASE + PGC_ACK_SEL_A53, 0xFFFFFFFF,
-			A53_PLAT_PDN_ACK | A53_PLAT_PUP_ACK);
+			A53_PLAT_PDN_ACK | SLT_COREx_PUP_ACK(last_core));
 	} else {
 		mmio_clrbits_32(IMX_GPC_BASE + SLTx_CFG(0), 0xFFFFFFFF);
 		mmio_clrbits_32(IMX_GPC_BASE + SLTx_CFG(1), 0xFFFFFFFF);
@@ -124,26 +320,89 @@
 	}
 }
 
+#define MAX_PLL_NUM	U(12)
+
+static const struct pll_override imx8mq_pll[MAX_PLL_NUM] = {
+	{.reg = 0x0, .override_mask = 0x140000, },
+	{.reg = 0x8, .override_mask = 0x140000, },
+	{.reg = 0x10, .override_mask = 0x140000, },
+	{.reg = 0x18, .override_mask = 0x140000, },
+	{.reg = 0x20, .override_mask = 0x140000, },
+	{.reg = 0x28, .override_mask = 0x140000, },
+	{.reg = 0x30, .override_mask = 0x1555540, },
+	{.reg = 0x3c, .override_mask = 0x1555540, },
+	{.reg = 0x48, .override_mask = 0x140, },
+	{.reg = 0x54, .override_mask = 0x140, },
+	{.reg = 0x60, .override_mask = 0x140, },
+	{.reg = 0x70, .override_mask = 0xa, },
+};
+
+void imx_anamix_override(bool enter)
+{
+	unsigned int i;
+
+	/* enable the pll override bit before entering DSM mode */
+	for (i = 0; i < MAX_PLL_NUM; i++) {
+		if (enter) {
+			mmio_setbits_32(IMX_ANAMIX_BASE + imx8mq_pll[i].reg,
+				imx8mq_pll[i].override_mask);
+		} else {
+			mmio_clrbits_32(IMX_ANAMIX_BASE + imx8mq_pll[i].reg,
+				imx8mq_pll[i].override_mask);
+		}
+	}
+}
+
+int imx_gpc_handler(uint32_t smc_fid,
+			  u_register_t x1,
+			  u_register_t x2,
+			  u_register_t x3)
+{
+	switch (x1) {
+	case FSL_SIP_CONFIG_GPC_CORE_WAKE:
+		imx_gpc_core_wake(x2);
+		break;
+	case FSL_SIP_CONFIG_GPC_SET_WAKE:
+		imx_gpc_set_wake(x2, x3);
+		break;
+	case FSL_SIP_CONFIG_GPC_MASK:
+		imx_gpc_hwirq_mask(x2);
+		break;
+	case FSL_SIP_CONFIG_GPC_UNMASK:
+		imx_gpc_hwirq_unmask(x2);
+		break;
+	case FSL_SIP_CONFIG_GPC_SET_AFF:
+		imx_gpc_set_affinity(x2, x3);
+		break;
+	default:
+		return SMC_UNK;
+	}
+
+	return 0;
+}
+
 void imx_gpc_init(void)
 {
 	uint32_t val;
-	int i;
+	unsigned int i, j;
+
 	/* mask all the interrupt by default */
-	for (i = 0; i < 4; i++) {
-		mmio_write_32(IMX_GPC_BASE + IMR1_CORE0_A53 + i * 4, ~0x0);
-		mmio_write_32(IMX_GPC_BASE + IMR1_CORE1_A53 + i * 4, ~0x0);
-		mmio_write_32(IMX_GPC_BASE + IMR1_CORE2_A53 + i * 4, ~0x0);
-		mmio_write_32(IMX_GPC_BASE + IMR1_CORE3_A53 + i * 4, ~0x0);
-		mmio_write_32(IMX_GPC_BASE + IMR1_CORE0_M4 + i * 4, ~0x0);
+	for (i = 0U; i < PLATFORM_CORE_COUNT; i++) {
+		for (j = 0U; j < ARRAY_SIZE(gpc_imr_offset); j++) {
+			mmio_write_32(gpc_imr_offset[j] + i * 4, ~0x0);
+		}
 	}
+
 	/* Due to the hardware design requirement, need to make
 	 * sure GPR interrupt(#32) is unmasked during RUN mode to
 	 * avoid entering DSM mode by mistake.
 	 */
-	mmio_write_32(IMX_GPC_BASE + IMR1_CORE0_A53, 0xFFFFFFFE);
-	mmio_write_32(IMX_GPC_BASE + IMR1_CORE1_A53, 0xFFFFFFFE);
-	mmio_write_32(IMX_GPC_BASE + IMR1_CORE2_A53, 0xFFFFFFFE);
-	mmio_write_32(IMX_GPC_BASE + IMR1_CORE3_A53, 0xFFFFFFFE);
+	for (i = 0U; i < PLATFORM_CORE_COUNT; i++) {
+		mmio_write_32(gpc_imr_offset[i], ~0x1);
+	}
+
+	/* leave the IOMUX_GPC bit 12 on for core wakeup */
+	mmio_setbits_32(IMX_IOMUX_GPR_BASE + 0x4, 1 << 12);
 
 	/* use external IRQs to wakeup C0~C3 from LPM */
 	val = mmio_read_32(IMX_GPC_BASE + LPCR_A53_BSC);
diff --git a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
index 4706c20..661f8e2 100644
--- a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,6 +21,7 @@
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
 
+#include <dram.h>
 #include <gpc.h>
 #include <imx_aipstz.h>
 #include <imx_uart.h>
@@ -34,6 +35,8 @@
 	MAP_REGION_FLAT(IMX_ROM_BASE, IMX_ROM_SIZE, MT_MEMORY | MT_RO), /* ROM map */
 	MAP_REGION_FLAT(IMX_AIPS_BASE, IMX_AIPS_SIZE, MT_DEVICE | MT_RW), /* AIPS map */
 	MAP_REGION_FLAT(IMX_GIC_BASE, IMX_GIC_SIZE, MT_DEVICE | MT_RW), /* GIC map */
+	MAP_REGION_FLAT(IMX_DDRPHY_BASE, IMX_DDR_IPS_SIZE, MT_DEVICE | MT_RW), /* DDRMIX map */
+	MAP_REGION_FLAT(IMX_DRAM_BASE, IMX_DRAM_SIZE, MT_MEMORY | MT_RW | MT_NS),
 	{0},
 };
 
@@ -82,7 +85,11 @@
 	ocotp_val = mmio_read_32(IMX_OCOTP_BASE + OCOTP_SOC_INFO_B1);
 	if (ocotp_val == 0xff0055aa) {
 		imx_soc_revision &= ~0xff;
-		imx_soc_revision |= 0x21;
+		if (rom_version == 0x22) {
+			imx_soc_revision |= 0x22;
+		} else {
+			imx_soc_revision |= 0x21;
+		}
 		return;
 	}
 }
@@ -208,6 +215,8 @@
 
 	/* gpc init */
 	imx_gpc_init();
+
+	dram_info_init(SAVED_DRAM_TIMING_BASE);
 }
 
 entry_point_info_t *bl31_plat_get_next_image_ep_info(unsigned int type)
diff --git a/plat/imx/imx8m/imx8mq/imx8mq_psci.c b/plat/imx/imx8m/imx8mq/imx8mq_psci.c
index 01582af..3375ce7 100644
--- a/plat/imx/imx8m/imx8mq/imx8mq_psci.c
+++ b/plat/imx/imx8m/imx8mq/imx8mq_psci.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,9 +9,11 @@
 #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 <dram.h>
 #include <gpc.h>
 #include <imx8m_psci.h>
 #include <plat_imx8.h>
@@ -39,6 +41,21 @@
 	return PSCI_E_SUCCESS;
 }
 
+void imx_pwr_domain_off(const psci_power_state_t *target_state)
+{
+	uint64_t mpidr = read_mpidr_el1();
+	unsigned int core_id = MPIDR_AFFLVL0_VAL(mpidr);
+
+	plat_gic_cpuif_disable();
+	imx_set_cpu_pwr_off(core_id);
+
+	/*
+	 *  TODO: Find out why this is still
+	 * needed in order not to break suspend
+	 */
+	udelay(50);
+}
+
 void imx_domain_suspend(const psci_power_state_t *target_state)
 {
 	uint64_t base_addr = BL31_START;
@@ -57,12 +74,14 @@
 	}
 
 	if (is_local_state_off(CLUSTER_PWR_STATE(target_state)))
-		imx_set_cluster_powerdown(core_id, true);
+		imx_set_cluster_powerdown(core_id, CLUSTER_PWR_STATE(target_state));
 	else
 		imx_set_cluster_standby(true);
 
 	if (is_local_state_retn(SYSTEM_PWR_STATE(target_state))) {
 		imx_set_sys_lpm(core_id, true);
+		dram_enter_retention();
+		imx_anamix_override(true);
 	}
 }
 
@@ -73,18 +92,22 @@
 
 	/* check the system level status */
 	if (is_local_state_retn(SYSTEM_PWR_STATE(target_state))) {
+		imx_anamix_override(false);
+		dram_exit_retention();
 		imx_set_sys_lpm(core_id, false);
 		imx_clear_rbc_count();
 	}
 
 	/* check the cluster level power status */
 	if (is_local_state_off(CLUSTER_PWR_STATE(target_state)))
-		imx_set_cluster_powerdown(core_id, false);
+		imx_set_cluster_powerdown(core_id, PSCI_LOCAL_STATE_RUN);
 	else
 		imx_set_cluster_standby(false);
 
 	/* check the core level power status */
 	if (is_local_state_off(CORE_PWR_STATE(target_state))) {
+		/* mark this core as awake by masking IRQ0 */
+		imx_gpc_set_a53_core_awake(core_id);
 		/* clear the core lpm setting */
 		imx_set_cpu_lpm(core_id, false);
 		/* enable the gic cpu interface */
diff --git a/plat/imx/imx8m/imx8mq/include/platform_def.h b/plat/imx/imx8m/imx8mq/include/platform_def.h
index bb57074..2526a02 100644
--- a/plat/imx/imx8m/imx8mq/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mq/include/platform_def.h
@@ -4,6 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <lib/utils_def.h>
 #include <plat/common/common_def.h>
 
 #define PLATFORM_LINKER_FORMAT		"elf64-littleaarch64"
@@ -82,6 +83,9 @@
 #define IMX_DDRC_BASE			U(0x3d400000)
 #define IMX_DDRPHY_BASE			U(0x3c000000)
 #define IMX_DDR_IPS_BASE		U(0x3d000000)
+#define IMX_DDR_IPS_SIZE		U(0x1800000)
+#define IMX_DRAM_BASE			U(0x40000000)
+#define IMX_DRAM_SIZE			U(0xc0000000)
 
 #define IMX_ROM_BASE			U(0x00000000)
 #define IMX_ROM_SIZE			U(0x20000)
@@ -119,6 +123,12 @@
 #define SNVS_LPCR_DP_EN			BIT(5)
 #define SNVS_LPCR_TOP			BIT(6)
 
+#define SAVED_DRAM_TIMING_BASE		U(0x40000000)
+
+#define HW_DRAM_PLL_CFG0		(IMX_ANAMIX_BASE + 0x60)
+#define HW_DRAM_PLL_CFG1		(IMX_ANAMIX_BASE + 0x64)
+#define HW_DRAM_PLL_CFG2		(IMX_ANAMIX_BASE + 0x68)
+#define DRAM_PLL_CTRL			HW_DRAM_PLL_CFG0
 
 #define IOMUXC_GPR10			U(0x28)
 #define GPR_TZASC_EN			BIT(0)
diff --git a/plat/imx/imx8m/imx8mq/platform.mk b/plat/imx/imx8m/imx8mq/platform.mk
index 901a974..b1c189f 100644
--- a/plat/imx/imx8m/imx8mq/platform.mk
+++ b/plat/imx/imx8m/imx8mq/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -14,6 +14,12 @@
 # Include GICv3 driver files
 include drivers/arm/gic/v3/gicv3.mk
 
+IMX_DRAM_SOURCES	:=	plat/imx/imx8m/ddr/dram.c		\
+				plat/imx/imx8m/ddr/clock.c		\
+				plat/imx/imx8m/ddr/dram_retention.c	\
+				plat/imx/imx8m/ddr/ddr4_dvfs.c		\
+				plat/imx/imx8m/ddr/lpddr4_dvfs.c
+
 IMX_GIC_SOURCES		:=	${GICV3_SOURCES}			\
 				plat/common/plat_gicv3.c		\
 				plat/common/plat_psci_common.c		\
@@ -36,12 +42,14 @@
 				drivers/delay_timer/delay_timer.c		\
 				drivers/delay_timer/generic_delay_timer.c	\
 				${XLAT_TABLES_LIB_SRCS}				\
+				${IMX_DRAM_SOURCES}				\
 				${IMX_GIC_SOURCES}
 
 ENABLE_PIE		:=	1
 USE_COHERENT_MEM	:=	1
 RESET_TO_BL31		:=	1
 A53_DISABLE_NON_TEMPORAL_HINT := 0
+WARMBOOT_ENABLE_DCACHE_EARLY	:=	1
 
 ERRATA_A53_835769	:=	1
 ERRATA_A53_843419	:=	1
diff --git a/plat/imx/imx8m/include/dram.h b/plat/imx/imx8m/include/dram.h
index ad11a27..719c390 100644
--- a/plat/imx/imx8m/include/dram.h
+++ b/plat/imx/imx8m/include/dram.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-2022 NXP
+ * Copyright 2019-2023 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -20,6 +20,13 @@
 #define DDRC_DDR3L		BIT(0)
 #define DDR_TYPE_MASK		U(0x3f)
 #define ACTIVE_RANK_MASK	U(0x3)
+#define DDRC_ACTIVE_ONE_RANK	U(0x1)
+#define DDRC_ACTIVE_TWO_RANK	U(0x2)
+
+#define MR12			U(12)
+#define MR14			U(14)
+
+#define MAX_FSP_NUM		U(3)
 
 /* reg & config param */
 struct dram_cfg_param {
@@ -57,6 +64,8 @@
 	struct dram_timing_info *timing_info;
 	/* mr, emr, emr2, emr3, mr11, mr12, mr22, mr14 */
 	uint32_t mr_table[3][8];
+	/* used for workaround for rank to rank issue */
+	uint32_t rank_setting[3][3];
 };
 
 extern struct dram_info dram_info;
diff --git a/plat/imx/imx8m/include/gpc.h b/plat/imx/imx8m/include/gpc.h
index a41030e..8eb3e06 100644
--- a/plat/imx/imx8m/include/gpc.h
+++ b/plat/imx/imx8m/include/gpc.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
  */
@@ -24,6 +24,7 @@
 #define COREx_LPM_PUP(core_id)		((core_id) < 2 ? (1 << ((core_id) * 2 + 9)) : (1 << ((core_id) * 2 + 21)))
 #define SLTx_CFG(n)			((SLT0_CFG + ((n) * 4)))
 #define SLT_COREx_PUP(core_id)		(0x2 << ((core_id) * 2))
+#define SLT_COREx_PUP_ACK(core_id)	((core_id) < 2 ? (1 << ((core_id) + 16)) : (1 << ((core_id) + 27)))
 
 #define IMR_MASK_ALL	0xffffffff
 
@@ -54,6 +55,11 @@
 	bool always_on;
 };
 
+struct pll_override {
+	uint32_t reg;
+	uint32_t override_mask;
+};
+
 DECLARE_BAKERY_LOCK(gpc_lock);
 
 /* function declare */
@@ -72,4 +78,9 @@
 void imx_anamix_override(bool enter);
 void imx_gpc_pm_domain_enable(uint32_t domain_id, bool on);
 
+#if defined(PLAT_imx8mq)
+void imx_gpc_set_a53_core_awake(uint32_t core_id);
+void imx_gpc_core_wake(uint32_t cpumask);
+#endif
+
 #endif /*IMX8M_GPC_H */
diff --git a/plat/intel/soc/agilex/platform.mk b/plat/intel/soc/agilex/platform.mk
index a1e58fc..e9fa666 100644
--- a/plat/intel/soc/agilex/platform.mk
+++ b/plat/intel/soc/agilex/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2019-2023, ARM Limited and Contributors. All rights reserved.
 # Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
@@ -77,7 +77,7 @@
 		plat/intel/soc/common/soc/socfpga_reset_manager.c
 
 PROGRAMMABLE_RESET_ADDRESS	:= 0
-BL2_AT_EL3			:= 1
+RESET_TO_BL2			:= 1
 BL2_INV_DCACHE			:= 0
 MULTI_CONSOLE_API		:= 1
 USE_COHERENT_MEM		:= 1
diff --git a/plat/intel/soc/n5x/platform.mk b/plat/intel/soc/n5x/platform.mk
index be1ad8c..4f3da4e 100644
--- a/plat/intel/soc/n5x/platform.mk
+++ b/plat/intel/soc/n5x/platform.mk
@@ -46,7 +46,7 @@
 		plat/intel/soc/common/soc/socfpga_reset_manager.c
 
 PROGRAMMABLE_RESET_ADDRESS	:= 0
-BL2_AT_EL3			:= 1
+RESET_TO_BL2			:= 1
 BL2_INV_DCACHE			:= 0
 MULTI_CONSOLE_API		:= 1
 USE_COHERENT_MEM		:= 1
diff --git a/plat/intel/soc/stratix10/platform.mk b/plat/intel/soc/stratix10/platform.mk
index b7eb4bd..6bc96fb 100644
--- a/plat/intel/soc/stratix10/platform.mk
+++ b/plat/intel/soc/stratix10/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2019-2023, ARM Limited and Contributors. All rights reserved.
 # Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
@@ -76,5 +76,5 @@
 		plat/intel/soc/common/soc/socfpga_reset_manager.c
 
 PROGRAMMABLE_RESET_ADDRESS	:= 0
-BL2_AT_EL3			:= 1
+RESET_TO_BL2			:= 1
 USE_COHERENT_MEM		:= 1
diff --git a/plat/marvell/armada/a8k/common/ble/ble.ld.S b/plat/marvell/armada/a8k/common/ble/ble.ld.S
index d7a0592..446849b 100644
--- a/plat/marvell/armada/a8k/common/ble/ble.ld.S
+++ b/plat/marvell/armada/a8k/common/ble/ble.ld.S
@@ -19,7 +19,7 @@
 {
     . = BLE_BASE;
 
-    ro . : {
+    .ro . : {
         __RO_START__ = .;
         *ble_main.o(.entry*)
         *(.text*)
@@ -40,9 +40,9 @@
         __DATA_END__ = .;
     } >RAM
 
-    stacks . (NOLOAD) : {
+    .stacks . (NOLOAD) : {
         __STACKS_START__ = .;
-        *(tzfw_normal_stacks)
+        *(.tzfw_normal_stacks)
         __STACKS_END__ = .;
     } >RAM
 
diff --git a/plat/marvell/armada/a8k/common/ble/ble.mk b/plat/marvell/armada/a8k/common/ble/ble.mk
index 160e98f..752ab41 100644
--- a/plat/marvell/armada/a8k/common/ble/ble.mk
+++ b/plat/marvell/armada/a8k/common/ble/ble.mk
@@ -21,7 +21,7 @@
 				-I$(CURDIR)/include/lib/libc			\
 				-I$(CURDIR)/include/lib/libc/aarch64
 
-BLE_LINKERFILE		:=	$(BLE_PATH)/ble.ld.S
+BLE_DEFAULT_LINKER_SCRIPT_SOURCE := $(BLE_PATH)/ble.ld.S
 
 BLE_OBJS := $(addprefix $(BUILD_PLAT)/ble/,$(call SOURCES_TO_OBJS,$(BLE_SOURCES)))
 $(BLE_OBJS): PLAT_INCLUDES += -I$(MV_DDR_PATH)
diff --git a/plat/marvell/armada/common/marvell_gicv3.c b/plat/marvell/armada/common/marvell_gicv3.c
index 0bd5545..5419506 100644
--- a/plat/marvell/armada/common/marvell_gicv3.c
+++ b/plat/marvell/armada/common/marvell_gicv3.c
@@ -38,8 +38,8 @@
  * We save and restore the GICv3 context on system suspend. Allocate the
  * data in the designated EL3 Secure carve-out memory
  */
-static gicv3_redist_ctx_t rdist_ctx __section("arm_el3_tzc_dram");
-static gicv3_dist_ctx_t dist_ctx __section("arm_el3_tzc_dram");
+static gicv3_redist_ctx_t rdist_ctx __section(".arm_el3_tzc_dram");
+static gicv3_dist_ctx_t dist_ctx __section(".arm_el3_tzc_dram");
 
 /*
  * MPIDR hashing function for translating MPIDRs read from GICR_TYPER register
diff --git a/plat/mediatek/build_helpers/mtk_build_helpers.mk b/plat/mediatek/build_helpers/mtk_build_helpers.mk
index fc3876e..83a4dd2 100644
--- a/plat/mediatek/build_helpers/mtk_build_helpers.mk
+++ b/plat/mediatek/build_helpers/mtk_build_helpers.mk
@@ -61,31 +61,6 @@
 $(eval $(call uppercase,$(2))_SOURCES += $(1))
 endef
 
-# MAKE_LINKERFILE change linker script source file name to
-# target linker script
-#   $(1) = linker script source file
-#   $(2) = BL stage
-define MAKE_LINKERFILE
-$(eval EXTRA_GENERATED_LINKER_SCRIPT += $(BUILD_PLAT)/$(2)/$(patsubst %.ld.S,%.ld,$(notdir $(1))))
-endef
-
-# MAKE_LINKERFILE_ITER call MAKE_LINKERFILE iteratively
-#   $(1) = linker script source file
-#   $(2) = BL stage
-define MAKE_LINKERFILE_ITER
-$(eval $(foreach link_src,$(1),$(call MAKE_LINKERFILE,$(link_src),$(2))))
-endef
-
-# MAKE_LD_ITER generate the linker scripts using the C preprocessor iteratively
-#   $(1) = output linker script
-#   $(2) = input template
-#   $(3) = BL stage (1, 2, 2u, 31, 32)
-define MAKE_LD_ITER
-$(eval index_list=$(shell seq $(words $(1))))
-$(eval $(foreach i, $(index_list), \
-$(call MAKE_LD,$(word $(i), $(1)), $(word $(i), $(2)),$(3))))
-endef
-
 # MAKE_MODULE reference MAKE_OBJS.
 # Create module folder under out/bl$(BL)/$(module)
 # Arguments:
diff --git a/plat/mediatek/build_helpers/mtk_build_helpers_epilogue.mk b/plat/mediatek/build_helpers/mtk_build_helpers_epilogue.mk
index 22a546c..4fed41f 100644
--- a/plat/mediatek/build_helpers/mtk_build_helpers_epilogue.mk
+++ b/plat/mediatek/build_helpers/mtk_build_helpers_epilogue.mk
@@ -9,22 +9,7 @@
 
 # Make next section align to page size
 ifneq ($(MTK_EXTRA_LINKERFILE),)
-$(eval $(call MAKE_LINKERFILE_ITER,$(MTK_LINKERFILE_SOURCE),bl31))
-
-# EXTRA_GENERATED_LINKER_SCRIPT is a global variable of derived linker
-# script list(from MTK_LINKERFILE_SOURCE) after MAKE_LINKERFILE_ITER
-# function call
-EXTRA_LINKERFILE += ${EXTRA_GENERATED_LINKER_SCRIPT}
-
-# Expand derived linker script as build target
-$(eval $(call MAKE_LD_ITER, $(EXTRA_GENERATED_LINKER_SCRIPT),$(MTK_LINKERFILE_SOURCE),bl31))
-
-# mtk_align.ld MUST BE THE LAST LINKER SCRIPT!
-EXTRA_LINKERFILE += ${MTK_PLAT}/include/mtk_align.ld
-
-# bl31.ld should depend on EXTRA_LINKERFILE
-$(eval ${BUILD_PLAT}/bl31/bl31.ld: ${EXTRA_LINKERFILE})
-EXTRA_LINKERFILE := $(addprefix -T,$(EXTRA_LINKERFILE))
-else
-EXTRA_LINKERFILE :=
+        # mtk_align.ld MUST BE THE LAST LINKER SCRIPT!
+        BL31_LINKER_SCRIPT_SOURCES += $(MTK_LINKERFILE_SOURCE)
+        BL31_LINKER_SCRIPT_SOURCES += ${MTK_PLAT}/include/mtk_align.ld
 endif
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 92b3873..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
  */
@@ -72,10 +72,11 @@
 	}
 
 #define SMC_ID_EXPAND_AS_DESCRIPTOR_INDEX(_smc_id, _smc_num) \
-	short _smc_id##_descriptor_index __section("mtk_plat_ro") = -1;
+	short _smc_id##_descriptor_index __section(".mtk_plat_ro") = -1;
 
 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/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/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..f677915 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
 };
 
diff --git a/plat/mediatek/include/plat.ld.rodata.inc b/plat/mediatek/include/plat.ld.rodata.inc
index 06ad491..e766472 100644
--- a/plat/mediatek/include/plat.ld.rodata.inc
+++ b/plat/mediatek/include/plat.ld.rodata.inc
@@ -25,6 +25,6 @@
 	__MTK_SMC_POOL_END_UNALIGNED__ = .;
 	. = ALIGN(8);
 #include <vendor_pubsub_events.h>
-	*(mtk_plat_ro)
+	*(.mtk_plat_ro)
 
 #endif /* PLAT_LD_RODATA_INC */
diff --git a/plat/mediatek/mt8173/drivers/spm/spm.c b/plat/mediatek/mt8173/drivers/spm/spm.c
index 1caab3b..8980e07 100644
--- a/plat/mediatek/mt8173/drivers/spm/spm.c
+++ b/plat/mediatek/mt8173/drivers/spm/spm.c
@@ -29,9 +29,9 @@
 
 DEFINE_BAKERY_LOCK(spm_lock);
 
-static int spm_hotplug_ready __section("tzfw_coherent_mem");
-static int spm_mcdi_ready __section("tzfw_coherent_mem");
-static int spm_suspend_ready __section("tzfw_coherent_mem");
+static int spm_hotplug_ready __section(".tzfw_coherent_mem");
+static int spm_mcdi_ready __section(".tzfw_coherent_mem");
+static int spm_suspend_ready __section(".tzfw_coherent_mem");
 
 void spm_lock_init(void)
 {
diff --git a/plat/mediatek/mt8186/drivers/mcdi/mt_mcdi.c b/plat/mediatek/mt8186/drivers/mcdi/mt_mcdi.c
index 0103612..efcf87f 100644
--- a/plat/mediatek/mt8186/drivers/mcdi/mt_mcdi.c
+++ b/plat/mediatek/mt8186/drivers/mcdi/mt_mcdi.c
@@ -62,7 +62,7 @@
 #define MCDI_INIT_2			U(2)
 #define MCDI_INIT_DONE			U(3)
 
-static int mcdi_init_status __section("tzfw_coherent_mem");
+static int mcdi_init_status __section(".tzfw_coherent_mem");
 
 static inline uint32_t mcdi_mbox_read(uint32_t id)
 {
diff --git a/plat/mediatek/mt8192/drivers/mcdi/mt_mcdi.c b/plat/mediatek/mt8192/drivers/mcdi/mt_mcdi.c
index 1635b67..765c7b2 100644
--- a/plat/mediatek/mt8192/drivers/mcdi/mt_mcdi.c
+++ b/plat/mediatek/mt8192/drivers/mcdi/mt_mcdi.c
@@ -63,7 +63,7 @@
 #define MCDI_INIT_2			2
 #define MCDI_INIT_DONE			3
 
-static int mcdi_init_status __section("tzfw_coherent_mem");
+static int mcdi_init_status __section(".tzfw_coherent_mem");
 
 static inline uint32_t mcdi_mbox_read(uint32_t id)
 {
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/drivers/mcdi/mt_mcdi.c b/plat/mediatek/mt8195/drivers/mcdi/mt_mcdi.c
index c14e83b..f7dfec3 100644
--- a/plat/mediatek/mt8195/drivers/mcdi/mt_mcdi.c
+++ b/plat/mediatek/mt8195/drivers/mcdi/mt_mcdi.c
@@ -63,7 +63,7 @@
 #define MCDI_INIT_2			2
 #define MCDI_INIT_DONE			3
 
-static int mcdi_init_status __section("tzfw_coherent_mem");
+static int mcdi_init_status __section(".tzfw_coherent_mem");
 
 static inline uint32_t mcdi_mbox_read(uint32_t id)
 {
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/tegra_platform.c b/plat/nvidia/tegra/common/tegra_platform.c
index f3aa3ea..6d736b5 100644
--- a/plat/nvidia/tegra/common/tegra_platform.c
+++ b/plat/nvidia/tegra/common/tegra_platform.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2020-2021, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2020-2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -272,10 +272,12 @@
  */
 int32_t plat_get_soc_version(void)
 {
-	uint32_t chip_id = ((tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK);
+	uint32_t chip_id = (tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK;
+	uint32_t major_rev = tegra_get_chipid_major();
 	uint32_t manfid = SOC_ID_SET_JEP_106(JEDEC_NVIDIA_BKID, JEDEC_NVIDIA_MFID);
 
-	return (int32_t)(manfid | (chip_id & SOC_ID_IMPL_DEF_MASK));
+	return (int32_t)(manfid | (((chip_id << MAJOR_VERSION_SHIFT) | major_rev) &
+			 SOC_ID_IMPL_DEF_MASK));
 }
 
 /*
diff --git a/plat/nvidia/tegra/drivers/flowctrl/flowctrl.c b/plat/nvidia/tegra/drivers/flowctrl/flowctrl.c
index 8f55554..4c9f4af 100644
--- a/plat/nvidia/tegra/drivers/flowctrl/flowctrl.c
+++ b/plat/nvidia/tegra/drivers/flowctrl/flowctrl.c
@@ -84,7 +84,7 @@
 void tegra_fc_ccplex_pgexit_lock(void)
 {
 	unsigned int i, cpu = read_mpidr() & MPIDR_CPU_MASK;
-	uint32_t flags = tegra_fc_read_32(FLOWCTRL_FC_SEQ_INTERCEPT) & ~INTERCEPT_IRQ_PENDING;;
+	uint32_t flags = tegra_fc_read_32(FLOWCTRL_FC_SEQ_INTERCEPT) & ~INTERCEPT_IRQ_PENDING;
 	uint32_t icept_cpu_flags[] = {
 		INTERCEPT_EXIT_PG_CORE0,
 		INTERCEPT_EXIT_PG_CORE1,
diff --git a/plat/nvidia/tegra/drivers/pmc/pmc.c b/plat/nvidia/tegra/drivers/pmc/pmc.c
index 6c5a73b..e70e7a6 100644
--- a/plat/nvidia/tegra/drivers/pmc/pmc.c
+++ b/plat/nvidia/tegra/drivers/pmc/pmc.c
@@ -103,7 +103,7 @@
 bool tegra_pmc_is_last_on_cpu(void)
 {
 	int i, cpu = read_mpidr() & MPIDR_CPU_MASK;
-	uint32_t val = tegra_pmc_read_32(PMC_PWRGATE_STATUS);;
+	uint32_t val = tegra_pmc_read_32(PMC_PWRGATE_STATUS);
 	bool status = true;
 
 	/* check if this is the last standing CPU */
diff --git a/plat/nvidia/tegra/platform.mk b/plat/nvidia/tegra/platform.mk
index 6ed1cdf..2365564 100644
--- a/plat/nvidia/tegra/platform.mk
+++ b/plat/nvidia/tegra/platform.mk
@@ -90,8 +90,8 @@
 # o resolve undefined symbols to el3_panic
 # o include only required sections
 TF_LDFLAGS	+= --diag_suppress=L6314,L6332 --no_scanlib --callgraph
-TF_LDFLAGS	+= --keep="*(__pubsub*)" --keep="*(rt_svc_descs*)" --keep="*(*cpu_ops)"
+TF_LDFLAGS	+= --keep="*(.__pubsub*)" --keep="*(.rt_svc_descs*)" --keep="*(.cpu_ops)"
 ifeq (${ENABLE_PMF},1)
-TF_LDFLAGS	+= --keep="*(*pmf_svc_descs*)"
+TF_LDFLAGS	+= --keep="*(.pmf_svc_descs*)"
 endif
 endif
diff --git a/plat/nvidia/tegra/scat/bl31.scat b/plat/nvidia/tegra/scat/bl31.scat
index 2d6d2b3..fdd6e33 100644
--- a/plat/nvidia/tegra/scat/bl31.scat
+++ b/plat/nvidia/tegra/scat/bl31.scat
@@ -48,14 +48,14 @@
 	/* Ensure 8-byte alignment for descriptors and ensure inclusion */
 	__RT_SVC_DESCS__ AlignExpr(ImageLimit(__RODATA__), 8) FIXED
 	{
-		*(rt_svc_descs)
+		*(.rt_svc_descs)
 	}
 
 #if ENABLE_PMF
 	/* Ensure 8-byte alignment for descriptors and ensure inclusion */
 	__PMF_SVC_DESCS__ AlignExpr(ImageLimit(__RT_SVC_DESCS__), 8) FIXED
 	{
-		*(pmf_svc_descs)
+		*(.pmf_svc_descs)
 	}
 #endif /* ENABLE_PMF */
 
@@ -65,7 +65,7 @@
 	 */
 	__CPU_OPS__ AlignExpr(+0, 8) FIXED
 	{
-		*(cpu_ops)
+		*(.cpu_ops)
 	}
 
 	/*
@@ -150,7 +150,7 @@
 {
 	__STACKS__ AlignExpr(+0, 64) FIXED
 	{
-		*(tzfw_normal_stacks)
+		*(.tzfw_normal_stacks)
 	}
 }
 
@@ -180,7 +180,7 @@
 	 */
 	__BAKERY_LOCKS__ AlignExpr(ImageLimit(__BSS__), CACHE_WRITEBACK_GRANULE) FIXED
 	{
-		*(bakery_lock)
+		*(.bakery_lock)
 	}
 
 	__BAKERY_LOCKS_EPILOGUE__ AlignExpr(ImageLimit(__BAKERY_LOCKS__), CACHE_WRITEBACK_GRANULE) FIXED EMPTY 0
@@ -229,9 +229,9 @@
 
 LR_XLAT_TABLE +0
 {
-	xlat_table +0 FIXED
+	.xlat_table +0 FIXED
 	{
-		*(xlat_table)
+		*(.xlat_table)
 	}
 }
 
@@ -251,8 +251,8 @@
 		 *
 		 * Each lock's data is contiguous and fully allocated by the compiler
 		 */
-		*(bakery_lock)
-		*(tzfw_coherent_mem)
+		*(.bakery_lock)
+		*(.tzfw_coherent_mem)
 	}
 
 	__COHERENT_RAM_EPILOGUE_UNALIGNED__ +0 FIXED EMPTY 0
diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c b/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
index a57bc11..6414e07 100644
--- a/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
+++ b/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
@@ -372,8 +372,8 @@
 	 * StandbyWFI or the equivalent signal, and always keeping the IDLE
 	 * voltage/frequency request register enabled.
 	 */
-	val = (((freq & MCE_AUTO_CC3_FREQ_MASK) << MCE_AUTO_CC3_FREQ_SHIFT) |\
-		((volt & MCE_AUTO_CC3_VTG_MASK) << MCE_AUTO_CC3_VTG_SHIFT) |\
+	val = (((freq & MCE_AUTO_CC3_FREQ_MASK) << MCE_AUTO_CC3_FREQ_SHIFT) |
+		((volt & MCE_AUTO_CC3_VTG_MASK) << MCE_AUTO_CC3_VTG_SHIFT) |
 		((enable != 0U) ? MCE_AUTO_CC3_ENABLE_BIT : 0U));
 
 	return ari_request_wait(ari_base, 0U,
diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c b/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c
index cbc9aa3..1a48563 100644
--- a/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c
+++ b/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c
@@ -246,8 +246,8 @@
 	 * StandbyWFI or the equivalent signal, and always keeping the IDLE
 	 * voltage/frequency request register enabled.
 	 */
-	val = (((freq & MCE_AUTO_CC3_FREQ_MASK) << MCE_AUTO_CC3_FREQ_SHIFT) |\
-		((volt & MCE_AUTO_CC3_VTG_MASK) << MCE_AUTO_CC3_VTG_SHIFT) |\
+	val = (((freq & MCE_AUTO_CC3_FREQ_MASK) << MCE_AUTO_CC3_FREQ_SHIFT) |
+		((volt & MCE_AUTO_CC3_VTG_MASK) << MCE_AUTO_CC3_VTG_SHIFT) |
 		((enable != 0U) ? MCE_AUTO_CC3_ENABLE_BIT : 0U));
 
 	nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_CC3_CTRL, (uint64_t)val);
diff --git a/plat/nvidia/tegra/soc/t194/plat_ras.c b/plat/nvidia/tegra/soc/t194/plat_ras.c
index 02f6158..a9fed0a 100644
--- a/plat/nvidia/tegra/soc/t194/plat_ras.c
+++ b/plat/nvidia/tegra/soc/t194/plat_ras.c
@@ -249,7 +249,6 @@
 	 * of range.
 	 */
 	*cookie = 0ULL;
-	return;
 }
 
 /* Function to probe an error from error record group. */
diff --git a/plat/nvidia/tegra/soc/t194/plat_smmu.c b/plat/nvidia/tegra/soc/t194/plat_smmu.c
index 310e951..710d5c5 100644
--- a/plat/nvidia/tegra/soc/t194/plat_smmu.c
+++ b/plat/nvidia/tegra/soc/t194/plat_smmu.c
@@ -24,7 +24,7 @@
 uint32_t plat_get_num_smmu_devices(void)
 {
 	uint32_t ret_num = MAX_NUM_SMMU_DEVICES;
-	uint32_t board_revid = ((tegra_misc_read_32(MISCREG_EMU_REVID) >> \
+	uint32_t board_revid = ((tegra_misc_read_32(MISCREG_EMU_REVID) >>
 							BOARD_SHIFT_BITS) & BOARD_MASK_BITS);
 
 	if (board_revid == BOARD_SYSTEM_FPGA_BASE) {
diff --git a/plat/nvidia/tegra/soc/t210/plat_sip_calls.c b/plat/nvidia/tegra/soc/t210/plat_sip_calls.c
index e3484be..93d1283 100644
--- a/plat/nvidia/tegra/soc/t210/plat_sip_calls.c
+++ b/plat/nvidia/tegra/soc/t210/plat_sip_calls.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2018, 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
  */
@@ -33,6 +33,7 @@
 /*******************************************************************************
  * Tegra210 SiP SMCs
  ******************************************************************************/
+#define TEGRA_SIP_PMC_COMMANDS_LEGACY	U(0xC2FEFE00)
 #define TEGRA_SIP_PMC_COMMANDS		U(0xC2FFFE00)
 
 /*******************************************************************************
@@ -54,7 +55,7 @@
 	if (!ns)
 		SMC_RET1(handle, SMC_UNK);
 
-	if (smc_fid == TEGRA_SIP_PMC_COMMANDS) {
+	if ((smc_fid == TEGRA_SIP_PMC_COMMANDS) || (smc_fid == TEGRA_SIP_PMC_COMMANDS_LEGACY)) {
 		/* check the address is within PMC range and is 4byte aligned */
 		if ((x2 >= TEGRA_PMC_SIZE) || (x2 & 0x3))
 			return -EINVAL;
diff --git a/plat/nxp/common/setup/common.mk b/plat/nxp/common/setup/common.mk
index 1fcf1d0..b7e16ae 100644
--- a/plat/nxp/common/setup/common.mk
+++ b/plat/nxp/common/setup/common.mk
@@ -7,7 +7,7 @@
 
 ###############################################################################
 # Flow begins in BL2 at EL3 mode
-BL2_AT_EL3			:= 1
+RESET_TO_BL2			:= 1
 
 # Though one core is powered up by default, there are
 # platform specific ways to release more than one core
diff --git a/plat/nxp/soc-ls1046a/aarch64/ls1046a_helpers.S b/plat/nxp/soc-ls1046a/aarch64/ls1046a_helpers.S
index d2a48ea..a213594 100644
--- a/plat/nxp/soc-ls1046a/aarch64/ls1046a_helpers.S
+++ b/plat/nxp/soc-ls1046a/aarch64/ls1046a_helpers.S
@@ -44,7 +44,7 @@
 
 func plat_reset_handler
 	mov	x29, x30
-#if (defined(IMAGE_BL2) && BL2_AT_EL3)
+#if (defined(IMAGE_BL2) && RESET_TO_BL2)
 	bl	l2_mem_init
 #endif
 	bl	apply_platform_errata
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..0b84e96 100644
--- a/plat/qemu/common/qemu_bl31_setup.c
+++ b/plat/qemu/common/qemu_bl31_setup.c
@@ -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.
@@ -64,10 +86,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..935ba7a 100644
--- a/plat/qemu/common/qemu_common.c
+++ b/plat/qemu/common/qemu_common.c
@@ -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)
diff --git a/plat/qemu/common/qemu_private.h b/plat/qemu/common/qemu_private.h
index 159c44f..199ca01 100644
--- a/plat/qemu/common/qemu_private.h
+++ b/plat/qemu/common/qemu_private.h
@@ -9,26 +9,13 @@
 
 #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);
 
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/platform.mk b/plat/qemu/qemu/platform.mk
index 4cbce9d..c076aba 100644
--- a/plat/qemu/qemu/platform.mk
+++ b/plat/qemu/qemu/platform.mk
@@ -18,6 +18,17 @@
 $(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,17 @@
 
 ifeq (${ARM_ARCH_MAJOR},8)
 PLAT_INCLUDES		+=	-Iinclude/plat/arm/common/${ARCH}
+
+QEMU_CPU_LIBS		:=	lib/cpus/aarch64/aem_generic.S		\
+				lib/cpus/aarch64/cortex_a53.S		\
+				lib/cpus/aarch64/cortex_a57.S		\
+				lib/cpus/aarch64/cortex_a72.S		\
+				lib/cpus/aarch64/cortex_a76.S		\
+				lib/cpus/aarch64/neoverse_n_common.S	\
+				lib/cpus/aarch64/neoverse_n1.S		\
+				lib/cpus/aarch64/qemu_max.S
+else
+QEMU_CPU_LIBS		:=	lib/cpus/${ARCH}/cortex_a15.S
 endif
 
 PLAT_BL_COMMON_SOURCES	:=	${PLAT_QEMU_COMMON_PATH}/qemu_common.c			\
@@ -135,14 +157,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 +218,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		\
@@ -282,8 +301,25 @@
 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
 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
diff --git a/plat/qemu/qemu_sbsa/include/platform_def.h b/plat/qemu/qemu_sbsa/include/platform_def.h
index d971ebe..85fbb4d 100644
--- a/plat/qemu/qemu_sbsa/include/platform_def.h
+++ b/plat/qemu/qemu_sbsa/include/platform_def.h
@@ -364,8 +364,8 @@
  * Name of the section to put the translation tables used by the S-EL1/S-EL0
  * context of a Secure Partition.
  */
-#define PLAT_SP_IMAGE_XLAT_SECTION_NAME		"qemu_sp_xlat_table"
-#define PLAT_SP_IMAGE_BASE_XLAT_SECTION_NAME	"qemu_sp_xlat_table"
+#define PLAT_SP_IMAGE_XLAT_SECTION_NAME		".qemu_sp_xlat_table"
+#define PLAT_SP_IMAGE_BASE_XLAT_SECTION_NAME	".qemu_sp_xlat_table"
 
 /* Cookies passed to the Secure Partition at boot. Not used by QEMU platforms.*/
 #define PLAT_SPM_COOKIE_0		ULL(0)
diff --git a/plat/qemu/qemu_sbsa/platform.mk b/plat/qemu/qemu_sbsa/platform.mk
index 2393b39..fec83db 100644
--- a/plat/qemu/qemu_sbsa/platform.mk
+++ b/plat/qemu/qemu_sbsa/platform.mk
@@ -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,18 @@
 				${PLAT_QEMU_COMMON_PATH}/qemu_console.c		\
 				drivers/arm/pl011/${ARCH}/pl011_console.S
 
+# Treating this as a memory-constrained port for now
+USE_COHERENT_MEM	:=	0
+
+# This can be overridden depending on CPU(s) used in the QEMU image
+HW_ASSISTED_COHERENCY	:=	1
+
+QEMU_CPU_LIBS		:=	lib/cpus/aarch64/cortex_a57.S			\
+				lib/cpus/aarch64/cortex_a72.S			\
+				lib/cpus/aarch64/neoverse_n_common.S		\
+				lib/cpus/aarch64/neoverse_n1.S			\
+				lib/cpus/aarch64/qemu_max.S
+
 include lib/xlat_tables_v2/xlat_tables.mk
 PLAT_BL_COMMON_SOURCES	+=	${XLAT_TABLES_LIB_SRCS}
 
@@ -49,9 +66,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				\
@@ -77,9 +92,7 @@
 				plat/common/plat_gicv3.c			\
 				${PLAT_QEMU_COMMON_PATH}/qemu_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			\
diff --git a/plat/qti/common/src/qti_pm.c b/plat/qti/common/src/qti_pm.c
index ae361e9..1405ca6 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;
 }
@@ -177,6 +191,18 @@
 	}
 }
 
+#if PSCI_OS_INIT_MODE
+static int qti_node_suspend(const psci_power_state_t *target_state)
+{
+	qtiseclib_psci_node_suspend((const uint8_t *)target_state->
+				    pwr_domain_state);
+	if (is_cpu_off(target_state)) {
+		plat_qti_gic_cpuif_disable();
+		qti_set_cpupwrctlr_val();
+	}
+	return PSCI_E_SUCCESS;
+}
+#else
 static void qti_node_suspend(const psci_power_state_t *target_state)
 {
 	qtiseclib_psci_node_suspend((const uint8_t *)target_state->
@@ -186,6 +212,7 @@
 		qti_set_cpupwrctlr_val();
 	}
 }
+#endif
 
 static void qti_node_suspend_finish(const psci_power_state_t *target_state)
 {
diff --git a/plat/qti/msm8916/platform.mk b/plat/qti/msm8916/platform.mk
index e516cea..2baf203 100644
--- a/plat/qti/msm8916/platform.mk
+++ b/plat/qti/msm8916/platform.mk
@@ -43,8 +43,7 @@
 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
 
 # MSM8916 uses ARM Cortex-A53 r0p0 so likely all the errata apply
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/common/aarch64/plat_helpers.S b/plat/renesas/common/aarch64/plat_helpers.S
index 21c3bed..a7fdfa0 100644
--- a/plat/renesas/common/aarch64/plat_helpers.S
+++ b/plat/renesas/common/aarch64/plat_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -126,7 +126,7 @@
 exit:
 	ret	x9
 _panic:
-	b	do_panic
+	b	el3_panic
 #endif
 
 endfunc plat_get_my_entrypoint
diff --git a/plat/renesas/common/aarch64/platform_common.c b/plat/renesas/common/aarch64/platform_common.c
index b0a88cb..17ccb28 100644
--- a/plat/renesas/common/aarch64/platform_common.c
+++ b/plat/renesas/common/aarch64/platform_common.c
@@ -28,7 +28,7 @@
 #endif
 
 const uint8_t version_of_renesas[VERSION_OF_RENESAS_MAXLEN]
-		__attribute__ ((__section__("ro"))) = VERSION_OF_RENESAS;
+		__attribute__ ((__section__(".ro"))) = VERSION_OF_RENESAS;
 
 #define MAP_SHARED_RAM		MAP_REGION_FLAT(RCAR_SHARED_MEM_BASE,	\
 					RCAR_SHARED_MEM_SIZE,		\
diff --git a/plat/renesas/common/common.mk b/plat/renesas/common/common.mk
index ca61f0e..25fbb2f 100644
--- a/plat/renesas/common/common.mk
+++ b/plat/renesas/common/common.mk
@@ -10,7 +10,7 @@
 TRUSTED_BOARD_BOOT		:= 1
 RESET_TO_BL31			:= 1
 GENERATE_COT			:= 1
-BL2_AT_EL3			:= 1
+RESET_TO_BL2			:= 1
 ENABLE_SVE_FOR_NS		:= 0
 MULTI_CONSOLE_API		:= 1
 
diff --git a/plat/rockchip/common/aarch32/plat_helpers.S b/plat/rockchip/common/aarch32/plat_helpers.S
index 475c297..9f49cbd 100644
--- a/plat/rockchip/common/aarch32/plat_helpers.S
+++ b/plat/rockchip/common/aarch32/plat_helpers.S
@@ -151,7 +151,7 @@
 	 * Per-CPU Secure entry point - resume or power up
 	 * --------------------------------------------------------------------
 	 */
-	.section tzfw_coherent_mem, "a"
+	.section .tzfw_coherent_mem, "a"
 	.align  3
 cpuson_entry_point:
 	.rept	PLATFORM_CORE_COUNT
diff --git a/plat/rockchip/common/aarch64/plat_helpers.S b/plat/rockchip/common/aarch64/plat_helpers.S
index 4af052b..c4c0dec 100644
--- a/plat/rockchip/common/aarch64/plat_helpers.S
+++ b/plat/rockchip/common/aarch64/plat_helpers.S
@@ -150,7 +150,7 @@
 	 * Per-CPU Secure entry point - resume or power up
 	 * --------------------------------------------------------------------
 	 */
-	.section tzfw_coherent_mem, "a"
+	.section .tzfw_coherent_mem, "a"
 	.align  3
 cpuson_entry_point:
 	.rept	PLATFORM_CORE_COUNT
diff --git a/plat/rockchip/px30/drivers/pmu/pmu.c b/plat/rockchip/px30/drivers/pmu/pmu.c
index 5f4e64f..8770b2e 100644
--- a/plat/rockchip/px30/drivers/pmu/pmu.c
+++ b/plat/rockchip/px30/drivers/pmu/pmu.c
@@ -45,7 +45,7 @@
 
 static uint32_t cores_pd_cfg_info[PLATFORM_CORE_COUNT]
 #if USE_COHERENT_MEM
-__attribute__ ((section("tzfw_coherent_mem")))
+__attribute__ ((section(".tzfw_coherent_mem")))
 #endif
 ;
 
@@ -101,7 +101,7 @@
 
 static struct px30_sleep_ddr_data ddr_data
 #if USE_COHERENT_MEM
-__attribute__ ((section("tzfw_coherent_mem")))
+__attribute__ ((section(".tzfw_coherent_mem")))
 #endif
 ;
 
diff --git a/plat/rockchip/rk3399/drivers/dp/cdn_dp.h b/plat/rockchip/rk3399/drivers/dp/cdn_dp.h
index c5cbae2..52c72d6 100644
--- a/plat/rockchip/rk3399/drivers/dp/cdn_dp.h
+++ b/plat/rockchip/rk3399/drivers/dp/cdn_dp.h
@@ -34,7 +34,7 @@
 #define HDCP_KEY_1X_STORE_DATA_ALIGN_SIZE	(6 * 64) / 8
 
 /* Checks the cdn_dp_hdcp_key_1x must be aligned on 6 x 64-bit word boundary */
-CASSERT(sizeof(struct cdn_dp_hdcp_key_1x) % HDCP_KEY_1X_STORE_DATA_ALIGN_SIZE, \
+CASSERT(sizeof(struct cdn_dp_hdcp_key_1x) % HDCP_KEY_1X_STORE_DATA_ALIGN_SIZE,
 	assert_hdcp_key_1x_store_data_align_size_mismatch);
 
 uint64_t dp_hdcp_ctrl(uint64_t type);
diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu.c b/plat/rockchip/rk3399/drivers/pmu/pmu.c
index 3084c4f..7bdefcc 100644
--- a/plat/rockchip/rk3399/drivers/pmu/pmu.c
+++ b/plat/rockchip/rk3399/drivers/pmu/pmu.c
@@ -64,7 +64,7 @@
 
 static uint32_t core_pm_cfg_info[PLATFORM_CORE_COUNT]
 #if USE_COHERENT_MEM
-__attribute__ ((section("tzfw_coherent_mem")))
+__attribute__ ((section(".tzfw_coherent_mem")))
 #endif
 ;/* coheront */
 
diff --git a/plat/socionext/synquacer/include/plat.ld.S b/plat/socionext/synquacer/include/plat.ld.S
index af7a172..d02afa7 100644
--- a/plat/socionext/synquacer/include/plat.ld.S
+++ b/plat/socionext/synquacer/include/plat.ld.S
@@ -23,8 +23,8 @@
 	 * not support inner shareable WBWA mappings so it is mapped normal
 	 * non-cacheable)
 	 */
-	sp_xlat_table (NOLOAD) : ALIGN(PAGE_SIZE) {
-		*(sp_xlat_table)
+	.sp_xlat_table (NOLOAD) : ALIGN(PAGE_SIZE) {
+		*(.sp_xlat_table)
 	} >SP_DRAM
 }
 
diff --git a/plat/socionext/synquacer/include/platform_def.h b/plat/socionext/synquacer/include/platform_def.h
index d6bfe42..acc74e2 100644
--- a/plat/socionext/synquacer/include/platform_def.h
+++ b/plat/socionext/synquacer/include/platform_def.h
@@ -180,8 +180,8 @@
 
 #define PLAT_SP_IMAGE_MMAP_REGIONS	30
 #define PLAT_SP_IMAGE_MAX_XLAT_TABLES	20
-#define PLAT_SP_IMAGE_XLAT_SECTION_NAME	"sp_xlat_table"
-#define PLAT_SP_IMAGE_BASE_XLAT_SECTION_NAME	"sp_xlat_table"
+#define PLAT_SP_IMAGE_XLAT_SECTION_NAME	".sp_xlat_table"
+#define PLAT_SP_IMAGE_BASE_XLAT_SECTION_NAME	".sp_xlat_table"
 
 #define PLAT_SQ_UART1_BASE		PLAT_SQ_BOOT_UART_BASE
 #define PLAT_SQ_UART1_SIZE		ULL(0x1000)
diff --git a/plat/socionext/synquacer/platform.mk b/plat/socionext/synquacer/platform.mk
index b76ae88..a6d9bef 100644
--- a/plat/socionext/synquacer/platform.mk
+++ b/plat/socionext/synquacer/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -17,7 +17,7 @@
 SQ_USE_SCMI_DRIVER              ?= 0
 else
 override RESET_TO_BL31          := 0
-override BL2_AT_EL3             := 1
+override RESET_TO_BL2		:= 1
 SQ_USE_SCMI_DRIVER              := 1
 BL2_CPPFLAGS                    += -DPLAT_XLAT_TABLES_DYNAMIC
 endif
diff --git a/plat/socionext/uniphier/platform.mk b/plat/socionext/uniphier/platform.mk
index 378497a..d466aa1 100644
--- a/plat/socionext/uniphier/platform.mk
+++ b/plat/socionext/uniphier/platform.mk
@@ -1,10 +1,10 @@
 #
-# Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-override BL2_AT_EL3			:= 1
+override RESET_TO_BL2			:= 1
 override COLD_BOOT_SINGLE_CPU		:= 1
 override PROGRAMMABLE_RESET_ADDRESS	:= 1
 override USE_COHERENT_MEM		:= 1
diff --git a/plat/st/stm32mp1/include/stm32mp1_mbedtls_config.h b/plat/st/stm32mp1/include/stm32mp1_mbedtls_config-2.h
similarity index 100%
rename from plat/st/stm32mp1/include/stm32mp1_mbedtls_config.h
rename to plat/st/stm32mp1/include/stm32mp1_mbedtls_config-2.h
diff --git a/plat/st/stm32mp1/include/stm32mp1_mbedtls_config-3.h b/plat/st/stm32mp1/include/stm32mp1_mbedtls_config-3.h
new file mode 100644
index 0000000..d7dab1f
--- /dev/null
+++ b/plat/st/stm32mp1/include/stm32mp1_mbedtls_config-3.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * Key algorithms currently supported on mbed TLS libraries
+ */
+#define TF_MBEDTLS_USE_RSA	0
+#define TF_MBEDTLS_USE_ECDSA	1
+
+/*
+ * Hash algorithms currently supported on mbed TLS libraries
+ */
+#define TF_MBEDTLS_SHA256		1
+#define TF_MBEDTLS_SHA384		2
+#define TF_MBEDTLS_SHA512		3
+
+/*
+ * Configuration file to build mbed TLS with the required features for
+ * Trusted Boot
+ */
+
+#define MBEDTLS_PLATFORM_MEMORY
+#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
+/* Prevent mbed TLS from using snprintf so that it can use tf_snprintf. */
+#define MBEDTLS_PLATFORM_SNPRINTF_ALT
+
+#define MBEDTLS_PKCS1_V21
+
+#define MBEDTLS_ASN1_PARSE_C
+#define MBEDTLS_ASN1_WRITE_C
+
+#define MBEDTLS_BASE64_C
+#define MBEDTLS_BIGNUM_C
+
+#define MBEDTLS_ERROR_C
+#define MBEDTLS_MD_C
+
+#define MBEDTLS_MEMORY_BUFFER_ALLOC_C
+#define MBEDTLS_OID_C
+
+#define MBEDTLS_PK_C
+#define MBEDTLS_PK_PARSE_C
+#define MBEDTLS_PK_WRITE_C
+
+#define MBEDTLS_PLATFORM_C
+
+#if TF_MBEDTLS_USE_ECDSA
+#define MBEDTLS_ECDSA_C
+#define MBEDTLS_ECP_C
+#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
+#endif
+#if TF_MBEDTLS_USE_RSA
+#define MBEDTLS_RSA_C
+#define MBEDTLS_X509_RSASSA_PSS_SUPPORT
+#endif
+
+/* The library does not currently support enabling SHA-256 without SHA-224. */
+#define MBEDTLS_SHA224_C
+#define MBEDTLS_SHA256_C
+
+#if (TF_MBEDTLS_HASH_ALG_ID != TF_MBEDTLS_SHA256)
+#define MBEDTLS_SHA384_C
+#define MBEDTLS_SHA512_C
+#endif
+
+#define MBEDTLS_VERSION_C
+
+#define MBEDTLS_X509_USE_C
+#define MBEDTLS_X509_CRT_PARSE_C
+
+#if TF_MBEDTLS_USE_AES_GCM
+#define MBEDTLS_AES_C
+#define MBEDTLS_CIPHER_C
+#define MBEDTLS_GCM_C
+#endif
+
+/* MPI / BIGNUM options */
+#define MBEDTLS_MPI_WINDOW_SIZE			2
+
+#if TF_MBEDTLS_USE_RSA
+#if TF_MBEDTLS_KEY_SIZE <= 2048
+#define MBEDTLS_MPI_MAX_SIZE			256
+#else
+#define MBEDTLS_MPI_MAX_SIZE			512
+#endif
+#else
+#define MBEDTLS_MPI_MAX_SIZE			256
+#endif
+
+/* Memory buffer allocator options */
+#define MBEDTLS_MEMORY_ALIGN_MULTIPLE		8
+
+/*
+ * Prevent the use of 128-bit division which
+ * creates dependency on external libraries.
+ */
+#define MBEDTLS_NO_UDBL_DIVISION
+
+#ifndef __ASSEMBLER__
+/* System headers required to build mbed TLS with the current configuration */
+#include <stdlib.h>
+#include <mbedtls/check_config.h>
+#endif
+
+/*
+ * Mbed TLS heap size is smal as we only use the asn1
+ * parsing functions
+ * digest, signature and crypto algorithm are done by
+ * other library.
+ */
+
+#define TF_MBEDTLS_HEAP_SIZE           U(5120)
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index 236296e..cddc695 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -1,12 +1,12 @@
 #
-# 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
 #
 
 ARM_CORTEX_A7		:=	yes
 ARM_WITH_NEON		:=	yes
-BL2_AT_EL3		:=	1
+RESET_TO_BL2		:=	1
 USE_COHERENT_MEM	:=	0
 
 STM32MP_EARLY_CONSOLE	?=	0
@@ -381,7 +381,19 @@
 
 endif
 TF_MBEDTLS_KEY_ALG 	:=	ecdsa
-MBEDTLS_CONFIG_FILE	?=	"<stm32mp1_mbedtls_config.h>"
+
+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
 
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 569e60c..ade10a6 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
@@ -21,7 +21,7 @@
 #include "ti_sci.h"
 
 #if USE_COHERENT_MEM
-__section("tzfw_coherent_mem")
+__section(".tzfw_coherent_mem")
 #endif
 static uint8_t message_sequence;
 
diff --git a/plat/ti/k3/common/k3_bl31_setup.c b/plat/ti/k3/common/k3_bl31_setup.c
index 9a1fd94..242b1ea 100644
--- a/plat/ti/k3/common/k3_bl31_setup.c
+++ b/plat/ti/k3/common/k3_bl31_setup.c
@@ -121,10 +121,6 @@
 	k3_gic_init();
 
 	ti_sci_init();
-
-	if (ti_sci_device_get(PLAT_BOARD_DEVICE_ID)) {
-		WARN("Unable to take system power reference\n");
-	}
 }
 
 void platform_mem_init(void)
diff --git a/plat/xilinx/common/include/plat_startup.h b/plat/xilinx/common/include/plat_startup.h
index 1733930..ce356f6 100644
--- a/plat/xilinx/common/include/plat_startup.h
+++ b/plat/xilinx/common/include/plat_startup.h
@@ -1,5 +1,6 @@
 /*
  * 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
  */
@@ -38,4 +39,8 @@
 					entry_point_info_t *bl33,
 					uint64_t atf_handoff_addr);
 
+/* JEDEC Standard Manufacturer's Identification Code and Bank ID JEP106 */
+#define JEDEC_XILINX_MFID	U(0x49)
+#define JEDEC_XILINX_BKID	U(0)
+
 #endif /* PLAT_STARTUP_H */
diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.h b/plat/xilinx/common/include/pm_api_sys.h
similarity index 94%
rename from plat/xilinx/versal/pm_service/pm_api_sys.h
rename to plat/xilinx/common/include/pm_api_sys.h
index c539aa7..baed43d 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
  */
@@ -38,8 +38,9 @@
 				 uintptr_t address, uint8_t ack, uint32_t flag);
 enum pm_ret_status pm_set_wakeup_source(uint32_t target, uint32_t device_id,
 					uint8_t enable, uint32_t flag);
-void pm_get_callbackdata(uint32_t *data, size_t count, 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,
diff --git a/plat/xilinx/common/include/pm_client.h b/plat/xilinx/common/include/pm_client.h
index eae1d98..8bf4ae3 100644
--- a/plat/xilinx/common/include/pm_client.h
+++ b/plat/xilinx/common/include/pm_client.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2020-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022, 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_defs.h b/plat/xilinx/common/include/pm_defs.h
new file mode 100644
index 0000000..0188443
--- /dev/null
+++ b/plat/xilinx/common/include/pm_defs.h
@@ -0,0 +1,279 @@
+/*
+ * 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,
+};
+
+/**
+ * @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,
+};
+
+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 */
+/**
+ * @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
+ */
+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 52dfc47..ede71df 100644
--- a/plat/xilinx/common/include/pm_ipi.h
+++ b/plat/xilinx/common/include/pm_ipi.h
@@ -25,7 +25,7 @@
 enum pm_ret_status pm_ipi_send_sync(const struct pm_proc *proc,
 				    uint32_t payload[PAYLOAD_ARG_CNT],
 				    uint32_t *value, size_t count);
-void pm_ipi_buff_read_callb(uint32_t *value, size_t count);
+enum pm_ret_status pm_ipi_buff_read_callb(uint32_t *value, size_t count);
 void pm_ipi_irq_enable(const struct pm_proc *proc);
 void pm_ipi_irq_clear(const struct pm_proc *proc);
 uint32_t pm_ipi_irq_status(const struct pm_proc *proc);
diff --git a/plat/xilinx/common/include/pm_node.h b/plat/xilinx/common/include/pm_node.h
new file mode 100644
index 0000000..b6c2d81
--- /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 = 0x54,
+	XPM_NODEIDX_DEV_ACPU_0_1 = 0x55,
+	XPM_NODEIDX_DEV_ACPU_0_2 = 0x56,
+	XPM_NODEIDX_DEV_ACPU_0_3 = 0x57,
+	XPM_NODEIDX_DEV_ACPU_1_0 = 0x58,
+	XPM_NODEIDX_DEV_ACPU_1_1 = 0x59,
+	XPM_NODEIDX_DEV_ACPU_1_2 = 0x5A,
+	XPM_NODEIDX_DEV_ACPU_1_3 = 0x5B,
+	XPM_NODEIDX_DEV_ACPU_2_0 = 0x5C,
+	XPM_NODEIDX_DEV_ACPU_2_1 = 0x5D,
+	XPM_NODEIDX_DEV_ACPU_2_2 = 0x5E,
+	XPM_NODEIDX_DEV_ACPU_2_3 = 0x5F,
+	XPM_NODEIDX_DEV_ACPU_3_0 = 0x60,
+	XPM_NODEIDX_DEV_ACPU_3_1 = 0x61,
+	XPM_NODEIDX_DEV_ACPU_3_2 = 0x62,
+	XPM_NODEIDX_DEV_ACPU_3_3 = 0x63,
+	XPM_NODEIDX_DEV_RPU_A_0 = 0x64,
+	XPM_NODEIDX_DEV_RPU_A_1 = 0x65,
+	XPM_NODEIDX_DEV_RPU_B_0 = 0x66,
+	XPM_NODEIDX_DEV_RPU_B_1 = 0x67,
+	XPM_NODEIDX_DEV_OCM_0_0 = 0x68,
+	XPM_NODEIDX_DEV_OCM_0_1 = 0x69,
+	XPM_NODEIDX_DEV_OCM_0_2 = 0x6A,
+	XPM_NODEIDX_DEV_OCM_0_3 = 0x6B,
+	XPM_NODEIDX_DEV_OCM_1_0 = 0x6C,
+	XPM_NODEIDX_DEV_OCM_1_1 = 0x6D,
+	XPM_NODEIDX_DEV_OCM_1_2 = 0x6E,
+	XPM_NODEIDX_DEV_OCM_1_3 = 0x6F,
+	XPM_NODEIDX_DEV_TCM_A_0A = 0x70,
+	XPM_NODEIDX_DEV_TCM_A_0B = 0x71,
+	XPM_NODEIDX_DEV_TCM_A_0C = 0x72,
+	XPM_NODEIDX_DEV_TCM_A_1A = 0x73,
+	XPM_NODEIDX_DEV_TCM_A_1B = 0x74,
+	XPM_NODEIDX_DEV_TCM_A_1C = 0x75,
+	XPM_NODEIDX_DEV_TCM_B_0A = 0x76,
+	XPM_NODEIDX_DEV_TCM_B_0B = 0x77,
+	XPM_NODEIDX_DEV_TCM_B_0C = 0x78,
+	XPM_NODEIDX_DEV_TCM_B_1A = 0x79,
+	XPM_NODEIDX_DEV_TCM_B_1B = 0x7A,
+	XPM_NODEIDX_DEV_TCM_B_1C = 0x7B,
+	XPM_NODEIDX_DEV_USB_1 = 0x7C,
+	XPM_NODEIDX_DEV_PMC_WWDT = 0x7D,
+	XPM_NODEIDX_DEV_LPD_SWDT_0 = 0x7E,
+	XPM_NODEIDX_DEV_LPD_SWDT_1 = 0x7F,
+	XPM_NODEIDX_DEV_FPD_SWDT_0 = 0x80,
+	XPM_NODEIDX_DEV_FPD_SWDT_1 = 0x81,
+	XPM_NODEIDX_DEV_FPD_SWDT_2 = 0x82,
+	XPM_NODEIDX_DEV_FPD_SWDT_3 = 0x83,
+#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/versal/pm_service/pm_api_sys.c b/plat/xilinx/common/pm_service/pm_api_sys.c
similarity index 88%
rename from plat/xilinx/versal/pm_service/pm_api_sys.c
rename to plat/xilinx/common/pm_service/pm_api_sys.c
index db9fae4..c36a0ec 100644
--- a/plat/xilinx/versal/pm_service/pm_api_sys.c
+++ b/plat/xilinx/common/pm_service/pm_api_sys.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022, 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,14 +10,20 @@
  * 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 <plat/common/platform.h>
-#include "pm_api_sys.h"
-#include "pm_client.h"
-#include "pm_defs.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;
 
@@ -34,6 +40,57 @@
 /* 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
@@ -196,19 +253,23 @@
  *        1 - Ack IPI after reading payload
  *
  * Read value from ipi buffer response buffer.
+ * @return	Returns status, either success or error
  */
-void pm_get_callbackdata(uint32_t *data, size_t count, uint32_t flag, uint32_t ack)
+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;
+		return ret;
 	}
 
-	pm_ipi_buff_read_callb(data, count);
+	ret = pm_ipi_buff_read_callb(data, count);
 
 	if (ack != 0U) {
 		pm_ipi_irq_clear(primary_proc);
 	}
+
+	return ret;
 }
 
 /**
@@ -400,7 +461,7 @@
 	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);
+	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) &&
@@ -454,10 +515,10 @@
 		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);
+		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, PM_PLL_PARAM_DATA, value, flag);
+		ret =  pm_pll_get_param(arg1, (uint32_t)PM_PLL_PARAM_DATA, value, flag);
 		break;
 	case IOCTL_SET_SGI:
 		/* Get the sgi number */
diff --git a/plat/xilinx/common/pm_service/pm_ipi.c b/plat/xilinx/common/pm_service/pm_ipi.c
index 513d6be..b19fc10 100644
--- a/plat/xilinx/common/pm_service/pm_ipi.c
+++ b/plat/xilinx/common/pm_service/pm_ipi.c
@@ -10,6 +10,7 @@
 #include <arch_helpers.h>
 #include <lib/bakery_lock.h>
 #include <lib/mmio.h>
+#include <lib/spinlock.h>
 #include <ipi.h>
 #include <plat_ipi.h>
 #include <plat_private.h>
@@ -21,7 +22,33 @@
 #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
@@ -36,7 +63,6 @@
  */
 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);
 }
 
@@ -90,11 +116,11 @@
 {
 	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;
 }
@@ -113,11 +139,11 @@
 {
 	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;
 }
@@ -136,7 +162,9 @@
 					   uint32_t *value, size_t count)
 {
 	size_t i;
+	enum pm_ret_status ret;
 #if IPI_CRC_CHECK
+	uint32_t *payload_ptr = value;
 	size_t j;
 	uint32_t response_payload[PAYLOAD_ARG_CNT];
 #endif
@@ -155,6 +183,8 @@
 		*value = mmio_read_32(buffer_base + (i * PAYLOAD_ARG_SIZE));
 		value++;
 	}
+
+	ret = mmio_read_32(buffer_base);
 #if IPI_CRC_CHECK
 	for (j = 0; j < PAYLOAD_ARG_CNT; j++) {
 		response_payload[j] = mmio_read_32(buffer_base +
@@ -165,30 +195,39 @@
 			calculate_crc(response_payload, IPI_W0_TO_W6_SIZE)) {
 		NOTICE("ERROR in CRC response payload value:0x%x\n",
 					response_payload[PAYLOAD_CRC_POS]);
+		ret = PM_RET_ERROR_INVALID_CRC;
+		/* Payload data is invalid as CRC validation failed
+		 * Clear the payload to avoid leakage of data to upper layers
+		 */
+		memset(payload_ptr, 0, count);
 	}
 #endif
 
-	return mmio_read_32(buffer_base);
+	return ret;
 }
 
 /**
- * pm_ipi_buff_read_callb() - Reads IPI response after remote processor has
- *			      handled interrupt
- * @value	Used to return value from IPI buffer element (optional)
+ * 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
  *
- * @return	Returns status, either success or error+reason
+ * This callback function fills requested data in @value from ipi response
+ * buffer.
+ * @return 	Returns status, either success or error
  */
-void pm_ipi_buff_read_callb(uint32_t *value, size_t count)
+enum pm_ret_status pm_ipi_buff_read_callb(uint32_t *value, size_t count)
 {
 	size_t i;
 #if IPI_CRC_CHECK
+	uint32_t *payload_ptr = value;
 	size_t j;
 	unsigned int response_payload[PAYLOAD_ARG_CNT] = {0};
 #endif
 	uintptr_t buffer_base = IPI_BUFFER_REMOTE_BASE +
 				IPI_BUFFER_TARGET_LOCAL_OFFSET +
 				IPI_BUFFER_REQ_OFFSET;
+	enum pm_ret_status ret = PM_RET_SUCCESS;
 
 	if (count > IPI_BUFFER_MAX_WORDS) {
 		count = IPI_BUFFER_MAX_WORDS;
@@ -208,8 +247,14 @@
 			calculate_crc(response_payload, IPI_W0_TO_W6_SIZE)) {
 		NOTICE("ERROR in CRC response payload value:0x%x\n",
 					response_payload[PAYLOAD_CRC_POS]);
+		ret = PM_RET_ERROR_INVALID_CRC;
+		/* Payload data is invalid as CRC validation failed
+		 * Clear the payload to avoid leakage of data to upper layers
+		 */
+		memset(payload_ptr, 0, count);
 	}
 #endif
+	return ret;
 }
 
 /**
@@ -230,7 +275,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) {
@@ -240,7 +285,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 92%
rename from plat/xilinx/versal/pm_service/pm_svc_main.c
rename to plat/xilinx/common/pm_service/pm_svc_main.c
index c90f9e1..1bd2192 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
  */
@@ -48,12 +48,17 @@
 				void *cookie)
 {
 	uint32_t payload[4] = {0};
+	enum pm_ret_status ret;
 
 	VERBOSE("Received IPI FIQ from firmware\n");
 
 	(void)plat_ic_acknowledge_interrupt();
 
+	ret = pm_get_callbackdata(payload, ARRAY_SIZE(payload), 0, 0);
+	if (ret != PM_RET_SUCCESS) {
+		payload[0] = ret;
+	}
+
-	pm_get_callbackdata(payload, ARRAY_SIZE(payload), 0, 0);
 	switch (payload[0]) {
 	case PM_INIT_SUSPEND_CB:
 	case PM_NOTIFY_CB:
@@ -61,6 +66,11 @@
 			notify_os();
 		}
 		break;
+	case PM_RET_ERROR_INVALID_CRC:
+		pm_ipi_irq_clear(primary_proc);
+		WARN("Invalid CRC in the payload\n");
+		break;
+
 	default:
 		pm_ipi_irq_clear(primary_proc);
 		WARN("Invalid IPI payload\n");
@@ -158,7 +168,7 @@
 
 	switch (api_id) {
 
-	case PM_IOCTL:
+	case (uint32_t)PM_IOCTL:
 	{
 		uint32_t value = 0U;
 
@@ -171,7 +181,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 };
 
@@ -182,7 +192,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};
 
@@ -220,25 +230,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);
 
@@ -274,8 +284,13 @@
 	case PM_GET_CALLBACK_DATA:
 	{
 		uint32_t result[4] = {0};
+		enum pm_ret_status ret;
+
+		ret = pm_get_callbackdata(result, ARRAY_SIZE(result), security_flag, 1U);
+		if (ret != 0) {
+			result[0] = ret;
+		}
 
-		pm_get_callbackdata(result, ARRAY_SIZE(result), security_flag, 1U);
 		SMC_RET2(handle,
 			(uint64_t)result[0] | ((uint64_t)result[1] << 32U),
 			(uint64_t)result[2] | ((uint64_t)result[3] << 32U));
@@ -315,7 +330,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) {
diff --git a/plat/xilinx/versal/aarch64/versal_common.c b/plat/xilinx/versal/aarch64/versal_common.c
index f55cde9..ed7f270 100644
--- a/plat/xilinx/versal/aarch64/versal_common.c
+++ b/plat/xilinx/versal/aarch64/versal_common.c
@@ -1,5 +1,6 @@
 /*
  * 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
  */
@@ -34,7 +35,7 @@
 
 static void versal_print_platform_name(void)
 {
-	NOTICE("ATF running on Xilinx %s\n", PLATFORM_NAME);
+	NOTICE("TF-A running on %s\n", PLATFORM_NAME);
 }
 
 void versal_config_setup(void)
diff --git a/plat/xilinx/versal/include/plat_ipi.h b/plat/xilinx/versal/include/plat_ipi.h
index 36a4380..9143dc6 100644
--- a/plat/xilinx/versal/include/plat_ipi.h
+++ b/plat/xilinx/versal/include/plat_ipi.h
@@ -34,7 +34,6 @@
 #define IPI_BUFFER_TARGET_APU_OFFSET	0x80U
 #define IPI_BUFFER_TARGET_PMC_OFFSET	0x40U
 
-#define IPI_BUFFER_LOCAL_BASE	IPI_BUFFER_APU_BASE
 #define IPI_BUFFER_REMOTE_BASE	IPI_BUFFER_PMC_BASE
 
 #define IPI_BUFFER_TARGET_LOCAL_OFFSET	IPI_BUFFER_TARGET_APU_OFFSET
diff --git a/plat/xilinx/versal/include/plat_macros.S b/plat/xilinx/versal/include/plat_macros.S
index 3a52212..f1f9bb7 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) 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/platform_def.h b/plat/xilinx/versal/include/platform_def.h
index 6d95fdc..bd23bfb 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) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -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 60431a5..ce4d98c 100644
--- a/plat/xilinx/versal/include/versal_def.h
+++ b/plat/xilinx/versal/include/versal_def.h
@@ -129,9 +129,10 @@
 #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 PMC_IPI_TRIG_BIT	(1U << 1U)
 #define IPI1_REG_BASE		U(0xFF340000)
 #define IPI1_TRIG_BIT		(1U << 3U)
 #define IPI2_REG_BASE		U(0xFF350000)
diff --git a/plat/xilinx/versal/platform.mk b/plat/xilinx/versal/platform.mk
index 8087297..71f6802 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) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 
@@ -82,6 +83,8 @@
 				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/versal/bl31_versal_setup.c		\
 				plat/xilinx/versal/plat_psci.c			\
 				plat/xilinx/versal/plat_versal.c		\
@@ -89,8 +92,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_client.c b/plat/xilinx/versal/pm_service/pm_client.c
index 54f4eb2..ecec405 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
  */
@@ -24,8 +25,6 @@
 #include "pm_defs.h"
 
 #define UNDEFINED_CPUID		(~0)
-#define IRQ_MAX		142U
-#define NUM_GICD_ISENABLER	((IRQ_MAX >> 5U) + 1U)
 
 DEFINE_BAKERY_LOCK(pm_client_secure_lock);
 
@@ -51,114 +50,83 @@
 
 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
  *
  * 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
- */
-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;
+	enum pm_device_node_idx dev_idx = XPM_NODEIDX_DEV_MIN;
 
-	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;
-			}
-
-			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;
+	default:
+		dev_idx = XPM_NODEIDX_DEV_MIN;
+		break;
 	}
+
+	return dev_idx;
 }
 
 /**
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 2922b5d..0000000
--- a/plat/xilinx/versal/pm_service/pm_defs.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (c) 2019-2022, Xilinx, 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;
-
-/**
- * @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_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_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 6f2ff94..28a4cb9 100644
--- a/plat/xilinx/versal/sip_svc_setup.c
+++ b/plat/xilinx/versal/sip_svc_setup.c
@@ -6,6 +6,8 @@
 
 /* Top level SMC handler for SiP calls. Dispatch PM calls to PM SMC handler. */
 
+#include <inttypes.h>
+
 #include <common/debug.h>
 #include <common/runtime_svc.h>
 #include <tools_share/uuid.h>
@@ -23,11 +25,12 @@
 #define SIP_SVC_VERSION_MINOR	U(1)
 
 /* These macros are used to identify PM calls from the SMC function ID */
-#define PM_FID_MASK	0xf000u
+#define SIP_FID_MASK	GENMASK(23, 16)
+#define XLNX_FID_MASK	GENMASK(23, 12)
 #define PM_FID_VALUE	0u
 #define IPI_FID_VALUE	0x1000u
-#define is_pm_fid(_fid) (((_fid) & PM_FID_MASK) == PM_FID_VALUE)
-#define is_ipi_fid(_fid) (((_fid) & PM_FID_MASK) == IPI_FID_VALUE)
+#define is_pm_fid(_fid) (((_fid) & XLNX_FID_MASK) == PM_FID_VALUE)
+#define is_ipi_fid(_fid) (((_fid) & XLNX_FID_MASK) == IPI_FID_VALUE)
 
 /* SiP Service UUID */
 DEFINE_SVC_UUID2(versal_sip_uuid,
@@ -62,6 +65,14 @@
 			     void *handle,
 			     u_register_t flags)
 {
+	VERBOSE("SMCID: 0x%08x, x1: 0x%016" PRIx64 ", x2: 0x%016" PRIx64 ", x3: 0x%016" PRIx64 ", x4: 0x%016" PRIx64 "\n",
+		smc_fid, x1, x2, x3, x4);
+
+	if (smc_fid & SIP_FID_MASK) {
+		WARN("SMC out of SiP assinged range: 0x%x\n", smc_fid);
+		SMC_RET1(handle, SMC_UNK);
+	}
+
 	/* Let PM SMC handler deal with PM-related requests */
 	if (is_pm_fid(smc_fid)) {
 		return pm_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle,
diff --git a/plat/xilinx/versal/versal_gicv3.c b/plat/xilinx/versal/versal_gicv3.c
index d410906..4f4e0d9 100644
--- a/plat/xilinx/versal/versal_gicv3.c
+++ b/plat/xilinx/versal/versal_gicv3.c
@@ -1,5 +1,6 @@
 /*
  * 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
  */
@@ -36,8 +37,8 @@
  * We save and restore the GICv3 context on system suspend. Allocate the
  * data in the designated EL3 Secure carve-out memory.
  */
-static gicv3_redist_ctx_t rdist_ctx __section("versal_el3_tzc_dram");
-static gicv3_dist_ctx_t dist_ctx __section("versal_el3_tzc_dram");
+static gicv3_redist_ctx_t rdist_ctx __section(".versal_el3_tzc_dram");
+static gicv3_dist_ctx_t dist_ctx __section(".versal_el3_tzc_dram");
 
 /*
  * MPIDR hashing function for translating MPIDRs read from GICR_TYPER register
@@ -60,8 +61,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 d821929..67915f4 100644
--- a/plat/xilinx/versal/versal_ipi.c
+++ b/plat/xilinx/versal/versal_ipi.c
@@ -20,16 +20,16 @@
 
 /* versal ipi configuration table */
 static const struct ipi_config versal_ipi_table[] = {
-	/* A72 IPI */
-	[IPI_ID_APU] = {
-		.ipi_bit_mask = IPI0_TRIG_BIT,
-		.ipi_reg_base = IPI0_REG_BASE,
-		.secure_only = 0U,
-	},
-
 	/* PMC IPI */
 	[IPI_ID_PMC] = {
 		.ipi_bit_mask = PMC_IPI_TRIG_BIT,
+		.ipi_reg_base = PMC_REG_BASE,
+		.secure_only = 0U,
+	},
+
+	/* A72 IPI */
+	[IPI_ID_APU] = {
+		.ipi_bit_mask = IPI0_TRIG_BIT,
 		.ipi_reg_base = IPI0_REG_BASE,
 		.secure_only = 0U,
 	},
diff --git a/plat/xilinx/versal_net/bl31_versal_net_setup.c b/plat/xilinx/versal_net/bl31_versal_net_setup.c
index c9942d6..a7bae72 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-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
  */
@@ -14,6 +14,7 @@
 #include <common/debug.h>
 #include <common/fdt_fixup.h>
 #include <common/fdt_wrappers.h>
+#include <drivers/arm/dcc.h>
 #include <drivers/arm/pl011.h>
 #include <drivers/console.h>
 #include <lib/mmio.h>
@@ -28,7 +29,6 @@
 
 static entry_point_info_t bl32_image_ep_info;
 static entry_point_info_t bl33_image_ep_info;
-static console_t versal_net_runtime_console;
 
 /*
  * Return a pointer to the 'entry_point_info' structure of the next image for
@@ -95,18 +95,30 @@
 		panic();
 	}
 
-	/* Initialize the console to provide early debug support */
-	rc = console_pl011_register(VERSAL_NET_UART_BASE, uart_clock,
+	if (VERSAL_NET_CONSOLE_IS(pl011_0) || VERSAL_NET_CONSOLE_IS(pl011_1)) {
+		static console_t versal_net_runtime_console;
+
+		/* Initialize the console to provide early debug support */
+		rc = console_pl011_register(VERSAL_NET_UART_BASE, uart_clock,
 				    VERSAL_NET_UART_BAUDRATE,
 				    &versal_net_runtime_console);
-	if (rc == 0) {
-		panic();
-	}
+		if (rc == 0) {
+			panic();
+		}
 
-	console_set_scope(&versal_net_runtime_console, CONSOLE_FLAG_BOOT |
-			  CONSOLE_FLAG_RUNTIME);
+		console_set_scope(&versal_net_runtime_console, CONSOLE_FLAG_BOOT |
+				CONSOLE_FLAG_RUNTIME);
+	} else if (VERSAL_NET_CONSOLE_IS(dcc)) {
+		/* Initialize the dcc console for debug.
+		 * dcc is over jtag and does not configures uart0 or uart1.
+		 */
+		rc = console_dcc_register();
+		if (rc == 0) {
+			panic();
+		}
+	}
 
-	NOTICE("TF-A running on Xilinx %s %d.%d\n", board_name_decode(),
+	NOTICE("TF-A running on %s %d.%d\n", board_name_decode(),
 	       platform_version / 10U, platform_version % 10U);
 
 	/* Initialize the platform config for future decision making */
diff --git a/plat/xilinx/versal_net/include/plat_ipi.h b/plat/xilinx/versal_net/include/plat_ipi.h
index 5255f8f..5ac611c 100644
--- a/plat/xilinx/versal_net/include/plat_ipi.h
+++ b/plat/xilinx/versal_net/include/plat_ipi.h
@@ -37,7 +37,6 @@
 #define IPI_BUFFER_TARGET_APU_OFFSET	0x80U
 #define IPI_BUFFER_TARGET_PMC_OFFSET	0x40U
 
-#define IPI_BUFFER_LOCAL_BASE	IPI_BUFFER_APU_BASE
 #define IPI_BUFFER_REMOTE_BASE	IPI_BUFFER_PMC_BASE
 
 #define IPI_BUFFER_TARGET_LOCAL_OFFSET	IPI_BUFFER_TARGET_APU_OFFSET
diff --git a/plat/xilinx/versal_net/include/plat_macros.S b/plat/xilinx/versal_net/include/plat_macros.S
index fb108b6..a0c6604 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) 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_private.h b/plat/xilinx/versal_net/include/plat_private.h
index 6a3bc19..ca4ed1d 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) 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 696771f..f74cb1e 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) 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
  */
@@ -95,20 +95,25 @@
 #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
  * terminology. On a GICv2 system or mode, the lists will be merged and treated
  * as Group 0 interrupts.
  */
-#define PLAT_VERSAL_IPI_IRQ	62
+#define PLAT_VERSAL_NET_IPI_IRQ	89
+#define PLAT_VERSAL_IPI_IRQ	PLAT_VERSAL_NET_IPI_IRQ
 
 #define PLAT_VERSAL_NET_G1S_IRQ_PROPS(grp) \
 	INTR_PROP_DESC(VERSAL_NET_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
 			GIC_INTR_CFG_LEVEL)
 
-#define PLAT_VERSAL_NET_G0_IRQ_PROPS(grp)
+#define PLAT_VERSAL_NET_G0_IRQ_PROPS(grp) \
+	INTR_PROP_DESC(PLAT_VERSAL_IPI_IRQ, GIC_HIGHEST_SEC_PRIORITY, grp, \
+			GIC_INTR_CFG_EDGE), \
+
+#define IRQ_MAX		200U
 
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/xilinx/versal_net/include/versal_net_def.h b/plat/xilinx/versal_net/include/versal_net_def.h
index 14e63d5..9d1b7c2 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) 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
  */
@@ -24,6 +24,7 @@
 #define VERSAL_NET_CONSOLE_ID_pl011	U(1)
 #define VERSAL_NET_CONSOLE_ID_pl011_0	U(1)
 #define VERSAL_NET_CONSOLE_ID_pl011_1	U(2)
+#define VERSAL_NET_CONSOLE_ID_dcc	U(3)
 
 #define VERSAL_NET_CONSOLE_IS(con)	(VERSAL_NET_CONSOLE_ID_ ## con == VERSAL_NET_CONSOLE)
 
@@ -142,12 +143,11 @@
 
 #define VERSAL_NET_UART_BAUDRATE	115200
 
-#if VERSAL_NET_CONSOLE_IS(pl011) || VERSAL_NET_CONSOLE_IS(pl011_0)
-#define VERSAL_NET_UART_BASE		VERSAL_NET_UART0_BASE
-#elif VERSAL_NET_CONSOLE_IS(pl011_1)
+#if VERSAL_NET_CONSOLE_IS(pl011_1)
 #define VERSAL_NET_UART_BASE		VERSAL_NET_UART1_BASE
 #else
-# error "invalid VERSAL_NET_CONSOLE"
+/* Default console is UART0 */
+#define VERSAL_NET_UART_BASE            VERSAL_NET_UART0_BASE
 #endif
 
 #define PLAT_VERSAL_NET_CRASH_UART_BASE		VERSAL_NET_UART_BASE
diff --git a/plat/xilinx/versal_net/plat_psci.c b/plat/xilinx/versal_net/plat_psci.c
index c5833a9..8bb9bda 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) 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..9d401a5 100644
--- a/plat/xilinx/versal_net/plat_psci_pm.c
+++ b/plat/xilinx/versal_net/plat_psci_pm.c
@@ -196,7 +196,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 +203,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 */
diff --git a/plat/xilinx/versal_net/platform.mk b/plat/xilinx/versal_net/platform.mk
index 622ae98..0bc5925 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) 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
 
@@ -53,7 +53,7 @@
 HW_ASSISTED_COHERENCY := 1
 
 VERSAL_NET_CONSOLE	?=	pl011
-ifeq (${VERSAL_NET_CONSOLE}, $(filter ${VERSAL_NET_CONSOLE},pl011 pl011_0 pl011_1))
+ifeq (${VERSAL_NET_CONSOLE}, $(filter ${VERSAL_NET_CONSOLE},pl011 pl011_0 pl011_1 dcc))
 else
   $(error Please define VERSAL_NET_CONSOLE)
 endif
@@ -72,6 +72,7 @@
 include lib/libfdt/libfdt.mk
 
 PLAT_BL_COMMON_SOURCES	:=	\
+				drivers/arm/dcc/dcc_console.c			\
 				drivers/delay_timer/delay_timer.c		\
 				drivers/delay_timer/generic_delay_timer.c	\
 				${GICV3_SOURCES}				\
@@ -86,10 +87,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
diff --git a/plat/xilinx/versal_net/pm_service/pm_client.c b/plat/xilinx/versal_net/pm_service/pm_client.c
index f543193..2741d47 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
  */
@@ -18,6 +18,7 @@
 #include <lib/mmio.h>
 #include <lib/mmio.h>
 #include <lib/utils.h>
+#include <lib/spinlock.h>
 #include <plat/common/platform.h>
 
 #include <plat_ipi.h>
@@ -29,7 +30,34 @@
 #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,
@@ -140,6 +168,133 @@
 }
 
 /**
+ * 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
+ */
+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
@@ -154,9 +309,11 @@
 	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,7 +334,7 @@
 	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();
 }
 
 /**
@@ -213,7 +370,7 @@
 		return;
 	}
 
-	bakery_lock_get(&pm_client_secure_lock);
+	pm_client_lock_get();
 
 	/* Clear powerdown request */
 	val = read_cpu_pwrctrl_val();
@@ -232,7 +389,7 @@
 	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();
 }
 
 /**
@@ -249,7 +406,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 +419,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 0e3940f..c91497c 100644
--- a/plat/xilinx/versal_net/sip_svc_setup.c
+++ b/plat/xilinx/versal_net/sip_svc_setup.c
@@ -9,6 +9,7 @@
 /* Top level SMC handler for SiP calls. Dispatch PM calls to PM SMC handler. */
 
 #include <errno.h>
+#include <inttypes.h>
 
 #include <common/debug.h>
 #include <common/runtime_svc.h>
@@ -28,11 +29,12 @@
 #define SIP_SVC_VERSION_MINOR		(1U)
 
 /* These macros are used to identify PM calls from the SMC function ID */
-#define PM_FID_MASK	0xf000u
+#define SIP_FID_MASK	GENMASK(23, 16)
+#define XLNX_FID_MASK	GENMASK(23, 12)
 #define PM_FID_VALUE	0u
 #define IPI_FID_VALUE	0x1000u
-#define is_pm_fid(_fid)	(((_fid) & PM_FID_MASK) == PM_FID_VALUE)
-#define is_ipi_fid(_fid) (((_fid) & PM_FID_MASK) == IPI_FID_VALUE)
+#define is_pm_fid(_fid) (((_fid) & XLNX_FID_MASK) == PM_FID_VALUE)
+#define is_ipi_fid(_fid) (((_fid) & XLNX_FID_MASK) == IPI_FID_VALUE)
 
 /* SiP Service UUID */
 DEFINE_SVC_UUID2(versal_net_sip_uuid,
@@ -62,6 +64,14 @@
 			     void *handle,
 			     u_register_t flags)
 {
+	VERBOSE("SMCID: 0x%08x, x1: 0x%016" PRIx64 ", x2: 0x%016" PRIx64 ", x3: 0x%016" PRIx64 ", x4: 0x%016" PRIx64 "\n",
+		smc_fid, x1, x2, x3, x4);
+
+	if (smc_fid & SIP_FID_MASK) {
+		WARN("SMC out of SiP assinged range: 0x%x\n", smc_fid);
+		SMC_RET1(handle, SMC_UNK);
+	}
+
 	/* Let PM SMC handler deal with PM-related requests */
 	if (is_pm_fid(smc_fid)) {
 		return smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle,
diff --git a/plat/xilinx/versal_net/versal_net_gicv3.c b/plat/xilinx/versal_net/versal_net_gicv3.c
index b7ac6ab..cee8092 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-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
  */
@@ -30,14 +30,6 @@
 /* The GICv3 driver only needs to be initialized in EL3 */
 static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
 
-static const uintptr_t gicr_base_addrs[2] = {
-	PLAT_VERSAL_NET_GICR_BASE,	/* GICR Base address of the primary CPU */
-	0U				/* Zero Termination */
-};
-
-/* List of zero terminated GICR frame addresses which CPUs will probe */
-static const uintptr_t *gicr_frames;
-
 static const interrupt_prop_t versal_net_interrupt_props[] = {
 	PLAT_VERSAL_NET_G1S_IRQ_PROPS(INTR_GROUP1S),
 	PLAT_VERSAL_NET_G0_IRQ_PROPS(INTR_GROUP0)
@@ -47,8 +39,8 @@
  * We save and restore the GICv3 context on system suspend. Allocate the
  * data in the designated EL3 Secure carve-out memory.
  */
-static gicv3_redist_ctx_t rdist_ctx __section("versal_net_el3_tzc_dram");
-static gicv3_dist_ctx_t dist_ctx __section("versal_net_el3_tzc_dram");
+static gicv3_redist_ctx_t rdist_ctx __section(".versal_net_el3_tzc_dram");
+static gicv3_dist_ctx_t dist_ctx __section(".versal_net_el3_tzc_dram");
 
 /*
  * MPIDR hashing function for translating MPIDRs read from GICR_TYPER register
@@ -71,8 +63,8 @@
 }
 
 static const gicv3_driver_data_t versal_net_gic_data __unused = {
-	.gicd_base = PLAT_VERSAL_NET_GICD_BASE,
-	.gicr_base = 0U,
+	.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,
@@ -90,12 +82,6 @@
 	 */
 #if IMAGE_BL31
 	gicv3_driver_init(&versal_net_gic_data);
-	gicr_frames = gicr_base_addrs;
-
-	if (gicv3_rdistif_probe(gicr_frames[0]) == -1) {
-		ERROR("No GICR base frame found for Primary CPU\n");
-		panic();
-	}
 #endif
 }
 
@@ -131,25 +117,6 @@
  *****************************************************************************/
 void plat_versal_net_gic_pcpu_init(void)
 {
-	int32_t result;
-	const uintptr_t *plat_gicr_frames = gicr_frames;
-
-	do {
-		result = gicv3_rdistif_probe(*plat_gicr_frames);
-
-		/* If the probe is successful, no need to proceed further */
-		if (result == 0) {
-			break;
-		}
-
-		plat_gicr_frames++;
-	} while (*plat_gicr_frames != 0U);
-
-	if (result == -1) {
-		ERROR("No GICR base frame found for CPU 0x%lx\n", read_mpidr());
-		panic();
-	}
-
 	gicv3_rdistif_init(plat_my_core_pos());
 }
 
diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
index 7bdd5bd..8f28636 100644
--- a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
+++ b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
@@ -1,5 +1,6 @@
 /*
  * 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
  */
@@ -10,12 +11,15 @@
 #include <common/debug.h>
 #include <drivers/generic_delay_timer.h>
 #include <lib/mmio.h>
+#include <lib/smccc.h>
 #include <lib/xlat_tables/xlat_tables.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.
@@ -303,13 +307,38 @@
 	maskid = ZYNQMP_CSU_IDCODE_XILINX_ID << ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT |
 		 ZYNQMP_CSU_IDCODE_FAMILY << ZYNQMP_CSU_IDCODE_FAMILY_SHIFT;
 	if (tmp != maskid) {
-		ERROR("Incorrect XILINX IDCODE 0x%x, maskid 0x%x\n", id, maskid);
+		ERROR("Incorrect IDCODE 0x%x, maskid 0x%x\n", id, maskid);
 		return "UNKN";
 	}
-	VERBOSE("Xilinx IDCODE 0x%x\n", id);
+	VERBOSE("IDCODE 0x%x\n", id);
 	return zynqmp_get_silicon_idcode_name();
 }
 
+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;
+	}
+
+	return SMC_ARCH_CALL_NOT_SUPPORTED;
+}
+
+int32_t plat_get_soc_version(void)
+{
+	uint32_t chip_id = zynqmp_get_silicon_ver();
+	uint32_t manfid = SOC_ID_SET_JEP_106(JEDEC_XILINX_BKID, JEDEC_XILINX_MFID);
+
+	return (int32_t)(manfid | (chip_id & 0xFFFF));
+}
+
+int32_t plat_get_soc_revision(void)
+{
+	return mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_IDCODE_OFFSET);
+}
+
 static uint32_t zynqmp_get_ps_ver(void)
 {
 	uint32_t ver = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_VERSION_OFFSET);
diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
index 1d59537..50fd67b 100644
--- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
+++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
@@ -1,5 +1,6 @@
 /*
  * 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
  */
@@ -16,6 +17,7 @@
 #include <plat/common/platform.h>
 #include <lib/mmio.h>
 
+#include <custom_svc.h>
 #include <plat_startup.h>
 #include <plat_private.h>
 #include <zynqmp_def.h>
@@ -118,18 +120,19 @@
 		enum fsbl_handoff ret = fsbl_atf_handover(&bl32_image_ep_info,
 							  &bl33_image_ep_info,
 							  atf_handoff_addr);
-		if (ret == FSBL_HANDOFF_NO_STRUCT) {
-			bl31_set_default_config();
-		} else if (ret != FSBL_HANDOFF_SUCCESS) {
+		if (ret != FSBL_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();
+
 }
 
 #if ZYNQMP_WDT_RESTART
@@ -168,7 +171,7 @@
 }
 #endif
 
-#if (BL31_LIMIT < PLAT_DDR_LOWMEM_MAX)
+#if (defined(XILINX_OF_BOARD_DTB_ADDR) && !IS_TFA_IN_OCM(BL31_BASE))
 static void prepare_dtb(void)
 {
 	void *dtb = (void *)XILINX_OF_BOARD_DTB_ADDR;
@@ -197,8 +200,9 @@
 	}
 
 	/* Reserve memory used by Trusted Firmware. */
-	if (fdt_add_reserved_memory(dtb, "tf-a", BL31_BASE, BL31_LIMIT - BL31_BASE)) {
-		WARN("Failed to add reserved memory nodes to DT.\n");
+	if (fdt_add_reserved_memory(dtb, "tf-a", BL31_BASE,
+				    BL31_LIMIT - BL31_BASE + 1)) {
+		WARN("Failed to add reserved memory nodes for BL31 to DT.\n");
 	}
 
 	ret = fdt_pack(dtb);
@@ -213,8 +217,8 @@
 
 void bl31_platform_setup(void)
 {
-#if (BL31_LIMIT < PLAT_DDR_LOWMEM_MAX)
-		prepare_dtb();
+#if (defined(XILINX_OF_BOARD_DTB_ADDR) && !IS_TFA_IN_OCM(BL31_BASE))
+	prepare_dtb();
 #endif
 
 	/* Initialize the gic cpu and distributor interfaces */
@@ -245,9 +249,8 @@
 	plat_arm_interconnect_init();
 	plat_arm_interconnect_enter_coherency();
 
-
 	const mmap_region_t bl_regions[] = {
-#if (BL31_LIMIT < PLAT_DDR_LOWMEM_MAX)
+#if (defined(XILINX_OF_BOARD_DTB_ADDR) && !IS_TFA_IN_OCM(BL31_BASE))
 		MAP_REGION_FLAT(XILINX_OF_BOARD_DTB_ADDR, XILINX_OF_BOARD_DTB_MAX_SIZE,
 			MT_MEMORY | MT_RW | MT_NS),
 #endif
@@ -263,6 +266,8 @@
 		{0}
 	};
 
+	custom_mmap_add();
+
 	setup_page_tables(bl_regions, plat_arm_get_mmap());
 	enable_mmu_el3(0);
 }
diff --git a/plat/xilinx/zynqmp/custom_sip_svc.c b/plat/xilinx/zynqmp/custom_sip_svc.c
new file mode 100644
index 0000000..fbb0a33
--- /dev/null
+++ b/plat/xilinx/zynqmp/custom_sip_svc.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2022-2023, Advanced Micro Devices Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <smccc_helpers.h>
+
+uint64_t custom_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
+			    uint64_t x3, uint64_t x4, void *cookie,
+			    void *handle, uint64_t flags)
+{
+	WARN("Unimplemented SiP Service Call: 0x%x\n", smc_fid);
+	SMC_RET1(handle, SMC_UNK);
+}
+
+void custom_early_setup(void)
+{
+}
+
+void custom_mmap_add(void)
+{
+}
diff --git a/plat/xilinx/zynqmp/include/custom_svc.h b/plat/xilinx/zynqmp/include/custom_svc.h
new file mode 100644
index 0000000..ef0eb67
--- /dev/null
+++ b/plat/xilinx/zynqmp/include/custom_svc.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2022-2023, Advanced Micro Devices Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef CUSTOM_SVC_H
+#define CUSTOM_SVC_H
+
+#define ZYNQMP_SIP_SVC_CUSTOM   U(0x82002000)
+#define ZYNQMP_SIP_SVC64_CUSTOM U(0xC2002000)
+
+uint64_t custom_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
+			    uint64_t x3, uint64_t x4, void *cookie,
+			    void *handle, uint64_t flags);
+
+void custom_early_setup(void);
+void custom_mmap_add(void);
+
+#endif /* CUSTOM_SVC_H */
diff --git a/plat/xilinx/zynqmp/include/plat_ipi.h b/plat/xilinx/zynqmp/include/plat_ipi.h
index a78f93a..bf56d5e 100644
--- a/plat/xilinx/zynqmp/include/plat_ipi.h
+++ b/plat/xilinx/zynqmp/include/plat_ipi.h
@@ -35,7 +35,6 @@
 #define IPI_BUFFER_APU_BASE	(IPI_BUFFER_BASEADDR + 0x400U)
 #define IPI_BUFFER_PMU_BASE	(IPI_BUFFER_BASEADDR + 0xE00U)
 
-#define IPI_BUFFER_LOCAL_BASE	IPI_BUFFER_APU_BASE
 #define IPI_BUFFER_REMOTE_BASE	IPI_BUFFER_PMU_BASE
 
 #define IPI_BUFFER_TARGET_LOCAL_OFFSET	0x80U
diff --git a/plat/xilinx/zynqmp/include/plat_pm_common.h b/plat/xilinx/zynqmp/include/plat_pm_common.h
index a57aebe..8167eb9 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) 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/platform_def.h b/plat/xilinx/zynqmp/include/platform_def.h
index c2d22c2..aebce30 100644
--- a/plat/xilinx/zynqmp/include/platform_def.h
+++ b/plat/xilinx/zynqmp/include/platform_def.h
@@ -1,5 +1,7 @@
 /*
  * 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.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -40,8 +42,8 @@
 # define BL31_BASE			U(0xfffea000)
 # define BL31_LIMIT			U(0x100000000)
 #else
-# define BL31_BASE			U(0xfffe5000)
-# define BL31_LIMIT			U(0x100000000)
+# define BL31_BASE			U(0x1000)
+# define BL31_LIMIT			U(0x7ffff)
 #endif
 #else
 # define BL31_BASE			(ZYNQMP_ATF_MEM_BASE)
@@ -83,19 +85,31 @@
 /*******************************************************************************
  * Platform specific page table and MMU setup constants
  ******************************************************************************/
-#define XILINX_OF_BOARD_DTB_ADDR	U(0x100000)
 #define XILINX_OF_BOARD_DTB_MAX_SIZE	U(0x200000)
 #define PLAT_DDR_LOWMEM_MAX		U(0x80000000)
+#define PLAT_OCM_BASE			U(0xFFFC0000)
+#define PLAT_OCM_LIMIT			U(0xFFFFFFFF)
+
+#define IS_TFA_IN_OCM(x)		((x >= PLAT_OCM_BASE) && (x < PLAT_OCM_LIMIT))
 
 #define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
 #define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
-#if (BL31_LIMIT < PLAT_DDR_LOWMEM_MAX)
+
+#ifndef MAX_MMAP_REGIONS
+#if (defined(XILINX_OF_BOARD_DTB_ADDR) && !IS_TFA_IN_OCM(BL31_BASE))
 #define MAX_MMAP_REGIONS		8
-#define MAX_XLAT_TABLES			6
 #else
 #define MAX_MMAP_REGIONS		7
+#endif
+#endif
+
+#ifndef MAX_XLAT_TABLES
+#if !IS_TFA_IN_OCM(BL31_BASE)
+#define MAX_XLAT_TABLES			8
+#else
 #define MAX_XLAT_TABLES			5
 #endif
+#endif
 
 #define CACHE_WRITEBACK_SHIFT   6
 #define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
diff --git a/plat/xilinx/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..5211ace 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) 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/platform.mk b/plat/xilinx/zynqmp/platform.mk
index 05adbd0..86b7839 100644
--- a/plat/xilinx/zynqmp/platform.mk
+++ b/plat/xilinx/zynqmp/platform.mk
@@ -1,10 +1,13 @@
 #
 # 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.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 
 override ERRATA_A53_855873 := 1
+ERRATA_A53_1530924 := 1
 override PROGRAMMABLE_RESET_ADDRESS := 1
 PSCI_EXTENDED_STATE_ID := 1
 A53_DISABLE_NON_TEMPORAL_HINT := 0
@@ -74,6 +77,10 @@
     $(eval $(call add_define,ZYNQMP_SECURE_EFUSES))
 endif
 
+ifdef XILINX_OF_BOARD_DTB_ADDR
+$(eval $(call add_define,XILINX_OF_BOARD_DTB_ADDR))
+endif
+
 PLAT_INCLUDES		:=	-Iinclude/plat/arm/common/			\
 				-Iinclude/plat/arm/common/aarch64/		\
 				-Iplat/xilinx/common/include/			\
@@ -109,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			\
@@ -116,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			\
@@ -138,6 +141,12 @@
 BL31_CPPFLAGS		+=	-fno-jump-tables
 TF_CFLAGS_aarch64	+=	-mbranch-protection=none
 
+ifdef CUSTOM_PKG_PATH
+include $(CUSTOM_PKG_PATH)/custom_pkg.mk
+else
+BL31_SOURCES		+=	plat/xilinx/zynqmp/custom_sip_svc.c
+endif
+
 ifneq (${RESET_TO_BL31},1)
   $(error "Using BL31 as the reset vector is only one option supported on ZynqMP. Please set RESET_TO_BL31 to 1.")
 endif
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
index e61310a..9f4278d 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) 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)
 
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
index c0bfd51..45038b0 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) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,10 +17,10 @@
 
 #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_pm_api_sys.h"
 
 /**
  * pm_ioctl_get_rpu_oper_mode () - Get current RPU operation 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..de93b2d 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) 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
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
index 8f37341..847ec2c 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) 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];
diff --git a/plat/xilinx/zynqmp/pm_service/pm_client.c b/plat/xilinx/zynqmp/pm_service/pm_client.c
index 7217fa1..f752525 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) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,9 +22,9 @@
 
 #include <plat_ipi.h>
 #include <zynqmp_def.h>
-#include "pm_api_sys.h"
 #include "pm_client.h"
 #include "pm_ipi.h"
+#include "zynqmp_pm_api_sys.h"
 
 #define IRQ_MAX		84U
 #define NUM_GICD_ISENABLER	((IRQ_MAX >> 5U) + 1U)
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 e335b94..0000000
--- a/plat/xilinx/zynqmp/pm_service/pm_defs.h
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * Copyright (c) 2013-2022, ARM Limited and Contributors. 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)
-
-/* 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 EM_FUNID_NUM_MASK    0xF0000U
-
-#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_FPGA_GET_VERSION,
-	PM_FPGA_GET_FEATURE_LIST,
-	PM_FEATURE_CHECK = 63,
-	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,
-};
-
-/**
- * @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_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_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,
-};
-
-/**
- * EM API IDs
- */
-enum em_api_id {
-	EM_SET_ACTION = 1,
-	EM_REMOVE_ACTION,
-	EM_SEND_ERRORS,
-};
-
-#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 c1781f3..0000000
--- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (c) 2013-2020, ARM Limited and Contributors. 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);
-
-uint64_t em_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 97%
rename from plat/xilinx/zynqmp/pm_service/pm_api_sys.c
rename to plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
index a17b6c5..9133121 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
@@ -1,5 +1,6 @@
 /*
  * 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
  */
@@ -15,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) | \
@@ -252,10 +253,6 @@
 	return pm_shutdown_scope;
 }
 
-#define EM_PACK_PAYLOAD1(pl, arg0) {	\
-	pl[0] = (uint16_t)(0xE) << 16 | (uint16_t)arg0;	\
-}
-
 /**
  * pm_self_suspend() - PM call for processor to suspend itself
  * @nid		Node id of the processor or subsystem
@@ -690,16 +687,19 @@
  * @data - array of PAYLOAD_ARG_CNT elements
  *
  * Read value from ipi buffer response buffer.
+ * @return      Returns status, either success or error
  */
-void pm_get_callbackdata(uint32_t *data, size_t count)
+enum pm_ret_status pm_get_callbackdata(uint32_t *data, size_t count)
 {
+	enum pm_ret_status ret = PM_RET_SUCCESS;
 	/* Return if interrupt is not from PMU */
 	if (!pm_ipi_irq_status(primary_proc)) {
-		return;
+		return ret;
 	}
 
-	pm_ipi_buff_read_callb(data, count);
+	ret = pm_ipi_buff_read_callb(data, count);
 	pm_ipi_irq_clear(primary_proc);
+	return ret;
 }
 
 /**
@@ -786,7 +786,7 @@
 {
 	switch (api_id) {
 	case PM_QUERY_DATA:
-		*version = ATF_API_BASE_VERSION;
+		*version = TFA_API_QUERY_DATA_VERSION;
 		bit_mask[0] = (uint32_t)(PM_QUERY_FEATURE_BITMASK);
 		bit_mask[1] = (uint32_t)(PM_QUERY_FEATURE_BITMASK >> 32);
 		return PM_RET_SUCCESS;
@@ -922,14 +922,16 @@
 	*version = ret_payload[0];
 
 	/* Update IOCTL bit mask which are implemented in ATF */
-	if (api_id == PM_IOCTL) {
+	if ((api_id == PM_IOCTL) || (api_id == PM_GET_OP_CHARACTERISTIC)) {
 		if (len < 2) {
 			return PM_RET_ERROR_ARGS;
 		}
 		bit_mask[0] = ret_payload[1];
 		bit_mask[1] = ret_payload[2];
-		/* Get IOCTL's implemented by ATF */
-		status = atf_ioctl_bitmask(bit_mask);
+		if (api_id == PM_IOCTL) {
+			/* Get IOCTL's implemented by ATF */
+			status = atf_ioctl_bitmask(bit_mask);
+		}
 	} else {
 		/* Requires for MISRA */
 	}
@@ -1494,7 +1496,7 @@
  *
  * 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) {
@@ -1805,32 +1807,5 @@
 	/* Send request to the PMU */
 	PM_PACK_PAYLOAD3(payload, PM_EFUSE_ACCESS, address_high, address_low);
 
-	return pm_ipi_send_sync(primary_proc, payload, value, 1);
-}
-
-enum pm_ret_status em_set_action(uint32_t *value)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMU */
-	EM_PACK_PAYLOAD1(payload, EM_SET_ACTION);
-	return pm_ipi_send_sync(primary_proc, payload, value, 1);
-}
-
-enum pm_ret_status em_remove_action(uint32_t *value)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMU */
-	EM_PACK_PAYLOAD1(payload, EM_REMOVE_ACTION);
-	return pm_ipi_send_sync(primary_proc, payload, value, 1);
-}
-
-enum pm_ret_status em_send_errors(uint32_t *value)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMU */
-	EM_PACK_PAYLOAD1(payload, EM_SEND_ERRORS);
 	return pm_ipi_send_sync(primary_proc, payload, value, 1);
 }
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 9ba9475..71a0bd5 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.h
@@ -1,17 +1,19 @@
 /*
  * 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,
@@ -127,7 +129,7 @@
 				    uint32_t size,
 				    uint32_t flags);
 uint32_t pm_get_shutdown_scope(void);
-void pm_get_callbackdata(uint32_t *data, size_t count);
+enum pm_ret_status pm_get_callbackdata(uint32_t *data, size_t count);
 enum pm_ret_status pm_ioctl(enum pm_node_id nid,
 			    uint32_t ioctl_id,
 			    uint32_t arg1,
@@ -149,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,
@@ -187,11 +189,8 @@
 enum pm_ret_status pm_pll_get_mode(enum pm_node_id nid, enum pm_pll_mode *mode);
 enum pm_ret_status pm_efuse_access(uint32_t address_high,
 				   uint32_t address_low, uint32_t *value);
-enum pm_ret_status em_set_action(uint32_t *value);
-enum pm_ret_status em_remove_action(uint32_t *value);
-enum pm_ret_status em_send_errors(uint32_t *value);
 enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *version,
 				    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..c82a3ef
--- /dev/null
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_defs.h
@@ -0,0 +1,209 @@
+/*
+ * 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 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
+
+/* 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,
+};
+
+/**
+ * @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_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 /* 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 91%
rename from plat/xilinx/zynqmp/pm_service/pm_svc_main.c
rename to plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c
index a3f0278..1ccf258 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c
@@ -1,5 +1,6 @@
 /*
  * 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
  */
@@ -21,10 +22,10 @@
 #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;
@@ -364,7 +365,11 @@
 		SMC_RET1(handle, (uint64_t)ret);
 
 	case PM_GET_CALLBACK_DATA:
-		pm_get_callbackdata(result, ARRAY_SIZE(result));
+		ret = pm_get_callbackdata(result, ARRAY_SIZE(result));
+		if (ret != PM_RET_SUCCESS) {
+			result[0] = ret;
+		}
+
 		SMC_RET2(handle,
 			 (uint64_t)result[0] | ((uint64_t)result[1] << 32),
 			 (uint64_t)result[2] | ((uint64_t)result[3] << 32));
@@ -568,56 +573,3 @@
 			 (uint64_t)result[1] | ((uint64_t)result[2] << 32U));
 	}
 }
-
-/**
- * em_smc_handler() - SMC handler for EM-API calls coming from EL1/EL2.
- * @smc_fid - Function Identifier
- * @x1 - x4 - Arguments
- * @cookie  - Unused
- * @handler - Pointer to caller's context structure
- *
- * @return  - Unused
- *
- * Determines that smc_fid is valid and supported EM SMC Function ID from the
- * list of em_api_ids, otherwise completes the request with
- * the unknown SMC Function ID
- *
- * The SMC calls for EM service are forwarded from SIP Service SMC handler
- * function with rt_svc_handle signature
- */
-uint64_t em_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)
-{
-	enum pm_ret_status ret;
-
-	switch (smc_fid & FUNCID_NUM_MASK) {
-	/* EM API Functions */
-	case EM_SET_ACTION:
-	{
-		uint32_t value;
-
-		ret = em_set_action(&value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
-	}
-
-	case EM_REMOVE_ACTION:
-	{
-		uint32_t value;
-
-		ret = em_remove_action(&value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
-	}
-
-	case EM_SEND_ERRORS:
-	{
-		uint32_t value;
-
-		ret = em_send_errors(&value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
-	}
-
-	default:
-		WARN("Unimplemented EM Service Call: 0x%x\n", smc_fid);
-		SMC_RET1(handle, SMC_UNK);
-	}
-}
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..03ff6d3
--- /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 4ce9b8a..3844b16 100644
--- a/plat/xilinx/zynqmp/sip_svc_setup.c
+++ b/plat/xilinx/zynqmp/sip_svc_setup.c
@@ -1,16 +1,21 @@
 /*
  * 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
  */
 
 /* Top level SMC handler for SiP calls. Dispatch PM calls to PM SMC handler. */
 
+#include <inttypes.h>
+
 #include <common/runtime_svc.h>
 #include <tools_share/uuid.h>
 
+#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)
@@ -22,14 +27,12 @@
 #define SIP_SVC_VERSION_MINOR	1
 
 /* These macros are used to identify PM, IPI calls from the SMC function ID */
-#define PM_FID_MASK	0xf000u
+#define SIP_FID_MASK	GENMASK(23, 16)
+#define XLNX_FID_MASK	GENMASK(23, 12)
 #define PM_FID_VALUE	0u
 #define IPI_FID_VALUE	0x1000u
-#define EM_FID_MASK     0xf0000u
-#define EM_FID_VALUE    0xE0000u
-#define is_em_fid(_fid) (((_fid) & EM_FID_MASK) == EM_FID_VALUE)
-#define is_pm_fid(_fid) (((_fid) & PM_FID_MASK) == PM_FID_VALUE)
-#define is_ipi_fid(_fid) (((_fid) & PM_FID_MASK) == IPI_FID_VALUE)
+#define is_pm_fid(_fid) (((_fid) & XLNX_FID_MASK) == PM_FID_VALUE)
+#define is_ipi_fid(_fid) (((_fid) & XLNX_FID_MASK) == IPI_FID_VALUE)
 
 /* SiP Service UUID */
 DEFINE_SVC_UUID2(zynqmp_sip_uuid,
@@ -62,12 +65,16 @@
 			      void *handle,
 			      u_register_t flags)
 {
-	/* Let EM SMC handler deal with EM-related requests */
-	if (is_em_fid(smc_fid)) {
-		return em_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle,
-					flags);
-	} else if (is_pm_fid(smc_fid)) {
+	VERBOSE("SMCID: 0x%08x, x1: 0x%016" PRIx64 ", x2: 0x%016" PRIx64 ", x3: 0x%016" PRIx64 ", x4: 0x%016" PRIx64 "\n",
+		smc_fid, x1, x2, x3, x4);
+
+	if (smc_fid & SIP_FID_MASK) {
+		WARN("SMC out of SiP assinged range: 0x%x\n", smc_fid);
+		SMC_RET1(handle, SMC_UNK);
+	}
+
 	/* Let PM SMC handler deal with PM-related requests */
+	if (is_pm_fid(smc_fid)) {
 		return pm_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle,
 				      flags);
 	}
@@ -89,6 +96,11 @@
 	case ZYNQMP_SIP_SVC_VERSION:
 		SMC_RET2(handle, SIP_SVC_VERSION_MAJOR, SIP_SVC_VERSION_MINOR);
 
+	case ZYNQMP_SIP_SVC_CUSTOM:
+	case ZYNQMP_SIP_SVC64_CUSTOM:
+		return custom_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
+					  handle, flags);
+
 	default:
 		WARN("Unimplemented SiP Service Call: 0x%x\n", smc_fid);
 		SMC_RET1(handle, SMC_UNK);
diff --git a/services/spd/opteed/opteed.mk b/services/spd/opteed/opteed.mk
index 643b054..477b45d 100644
--- a/services/spd/opteed/opteed.mk
+++ b/services/spd/opteed/opteed.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -16,3 +16,19 @@
 
 # required so that optee code can control access to the timer registers
 NS_TIMER_SWITCH		:=	1
+
+# WARNING: This enables loading of OP-TEE via an SMC, which can be potentially
+# insecure. This removes the boundary between the startup of the secure and
+# non-secure worlds until the point where this SMC is invoked. Only use this
+# setting if you can ensure that the non-secure OS can remain trusted up until
+# the point where this SMC is invoked.
+OPTEE_ALLOW_SMC_LOAD		:=	0
+ifeq ($(OPTEE_ALLOW_SMC_LOAD),1)
+ifeq ($(PLAT_XLAT_TABLES_DYNAMIC),0)
+$(error When OPTEE_ALLOW_SMC_LOAD=1, PLAT_XLAT_TABLES_DYNAMIC must also be 1)
+endif
+$(warning "OPTEE_ALLOW_SMC_LOAD is enabled which may result in an insecure \
+	platform")
+$(eval $(call add_define,PLAT_XLAT_TABLES_DYNAMIC))
+$(eval $(call add_define,OPTEE_ALLOW_SMC_LOAD))
+endif
diff --git a/services/spd/opteed/opteed_main.c b/services/spd/opteed/opteed_main.c
index 160a693..ff09e7e 100644
--- a/services/spd/opteed/opteed_main.c
+++ b/services/spd/opteed/opteed_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,6 +16,7 @@
  ******************************************************************************/
 #include <assert.h>
 #include <errno.h>
+#include <inttypes.h>
 #include <stddef.h>
 
 #include <arch_helpers.h>
@@ -24,12 +25,13 @@
 #include <common/debug.h>
 #include <common/runtime_svc.h>
 #include <lib/el3_runtime/context_mgmt.h>
+#include <lib/optee_utils.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
 #include <tools_share/uuid.h>
 
 #include "opteed_private.h"
 #include "teesmc_opteed.h"
-#include "teesmc_opteed_macros.h"
 
 /*******************************************************************************
  * Address of the entrypoint vector table in OPTEE. It is
@@ -43,7 +45,16 @@
 optee_context_t opteed_sp_context[OPTEED_CORE_COUNT];
 uint32_t opteed_rw;
 
+#if OPTEE_ALLOW_SMC_LOAD
+static bool opteed_allow_load;
+#else
 static int32_t opteed_init(void);
+#endif
+
+uint64_t dual32to64(uint32_t high, uint32_t low)
+{
+	return ((uint64_t)high << 32) | low;
+}
 
 /*******************************************************************************
  * This function is the handler registered for S-EL1 interrupts by the
@@ -93,6 +104,11 @@
  ******************************************************************************/
 static int32_t opteed_setup(void)
 {
+#if OPTEE_ALLOW_SMC_LOAD
+	opteed_allow_load = true;
+	INFO("Delaying OP-TEE setup until we receive an SMC call to load it\n");
+	return 0;
+#else
 	entry_point_info_t *optee_ep_info;
 	uint32_t linear_id;
 	uint64_t opteed_pageable_part;
@@ -142,6 +158,7 @@
 	bl31_register_bl32_init(&opteed_init);
 
 	return 0;
+#endif  /* OPTEE_ALLOW_SMC_LOAD */
 }
 
 /*******************************************************************************
@@ -151,20 +168,15 @@
  * used.  It also assumes that a valid non-secure context has been
  * initialised by PSCI so it does not need to save and restore any
  * non-secure state. This function performs a synchronous entry into
- * OPTEE. OPTEE passes control back to this routine through a SMC.
+ * OPTEE. OPTEE passes control back to this routine through a SMC. This returns
+ * a non-zero value on success and zero on failure.
  ******************************************************************************/
-static int32_t opteed_init(void)
+static int32_t
+opteed_init_with_entry_point(entry_point_info_t *optee_entry_point)
 {
 	uint32_t linear_id = plat_my_core_pos();
 	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
-	entry_point_info_t *optee_entry_point;
 	uint64_t rc;
-
-	/*
-	 * Get information about the OPTEE (BL32) image. Its
-	 * absence is a critical failure.
-	 */
-	optee_entry_point = bl31_plat_get_next_image_ep_info(SECURE);
 	assert(optee_entry_point);
 
 	cm_init_my_context(optee_entry_point);
@@ -179,6 +191,121 @@
 	return rc;
 }
 
+#if !OPTEE_ALLOW_SMC_LOAD
+static int32_t opteed_init(void)
+{
+	entry_point_info_t *optee_entry_point;
+	/*
+	 * Get information about the OP-TEE (BL32) image. Its
+	 * absence is a critical failure.
+	 */
+	optee_entry_point = bl31_plat_get_next_image_ep_info(SECURE);
+	return opteed_init_with_entry_point(optee_entry_point);
+}
+#endif  /* !OPTEE_ALLOW_SMC_LOAD */
+
+#if OPTEE_ALLOW_SMC_LOAD
+/*******************************************************************************
+ * 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
+ * address of the payload as parameters.
+ ******************************************************************************/
+static int32_t opteed_handle_smc_load(uint64_t data_size, uint32_t data_pa)
+{
+	uintptr_t data_va = data_pa;
+	uint64_t mapped_data_pa;
+	uintptr_t mapped_data_va;
+	uint64_t data_map_size;
+	int32_t rc;
+	optee_header_t *image_header;
+	uint8_t *image_ptr;
+	uint64_t target_pa;
+	uint64_t target_end_pa;
+	uint64_t image_pa;
+	uintptr_t image_va;
+	optee_image_t *curr_image;
+	uintptr_t target_va;
+	uint64_t target_size;
+	entry_point_info_t optee_ep_info;
+	uint32_t linear_id = plat_my_core_pos();
+
+	mapped_data_pa = page_align(data_pa, DOWN);
+	mapped_data_va = mapped_data_pa;
+	data_map_size = page_align(data_size + (mapped_data_pa - data_pa), UP);
+
+	/*
+	 * We do not validate the passed in address because we are trusting the
+	 * non-secure world at this point still.
+	 */
+	rc = mmap_add_dynamic_region(mapped_data_pa, mapped_data_va,
+				     data_map_size, MT_MEMORY | MT_RO | MT_NS);
+	if (rc != 0) {
+		return rc;
+	}
+
+	image_header = (optee_header_t *)data_va;
+	if (image_header->magic != TEE_MAGIC_NUM_OPTEE ||
+	    image_header->version != 2 || image_header->nb_images != 1) {
+		mmap_remove_dynamic_region(mapped_data_va, data_map_size);
+		return -EINVAL;
+	}
+
+	image_ptr = (uint8_t *)data_va + sizeof(optee_header_t) +
+			sizeof(optee_image_t);
+	if (image_header->arch == 1) {
+		opteed_rw = OPTEE_AARCH64;
+	} else {
+		opteed_rw = OPTEE_AARCH32;
+	}
+
+	curr_image = &image_header->optee_image_list[0];
+	image_pa = dual32to64(curr_image->load_addr_hi,
+			      curr_image->load_addr_lo);
+	image_va = image_pa;
+	target_end_pa = image_pa + curr_image->size;
+
+	/* Now also map the memory we want to copy it to. */
+	target_pa = page_align(image_pa, DOWN);
+	target_va = target_pa;
+	target_size = page_align(target_end_pa, UP) - target_pa;
+
+	rc = mmap_add_dynamic_region(target_pa, target_va, target_size,
+				     MT_MEMORY | MT_RW | MT_SECURE);
+	if (rc != 0) {
+		mmap_remove_dynamic_region(mapped_data_va, data_map_size);
+		return rc;
+	}
+
+	INFO("Loaded OP-TEE via SMC: size %d addr 0x%" PRIx64 "\n",
+	     curr_image->size, image_va);
+
+	memcpy((void *)image_va, image_ptr, curr_image->size);
+	flush_dcache_range(target_pa, target_size);
+
+	mmap_remove_dynamic_region(mapped_data_va, data_map_size);
+	mmap_remove_dynamic_region(target_va, target_size);
+
+	/* Save the non-secure state */
+	cm_el1_sysregs_context_save(NON_SECURE);
+
+	opteed_init_optee_ep_state(&optee_ep_info,
+				   opteed_rw,
+				   image_pa,
+				   0,
+				   0,
+				   0,
+				   &opteed_sp_context[linear_id]);
+	if (opteed_init_with_entry_point(&optee_ep_info) == 0) {
+		rc = -EFAULT;
+	}
+
+	/* Restore non-secure state */
+	cm_el1_sysregs_context_restore(NON_SECURE);
+	cm_set_next_eret_context(NON_SECURE);
+
+	return rc;
+}
+#endif  /* OPTEE_ALLOW_SMC_LOAD */
 
 /*******************************************************************************
  * This function is responsible for handling all SMCs in the Trusted OS/App
@@ -207,6 +334,34 @@
 	 */
 
 	if (is_caller_non_secure(flags)) {
+#if OPTEE_ALLOW_SMC_LOAD
+		if (smc_fid == NSSMC_OPTEED_CALL_LOAD_IMAGE) {
+			/*
+			 * TODO: Consider wiping the code for SMC loading from
+			 * memory after it has been invoked similar to what is
+			 * done under RECLAIM_INIT, but extended to happen
+			 * later.
+			 */
+			if (!opteed_allow_load) {
+				SMC_RET1(handle, -EPERM);
+			}
+
+			opteed_allow_load = false;
+			uint64_t data_size = dual32to64(x1, x2);
+			uint64_t data_pa = dual32to64(x3, x4);
+			if (!data_size || !data_pa) {
+				/*
+				 * This is invoked when the OP-TEE image didn't
+				 * load correctly in the kernel but we want to
+				 * block off loading of it later for security
+				 * reasons.
+				 */
+				SMC_RET1(handle, -EINVAL);
+			}
+			SMC_RET1(handle, opteed_handle_smc_load(
+					data_size, data_pa));
+		}
+#endif  /* OPTEE_ALLOW_SMC_LOAD */
 		/*
 		 * This is a fresh request from the non-secure client.
 		 * The parameters are in x1 and x2. Figure out which
@@ -219,8 +374,18 @@
 
 		/*
 		 * We are done stashing the non-secure context. Ask the
-		 * OPTEE to do the work now.
+		 * OP-TEE to do the work now. If we are loading vi an SMC,
+		 * then we also need to init this CPU context if not done
+		 * already.
 		 */
+		if (optee_vector_table == NULL) {
+			SMC_RET1(handle, -EINVAL);
+		}
+
+		if (get_optee_pstate(optee_ctx->state) ==
+		    OPTEE_PSTATE_UNKNOWN) {
+			opteed_cpu_on_finish_handler(0);
+		}
 
 		/*
 		 * Verify if there is a valid context to use, copy the
diff --git a/services/spd/opteed/opteed_pm.c b/services/spd/opteed/opteed_pm.c
index 719eeb7..fa724a1 100644
--- a/services/spd/opteed/opteed_pm.c
+++ b/services/spd/opteed/opteed_pm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -32,6 +32,10 @@
 	uint32_t linear_id = plat_my_core_pos();
 	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
 
+	if (get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_UNKNOWN) {
+		return 0;
+	}
+
 	assert(optee_vector_table);
 	assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_ON);
 
@@ -65,6 +69,10 @@
 	uint32_t linear_id = plat_my_core_pos();
 	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
 
+	if (get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_UNKNOWN) {
+		return;
+	}
+
 	assert(optee_vector_table);
 	assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_ON);
 
@@ -92,7 +100,7 @@
  * after initialising minimal architectural state that guarantees safe
  * execution.
  ******************************************************************************/
-static void opteed_cpu_on_finish_handler(u_register_t unused)
+void opteed_cpu_on_finish_handler(u_register_t unused)
 {
 	int32_t rc = 0;
 	uint32_t linear_id = plat_my_core_pos();
@@ -100,7 +108,8 @@
 	entry_point_info_t optee_on_entrypoint;
 
 	assert(optee_vector_table);
-	assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_OFF);
+	assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_OFF ||
+	       get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_UNKNOWN);
 
 	opteed_init_optee_ep_state(&optee_on_entrypoint, opteed_rw,
 				(uint64_t)&optee_vector_table->cpu_on_entry,
@@ -134,6 +143,10 @@
 	uint32_t linear_id = plat_my_core_pos();
 	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
 
+	if (get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_UNKNOWN) {
+		return;
+	}
+
 	assert(optee_vector_table);
 	assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_SUSPEND);
 
@@ -173,6 +186,14 @@
 	uint32_t linear_id = plat_my_core_pos();
 	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
 
+	/*
+	 * OP-TEE must have been initialized in order to reach this location so
+	 * it is safe to init the CPU context if not already done for this core.
+	 */
+	if (get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_UNKNOWN) {
+		opteed_cpu_on_finish_handler(0);
+	}
+
 	assert(optee_vector_table);
 	assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_ON);
 
@@ -193,6 +214,14 @@
 	uint32_t linear_id = plat_my_core_pos();
 	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
 
+	/*
+	 * OP-TEE must have been initialized in order to reach this location so
+	 * it is safe to init the CPU context if not already done for this core.
+	 */
+	if (get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_UNKNOWN) {
+		opteed_cpu_on_finish_handler(0);
+	}
+
 	assert(optee_vector_table);
 	assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_ON);
 
diff --git a/services/spd/opteed/opteed_private.h b/services/spd/opteed/opteed_private.h
index 242154f..c8fbc22 100644
--- a/services/spd/opteed/opteed_private.h
+++ b/services/spd/opteed/opteed_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,9 +18,10 @@
  * OPTEE PM state information e.g. OPTEE is suspended, uninitialised etc
  * and macros to access the state information in the per-cpu 'state' flags
  ******************************************************************************/
-#define OPTEE_PSTATE_OFF		0
-#define OPTEE_PSTATE_ON			1
-#define OPTEE_PSTATE_SUSPEND		2
+#define OPTEE_PSTATE_OFF		1
+#define OPTEE_PSTATE_ON			2
+#define OPTEE_PSTATE_SUSPEND		3
+#define OPTEE_PSTATE_UNKNOWN		0
 #define OPTEE_PSTATE_SHIFT		0
 #define OPTEE_PSTATE_MASK		0x3
 #define get_optee_pstate(state)	((state >> OPTEE_PSTATE_SHIFT) & \
@@ -113,7 +114,7 @@
  * have the same double word aligned view of the size of the C runtime
  * register context.
  */
-CASSERT(OPTEED_C_RT_CTX_SIZE == sizeof(c_rt_regs_t),	\
+CASSERT(OPTEED_C_RT_CTX_SIZE == sizeof(c_rt_regs_t),
 	assert_spd_c_rt_regs_size_mismatch);
 
 /*******************************************************************************
@@ -153,6 +154,7 @@
 				uint64_t mem_limit,
 				uint64_t dt_addr,
 				optee_context_t *optee_ctx);
+void opteed_cpu_on_finish_handler(u_register_t unused);
 
 extern optee_context_t opteed_sp_context[OPTEED_CORE_COUNT];
 extern uint32_t opteed_rw;
diff --git a/services/spd/opteed/teesmc_opteed.h b/services/spd/opteed/teesmc_opteed.h
index c82b58a..eae3ed2 100644
--- a/services/spd/opteed/teesmc_opteed.h
+++ b/services/spd/opteed/teesmc_opteed.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,8 +9,10 @@
 #ifndef TEESMC_OPTEED_H
 #define TEESMC_OPTEED_H
 
+#include "teesmc_opteed_macros.h"
+
 /*
- * This file specifies SMC function IDs used when returning from TEE to the
+ * This section specifies SMC function IDs used when returning from TEE to the
  * secure monitor.
  *
  * All SMC Function IDs indicates SMC32 Calling Convention but will carry
@@ -120,4 +122,39 @@
 #define TEESMC_OPTEED_RETURN_SYSTEM_RESET_DONE \
 	TEESMC_OPTEED_RV(TEESMC_OPTEED_FUNCID_RETURN_SYSTEM_RESET_DONE)
 
+/*
+ * This section specifies SMC function IDs used when the secure monitor is
+ * invoked from the non-secure world.
+ */
+
+/*
+ * Load OP-TEE image from the payload specified in the registers.
+ *
+ * WARNING: Use this cautiously as it could lead to insecure loading of the
+ * Trusted OS. Further details are in opteed.mk.
+ *
+ * Call register usage:
+ * x0 SMC Function ID, OPTEE_SMC_CALL_LOAD_IMAGE
+ * x1 Upper 32bit of a 64bit size for the payload
+ * x2 Lower 32bit of a 64bit size for the payload
+ * x3 Upper 32bit of the physical address for the payload
+ * x4 Lower 32bit of the physical address for the payload
+ *
+ * The payload consists of a optee_header struct that contains optee_image
+ * structs in a flex array, immediately following that in memory is the data
+ * referenced by the optee_image structs.
+ * Example:
+ *
+ * struct optee_header (with n images specified)
+ * image 0 data
+ * image 1 data
+ * ...
+ * image n-1 data
+ *
+ * Returns 0 on success and an error code otherwise.
+ */
+#define NSSMC_OPTEED_FUNCID_LOAD_IMAGE 2
+#define NSSMC_OPTEED_CALL_LOAD_IMAGE \
+	NSSMC_OPTEED_CALL(NSSMC_OPTEED_FUNCID_LOAD_IMAGE)
+
 #endif /*TEESMC_OPTEED_H*/
diff --git a/services/spd/opteed/teesmc_opteed_macros.h b/services/spd/opteed/teesmc_opteed_macros.h
index 9d8a169..ad3ed75 100644
--- a/services/spd/opteed/teesmc_opteed_macros.h
+++ b/services/spd/opteed/teesmc_opteed_macros.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 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,4 +14,10 @@
 		 (62 << FUNCID_OEN_SHIFT) | \
 		 ((func_num) & FUNCID_NUM_MASK))
 
+#define NSSMC_OPTEED_CALL(func_num) \
+		((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) | \
+		((SMC_32) << FUNCID_CC_SHIFT) | \
+		(50 << FUNCID_OEN_SHIFT) | \
+		((func_num) & FUNCID_NUM_MASK))
+
 #endif /* TEESMC_OPTEED_MACROS_H */
diff --git a/services/spd/tlkd/tlkd_private.h b/services/spd/tlkd/tlkd_private.h
index 5d5d0e8..ad36f5e 100644
--- a/services/spd/tlkd/tlkd_private.h
+++ b/services/spd/tlkd/tlkd_private.h
@@ -85,7 +85,7 @@
  * have the same double word aligned view of the size of the C runtime
  * register context.
  */
-CASSERT(TLKD_C_RT_CTX_SIZE == sizeof(c_rt_regs_t),	\
+CASSERT(TLKD_C_RT_CTX_SIZE == sizeof(c_rt_regs_t),
 	assert_tlkd_c_rt_regs_size_mismatch);
 
 /*******************************************************************************
diff --git a/services/spd/tspd/tspd_private.h b/services/spd/tspd/tspd_private.h
index d6c03c9..043644a 100644
--- a/services/spd/tspd/tspd_private.h
+++ b/services/spd/tspd/tspd_private.h
@@ -146,7 +146,7 @@
  * have the same double word aligned view of the size of the C runtime
  * register context.
  */
-CASSERT(TSPD_C_RT_CTX_SIZE == sizeof(c_rt_regs_t),	\
+CASSERT(TSPD_C_RT_CTX_SIZE == sizeof(c_rt_regs_t),
 	assert_spd_c_rt_regs_size_mismatch);
 
 /* SEL1 Secure payload (SP) caller saved register context structure. */
@@ -157,7 +157,7 @@
  * have the same double word aligned view of the size of the C runtime
  * register context.
  */
-CASSERT(TSPD_SP_CTX_SIZE == sizeof(sp_ctx_regs_t),	\
+CASSERT(TSPD_SP_CTX_SIZE == sizeof(sp_ctx_regs_t),
 	assert_spd_sp_regs_size_mismatch);
 
 /*******************************************************************************
diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c
index 6bd9fdf..24f6c41 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
  */
@@ -117,19 +117,14 @@
  ******************************************************************************/
 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);
+	}
 }
 
 /*******************************************************************************
@@ -171,7 +166,7 @@
 	uint32_t ep_attr;
 	unsigned int linear_id = plat_my_core_pos();
 	rmmd_rmm_context_t *rmm_ctx = &rmm_context[linear_id];
-	rmm_manifest_t *manifest;
+	struct rmm_manifest *manifest;
 	int rc;
 
 	/* Make sure RME is supported. */
@@ -206,7 +201,7 @@
 					((void *)shared_buf_base != NULL));
 
 	/* Load the boot manifest at the beginning of the shared area */
-	manifest = (rmm_manifest_t *)shared_buf_base;
+	manifest = (struct rmm_manifest *)shared_buf_base;
 	rc = plat_rmmd_load_manifest(manifest);
 	if (rc != 0) {
 		ERROR("Error loading RMM Boot Manifest (%i)\n", rc);
diff --git a/services/std_svc/rmmd/trp/linker.lds b/services/std_svc/rmmd/trp/linker.ld.S
similarity index 89%
rename from services/std_svc/rmmd/trp/linker.lds
rename to services/std_svc/rmmd/trp/linker.ld.S
index 2b7f383..9895cf9 100644
--- a/services/std_svc/rmmd/trp/linker.lds
+++ b/services/std_svc/rmmd/trp/linker.ld.S
@@ -1,6 +1,7 @@
 /*
- * (C) COPYRIGHT 2021 Arm Limited or its affiliates.
- * ALL RIGHTS RESERVED
+ * Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <common/bl_common.ld.h>
diff --git a/services/std_svc/rmmd/trp/trp.mk b/services/std_svc/rmmd/trp/trp.mk
index 44bbf22..e511bf5 100644
--- a/services/std_svc/rmmd/trp/trp.mk
+++ b/services/std_svc/rmmd/trp/trp.mk
@@ -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
 #
@@ -8,7 +8,7 @@
 				services/std_svc/rmmd/trp/trp_main.c  \
 				services/std_svc/rmmd/trp/trp_helpers.c
 
-RMM_LINKERFILE		:=	services/std_svc/rmmd/trp/linker.lds
+RMM_DEFAULT_LINKER_SCRIPT_SOURCE := services/std_svc/rmmd/trp/linker.ld.S
 
 # Include the platform-specific TRP Makefile
 # If no platform-specific TRP Makefile exists, it means TRP is not supported
diff --git a/services/std_svc/rmmd/trp/trp_main.c b/services/std_svc/rmmd/trp/trp_main.c
index 196bc11..4eb3e12 100644
--- a/services/std_svc/rmmd/trp/trp_main.c
+++ b/services/std_svc/rmmd/trp/trp_main.c
@@ -62,7 +62,7 @@
 			   sizeof(trp_shared_region_start));
 
 	/* Perform early platform-specific setup */
-	trp_early_platform_setup((rmm_manifest_t *)trp_shared_region_start);
+	trp_early_platform_setup((struct rmm_manifest *)trp_shared_region_start);
 }
 
 int trp_validate_warmboot_args(uint64_t x0, uint64_t x1,
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/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_xlat.c b/services/std_svc/spm/spm_mm/spm_mm_xlat.c
index 6261016..b1ca55a 100644
--- a/services/std_svc/spm/spm_mm/spm_mm_xlat.c
+++ b/services/std_svc/spm/spm_mm/spm_mm_xlat.c
@@ -19,7 +19,7 @@
 
 /* Place translation tables by default along with the ones used by BL31. */
 #ifndef PLAT_SP_IMAGE_XLAT_SECTION_NAME
-#define PLAT_SP_IMAGE_XLAT_SECTION_NAME	"xlat_table"
+#define PLAT_SP_IMAGE_XLAT_SECTION_NAME	".xlat_table"
 #endif
 #ifndef PLAT_SP_IMAGE_BASE_XLAT_SECTION_NAME
 #define PLAT_SP_IMAGE_BASE_XLAT_SECTION_NAME	".bss"
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 afd0f2e..0e1899e 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,10 +16,14 @@
 #include <bl31/interrupt_mgmt.h>
 #include <common/debug.h>
 #include <common/runtime_svc.h>
+#include <common/tbbr/tbbr_img_def.h>
 #include <lib/el3_runtime/context_mgmt.h>
+#include <lib/fconf/fconf.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
 #include <lib/smccc.h>
 #include <lib/spinlock.h>
 #include <lib/utils.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/common_def.h>
 #include <plat/common/platform.h>
 #include <platform_def.h>
@@ -245,6 +249,92 @@
 	SMC_RET0(&ctx->cpu_ctx);
 }
 
+#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,
+				 size_t *align_size)
+{
+	uintptr_t base_addr_align;
+	size_t mapped_size_align;
+	int rc;
+
+	/* Page aligned address and size if necessary */
+	base_addr_align = page_align(base_addr, DOWN);
+	mapped_size_align = page_align(size, UP);
+
+	if ((base_addr != base_addr_align) &&
+	    (size == mapped_size_align)) {
+		mapped_size_align += PAGE_SIZE;
+	}
+
+	/*
+	 * Map dynamically given region with its aligned base address and
+	 * size
+	 */
+	rc = mmap_add_dynamic_region((unsigned long long)base_addr_align,
+				     base_addr_align,
+				     mapped_size_align,
+				     attr);
+	if (rc == 0) {
+		*align_addr = base_addr_align;
+		*align_size = mapped_size_align;
+	}
+
+	return rc;
+}
+
+static void spmd_do_sec_cpy(uintptr_t root_base_addr, uintptr_t sec_base_addr,
+			    size_t size)
+{
+	uintptr_t root_base_addr_align, sec_base_addr_align;
+	size_t root_mapped_size_align, sec_mapped_size_align;
+	int rc;
+
+	assert(root_base_addr != 0UL);
+	assert(sec_base_addr != 0UL);
+	assert(size != 0UL);
+
+	/* Map the memory with required attributes */
+	rc = spmd_dynamic_map_mem(root_base_addr, size, MT_RO_DATA | MT_ROOT,
+				  &root_base_addr_align,
+				  &root_mapped_size_align);
+	if (rc != 0) {
+		ERROR("%s %s %lu (%d)\n", "Error while mapping", "root region",
+		      root_base_addr, rc);
+		panic();
+	}
+
+	rc = spmd_dynamic_map_mem(sec_base_addr, size, MT_RW_DATA | MT_SECURE,
+				  &sec_base_addr_align, &sec_mapped_size_align);
+	if (rc != 0) {
+		ERROR("%s %s %lu (%d)\n", "Error while mapping",
+		      "secure region", sec_base_addr, rc);
+		panic();
+	}
+
+	/* Do copy operation */
+	(void)memcpy((void *)sec_base_addr, (void *)root_base_addr, size);
+
+	/* Unmap root memory region */
+	rc = mmap_remove_dynamic_region(root_base_addr_align,
+					root_mapped_size_align);
+	if (rc != 0) {
+		ERROR("%s %s %lu (%d)\n", "Error while unmapping",
+		      "root region", root_base_addr_align, rc);
+		panic();
+	}
+
+	/* Unmap secure memory region */
+	rc = mmap_remove_dynamic_region(sec_base_addr_align,
+					sec_mapped_size_align);
+	if (rc != 0) {
+		ERROR("%s %s %lu (%d)\n", "Error while unmapping",
+		      "secure region", sec_base_addr_align, rc);
+		panic();
+	}
+}
+#endif /* ENABLE_RME && SPMD_SPM_AT_SEL2 && !RESET_TO_BL31 */
+
 /*******************************************************************************
  * Loads SPMC manifest and inits SPMC.
  ******************************************************************************/
@@ -254,6 +344,7 @@
 	unsigned int core_id;
 	uint32_t ep_attr, flags;
 	int rc;
+	const struct dyn_cfg_dtb_info_t *image_info __unused;
 
 	/* Load the SPM Core manifest */
 	rc = plat_spm_core_manifest_load(&spmc_attrs, pm_addr);
@@ -308,7 +399,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;
 	}
@@ -344,6 +435,26 @@
 					     DISABLE_ALL_EXCEPTIONS);
 	}
 
+#if ENABLE_RME && SPMD_SPM_AT_SEL2 && !RESET_TO_BL31
+	image_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TOS_FW_CONFIG_ID);
+	assert(image_info != NULL);
+
+	if ((image_info->config_addr == 0UL) ||
+	    (image_info->secondary_config_addr == 0UL) ||
+	    (image_info->config_max_size == 0UL)) {
+		return -EINVAL;
+	}
+
+	/* Copy manifest from root->secure region */
+	spmd_do_sec_cpy(image_info->config_addr,
+			image_info->secondary_config_addr,
+			image_info->config_max_size);
+
+	/* Update ep info of BL32 */
+	assert(spmc_ep_info != NULL);
+	spmc_ep_info->args.arg0 = image_info->secondary_config_addr;
+#endif /* ENABLE_RME && SPMD_SPM_AT_SEL2 && !RESET_TO_BL31 */
+
 	/* Set an initial SPMC context state for all cores. */
 	for (core_id = 0U; core_id < PLATFORM_CORE_COUNT; core_id++) {
 		spm_core_context[core_id].state = SPMC_STATE_OFF;
@@ -402,15 +513,15 @@
 
 		rc = spmc_setup();
 		if (rc != 0) {
-			ERROR("SPMC initialisation failed 0x%x.\n", rc);
+			WARN("SPMC initialisation failed 0x%x.\n", rc);
 		}
-		return rc;
+		return 0;
 	}
 
 	spmc_ep_info = bl31_plat_get_next_image_ep_info(SECURE);
 	if (spmc_ep_info == NULL) {
 		WARN("No SPM Core image provided by BL2 boot loader.\n");
-		return -EINVAL;
+		return 0;
 	}
 
 	/* Under no circumstances will this parameter be 0 */
@@ -422,8 +533,8 @@
 	 */
 	spmc_manifest = (void *)spmc_ep_info->args.arg0;
 	if (spmc_manifest == NULL) {
-		ERROR("Invalid or absent SPM Core manifest.\n");
-		return -EINVAL;
+		WARN("Invalid or absent SPM Core manifest.\n");
+		return 0;
 	}
 
 	/* Load manifest, init SPMC */
@@ -432,7 +543,7 @@
 		WARN("Booting device without SPM initialization.\n");
 	}
 
-	return rc;
+	return 0;
 }
 
 /*******************************************************************************
@@ -470,10 +581,40 @@
 #endif
 	cm_set_next_eret_context(secure_state_out);
 
+#if SPMD_SPM_AT_SEL2
+	/*
+	 * If SPMC is at SEL2, save additional registers x8-x17, which may
+	 * be used in FF-A calls such as FFA_PARTITION_INFO_GET_REGS.
+	 * Note that technically, all SPMCs can support this, but this code is
+	 * under ifdef to minimize breakage in case other SPMCs do not save
+	 * and restore x8-x17.
+	 * We also need to pass through these registers since not all FF-A ABIs
+	 * modify x8-x17, in which case, SMCCC requires that these registers be
+	 * preserved, so the SPMD passes through these registers and expects the
+	 * SPMC to save and restore (potentially also modify) them.
+	 */
+	SMC_RET18(cm_get_context(secure_state_out), smc_fid, x1, x2, x3, x4,
+			SMC_GET_GP(handle, CTX_GPREG_X5),
+			SMC_GET_GP(handle, CTX_GPREG_X6),
+			SMC_GET_GP(handle, CTX_GPREG_X7),
+			SMC_GET_GP(handle, CTX_GPREG_X8),
+			SMC_GET_GP(handle, CTX_GPREG_X9),
+			SMC_GET_GP(handle, CTX_GPREG_X10),
+			SMC_GET_GP(handle, CTX_GPREG_X11),
+			SMC_GET_GP(handle, CTX_GPREG_X12),
+			SMC_GET_GP(handle, CTX_GPREG_X13),
+			SMC_GET_GP(handle, CTX_GPREG_X14),
+			SMC_GET_GP(handle, CTX_GPREG_X15),
+			SMC_GET_GP(handle, CTX_GPREG_X16),
+			SMC_GET_GP(handle, CTX_GPREG_X17)
+			);
+
+#else
 	SMC_RET8(cm_get_context(secure_state_out), smc_fid, x1, x2, x3, x4,
 			SMC_GET_GP(handle, CTX_GPREG_X5),
 			SMC_GET_GP(handle, CTX_GPREG_X6),
 			SMC_GET_GP(handle, CTX_GPREG_X7));
+#endif
 }
 
 /*******************************************************************************
@@ -931,7 +1072,23 @@
 			return spmd_ffa_error_return(handle, FFA_ERROR_DENIED);
 		}
 		break; /* Not reached */
+#if MAKE_FFA_VERSION(1, 1) <= FFA_VERSION_COMPILED
+	case FFA_PARTITION_INFO_GET_REGS_SMC64:
+		if (secure_origin) {
+			/* TODO: Future patches to enable support for this */
+			return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
+		}
+
+		/* Call only supported with SMCCC 1.2+ */
+		if (MAKE_SMCCC_VERSION(SMCCC_MAJOR_VERSION, SMCCC_MINOR_VERSION) < 0x10002) {
+			return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
+		}
 
+		return spmd_smc_forward(smc_fid, secure_origin,
+					x1, x2, x3, x4, cookie,
+					handle, flags);
+		break; /* Not reached */
+#endif
 	default:
 		WARN("SPM: Unsupported call 0x%08x\n", smc_fid);
 		return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
diff --git a/tools/cert_create/src/key.c b/tools/cert_create/src/key.c
index 487777b..27ec979 100644
--- a/tools/cert_create/src/key.c
+++ b/tools/cert_create/src/key.c
@@ -212,7 +212,7 @@
 			*err_code = KEY_ERR_OPEN;
 		}
 	} else {
-		WARN("Key filename not specified\n");
+		VERBOSE("Key filename not specified\n");
 		*err_code = KEY_ERR_FILENAME;
 	}
 
diff --git a/tools/marvell/doimage/doimage.c b/tools/marvell/doimage/doimage.c
index e08b820..513f33f 100644
--- a/tools/marvell/doimage/doimage.c
+++ b/tools/marvell/doimage/doimage.c
@@ -17,12 +17,6 @@
 #ifdef CONFIG_MVEBU_SECURE_BOOT
 #include <libconfig.h>	/* for parsing config file */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
 /* mbedTLS stuff */
 #if defined(MBEDTLS_BIGNUM_C) && defined(MBEDTLS_ENTROPY_C) && \
 	defined(MBEDTLS_SHA256_C) && \
@@ -34,6 +28,7 @@
 #include <mbedtls/md.h>
 #include <mbedtls/pk.h>
 #include <mbedtls/sha256.h>
+#include <mbedtls/version.h>
 #include <mbedtls/x509.h>
 #else
 #error "Bad mbedTLS configuration!"