Merge "feat(rmmd): enable SME for RMM" into integration
diff --git a/Makefile b/Makefile
index faef728..8e8fba9 100644
--- a/Makefile
+++ b/Makefile
@@ -151,69 +151,6 @@
 DOCS_PATH		?=	docs
 
 ################################################################################
-# Process BRANCH_PROTECTION value and set
-# Pointer Authentication and Branch Target Identification flags
-################################################################################
-ifeq (${BRANCH_PROTECTION},0)
-	# Default value turns off all types of branch protection
-	BP_OPTION := none
-else ifneq (${ARCH},aarch64)
-        $(error BRANCH_PROTECTION requires AArch64)
-else ifeq (${BRANCH_PROTECTION},1)
-	# Enables all types of branch protection features
-	BP_OPTION := standard
-	ENABLE_BTI := 1
-	ENABLE_PAUTH := 1
-else ifeq (${BRANCH_PROTECTION},2)
-	# Return address signing to its standard level
-	BP_OPTION := pac-ret
-	ENABLE_PAUTH := 1
-else ifeq (${BRANCH_PROTECTION},3)
-	# Extend the signing to include leaf functions
-	BP_OPTION := pac-ret+leaf
-	ENABLE_PAUTH := 1
-else ifeq (${BRANCH_PROTECTION},4)
-	# Turn on branch target identification mechanism
-	BP_OPTION := bti
-	ENABLE_BTI := 1
-else
-        $(error Unknown BRANCH_PROTECTION value ${BRANCH_PROTECTION})
-endif #(BRANCH_PROTECTION)
-
-################################################################################
-# RME dependent flags configuration
-################################################################################
-# FEAT_RME
-ifeq (${ENABLE_RME},1)
-	# RME doesn't support PIE
-	ifneq (${ENABLE_PIE},0)
-                $(error ENABLE_RME does not support PIE)
-	endif
-
-	# RME doesn't support BRBE
-	ifneq (${ENABLE_BRBE_FOR_NS},0)
-                $(error ENABLE_RME does not support BRBE.)
-	endif
-
-	# RME requires AARCH64
-	ifneq (${ARCH},aarch64)
-                $(error ENABLE_RME requires AArch64)
-	endif
-
-	# RME requires el2 context to be saved for now.
-	CTX_INCLUDE_EL2_REGS := 1
-	CTX_INCLUDE_AARCH32_REGS := 0
-	ARM_ARCH_MAJOR := 8
-	ARM_ARCH_MINOR := 5
-	ENABLE_FEAT_ECV = 1
-	ENABLE_FEAT_FGT = 1
-	CTX_INCLUDE_PAUTH_REGS := 1
-
-	# RME enables CSV2_2 extension by default.
-	ENABLE_FEAT_CSV2_2 = 1
-endif #(FEAT_RME)
-
-################################################################################
 # Compiler Configuration based on ARCH_MAJOR and ARCH_MINOR flags
 ################################################################################
 ifeq (${ARM_ARCH_MAJOR},7)
@@ -228,39 +165,6 @@
 ################################################################################
 arch-features		=	${ARM_ARCH_FEATURE}
 
-####################################################
-# Enable required options for Memory Stack Tagging.
-####################################################
-
-# Memory tagging is supported in architecture Armv8.5-A AArch64 and onwards
-ifeq ($(ARCH), aarch64)
-	# Check if revision is greater than or equal to 8.5
-	ifeq "8.5" "$(word 1, $(sort 8.5 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
-		mem_tag_arch_support	= 	yes
-	endif
-endif #(ARCH=aarch64)
-
-# Currently, these options are enabled only for clang and armclang compiler.
-ifeq (${SUPPORT_STACK_MEMTAG},yes)
-	ifdef mem_tag_arch_support
-		# Check for armclang and clang compilers
-		ifneq ( ,$(filter $(notdir $(CC)),armclang clang))
-		# Add "memtag" architecture feature modifier if not specified
-			ifeq ( ,$(findstring memtag,$(arch-features)))
-				arch-features	:=	$(arch-features)+memtag
-			endif	# memtag
-			ifeq ($(notdir $(CC)),armclang)
-				TF_CFLAGS	+=	-mmemtag-stack
-			else ifeq ($(notdir $(CC)),clang)
-				TF_CFLAGS	+=	-fsanitize=memtag
-			endif	# armclang
-		endif
-	else
-                $(error "Error: stack memory tagging is not supported for  \
-                 architecture ${ARCH},armv${ARM_ARCH_MAJOR}.${ARM_ARCH_MINOR}-a")
-	endif #(mem_tag_arch_support)
-endif #(SUPPORT_STACK_MEMTAG)
-
 # Set the compiler's architecture feature modifiers
 ifneq ($(arch-features), none)
 	# Strip "none+" from arch-features
@@ -334,10 +238,6 @@
 TF_CFLAGS_aarch32	+=	-mno-unaligned-access
 TF_CFLAGS_aarch64	+=	-mgeneral-regs-only -mstrict-align
 
-ifneq (${BP_OPTION},none)
-	TF_CFLAGS_aarch64	+=	-mbranch-protection=${BP_OPTION}
-endif #(BP_OPTION)
-
 ASFLAGS		+=	$(march-directive)
 
 ##############################################################################
@@ -501,6 +401,14 @@
 				-x assembler-with-cpp $(DEFINES)
 
 ################################################################################
+# Setup ARCH_MAJOR/MINOR before parsing arch_features.
+################################################################################
+ifeq (${ENABLE_RME},1)
+	ARM_ARCH_MAJOR := 8
+	ARM_ARCH_MINOR := 6
+endif
+
+################################################################################
 # Common sources and include directories
 ################################################################################
 include ${MAKE_HELPERS_DIRECTORY}arch_features.mk
@@ -519,13 +427,6 @@
 				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
@@ -544,6 +445,104 @@
 include common/backtrace/backtrace.mk
 
 ################################################################################
+# Process BRANCH_PROTECTION value and set
+# Pointer Authentication and Branch Target Identification flags
+################################################################################
+ifeq (${BRANCH_PROTECTION},0)
+	# Default value turns off all types of branch protection
+	BP_OPTION := none
+else ifneq (${ARCH},aarch64)
+        $(error BRANCH_PROTECTION requires AArch64)
+else ifeq (${BRANCH_PROTECTION},1)
+	# Enables all types of branch protection features
+	BP_OPTION := standard
+	ENABLE_BTI := 1
+	ENABLE_PAUTH := 1
+else ifeq (${BRANCH_PROTECTION},2)
+	# Return address signing to its standard level
+	BP_OPTION := pac-ret
+	ENABLE_PAUTH := 1
+else ifeq (${BRANCH_PROTECTION},3)
+	# Extend the signing to include leaf functions
+	BP_OPTION := pac-ret+leaf
+	ENABLE_PAUTH := 1
+else ifeq (${BRANCH_PROTECTION},4)
+	# Turn on branch target identification mechanism
+	BP_OPTION := bti
+	ENABLE_BTI := 1
+else
+        $(error Unknown BRANCH_PROTECTION value ${BRANCH_PROTECTION})
+endif #(BRANCH_PROTECTION)
+
+ifeq ($(ENABLE_PAUTH),1)
+	CTX_INCLUDE_PAUTH_REGS := 1
+endif
+ifneq (${BP_OPTION},none)
+	TF_CFLAGS_aarch64	+=	-mbranch-protection=${BP_OPTION}
+endif #(BP_OPTION)
+
+# 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
+
+####################################################
+# Enable required options for Memory Stack Tagging.
+####################################################
+
+# Currently, these options are enabled only for clang and armclang compiler.
+ifeq (${SUPPORT_STACK_MEMTAG},yes)
+    ifdef mem_tag_arch_support
+        # Check for armclang and clang compilers
+        ifneq ( ,$(filter $(notdir $(CC)),armclang clang))
+        # Add "memtag" architecture feature modifier if not specified
+            ifeq ( ,$(findstring memtag,$(arch-features)))
+                arch-features	:=	$(arch-features)+memtag
+            endif	# memtag
+            ifeq ($(notdir $(CC)),armclang)
+                TF_CFLAGS	+=	-mmemtag-stack
+            else ifeq ($(notdir $(CC)),clang)
+                TF_CFLAGS	+=	-fsanitize=memtag
+            endif	# armclang
+        endif
+    else
+        $(error "Error: stack memory tagging is not supported for  \
+        architecture ${ARCH},armv${ARM_ARCH_MAJOR}.${ARM_ARCH_MINOR}-a")
+	endif #(mem_tag_arch_support)
+endif #(SUPPORT_STACK_MEMTAG)
+
+################################################################################
+# RME dependent flags configuration, Enable optional features for RME.
+################################################################################
+# FEAT_RME
+ifeq (${ENABLE_RME},1)
+	# RME doesn't support PIE
+	ifneq (${ENABLE_PIE},0)
+                $(error ENABLE_RME does not support PIE)
+	endif
+
+	# RME doesn't support BRBE
+	ifneq (${ENABLE_BRBE_FOR_NS},0)
+                $(error ENABLE_RME does not support BRBE.)
+	endif
+
+	# RME requires AARCH64
+	ifneq (${ARCH},aarch64)
+                $(error ENABLE_RME requires AArch64)
+	endif
+
+	# RME requires el2 context to be saved for now.
+	CTX_INCLUDE_EL2_REGS := 1
+	CTX_INCLUDE_AARCH32_REGS := 0
+	CTX_INCLUDE_PAUTH_REGS := 1
+
+	# RME enables CSV2_2 extension by default.
+	ENABLE_FEAT_CSV2_2 = 1
+endif #(FEAT_RME)
+
+################################################################################
 # Generic definitions
 ################################################################################
 include ${MAKE_HELPERS_DIRECTORY}plat_helpers.mk
@@ -1021,6 +1020,10 @@
         $(info DRTM_SUPPORT is an experimental feature)
 endif
 
+ifeq (${TRANSFER_LIST},1)
+        $(info TRANSFER_LIST is an experimental feature)
+endif
+
 ifeq (${ENABLE_RME},1)
 	ifneq (${SEPARATE_CODE_AND_RODATA},1)
                 $(error `ENABLE_RME=1` requires `SEPARATE_CODE_AND_RODATA=1`)
@@ -1185,6 +1188,7 @@
 	SPMC_AT_EL3 \
 	SPMD_SPM_AT_SEL2 \
 	ENABLE_SPMD_LP \
+	TRANSFER_LIST \
 	TRUSTED_BOARD_BOOT \
 	USE_COHERENT_MEM \
 	USE_DEBUGFS \
@@ -1345,6 +1349,7 @@
 	SPM_MM \
 	SPMC_AT_EL3 \
 	SPMD_SPM_AT_SEL2 \
+	TRANSFER_LIST \
 	TRUSTED_BOARD_BOOT \
 	CRYPTO_SUPPORT \
 	TRNG_SUPPORT \
diff --git a/bl31/ehf.c b/bl31/ehf.c
index b328380..6f3d941 100644
--- a/bl31/ehf.c
+++ b/bl31/ehf.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
  */
@@ -458,7 +458,7 @@
 	int ret __unused;
 
 	/* Ensure EL3 interrupts are supported */
-	assert(plat_ic_has_interrupt_type(INTR_TYPE_EL3) != 0);
+	assert(plat_ic_has_interrupt_type(INTR_TYPE_EL3));
 
 	/*
 	 * Make sure that priority water mark has enough bits to represent the
diff --git a/bl31/interrupt_mgmt.c b/bl31/interrupt_mgmt.c
index b8cc3de..68c7f10 100644
--- a/bl31/interrupt_mgmt.c
+++ b/bl31/interrupt_mgmt.c
@@ -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
  */
@@ -47,9 +47,9 @@
  ******************************************************************************/
 static int32_t validate_interrupt_type(uint32_t type)
 {
-	if ((type == INTR_TYPE_S_EL1) || (type == INTR_TYPE_NS) ||
-	    (type == INTR_TYPE_EL3))
+	if (plat_ic_has_interrupt_type(type)) {
 		return 0;
+	}
 
 	return -EINVAL;
 }
diff --git a/changelog.yaml b/changelog.yaml
index cdbedbb..3f7979e 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -709,8 +709,11 @@
       - title: TRNG
         scope: trng
 
-      - title: ERRATA_ABI
-        scope: errata_abi
+      - title: ERRATA ABI
+        scope: errata-abi
+
+        deprecated:
+          - errata_abi
 
   - title: Libraries
 
@@ -784,6 +787,9 @@
       - title: Semihosting
         scope: semihosting
 
+      - title: Firmware Handoff
+        scope: handoff
+
   - title: Drivers
 
     subsections:
@@ -899,6 +905,9 @@
                   - title: GIC-600AE
                     scope: gic600ae
 
+              - title: GICv2
+                scope: gicv2
+
           - title: SMMU
             scope: smmu
 
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index 447d108..6042053 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -501,8 +501,8 @@
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :|M|: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
 :|G|: `abdellatif-elkhlifi`_
-:|M|: Vishnu Banavath <vishnu.banavath@arm.com>
-:|G|: `vishnu-banavath`_
+:|M|: Xueliang Zhong <xueliang.zhong@arm.com>
+:|G|: `xueliang-zhong-arm`_
 :|F|: plat/arm/board/corstone700
 :|F|: plat/arm/board/a5ds
 :|F|: plat/arm/board/corstone1000
@@ -1027,3 +1027,4 @@
 .. _hilamirandakuzi1: https://github.com/hilamirandakuzi1
 .. _rutigl: https://github.com/rutigl
 .. _avifishman: https://github.com/avifishman
+.. _xueliang-zhong-arm: https://github.com/xueliang-zhong-arm
diff --git a/docs/about/release-information.rst b/docs/about/release-information.rst
index 0768e1f..9b51dab 100644
--- a/docs/about/release-information.rst
+++ b/docs/about/release-information.rst
@@ -54,7 +54,7 @@
 +-----------------+---------------------------+------------------------------+
 | v2.9            | 4th week of May '23       | 2nd week of May '23          |
 +-----------------+---------------------------+------------------------------+
-| v3.0            | 2nd week of Nov '23       | 2nd week of Oct '23          |
+| v2.10           | 4th week of Nov '23       | 2nd week of Nov '23          |
 +-----------------+---------------------------+------------------------------+
 
 Removal of Deprecated Interfaces
@@ -84,9 +84,9 @@
 |                                | Date        | after   |                                                         |
 |                                |             | Release |                                                         |
 +================================+=============+=========+=========================================================+
-| CryptoCell-712                 |     2.9     |   3.0   | No longer maintained.                                   |
+| CryptoCell-712                 |     2.9     |   2.10  | No longer maintained.                                   |
 +--------------------------------+-------------+---------+---------------------------------------------------------+
-| CryptoCell-713                 |     2.9     |   3.0   | No longer maintained.                                   |
+| CryptoCell-713                 |     2.9     |   2.10  | No longer maintained.                                   |
 +--------------------------------+-------------+---------+---------------------------------------------------------+
 
 --------------
diff --git a/docs/components/platform-interrupt-controller-API.rst b/docs/components/platform-interrupt-controller-API.rst
index 069c87b..4de39d1 100644
--- a/docs/components/platform-interrupt-controller-API.rst
+++ b/docs/components/platform-interrupt-controller-API.rst
@@ -120,39 +120,39 @@
 In case of Arm standard platforms using GIC, the implementation of the API
 writes to GIC *Priority Register* set interrupt priority.
 
-Function: int plat_ic_has_interrupt_type(unsigned int type); [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Function: bool plat_ic_has_interrupt_type(unsigned int type); [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 ::
 
     Argument : unsigned int
-    Return   : int
+    Return   : bool
 
 This API should return whether the platform supports a given interrupt type. The
 parameter ``type`` shall be one of ``INTR_TYPE_EL3``, ``INTR_TYPE_S_EL1``, or
 ``INTR_TYPE_NS``.
 
 In case of Arm standard platforms using GICv3, the implementation of the API
-returns ``1`` for all interrupt types.
+returns *true* for all interrupt types.
 
-In case of Arm standard platforms using GICv2, the API always return ``1`` for
+In case of Arm standard platforms using GICv2, the API always return *true* for
 ``INTR_TYPE_NS``. Return value for other types depends on the value of build
 option ``GICV2_G0_FOR_EL3``:
 
 - For interrupt type ``INTR_TYPE_EL3``:
 
-  - When ``GICV2_G0_FOR_EL3`` is ``0``, it returns ``0``, indicating no support
+  - When ``GICV2_G0_FOR_EL3`` is ``0``, it returns *false*, indicating no support
     for EL3 interrupts.
 
-  - When ``GICV2_G0_FOR_EL3`` is ``1``, it returns ``1``, indicating support for
+  - When ``GICV2_G0_FOR_EL3`` is ``1``, it returns *true*, indicating support for
     EL3 interrupts.
 
 - For interrupt type ``INTR_TYPE_S_EL1``:
 
-  - When ``GICV2_G0_FOR_EL3`` is ``0``, it returns ``1``, indicating support for
+  - When ``GICV2_G0_FOR_EL3`` is ``0``, it returns *true*, indicating support for
     Secure EL1 interrupts.
 
-  - When ``GICV2_G0_FOR_EL3`` is ``1``, it returns ``0``, indicating no support
+  - When ``GICV2_G0_FOR_EL3`` is ``1``, it returns *false*, indicating no support
     for Secure EL1 interrupts.
 
 Function: void plat_ic_set_interrupt_type(unsigned int id, unsigned int type); [optional]
@@ -306,4 +306,4 @@
 
 --------------
 
-*Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index d1bf0d3..bf04558 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -523,11 +523,27 @@
 
 For Neoverse V2, the following errata build flags are defined :
 
+-  ``ERRATA_V2_2331132``: This applies errata 2331132 workaround to Neoverse-V2
+   CPU. This needs to be enabled for revisions r0p0, r0p1 and r0p2. It is still
+   open.
+
 -  ``ERRATA_V2_2719103``: This applies errata 2719103 workaround to Neoverse-V2
    CPU, this affects system configurations that do not use and ARM interconnect
    IP. This needs to be enabled for revisions r0p0 and r0p1. It has been fixed
    in r0p2.
 
+-  ``ERRATA_V2_2719105``: This applies errata 2719105 workaround to Neoverse-V2
+   CPU. This needs to be enabled for revisions r0p0 and r0p1. It is fixed in
+   r0p2.
+
+-  ``ERRATA_V2_2743011``: This applies errata 2743011 workaround to Neoverse-V2
+   CPU. This needs to be enabled for revisions r0p0 and r0p1. It is fixed in
+   r0p2.
+
+-  ``ERRATA_V2_2779510``: This applies errata 2779510 workaround to Neoverse-V2
+   CPU. This needs to be enabled for revisions r0p0 and r0p1. It is fixed in
+   r0p2.
+
 -  ``ERRATA_V2_2801372``: This applies errata 2801372 workaround to Neoverse-V2
    CPU, this affects all configurations. This needs to be enabled for revisions
    r0p0 and r0p1. It has been fixed in r0p2.
diff --git a/docs/design/trusted-board-boot.rst b/docs/design/trusted-board-boot.rst
index 46177d7..fed202a 100644
--- a/docs/design/trusted-board-boot.rst
+++ b/docs/design/trusted-board-boot.rst
@@ -216,10 +216,11 @@
 
 The ``cert_create`` tool is built and runs on the host machine as part of the
 TF-A build process when ``GENERATE_COT=1``. It takes the boot loader images
-and keys as inputs (keys must be in PEM format) and generates the
-certificates (in DER format) required to establish the CoT. New keys can be
-generated by the tool in case they are not provided. The certificates are then
-passed as inputs to the ``fiptool`` utility for creating the FIP.
+and keys as inputs and generates the certificates (in DER format) required to
+establish the CoT. The input keys must either be a file in PEM format or a
+PKCS11 URI in case a HSM is used. New keys can be generated by the tool in
+case they are not provided. The certificates are then passed as inputs to
+the ``fiptool`` utility for creating the FIP.
 
 The certificates are also stored individually in the output build directory.
 
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index e440dbd..7c84ef1 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -80,9 +80,9 @@
    BL31 image for the ``fip`` target. In this case, the BL31 in TF-A will not
    be built.
 
--  ``BL31_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the
-   file that contains the BL31 private key in PEM format. If ``SAVE_KEYS=1``,
-   this file name will be used to save the key.
+-  ``BL31_KEY``: This option is used when ``GENERATE_COT=1``. It specifies a
+   file that contains the BL31 private key in PEM format or a PKCS11 URI. If
+   ``SAVE_KEYS=1``, only a file is accepted and it will be used to save the key.
 
 -  ``BL32``: This is an optional build option which specifies the path to
    BL32 image for the ``fip`` target. In this case, the BL32 in TF-A will not
@@ -94,16 +94,16 @@
 -  ``BL32_EXTRA2``: This is an optional build option which specifies the path to
    Trusted OS Extra2 image for the ``fip`` target.
 
--  ``BL32_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the
-   file that contains the BL32 private key in PEM format. If ``SAVE_KEYS=1``,
-   this file name will be used to save the key.
+-  ``BL32_KEY``: This option is used when ``GENERATE_COT=1``. It specifies a
+   file that contains the BL32 private key in PEM format or a PKCS11 URI. If
+   ``SAVE_KEYS=1``, only a file is accepted and it will be used to save the key.
 
 -  ``BL33``: Path to BL33 image in the host file system. This is mandatory for
    ``fip`` target in case TF-A BL2 is used.
 
--  ``BL33_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the
-   file that contains the BL33 private key in PEM format. If ``SAVE_KEYS=1``,
-   this file name will be used to save the key.
+-  ``BL33_KEY``: This option is used when ``GENERATE_COT=1``. It specifies a
+   file that contains the BL33 private key in PEM format or a PKCS11 URI. If
+   ``SAVE_KEYS=1``, only a file is accepted and it will be used to save the key.
 
 -  ``BRANCH_PROTECTION``: Numeric value to enable ARMv8.3 Pointer Authentication
    and ARMv8.5 Branch Target Identification support for TF-A BL images themselves.
@@ -749,8 +749,9 @@
       MARCH_DIRECTIVE := -march=armv8.5-a
 
 -  ``NON_TRUSTED_WORLD_KEY``: This option is used when ``GENERATE_COT=1``. It
-   specifies the file that contains the Non-Trusted World private key in PEM
-   format. If ``SAVE_KEYS=1``, this file name will be used to save the key.
+   specifies a file that contains the Non-Trusted World private key in PEM
+   format or a PKCS11 URI. If ``SAVE_KEYS=1``, only a file is accepted and it
+   will be used to save the key.
 
 -  ``NS_BL2U``: Path to NS_BL2U image in the host file system. This image is
    optional. It is only needed if the platform makefile specifies that it
@@ -827,10 +828,10 @@
    instead of the BL1 entrypoint. It can take the value 0 (CPU reset to BL1
    entrypoint) or 1 (CPU reset to SP_MIN entrypoint). The default value is 0.
 
--  ``ROT_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the
-   file that contains the ROT private key in PEM format and enforces public key
-   hash generation. If ``SAVE_KEYS=1``, this
-   file name will be used to save the key.
+-  ``ROT_KEY``: This option is used when ``GENERATE_COT=1``. It specifies a
+   file that contains the ROT private key in PEM format or a PKCS11 URI and
+   enforces public key hash generation. If ``SAVE_KEYS=1``, only a file is
+   accepted and it will be used to save the key.
 
 -  ``SAVE_KEYS``: This option is used when ``GENERATE_COT=1``. It tells the
    certificate generation tool to save the keys used to establish the Chain of
@@ -840,9 +841,9 @@
    If a SCP_BL2 image is present then this option must be passed for the ``fip``
    target.
 
--  ``SCP_BL2_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the
-   file that contains the SCP_BL2 private key in PEM format. If ``SAVE_KEYS=1``,
-   this file name will be used to save the key.
+-  ``SCP_BL2_KEY``: This option is used when ``GENERATE_COT=1``. It specifies a
+   file that contains the SCP_BL2 private key in PEM format or a PKCS11 URI.
+   If ``SAVE_KEYS=1``, only a file is accepted and it will be used to save the key.
 
 -  ``SCP_BL2U``: Path to SCP_BL2U image in the host file system. This image is
    optional. It is only needed if the platform makefile specifies that it
@@ -944,6 +945,11 @@
    hardware will limit the effective VL to the maximum physically supported
    VL.
 
+-  ``TRANSFER_LIST``: Setting this to ``1`` enables support for Firmware
+   Handoff using Transfer List defined in `Firmware Handoff specification`_.
+   This defaults to ``0``. Please note that this is an experimental feature
+   based on Firmware Handoff specification v0.9.
+
 -  ``TRNG_SUPPORT``: Setting this to ``1`` enables support for True
    Random Number Generator Interface to BL31 image. This defaults to ``0``.
 
@@ -959,8 +965,9 @@
       already exist in disk, they will be overwritten without further notice.
 
 -  ``TRUSTED_WORLD_KEY``: This option is used when ``GENERATE_COT=1``. It
-   specifies the file that contains the Trusted World private key in PEM
-   format. If ``SAVE_KEYS=1``, this file name will be used to save the key.
+   specifies a file that contains the Trusted World private key in PEM
+   format or a PKCS11 URI. If ``SAVE_KEYS=1``, only a file is accepted and
+   it will be used to save the key.
 
 -  ``TSP_INIT_ASYNC``: Choose BL32 initialization method as asynchronous or
    synchronous, (see "Initializing a BL32 Image" section in
@@ -1298,3 +1305,4 @@
 .. _PSA DRTM specification: https://developer.arm.com/documentation/den0113/a
 .. _GCC: https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
 .. _Clang: https://clang.llvm.org/docs/DiagnosticsReference.html
+.. _Firmware Handoff specification: https://github.com/FirmwareHandoff/firmware_handoff/releases/tag/v0.9
diff --git a/docs/plat/ast2700.rst b/docs/plat/ast2700.rst
index 0352aea..6deade3 100644
--- a/docs/plat/ast2700.rst
+++ b/docs/plat/ast2700.rst
@@ -7,11 +7,11 @@
 Boot Flow
 ---------
 
-    BootRom --> BL1/BL2 --> TF-A BL31 --> BL32 (optional) --> BL33 --> Linux Kernel
+    BootRom --> TF-A BL31 --> BL32 --> BL33 --> Linux Kernel
 
 How to build
 ------------
 
 .. code:: shell
 
-    make CROSS_COMPILE=aarch64-linux-gnu- PLAT=ast2700
+    make CROSS_COMPILE=aarch64-linux-gnu- PLAT=ast2700 SPD=opteed
diff --git a/docs/plat/index.rst b/docs/plat/index.rst
index 7a05fb6..fc3effd 100644
--- a/docs/plat/index.rst
+++ b/docs/plat/index.rst
@@ -73,13 +73,13 @@
 +----------------+----------------+--------------------+--------------------+
 |    mt6795      |      MTK       |        2.5         |       2.7          |
 +----------------+----------------+--------------------+--------------------+
-|    sgi575      |      Arm       |        2.8         |       3.0          |
+|    sgi575      |      Arm       |        2.8         |       2.10         |
 +----------------+----------------+--------------------+--------------------+
-|    rdn1edge    |      Arm       |        2.8         |       3.0          |
+|    rdn1edge    |      Arm       |        2.8         |       2.10         |
 +----------------+----------------+--------------------+--------------------+
-|    tc0         |      Arm       |        2.8         |       3.0          |
+|    tc0         |      Arm       |        2.8         |       2.10         |
 +----------------+----------------+--------------------+--------------------+
-|    rde1edge    |      Arm       |        2.9         |       3.1          |
+|    rde1edge    |      Arm       |        2.9         |       3.0          |
 +----------------+----------------+--------------------+--------------------+
 
 --------------
diff --git a/docs/plat/rpi3.rst b/docs/plat/rpi3.rst
index 38c3dfa..5d97a88 100644
--- a/docs/plat/rpi3.rst
+++ b/docs/plat/rpi3.rst
@@ -296,11 +296,6 @@
   address by changing the file ``armstub8.bin``, so there's no point in using
   TF-A in this case.
 
-- ``MULTI_CONSOLE_API=0``: The multi console API must be enabled. Note that the
-  crash console uses the internal 16550 driver functions directly in order to be
-  able to print error messages during early crashes before setting up the
-  multi console API.
-
 Building the firmware for kernels that don't support PSCI
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/docs/plat/st/stm32mp1.rst b/docs/plat/st/stm32mp1.rst
index 35e8f8c..b6e4b0d 100644
--- a/docs/plat/st/stm32mp1.rst
+++ b/docs/plat/st/stm32mp1.rst
@@ -205,6 +205,7 @@
         --nt-fw <u-boot_directory>/u-boot-nodtb.bin \
         --hw-config <u-boot_directory>/u-boot.dtb \
         --fw-config build/stm32mp1/release/fdts/fw-config.dtb \
+        --trusted-key-cert build/stm32mp1/release/trusted_key.crt \
         --tos-fw-cert build/stm32mp1/release/tos_fw_content.crt \
         --tos-fw-key-cert build/stm32mp1/release/tos_fw_key.crt \
         --nt-fw-cert build/stm32mp1/release/nt_fw_content.crt \
diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst
index 5a017ce..f612e1c 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -3463,6 +3463,15 @@
    to ``no``. If any of the options ``EL3_PAYLOAD_BASE`` or ``PRELOADED_BL33_BASE``
    are used, this flag will be set to ``no`` automatically.
 
+-  **ARM_ARCH_MAJOR and ARM_ARCH_MINOR**
+   By default, ARM_ARCH_MAJOR.ARM_ARCH_MINOR is set to 8.0 in ``defaults.mk``,
+   if the platform makefile/build defines or uses the correct ARM_ARCH_MAJOR and
+   ARM_ARCH_MINOR then mandatory Architectural features available for that Arch
+   version will be enabled by default and any optional Arch feature supported by
+   the Architecture and available in TF-A can be enabled from platform specific
+   makefile. Look up to ``arch_features.mk`` for details pertaining to mandatory
+   and optional Arch specific features.
+
 Platform include paths
 ----------------------
 
diff --git a/drivers/arm/dcc/dcc_console.c b/drivers/arm/dcc/dcc_console.c
index 0b7e541..8d9f793 100644
--- a/drivers/arm/dcc/dcc_console.c
+++ b/drivers/arm/dcc/dcc_console.c
@@ -114,12 +114,6 @@
 	return __dcc_getchar();
 }
 
-int32_t dcc_console_init(unsigned long base_addr, uint32_t uart_clk,
-		      uint32_t baud_rate)
-{
-	return 0; /* No init needed */
-}
-
 /**
  * dcc_console_flush() - Function to force a write of all buffered data
  *		          that hasn't been output.
@@ -150,3 +144,9 @@
 {
 	return console_register(&dcc_console.console);
 }
+
+void console_dcc_unregister(void)
+{
+	dcc_console_flush(&dcc_console.console);
+	(void)console_unregister(&dcc_console.console);
+}
diff --git a/drivers/arm/ethosn/ethosn_big_fw.c b/drivers/arm/ethosn/ethosn_big_fw.c
index ea48a24..2aad5da 100644
--- a/drivers/arm/ethosn/ethosn_big_fw.c
+++ b/drivers/arm/ethosn/ethosn_big_fw.c
@@ -12,7 +12,7 @@
 #define ETHOSN_BIG_FW_MAGIC	('E' | ('N' << 8) | ('F' << 16) | ('W' << 24))
 
 /* Supported big firmware version */
-#define ETHOSN_BIG_FW_VERSION_MAJOR	12
+#define ETHOSN_BIG_FW_VERSION_MAJOR	15
 
 #define ETHOSN_ARCH_VER_MAJOR_MASK	U(0xF000)
 #define ETHOSN_ARCH_VER_MAJOR_SHIFT	U(0xC)
diff --git a/drivers/arm/ethosn/ethosn_smc.c b/drivers/arm/ethosn/ethosn_smc.c
index 42158e4..9aa7e23 100644
--- a/drivers/arm/ethosn/ethosn_smc.c
+++ b/drivers/arm/ethosn/ethosn_smc.c
@@ -46,7 +46,7 @@
 #define ETHOSN_AUX_FEAT_STASHING	U(0x2)
 
 #define SEC_AUXCTLR_REG			U(0x0024)
-#define SEC_AUXCTLR_VAL			U(0x80)
+#define SEC_AUXCTLR_VAL			U(0x000ce080)
 #define SEC_AUXCTLR_LEVEL_IRQ_VAL	U(0x04)
 #define SEC_AUXCTLR_STASHING_VAL	U(0xA5000000)
 
@@ -73,7 +73,7 @@
 #define SEC_SYSCTRL0_HARD_RESET		U(1U << 31)
 
 #define SEC_SYSCTRL1_REG		U(0x001C)
-#define SEC_SYSCTRL1_VAL		U(0x180110)
+#define SEC_SYSCTRL1_VAL		U(0xe0180110)
 
 #define SEC_NSAID_REG_BASE		U(0x3004)
 #define SEC_NSAID_OFFSET		U(0x1000)
diff --git a/drivers/arm/gic/v2/gicv2_main.c b/drivers/arm/gic/v2/gicv2_main.c
index ca2a038..696bede 100644
--- a/drivers/arm/gic/v2/gicv2_main.c
+++ b/drivers/arm/gic/v2/gicv2_main.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.
  * Portions copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -390,7 +390,7 @@
  * This function assigns group for the interrupt identified by id. The group can
  * be any of GICV2_INTR_GROUP*
  ******************************************************************************/
-void gicv2_set_interrupt_type(unsigned int id, unsigned int type)
+void gicv2_set_interrupt_group(unsigned int id, unsigned int group)
 {
 	assert(driver_data != NULL);
 	assert(driver_data->gicd_base != 0U);
@@ -398,7 +398,7 @@
 
 	/* Serialize read-modify-write to Distributor registers */
 	spin_lock(&gic_lock);
-	switch (type) {
+	switch (group) {
 	case GICV2_INTR_GROUP1:
 		gicd_set_igroupr(driver_data->gicd_base, id);
 		break;
diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c
index 2c74800..3c99517 100644
--- a/drivers/arm/gic/v3/gicv3_main.c
+++ b/drivers/arm/gic/v3/gicv3_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -421,16 +421,15 @@
 }
 
 /*******************************************************************************
- * This function returns the type of the interrupt id depending upon the group
- * this interrupt has been configured under by the interrupt controller i.e.
- * group0 or group1 Secure / Non Secure. The return value can be one of the
- * following :
+ * This function returns the group that has been configured under by the
+ * interrupt controller for the given interrupt id i.e. either group0 or group1
+ * Secure / Non Secure. The return value can be one of the following :
  *    INTR_GROUP0  : The interrupt type is a Secure Group 0 interrupt
  *    INTR_GROUP1S : The interrupt type is a Secure Group 1 secure interrupt
  *    INTR_GROUP1NS: The interrupt type is a Secure Group 1 non secure
  *                   interrupt.
  ******************************************************************************/
-unsigned int gicv3_get_interrupt_type(unsigned int id, unsigned int proc_num)
+unsigned int gicv3_get_interrupt_group(unsigned int id, unsigned int proc_num)
 {
 	unsigned int igroup, grpmodr;
 	uintptr_t gicr_base;
@@ -1059,8 +1058,8 @@
  * is used if the interrupt is SGI or (E)PPI, and programs the corresponding
  * Redistributor interface. The group can be any of GICV3_INTR_GROUP*
  ******************************************************************************/
-void gicv3_set_interrupt_type(unsigned int id, unsigned int proc_num,
-		unsigned int type)
+void gicv3_set_interrupt_group(unsigned int id, unsigned int proc_num,
+		unsigned int group)
 {
 	bool igroup = false, grpmod = false;
 	uintptr_t gicr_base;
@@ -1071,7 +1070,7 @@
 	assert(proc_num < gicv3_driver_data->rdistif_num);
 	assert(gicv3_driver_data->rdistif_base_addrs != NULL);
 
-	switch (type) {
+	switch (group) {
 	case INTR_GROUP1S:
 		igroup = false;
 		grpmod = true;
diff --git a/drivers/auth/auth_mod.c b/drivers/auth/auth_mod.c
index 105dc05..14c3172 100644
--- a/drivers/auth/auth_mod.c
+++ b/drivers/auth/auth_mod.c
@@ -150,8 +150,8 @@
 			  const auth_img_desc_t *img_desc,
 			  void *img, unsigned int img_len)
 {
-	void *data_ptr, *pk_ptr, *pk_plat_ptr, *sig_ptr, *sig_alg_ptr, *pk_oid;
-	unsigned int data_len, pk_len, pk_plat_len, sig_len, sig_alg_len;
+	void *data_ptr, *pk_ptr, *cnv_pk_ptr, *pk_plat_ptr, *sig_ptr, *sig_alg_ptr, *pk_oid;
+	unsigned int data_len, pk_len, cnv_pk_len, pk_plat_len, sig_len, sig_alg_len;
 	unsigned int flags = 0;
 	int rc = 0;
 
@@ -210,14 +210,14 @@
 			 * platform may store the hash of a prefixed,
 			 * suffixed or modified pk
 			 */
-			rc = crypto_mod_convert_pk(pk_ptr, pk_len, &pk_ptr, &pk_len);
+			rc = crypto_mod_convert_pk(pk_ptr, pk_len, &cnv_pk_ptr, &cnv_pk_len);
 			return_if_error(rc);
 
 			/*
 			 * The hash of the certificate's public key must match
 			 * the hash of the ROTPK.
 			 */
-			rc = crypto_mod_verify_hash(pk_ptr, pk_len,
+			rc = crypto_mod_verify_hash(cnv_pk_ptr, cnv_pk_len,
 						    pk_plat_ptr, pk_plat_len);
 			return_if_error(rc);
 		} else {
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 57f4748..b51e744 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -83,7 +83,7 @@
 static int mmc_device_state(void)
 {
 	int retries = MMC_DEFAULT_MAX_RETRIES;
-	unsigned int resp_data[4];
+	unsigned int resp_data[4] = {0};
 
 	do {
 		int ret;
diff --git a/drivers/st/ddr/stm32mp1_ram.c b/drivers/st/ddr/stm32mp1_ram.c
index b510c8f..c96fa04 100644
--- a/drivers/st/ddr/stm32mp1_ram.c
+++ b/drivers/st/ddr/stm32mp1_ram.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2018-2023, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
  */
@@ -56,7 +56,8 @@
 	int ret;
 	struct stm32mp_ddr_config config;
 	int node;
-	uint32_t uret;
+	uintptr_t uret;
+	size_t retsize;
 	void *fdt;
 
 	const struct stm32mp_ddr_param param[] = {
@@ -106,26 +107,28 @@
 	}
 
 	uret = stm32mp_ddr_test_data_bus();
-	if (uret != 0U) {
-		ERROR("DDR data bus test: can't access memory @ 0x%x\n",
+	if (uret != 0UL) {
+		ERROR("DDR data bus test: can't access memory @ 0x%lx\n",
 		      uret);
 		panic();
 	}
 
 	uret = stm32mp_ddr_test_addr_bus(config.info.size);
-	if (uret != 0U) {
-		ERROR("DDR addr bus test: can't access memory @ 0x%x\n",
+	if (uret != 0UL) {
+		ERROR("DDR addr bus test: can't access memory @ 0x%lx\n",
 		      uret);
 		panic();
 	}
 
-	uret = stm32mp_ddr_check_size();
-	if (uret < config.info.size) {
-		ERROR("DDR size: 0x%x does not match DT config: 0x%x\n",
-		      uret, config.info.size);
+	retsize = stm32mp_ddr_check_size();
+	if (retsize < config.info.size) {
+		ERROR("DDR size: 0x%zx does not match DT config: 0x%zx\n",
+		      retsize, config.info.size);
 		panic();
 	}
 
+	INFO("Memory size = 0x%zx (%zu MB)\n", retsize, retsize / (1024U * 1024U));
+
 	if (stm32mp_unmap_ddr() != 0) {
 		panic();
 	}
diff --git a/drivers/st/ddr/stm32mp_ddr_test.c b/drivers/st/ddr/stm32mp_ddr_test.c
index 6733cc6..0f6aff1 100644
--- a/drivers/st/ddr/stm32mp_ddr_test.c
+++ b/drivers/st/ddr/stm32mp_ddr_test.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2022-2023, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,19 +18,19 @@
  * Note that the previous content is restored after test.
  * Returns 0 if success, and address value else.
  ******************************************************************************/
-uint32_t stm32mp_ddr_test_rw_access(void)
+uintptr_t stm32mp_ddr_test_rw_access(void)
 {
 	uint32_t saved_value = mmio_read_32(STM32MP_DDR_BASE);
 
 	mmio_write_32(STM32MP_DDR_BASE, DDR_PATTERN);
 
 	if (mmio_read_32(STM32MP_DDR_BASE) != DDR_PATTERN) {
-		return (uint32_t)STM32MP_DDR_BASE;
+		return STM32MP_DDR_BASE;
 	}
 
 	mmio_write_32(STM32MP_DDR_BASE, saved_value);
 
-	return 0U;
+	return 0UL;
 }
 
 /*******************************************************************************
@@ -41,7 +41,7 @@
  * File: memtest.c - This source code belongs to Public Domain.
  * Returns 0 if success, and address value else.
  ******************************************************************************/
-uint32_t stm32mp_ddr_test_data_bus(void)
+uintptr_t stm32mp_ddr_test_data_bus(void)
 {
 	uint32_t pattern;
 
@@ -49,11 +49,11 @@
 		mmio_write_32(STM32MP_DDR_BASE, pattern);
 
 		if (mmio_read_32(STM32MP_DDR_BASE) != pattern) {
-			return (uint32_t)STM32MP_DDR_BASE;
+			return STM32MP_DDR_BASE;
 		}
 	}
 
-	return 0;
+	return 0UL;
 }
 
 /*******************************************************************************
@@ -65,38 +65,34 @@
  * size: size in bytes of the DDR memory device.
  * Returns 0 if success, and address value else.
  ******************************************************************************/
-uint32_t stm32mp_ddr_test_addr_bus(uint64_t size)
+uintptr_t stm32mp_ddr_test_addr_bus(size_t size)
 {
-	uint64_t addressmask = size - 1U;
-	uint64_t offset;
-	uint64_t testoffset = 0U;
+	size_t addressmask = size - 1U;
+	size_t offset;
+	size_t testoffset = 0U;
 
 	/* Write the default pattern at each of the power-of-two offsets. */
 	for (offset = sizeof(uint32_t); (offset & addressmask) != 0U;
 	     offset <<= 1U) {
-		mmio_write_32(STM32MP_DDR_BASE + (uint32_t)offset,
-			      DDR_PATTERN);
+		mmio_write_32(STM32MP_DDR_BASE + offset, DDR_PATTERN);
 	}
 
 	/* Check for address bits stuck high. */
-	mmio_write_32(STM32MP_DDR_BASE + (uint32_t)testoffset,
-		      DDR_ANTIPATTERN);
+	mmio_write_32(STM32MP_DDR_BASE + testoffset, DDR_ANTIPATTERN);
 
 	for (offset = sizeof(uint32_t); (offset & addressmask) != 0U;
 	     offset <<= 1U) {
-		if (mmio_read_32(STM32MP_DDR_BASE + (uint32_t)offset) !=
-		    DDR_PATTERN) {
-			return (uint32_t)(STM32MP_DDR_BASE + offset);
+		if (mmio_read_32(STM32MP_DDR_BASE + offset) != DDR_PATTERN) {
+			return STM32MP_DDR_BASE + offset;
 		}
 	}
 
-	mmio_write_32(STM32MP_DDR_BASE + (uint32_t)testoffset, DDR_PATTERN);
+	mmio_write_32(STM32MP_DDR_BASE + testoffset, DDR_PATTERN);
 
 	/* Check for address bits stuck low or shorted. */
 	for (testoffset = sizeof(uint32_t); (testoffset & addressmask) != 0U;
 	     testoffset <<= 1U) {
-		mmio_write_32(STM32MP_DDR_BASE + (uint32_t)testoffset,
-			      DDR_ANTIPATTERN);
+		mmio_write_32(STM32MP_DDR_BASE + testoffset, DDR_ANTIPATTERN);
 
 		if (mmio_read_32(STM32MP_DDR_BASE) != DDR_PATTERN) {
 			return STM32MP_DDR_BASE;
@@ -104,18 +100,16 @@
 
 		for (offset = sizeof(uint32_t); (offset & addressmask) != 0U;
 		     offset <<= 1) {
-			if ((mmio_read_32(STM32MP_DDR_BASE +
-					  (uint32_t)offset) != DDR_PATTERN) &&
+			if ((mmio_read_32(STM32MP_DDR_BASE + offset) != DDR_PATTERN) &&
 			    (offset != testoffset)) {
-				return (uint32_t)(STM32MP_DDR_BASE + offset);
+				return STM32MP_DDR_BASE + offset;
 			}
 		}
 
-		mmio_write_32(STM32MP_DDR_BASE + (uint32_t)testoffset,
-			      DDR_PATTERN);
+		mmio_write_32(STM32MP_DDR_BASE + testoffset, DDR_PATTERN);
 	}
 
-	return 0U;
+	return 0UL;
 }
 
 /*******************************************************************************
@@ -125,9 +119,9 @@
  * restore its content.
  * Returns DDR computed size.
  ******************************************************************************/
-uint32_t stm32mp_ddr_check_size(void)
+size_t stm32mp_ddr_check_size(void)
 {
-	uint32_t offset = sizeof(uint32_t);
+	size_t offset = sizeof(uint32_t);
 
 	mmio_write_32(STM32MP_DDR_BASE, DDR_PATTERN);
 
@@ -142,7 +136,5 @@
 		offset <<= 1U;
 	}
 
-	INFO("Memory size = 0x%x (%u MB)\n", offset, offset / (1024U * 1024U));
-
 	return offset;
 }
diff --git a/drivers/st/ddr/stm32mp_ram.c b/drivers/st/ddr/stm32mp_ram.c
index 0804568..28dc17d 100644
--- a/drivers/st/ddr/stm32mp_ram.c
+++ b/drivers/st/ddr/stm32mp_ram.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2022-2023, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -23,8 +23,8 @@
 		VERBOSE("%s: no st,mem-speed\n", __func__);
 		return -EINVAL;
 	}
-	ret = fdt_read_uint32(fdt, node, "st,mem-size", &info->size);
-	if (ret < 0) {
+	info->size = dt_get_ddr_size();
+	if (info->size == 0U) {
 		VERBOSE("%s: no st,mem-size\n", __func__);
 		return -EINVAL;
 	}
diff --git a/drivers/ufs/ufs.c b/drivers/ufs/ufs.c
index 5ba5eb0..19f894f 100644
--- a/drivers/ufs/ufs.c
+++ b/drivers/ufs/ufs.c
@@ -609,7 +609,7 @@
 	       UTRIACR_IATOVAL(0xFF);
 	mmio_write_32(ufs_params.reg_base + UTRIACR, data);
 	/* send request */
-	mmio_setbits_32(ufs_params.reg_base + UTRLDBR, 1 << slot);
+	mmio_setbits_32(ufs_params.reg_base + UTRLDBR, 1U << slot);
 }
 
 static int ufs_check_resp(utp_utrd_t *utrd, int trans_type, unsigned int timeout_ms)
diff --git a/include/drivers/arm/dcc.h b/include/drivers/arm/dcc.h
index 1f1fd03..072bed5 100644
--- a/include/drivers/arm/dcc.h
+++ b/include/drivers/arm/dcc.h
@@ -15,5 +15,6 @@
  * framework.
  */
 int console_dcc_register(void);
+void console_dcc_unregister(void);
 
 #endif /* DCC */
diff --git a/include/drivers/arm/ethosn.h b/include/drivers/arm/ethosn.h
index 993dd12..51ce65d 100644
--- a/include/drivers/arm/ethosn.h
+++ b/include/drivers/arm/ethosn.h
@@ -47,7 +47,7 @@
 #define is_ethosn_fid(_fid) (((_fid) & ETHOSN_FID_MASK) == ETHOSN_FID_VALUE)
 
 /* Service version  */
-#define ETHOSN_VERSION_MAJOR U(3)
+#define ETHOSN_VERSION_MAJOR U(4)
 #define ETHOSN_VERSION_MINOR U(0)
 
 /* Return codes for function calls */
diff --git a/include/drivers/arm/gicv2.h b/include/drivers/arm/gicv2.h
index cfc168d..bebd9ce 100644
--- a/include/drivers/arm/gicv2.h
+++ b/include/drivers/arm/gicv2.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  * Portions copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -188,7 +188,7 @@
 void gicv2_enable_interrupt(unsigned int id);
 void gicv2_disable_interrupt(unsigned int id);
 void gicv2_set_interrupt_priority(unsigned int id, unsigned int priority);
-void gicv2_set_interrupt_type(unsigned int id, unsigned int type);
+void gicv2_set_interrupt_group(unsigned int id, unsigned int group);
 void gicv2_raise_sgi(int sgi_num, bool ns, int proc_num);
 void gicv2_set_spi_routing(unsigned int id, int proc_num);
 void gicv2_set_interrupt_pending(unsigned int id);
diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h
index 5bb22fd..cf6a746 100644
--- a/include/drivers/arm/gicv3.h
+++ b/include/drivers/arm/gicv3.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
  */
@@ -556,7 +556,7 @@
 void gicv3_cpuif_disable(unsigned int proc_num);
 unsigned int gicv3_get_pending_interrupt_type(void);
 unsigned int gicv3_get_pending_interrupt_id(void);
-unsigned int gicv3_get_interrupt_type(unsigned int id,
+unsigned int gicv3_get_interrupt_group(unsigned int id,
 					  unsigned int proc_num);
 void gicv3_distif_init_restore(const gicv3_dist_ctx_t * const dist_ctx);
 void gicv3_distif_save(gicv3_dist_ctx_t * const dist_ctx);
@@ -579,8 +579,8 @@
 void gicv3_disable_interrupt(unsigned int id, unsigned int proc_num);
 void gicv3_set_interrupt_priority(unsigned int id, unsigned int proc_num,
 		unsigned int priority);
-void gicv3_set_interrupt_type(unsigned int id, unsigned int proc_num,
-		unsigned int type);
+void gicv3_set_interrupt_group(unsigned int id, unsigned int proc_num,
+		unsigned int group);
 void gicv3_raise_sgi(unsigned int sgi_num, gicv3_irq_group_t group,
 					 u_register_t target);
 void gicv3_set_spi_routing(unsigned int id, unsigned int irm,
diff --git a/include/drivers/st/stm32mp_ddr.h b/include/drivers/st/stm32mp_ddr.h
index 1efca42..4535e3c 100644
--- a/include/drivers/st/stm32mp_ddr.h
+++ b/include/drivers/st/stm32mp_ddr.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2022-2023, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
  */
@@ -53,8 +53,8 @@
 
 struct stm32mp_ddr_info {
 	const char *name;
-	uint32_t speed; /* in kHZ */
-	uint32_t size;  /* Memory size in byte = col * row * width */
+	uint32_t speed; /* in kHz */
+	size_t size;    /* Memory size in byte = col * row * width */
 };
 
 #define TIMEOUT_US_1S	1000000U
diff --git a/include/drivers/st/stm32mp_ddr_test.h b/include/drivers/st/stm32mp_ddr_test.h
index 34e522a..cef5b48 100644
--- a/include/drivers/st/stm32mp_ddr_test.h
+++ b/include/drivers/st/stm32mp_ddr_test.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2022-2023, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,9 +9,9 @@
 
 #include <stdint.h>
 
-uint32_t stm32mp_ddr_test_rw_access(void);
-uint32_t stm32mp_ddr_test_data_bus(void);
-uint32_t stm32mp_ddr_test_addr_bus(uint64_t size);
-uint32_t stm32mp_ddr_check_size(void);
+uintptr_t stm32mp_ddr_test_rw_access(void);
+uintptr_t stm32mp_ddr_test_data_bus(void);
+uintptr_t stm32mp_ddr_test_addr_bus(size_t size);
+size_t stm32mp_ddr_check_size(void);
 
 #endif /* STM32MP_DDR_TEST_H */
diff --git a/include/lib/cpus/aarch64/neoverse_v2.h b/include/lib/cpus/aarch64/neoverse_v2.h
index efb960e..68c1558 100644
--- a/include/lib/cpus/aarch64/neoverse_v2.h
+++ b/include/lib/cpus/aarch64/neoverse_v2.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
  */
@@ -23,4 +23,31 @@
 #define NEOVERSE_V2_CPUPWRCTLR_EL1			S3_0_C15_C2_7
 #define NEOVERSE_V2_CPUPWRCTLR_EL1_CORE_PWRDN_BIT	U(1)
 
+/*******************************************************************************
+ * CPU Extended Control register 2 specific definitions.
+ ******************************************************************************/
+#define NEOVERSE_V2_CPUECTLR2_EL1			S3_0_C15_C1_5
+#define NEOVERSE_V2_CPUECTLR2_EL1_PF_MODE_CNSRV		ULL(9)
+#define NEOVERSE_V2_CPUECTLR2_EL1_PF_MODE_LSB		U(11)
+#define NEOVERSE_V2_CPUECTLR2_EL1_PF_MODE_WIDTH		U(4)
+
+/*******************************************************************************
+ * CPU Auxiliary Control register 2 specific definitions.
+ ******************************************************************************/
+#define NEOVERSE_V2_CPUACTLR2_EL1			S3_0_C15_C1_1
+#define NEOVERSE_V2_CPUACTLR2_EL1_BIT_0			(ULL(1) << 0)
+
+/*******************************************************************************
+ * CPU Auxiliary Control register 3 specific definitions.
+ ******************************************************************************/
+#define NEOVERSE_V2_CPUACTLR3_EL1			S3_0_C15_C1_2
+#define NEOVERSE_V2_CPUACTLR3_EL1_BIT_47		(ULL(1) << 47)
+
+/*******************************************************************************
+ * CPU Auxiliary Control register 5 specific definitions.
+ ******************************************************************************/
+#define NEOVERSE_V2_CPUACTLR5_EL1			S3_0_C15_C8_0
+#define NEOVERSE_V2_CPUACTLR5_EL1_BIT_56		(ULL(1) << 56)
+#define NEOVERSE_V2_CPUACTLR5_EL1_BIT_55		(ULL(1) << 55)
+
 #endif /* NEOVERSE_V2_H */
diff --git a/include/lib/transfer_list.h b/include/lib/transfer_list.h
new file mode 100644
index 0000000..54c8643
--- /dev/null
+++ b/include/lib/transfer_list.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2023, Linaro Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __TRANSFER_LIST_H
+#define __TRANSFER_LIST_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <lib/utils_def.h>
+
+#define	TRANSFER_LIST_SIGNATURE		U(0x006ed0ff)
+#define TRANSFER_LIST_VERSION		U(0x0001)
+
+// Init value of maximum alignment required by any TE data in the TL
+// specified as a power of two
+#define TRANSFER_LIST_INIT_MAX_ALIGN	U(3)
+
+// alignment required by TE header start address, in bytes
+#define TRANSFER_LIST_GRANULE		U(8)
+
+// version of the register convention used.
+// Set to 1 for both AArch64 and AArch32 according to fw handoff spec v0.9
+#define REGISTER_CONVENTION_VERSION_MASK (1 << 24)
+
+#ifndef __ASSEMBLER__
+
+enum transfer_list_tag_id {
+	TL_TAG_EMPTY = 0,
+	TL_TAG_FDT = 1,
+	TL_TAG_HOB_BLOCK = 2,
+	TL_TAG_HOB_LIST = 3,
+	TL_TAG_ACPI_TABLE_AGGREGATE = 4,
+};
+
+enum transfer_list_ops {
+	TL_OPS_NON,	// invalid for any operation
+	TL_OPS_ALL,	// valid for all operations
+	TL_OPS_RO,	// valid for read only
+	TL_OPS_CUS,	// either abort or switch to special code to interpret
+};
+
+struct transfer_list_header {
+	uint32_t	signature;
+	uint8_t		checksum;
+	uint8_t		version;
+	uint8_t		hdr_size;
+	uint8_t		alignment;	// max alignment of TE data
+	uint32_t	size;		// TL header + all TEs
+	uint32_t	max_size;
+	/*
+	 * Commented out element used to visualize dynamic part of the
+	 * data structure.
+	 *
+	 * Note that struct transfer_list_entry also is dynamic in size
+	 * so the elements can't be indexed directly but instead must be
+	 * traversed in order
+	 *
+	 * struct transfer_list_entry entries[];
+	 */
+};
+
+struct transfer_list_entry {
+	uint16_t	tag_id;
+	uint8_t		reserved0;	// place holder
+	uint8_t		hdr_size;
+	uint32_t	data_size;
+	/*
+	 * Commented out element used to visualize dynamic part of the
+	 * data structure.
+	 *
+	 * Note that padding is added at the end of @data to make to reach
+	 * a 8-byte boundary.
+	 *
+	 * uint8_t	data[ROUNDUP(data_size, 8)];
+	 */
+};
+
+void transfer_list_dump(struct transfer_list_header *tl);
+struct transfer_list_header *transfer_list_init(void *addr, size_t max_size);
+
+struct transfer_list_header *transfer_list_relocate(struct transfer_list_header *tl,
+						    void *addr, size_t max_size);
+enum transfer_list_ops transfer_list_check_header(const struct transfer_list_header *tl);
+
+void transfer_list_update_checksum(struct transfer_list_header *tl);
+bool transfer_list_verify_checksum(const struct transfer_list_header *tl);
+
+bool transfer_list_set_data_size(struct transfer_list_header *tl,
+				 struct transfer_list_entry *entry,
+				 uint32_t new_data_size);
+
+void *transfer_list_entry_data(struct transfer_list_entry *entry);
+bool transfer_list_rem(struct transfer_list_header *tl, struct transfer_list_entry *entry);
+
+struct transfer_list_entry *transfer_list_add(struct transfer_list_header *tl,
+					      uint16_t tag_id, uint32_t data_size,
+					      const void *data);
+
+struct transfer_list_entry *transfer_list_add_with_align(struct transfer_list_header *tl,
+							 uint16_t tag_id, uint32_t data_size,
+							 const void *data, uint8_t alignment);
+
+struct transfer_list_entry *transfer_list_next(struct transfer_list_header *tl,
+					       struct transfer_list_entry *last);
+
+struct transfer_list_entry *transfer_list_find(struct transfer_list_header *tl,
+					       uint16_t tag_id);
+
+#endif /*__ASSEMBLER__*/
+#endif /*__TRANSFER_LIST_H*/
diff --git a/include/lib/utils_def.h b/include/lib/utils_def.h
index ba52bc6..a170a09 100644
--- a/include/lib/utils_def.h
+++ b/include/lib/utils_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -104,6 +104,41 @@
 #define round_down(value, boundary)		\
 	((value) & ~round_boundary(value, boundary))
 
+/* add operation together with checking whether the operation overflowed
+ * The result is '*res',
+ * return 0 on success and 1 on overflow
+ */
+#define add_overflow(a, b, res) __builtin_add_overflow((a), (b), (res))
+
+/*
+ * Round up a value to align with a given size and
+ * check whether overflow happens.
+ * The rounduped value is '*res',
+ * return 0 on success and 1 on overflow
+ */
+#define round_up_overflow(v, size, res) (__extension__({ \
+	typeof(res) __res = res; \
+	typeof(*(__res)) __roundup_tmp = 0; \
+	typeof(v) __roundup_mask = (typeof(v))(size) - 1; \
+	\
+	add_overflow((v), __roundup_mask, &__roundup_tmp) ? 1 : \
+		(void)(*(__res) = __roundup_tmp & ~__roundup_mask), 0; \
+}))
+
+/*
+ * Add a with b, then round up the result to align with a given size and
+ * check whether overflow happens.
+ * The rounduped value is '*res',
+ * return 0 on success and 1 on overflow
+ */
+#define add_with_round_up_overflow(a, b, size, res) (__extension__({ \
+	typeof(a) __a = (a); \
+	typeof(__a) __add_res = 0; \
+	\
+	add_overflow((__a), (b), &__add_res) ? 1 : \
+		round_up_overflow(__add_res, (size), (res)) ? 1 : 0; \
+}))
+
 /**
  * Helper macro to ensure a value lies on a given boundary.
  */
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index e024d91..c92121f 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -111,7 +111,7 @@
 unsigned int plat_ic_get_interrupt_active(unsigned int id);
 void plat_ic_disable_interrupt(unsigned int id);
 void plat_ic_enable_interrupt(unsigned int id);
-int plat_ic_has_interrupt_type(unsigned int type);
+bool plat_ic_has_interrupt_type(unsigned int type);
 void plat_ic_set_interrupt_type(unsigned int id, unsigned int type);
 void plat_ic_set_interrupt_priority(unsigned int id, unsigned int priority);
 void plat_ic_raise_el3_sgi(int sgi_num, u_register_t target);
diff --git a/include/services/el3_spmd_logical_sp.h b/include/services/el3_spmd_logical_sp.h
index 1f9ef0d..15bea9f 100644
--- a/include/services/el3_spmd_logical_sp.h
+++ b/include/services/el3_spmd_logical_sp.h
@@ -105,33 +105,33 @@
 }
 
 static inline uint16_t ffa_partition_info_regs_get_last_idx(
-	struct ffa_value args)
+	struct ffa_value *args)
 {
-	return (uint16_t)(args.arg2 & 0xFFFFU);
+	return (uint16_t)(args->arg2 & 0xFFFFU);
 }
 
 static inline uint16_t ffa_partition_info_regs_get_curr_idx(
-	struct ffa_value args)
+	struct ffa_value *args)
 {
-	return (uint16_t)((args.arg2 >> 16) & 0xFFFFU);
+	return (uint16_t)((args->arg2 >> 16) & 0xFFFFU);
 }
 
-static inline uint16_t ffa_partition_info_regs_get_tag(struct ffa_value args)
+static inline uint16_t ffa_partition_info_regs_get_tag(struct ffa_value *args)
 {
-	return (uint16_t)((args.arg2 >> 32) & 0xFFFFU);
+	return (uint16_t)((args->arg2 >> 32) & 0xFFFFU);
 }
 
 static inline uint16_t ffa_partition_info_regs_get_desc_size(
-	struct ffa_value args)
+	struct ffa_value *args)
 {
-	return (uint16_t)(args.arg2 >> 48);
+	return (uint16_t)(args->arg2 >> 48);
 }
 
 uint64_t spmd_el3_populate_logical_partition_info(void *handle, uint64_t x1,
 						  uint64_t x2, uint64_t x3);
 
 bool ffa_partition_info_regs_get_part_info(
-	struct ffa_value args, uint8_t idx,
+	struct ffa_value *args, uint8_t idx,
 	struct ffa_partition_info_v1_1 *partition_info);
 
 bool spmd_el3_invoke_partition_info_get(
diff --git a/lib/cpus/aarch64/cortex_a78_ae.S b/lib/cpus/aarch64/cortex_a78_ae.S
index 9f729c1..94f6465 100644
--- a/lib/cpus/aarch64/cortex_a78_ae.S
+++ b/lib/cpus/aarch64/cortex_a78_ae.S
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
- * Copyright (c) 2021-2022, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2021-2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -23,7 +23,7 @@
 #endif /* WORKAROUND_CVE_2022_23960 */
 
 workaround_reset_start cortex_a78_ae, ERRATUM(1941500), ERRATA_A78_AE_1941500
-	sysreg_bit_clear CORTEX_A78_AE_CPUECTLR_EL1, CORTEX_A78_AE_CPUECTLR_EL1_BIT_8
+	sysreg_bit_set CORTEX_A78_AE_CPUECTLR_EL1, CORTEX_A78_AE_CPUECTLR_EL1_BIT_8
 workaround_reset_end cortex_a78_ae, ERRATUM(1941500)
 
 check_erratum_ls cortex_a78_ae, ERRATUM(1941500), CPU_REV(0, 1)
diff --git a/lib/cpus/aarch64/neoverse_v2.S b/lib/cpus/aarch64/neoverse_v2.S
index 36ae4de..bfd088d 100644
--- a/lib/cpus/aarch64/neoverse_v2.S
+++ b/lib/cpus/aarch64/neoverse_v2.S
@@ -22,6 +22,32 @@
 #error "Neoverse V2 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
 #endif
 
+workaround_reset_start neoverse_v2, ERRATUM(2331132), ERRATA_V2_2331132
+	sysreg_bitfield_insert NEOVERSE_V2_CPUECTLR2_EL1, NEOVERSE_V2_CPUECTLR2_EL1_PF_MODE_CNSRV, \
+		NEOVERSE_V2_CPUECTLR2_EL1_PF_MODE_LSB, NEOVERSE_V2_CPUECTLR2_EL1_PF_MODE_WIDTH
+workaround_reset_end neoverse_v2, ERRATUM(2331132)
+
+check_erratum_ls neoverse_v2, ERRATUM(2331132), CPU_REV(0, 2)
+
+workaround_reset_start neoverse_v2, ERRATUM(2719105), ERRATA_V2_2719105
+	sysreg_bit_set NEOVERSE_V2_CPUACTLR2_EL1, NEOVERSE_V2_CPUACTLR2_EL1_BIT_0
+workaround_reset_end neoverse_v2, ERRATUM(2719105)
+
+check_erratum_ls neoverse_v2, ERRATUM(2719105), CPU_REV(0, 1)
+
+workaround_reset_start neoverse_v2, ERRATUM(2743011), ERRATA_V2_2743011
+	sysreg_bit_set NEOVERSE_V2_CPUACTLR5_EL1, NEOVERSE_V2_CPUACTLR5_EL1_BIT_55
+	sysreg_bit_clear NEOVERSE_V2_CPUACTLR5_EL1, NEOVERSE_V2_CPUACTLR5_EL1_BIT_56
+workaround_reset_end neoverse_v2, ERRATUM(2743011)
+
+check_erratum_ls neoverse_v2, ERRATUM(2743011), CPU_REV(0, 1)
+
+workaround_reset_start neoverse_v2, ERRATUM(2779510), ERRATA_V2_2779510
+	sysreg_bit_set NEOVERSE_V2_CPUACTLR3_EL1, NEOVERSE_V2_CPUACTLR3_EL1_BIT_47
+workaround_reset_end neoverse_v2, ERRATUM(2779510)
+
+check_erratum_ls neoverse_v2, ERRATUM(2779510), CPU_REV(0, 1)
+
 workaround_runtime_start neoverse_v2, ERRATUM(2801372), ERRATA_V2_2801372
 	/* dsb before isb of power down sequence */
 	dsb	sy
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 0d8f4d4..77cc41e 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -794,10 +794,26 @@
 # Cortex-A510 cpu and is fixed in r1p3.
 CPU_FLAG_LIST += ERRATA_A510_2684597
 
+# Flag to apply erratum 2331132 workaround during reset. This erratum applies
+# to revisions r0p0, r0p1 and r0p2. It is still open.
+CPU_FLAG_LIST += ERRATA_V2_2331132
+
 # Flag to apply erratum 2719103 workaround for non-arm interconnect ip. This
 # erratum applies to revisions r0p0, rop1. Fixed in r0p2.
 CPU_FLAG_LIST += ERRATA_V2_2719103
 
+# Flag to apply erratum 2719105 workaround during reset. This erratum applies
+# to revisions r0p0 and r0p1. It is fixed in r0p2.
+CPU_FLAG_LIST += ERRATA_V2_2719105
+
+# Flag to apply erratum 2743011 workaround during reset. This erratum applies
+# to revisions r0p0 and r0p1. It is fixed in r0p2.
+CPU_FLAG_LIST += ERRATA_V2_2743011
+
+# Flag to apply erratum 2779510 workaround during reset. This erratum applies
+# to revisions r0p0 and r0p1. It is fixed in r0p2.
+CPU_FLAG_LIST += ERRATA_V2_2779510
+
 # Flag to apply erratum 2801372 workaround for all configurations.
 # This erratum applies to revisions r0p0, r0p1. Fixed in r0p2.
 CPU_FLAG_LIST += ERRATA_V2_2801372
diff --git a/lib/transfer_list/transfer_list.c b/lib/transfer_list/transfer_list.c
new file mode 100644
index 0000000..e38bf74
--- /dev/null
+++ b/lib/transfer_list/transfer_list.c
@@ -0,0 +1,474 @@
+/*
+ * Copyright (c) 2023, Linaro Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <inttypes.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <lib/transfer_list.h>
+#include <lib/utils_def.h>
+
+void transfer_list_dump(struct transfer_list_header *tl)
+{
+	struct transfer_list_entry *te = NULL;
+	int i = 0;
+
+	if (!tl) {
+		return;
+	}
+	NOTICE("Dump transfer list:\n");
+	NOTICE("signature  0x%x\n", tl->signature);
+	NOTICE("checksum   0x%x\n", tl->checksum);
+	NOTICE("version    0x%x\n", tl->version);
+	NOTICE("hdr_size   0x%x\n", tl->hdr_size);
+	NOTICE("alignment  0x%x\n", tl->alignment);
+	NOTICE("size       0x%x\n", tl->size);
+	NOTICE("max_size   0x%x\n", tl->max_size);
+	while (true) {
+		te = transfer_list_next(tl, te);
+		if (!te) {
+			break;
+		}
+		NOTICE("Entry %d:\n", i++);
+		NOTICE("tag_id     0x%x\n", te->tag_id);
+		NOTICE("hdr_size   0x%x\n", te->hdr_size);
+		NOTICE("data_size  0x%x\n", te->data_size);
+		NOTICE("data_addr  0x%lx\n",
+		(unsigned long)transfer_list_entry_data(te));
+	}
+}
+
+/*******************************************************************************
+ * Creating a transfer list in a reserved memory region specified
+ * Compliant to 2.4.5 of Firmware handoff specification (v0.9)
+ * Return pointer to the created transfer list or NULL on error
+ ******************************************************************************/
+struct transfer_list_header *transfer_list_init(void *addr, size_t max_size)
+{
+	struct transfer_list_header *tl = addr;
+
+	if (!addr || max_size == 0) {
+		return NULL;
+	}
+
+	if (!is_aligned((uintptr_t)addr, 1 << TRANSFER_LIST_INIT_MAX_ALIGN) ||
+	    !is_aligned(max_size, 1 << TRANSFER_LIST_INIT_MAX_ALIGN) ||
+	    max_size < sizeof(*tl)) {
+		return NULL;
+	}
+
+	memset(tl, 0, max_size);
+	tl->signature = TRANSFER_LIST_SIGNATURE;
+	tl->version = TRANSFER_LIST_VERSION;
+	tl->hdr_size = sizeof(*tl);
+	tl->alignment = TRANSFER_LIST_INIT_MAX_ALIGN; // initial max align
+	tl->size = sizeof(*tl); // initial size is the size of header
+	tl->max_size = max_size;
+
+	transfer_list_update_checksum(tl);
+
+	return tl;
+}
+
+/*******************************************************************************
+ * Relocating a transfer list to a reserved memory region specified
+ * Compliant to 2.4.6 of Firmware handoff specification (v0.9)
+ * Return true on success or false on error
+ ******************************************************************************/
+struct transfer_list_header *transfer_list_relocate(
+						struct transfer_list_header *tl,
+						void *addr, size_t max_size)
+{
+	uintptr_t new_addr, align_mask, align_off;
+	struct transfer_list_header *new_tl;
+	uint32_t new_max_size;
+
+	if (!tl || !addr || max_size == 0) {
+		return NULL;
+	}
+
+	align_mask = (1 << tl->alignment) - 1;
+	align_off = (uintptr_t)tl & align_mask;
+	new_addr = ((uintptr_t)addr & ~align_mask) + align_off;
+
+	if (new_addr < (uintptr_t)addr) {
+		new_addr += (1 << tl->alignment);
+	}
+
+	new_max_size = max_size - (new_addr - (uintptr_t)addr);
+
+	// the new space is not sufficient for the tl
+	if (tl->size > new_max_size) {
+		return NULL;
+	}
+
+	new_tl = (struct transfer_list_header *)new_addr;
+	memmove(new_tl, tl, tl->size);
+	new_tl->max_size = new_max_size;
+
+	transfer_list_update_checksum(new_tl);
+
+	return new_tl;
+}
+
+/*******************************************************************************
+ * Verifying the header of a transfer list
+ * Compliant to 2.4.1 of Firmware handoff specification (v0.9)
+ * Return transfer list operation status code
+ ******************************************************************************/
+enum transfer_list_ops transfer_list_check_header(
+					const struct transfer_list_header *tl)
+{
+	if (!tl) {
+		return TL_OPS_NON;
+	}
+
+	if (tl->signature != TRANSFER_LIST_SIGNATURE) {
+		ERROR("Bad transfer list signature %#"PRIx32"\n",
+		      tl->signature);
+		return TL_OPS_NON;
+	}
+
+	if (!tl->max_size) {
+		ERROR("Bad transfer list max size %#"PRIx32"\n",
+		      tl->max_size);
+		return TL_OPS_NON;
+	}
+
+	if (tl->size > tl->max_size) {
+		ERROR("Bad transfer list size %#"PRIx32"\n", tl->size);
+		return TL_OPS_NON;
+	}
+
+	if (tl->hdr_size != sizeof(struct transfer_list_header)) {
+		ERROR("Bad transfer list header size %#"PRIx32"\n", tl->hdr_size);
+		return TL_OPS_NON;
+	}
+
+	if (!transfer_list_verify_checksum(tl)) {
+		ERROR("Bad transfer list checksum %#"PRIx32"\n", tl->checksum);
+		return TL_OPS_NON;
+	}
+
+	if (tl->version == 0) {
+		ERROR("Transfer list version is invalid\n");
+		return TL_OPS_NON;
+	} else if (tl->version == TRANSFER_LIST_VERSION) {
+		INFO("Transfer list version is valid for all operations\n");
+		return TL_OPS_ALL;
+	} else if (tl->version > TRANSFER_LIST_VERSION) {
+		INFO("Transfer list version is valid for read-only\n");
+		return TL_OPS_RO;
+	}
+
+	INFO("Old transfer list version is detected\n");
+	return TL_OPS_CUS;
+}
+
+/*******************************************************************************
+ * Enumerate the next transfer entry
+ * Return pointer to the next transfer entry or NULL on error
+ ******************************************************************************/
+struct transfer_list_entry *transfer_list_next(struct transfer_list_header *tl,
+					       struct transfer_list_entry *last)
+{
+	struct transfer_list_entry *te = NULL;
+	uintptr_t tl_ev = 0;
+	uintptr_t va = 0;
+	uintptr_t ev = 0;
+	size_t sz = 0;
+
+	if (!tl) {
+		return NULL;
+	}
+
+	tl_ev = (uintptr_t)tl + tl->size;
+
+	if (last) {
+		va = (uintptr_t)last;
+		// check if the total size overflow
+		if (add_overflow(last->hdr_size,
+			last->data_size, &sz)) {
+			return NULL;
+		}
+		// roundup to the next entry
+		if (add_with_round_up_overflow(va, sz,
+			TRANSFER_LIST_GRANULE, &va)) {
+			return NULL;
+		}
+	} else {
+		va = (uintptr_t)tl + tl->hdr_size;
+	}
+
+	te = (struct transfer_list_entry *)va;
+
+	if (va + sizeof(*te) > tl_ev || te->hdr_size < sizeof(*te) ||
+		add_overflow(te->hdr_size, te->data_size, &sz) ||
+		add_overflow(va, sz, &ev) ||
+		ev > tl_ev) {
+		return NULL;
+	}
+
+	return te;
+}
+
+/*******************************************************************************
+ * Calculate the byte sum of a transfer list
+ * Return byte sum of the transfer list
+ ******************************************************************************/
+static uint8_t calc_byte_sum(const struct transfer_list_header *tl)
+{
+	uint8_t *b = (uint8_t *)tl;
+	uint8_t cs = 0;
+	size_t n = 0;
+
+	if (!tl) {
+		return 0;
+	}
+
+	for (n = 0; n < tl->size; n++) {
+		cs += b[n];
+	}
+
+	return cs;
+}
+
+/*******************************************************************************
+ * Update the checksum of a transfer list
+ * Return updated checksum of the transfer list
+ ******************************************************************************/
+void transfer_list_update_checksum(struct transfer_list_header *tl)
+{
+	uint8_t cs;
+
+	if (!tl) {
+		return;
+	}
+
+	cs = calc_byte_sum(tl);
+	cs -= tl->checksum;
+	cs = 256 - cs;
+	tl->checksum = cs;
+	assert(transfer_list_verify_checksum(tl));
+}
+
+/*******************************************************************************
+ * Verify the checksum of a transfer list
+ * Return true if verified or false if not
+ ******************************************************************************/
+bool transfer_list_verify_checksum(const struct transfer_list_header *tl)
+{
+	return !calc_byte_sum(tl);
+}
+
+/*******************************************************************************
+ * Update the data size of a transfer entry
+ * Return true on success or false on error
+ ******************************************************************************/
+bool transfer_list_set_data_size(struct transfer_list_header *tl,
+				 struct transfer_list_entry *te,
+				 uint32_t new_data_size)
+{
+	uintptr_t tl_old_ev, new_ev = 0, old_ev = 0, ru_new_ev;
+	struct transfer_list_entry *dummy_te = NULL;
+	size_t gap = 0;
+	size_t mov_dis = 0;
+	size_t sz = 0;
+
+	if (!tl || !te) {
+		return false;
+	}
+	tl_old_ev = (uintptr_t)tl + tl->size;
+
+	// calculate the old and new end of TE
+	// both must be roundup to align with TRANSFER_LIST_GRANULE
+	if (add_overflow(te->hdr_size, te->data_size, &sz) ||
+		add_with_round_up_overflow((uintptr_t)te, sz,
+		TRANSFER_LIST_GRANULE, &old_ev)) {
+		return false;
+	}
+	if (add_overflow(te->hdr_size, new_data_size, &sz) ||
+		add_with_round_up_overflow((uintptr_t)te, sz,
+		TRANSFER_LIST_GRANULE, &new_ev)) {
+		return false;
+	}
+
+	if (new_ev > old_ev) {
+		// move distance should be roundup
+		// to meet the requirement of TE data max alignment
+		// ensure that the increased size doesn't exceed
+		// the max size of TL
+		mov_dis = new_ev - old_ev;
+		if (round_up_overflow(mov_dis, 1 << tl->alignment,
+			&mov_dis) || tl->size + mov_dis > tl->max_size) {
+			return false;
+		}
+		ru_new_ev = old_ev + mov_dis;
+		memmove((void *)ru_new_ev, (void *)old_ev, tl_old_ev - old_ev);
+		tl->size += mov_dis;
+		gap = ru_new_ev - new_ev;
+	} else {
+		gap = old_ev - new_ev;
+	}
+
+	if (gap >= sizeof(*dummy_te)) {
+		// create a dummy TE to fill up the gap
+		dummy_te = (struct transfer_list_entry *)new_ev;
+		dummy_te->tag_id = TL_TAG_EMPTY;
+		dummy_te->reserved0 = 0;
+		dummy_te->hdr_size = sizeof(*dummy_te);
+		dummy_te->data_size = gap - sizeof(*dummy_te);
+	}
+
+	te->data_size = new_data_size;
+
+	transfer_list_update_checksum(tl);
+	return true;
+}
+
+/*******************************************************************************
+ * Remove a specified transfer entry from a transfer list
+ * Return true on success or false on error
+ ******************************************************************************/
+bool transfer_list_rem(struct transfer_list_header *tl,
+			struct transfer_list_entry *te)
+{
+	if (!tl || !te || (uintptr_t)te > (uintptr_t)tl + tl->size) {
+		return false;
+	}
+	te->tag_id = TL_TAG_EMPTY;
+	te->reserved0 = 0;
+	transfer_list_update_checksum(tl);
+	return true;
+}
+
+/*******************************************************************************
+ * Add a new transfer entry into a transfer list
+ * Compliant to 2.4.3 of Firmware handoff specification (v0.9)
+ * Return pointer to the added transfer entry or NULL on error
+ ******************************************************************************/
+struct transfer_list_entry *transfer_list_add(struct transfer_list_header *tl,
+					      uint16_t tag_id,
+					      uint32_t data_size,
+					      const void *data)
+{
+	uintptr_t max_tl_ev, tl_ev, ev;
+	struct transfer_list_entry *te = NULL;
+	uint8_t *te_data = NULL;
+	size_t sz = 0;
+
+	if (!tl) {
+		return NULL;
+	}
+
+	max_tl_ev = (uintptr_t)tl + tl->max_size;
+	tl_ev = (uintptr_t)tl + tl->size;
+	ev = tl_ev;
+
+	// skip the step 1 (optional step)
+	// new TE will be added into the tail
+	if (add_overflow(sizeof(*te), data_size, &sz) ||
+		add_with_round_up_overflow(ev, sz,
+		TRANSFER_LIST_GRANULE, &ev) || ev > max_tl_ev) {
+		return NULL;
+	}
+
+	te = (struct transfer_list_entry *)tl_ev;
+	te->tag_id = tag_id;
+	te->reserved0 = 0;
+	te->hdr_size = sizeof(*te);
+	te->data_size = data_size;
+	tl->size += ev - tl_ev;
+
+	if (data) {
+		// get TE data pointer
+		te_data = transfer_list_entry_data(te);
+		if (!te_data) {
+			return NULL;
+		}
+		memmove(te_data, data, data_size);
+	}
+
+	transfer_list_update_checksum(tl);
+
+	return te;
+}
+
+/*******************************************************************************
+ * Add a new transfer entry into a transfer list with specified new data
+ * alignment requirement
+ * Compliant to 2.4.4 of Firmware handoff specification (v0.9)
+ * Return pointer to the added transfer entry or NULL on error
+ ******************************************************************************/
+struct transfer_list_entry *transfer_list_add_with_align(
+					struct transfer_list_header *tl,
+					uint16_t tag_id, uint32_t data_size,
+					const void *data, uint8_t alignment)
+{
+	struct transfer_list_entry *te = NULL;
+	uintptr_t tl_ev, ev, new_tl_ev;
+	size_t dummy_te_data_sz = 0;
+
+	if (!tl) {
+		return NULL;
+	}
+
+	tl_ev = (uintptr_t)tl + tl->size;
+	ev = tl_ev + sizeof(struct transfer_list_entry);
+
+	if (!is_aligned(ev, 1 << alignment)) {
+		// TE data address is not aligned to the new alignment
+		// fill the gap with an empty TE as a placeholder before
+		// adding the desire TE
+		new_tl_ev = round_up(ev, 1 << alignment) -
+				sizeof(struct transfer_list_entry);
+		dummy_te_data_sz = new_tl_ev - tl_ev -
+					sizeof(struct transfer_list_entry);
+		if (!transfer_list_add(tl, TL_TAG_EMPTY, dummy_te_data_sz,
+					NULL)) {
+			return NULL;
+		}
+	}
+
+	te = transfer_list_add(tl, tag_id, data_size, data);
+
+	if (alignment > tl->alignment) {
+		tl->alignment = alignment;
+		transfer_list_update_checksum(tl);
+	}
+
+	return te;
+}
+
+/*******************************************************************************
+ * Search for an existing transfer entry with the specified tag id from a
+ * transfer list
+ * Return pointer to the found transfer entry or NULL on error
+ ******************************************************************************/
+struct transfer_list_entry *transfer_list_find(struct transfer_list_header *tl,
+					       uint16_t tag_id)
+{
+	struct transfer_list_entry *te = NULL;
+
+	do {
+		te = transfer_list_next(tl, te);
+	} while (te && (te->tag_id != tag_id || te->reserved0 != 0));
+
+	return te;
+}
+
+/*******************************************************************************
+ * Retrieve the data pointer of a specified transfer entry
+ * Return pointer to the transfer entry data or NULL on error
+ ******************************************************************************/
+void *transfer_list_entry_data(struct transfer_list_entry *entry)
+{
+	if (!entry) {
+		return NULL;
+	}
+	return (uint8_t *)entry + entry->hdr_size;
+}
diff --git a/lib/transfer_list/transfer_list.mk b/lib/transfer_list/transfer_list.mk
new file mode 100644
index 0000000..42574e8
--- /dev/null
+++ b/lib/transfer_list/transfer_list.mk
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ifeq (${TRANSFER_LIST},1)
+
+ifeq (${ARCH},aarch32)
+$(eval $(call add_define,TRANSFER_LIST_AARCH32))
+endif
+
+TRANSFER_LIST_SOURCES	+=	$(addprefix lib/transfer_list/,	\
+				transfer_list.c)
+
+BL31_SOURCES	+=	$(TRANSFER_LIST_SOURCES)
+BL2_SOURCES	+=	$(TRANSFER_LIST_SOURCES)
+
+endif	# TRANSFER_LIST
+
diff --git a/make_helpers/arch_features.mk b/make_helpers/arch_features.mk
index b799697..f90136b 100644
--- a/make_helpers/arch_features.mk
+++ b/make_helpers/arch_features.mk
@@ -1,41 +1,323 @@
 #
-# Copyright (c) 2022, Arm Limited. All rights reserved.
+# Copyright (c) 2022-2023, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-# This file lists all the checks related to the Architectural Feature
-# Enablement flags, based on the Architectural version.
+# This file lists all of the architectural features, and initializes
+# and enables them based on the configured architecture version.
+
+# This file follows the following format:
+#   - By default disable any mandatory features.
+#   - Then Enable mandatory feature if applicable to an Arch Version.
+#   - Disable or enable any optional feature this would be enabled/disabled if needed by platform.
+
+#
+################################################################################
+# Set mandatory features by default to zero.
+################################################################################
+#
+
+#----
+# 8.1
+#----
+
+# Flag to enable access to Privileged Access Never bit of PSTATE.
+ENABLE_FEAT_PAN			:=	0
+
+# Flag to enable Virtualization Host Extensions.
+ENABLE_FEAT_VHE			:=	0
+
+#----
+# 8.2
+#----
+
+# Enable RAS Support.
+ENABLE_FEAT_RAS			:=	0
+
+#----
+# 8.3
+#----
+
+# Flag to enable Pointer Authentication. Internal flag not meant for
+# direct setting. Use BRANCH_PROTECTION to enable PAUTH.
+ENABLE_PAUTH			:=	0
+
+# Include pointer authentication (ARMv8.3-PAuth) registers in cpu context. This
+# must be set to 1 if the platform wants to use this feature in the Secure
+# world. It is not necessary for use in the Non-secure world.
+CTX_INCLUDE_PAUTH_REGS		:=	0
+
+#----
+# 8.4
+#----
+
+# Flag to enable Secure EL-2 feature.
+ENABLE_FEAT_SEL2		:=	0
+
+# By default, disable trace filter control register access to lower non-secure
+# exception levels, i.e. NS-EL2, or NS-EL1 if NS-EL2 is implemented, but
+# trace filter control register access is unused if FEAT_TRF is implemented.
+ENABLE_TRF_FOR_NS		:=	0
+
+# Flag to enable Data Independent Timing instructions.
+ENABLE_FEAT_DIT			:=	0
+
+#----
+# 8.5
+#----
+
+# Flag to enable access to the Random Number Generator registers.
+ENABLE_FEAT_RNG			:=	0
+
+# Flag to enable Speculation Barrier Instruction.
+ENABLE_FEAT_SB			:=	0
+
+# Flag to enable Branch Target Identification.
+# Internal flag not meant for direct setting.
+# Use BRANCH_PROTECTION to enable BTI.
+ENABLE_BTI			:=	0
+
+#----
+# 8.6
+#----
+
+# Flag to enable access to the CNTPOFF_EL2 register.
+ENABLE_FEAT_ECV			:=	0
+
+# Flag to enable access to the HDFGRTR_EL2 register.
+ENABLE_FEAT_FGT			:=	0
+
+#----
+# 8.7
+#----
+
+# Flag to enable access to the HCRX_EL2 register by setting SCR_EL3.HXEn.
+ENABLE_FEAT_HCX			:=	0
+
+#----
+# 8.9
+#----
+
+# Flag to enable access to TCR2 (FEAT_TCR2).
+ENABLE_FEAT_TCR2		:=	0
+
+#
+################################################################################
+# Enable Mandatory features based on Arch versions.
+################################################################################
+#
 
 # Enable the features which are mandatory from ARCH version 8.1 and upwards.
 ifeq "8.1" "$(word 1, $(sort 8.1 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
-ENABLE_FEAT_PAN		=	1
-ENABLE_FEAT_VHE		=	1
+ENABLE_FEAT_PAN				:=	1
+ENABLE_FEAT_VHE				:=	1
 endif
 
 # Enable the features which are mandatory from ARCH version 8.2 and upwards.
 ifeq "8.2" "$(word 1, $(sort 8.2 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
-ENABLE_FEAT_RAS		=	1
+ENABLE_FEAT_RAS				:=	1
 endif
 
 # Enable the features which are mandatory from ARCH version 8.4 and upwards.
 ifeq "8.4" "$(word 1, $(sort 8.4 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
-ENABLE_FEAT_DIT		=	1
-ENABLE_FEAT_SEL2	=	1
+ENABLE_FEAT_SEL2			:=	1
+ENABLE_TRF_FOR_NS			:=	1
+ENABLE_FEAT_DIT				:=	1
 endif
 
 # Enable the features which are mandatory from ARCH version 8.5 and upwards.
 ifeq "8.5" "$(word 1, $(sort 8.5 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
-ENABLE_FEAT_SB		=	1
+ENABLE_FEAT_RNG				:=	1
+ENABLE_FEAT_SB				:=	1
+
+# Enable Memory tagging, Branch Target Identification for aarch64 only.
+ifeq ($(ARCH), aarch64)
+	mem_tag_arch_support		:= 	yes
+endif #(ARCH=aarch64)
+
 endif
 
 # Enable the features which are mandatory from ARCH version 8.6 and upwards.
 ifeq "8.6" "$(word 1, $(sort 8.6 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
-ENABLE_FEAT_FGT		=	1
-ENABLE_FEAT_ECV		=	1
+ENABLE_FEAT_ECV				:=	1
+ENABLE_FEAT_FGT				:=	1
 endif
 
 # Enable the features which are mandatory from ARCH version 8.7 and upwards.
 ifeq "8.7" "$(word 1, $(sort 8.7 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
-ENABLE_FEAT_HCX		=	1
+ENABLE_FEAT_HCX				:=	1
 endif
+
+# Enable the features which are mandatory from ARCH version 8.9 and upwards.
+ifeq "8.9" "$(word 1, $(sort 8.9 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
+ENABLE_FEAT_TCR2			:=	1
+endif
+
+#
+################################################################################
+# Optional Features defaulted to 0 or 2, if they are not enabled from
+# build option. Can also be disabled or enabled by platform if needed.
+################################################################################
+#
+
+#----
+# 8.0
+#----
+
+# Flag to enable CSV2_2 extension.
+ENABLE_FEAT_CSV2_2			?=	0
+
+# By default, disable access of trace system registers from NS lower
+# ELs  i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused if
+# system register trace is implemented. This feature is available if
+# trace unit such as ETMv4.x, This feature is OPTIONAL and is only
+# permitted in Armv8 implementations.
+ENABLE_SYS_REG_TRACE_FOR_NS		?=	0
+
+#----
+# 8.2
+#----
+
+# Build option to enable/disable the Statistical Profiling Extension,
+# keep it enabled by default for AArch64.
+ifeq (${ARCH},aarch64)
+	ENABLE_SPE_FOR_NS		?=	2
+else ifeq (${ARCH},aarch32)
+	ifdef ENABLE_SPE_FOR_NS
+		$(error ENABLE_SPE_FOR_NS is not supported for AArch32)
+	else
+		ENABLE_SPE_FOR_NS 	:=	0
+	endif
+endif
+
+# Enable SVE for non-secure world by default.
+ifeq (${ARCH},aarch64)
+	ENABLE_SVE_FOR_NS		?=	2
+# SVE is only supported on AArch64 so disable it on AArch32.
+else ifeq (${ARCH},aarch32)
+	ifdef ENABLE_SVE_FOR_NS
+		$(error ENABLE_SVE_FOR_NS is not supported for AArch32)
+	else
+		ENABLE_SVE_FOR_NS 	:=	0
+	endif
+endif
+
+#----
+# 8.4
+#----
+
+# Feature flags for supporting Activity monitor extensions.
+ENABLE_FEAT_AMU				?=	0
+ENABLE_AMU_AUXILIARY_COUNTERS		?=	0
+ENABLE_AMU_FCONF			?=	0
+AMU_RESTRICT_COUNTERS			?=	0
+
+# Build option to enable MPAM for lower ELs.
+ENABLE_MPAM_FOR_LOWER_ELS		?=	0
+
+# Include nested virtualization control (Armv8.4-NV) registers in cpu context.
+# This must be set to 1 if architecture implements Nested Virtualization
+# Extension and platform wants to use this feature in the Secure world.
+CTX_INCLUDE_NEVE_REGS			?=	0
+
+#----
+# 8.5
+#----
+
+# Flag to enable support for EL3 trapping of reads of the RNDR and RNDRRS
+# registers, by setting SCR_EL3.TRNDR.
+ENABLE_FEAT_RNG_TRAP			?=	0
+
+# Include Memory Tagging Extension registers in cpu context. This must be set
+# to 1 if the platform wants to use this feature in the Secure world and MTE is
+# enabled at ELX.
+CTX_INCLUDE_MTE_REGS			?=	0
+
+#----
+# 8.6
+#----
+
+# Flag to enable AMUv1p1 extension.
+ENABLE_FEAT_AMUv1p1			?=	0
+
+# Flag to enable delayed trapping of WFE instruction (FEAT_TWED).
+ENABLE_FEAT_TWED			?=	0
+
+# In v8.6+ platforms with delayed trapping of WFE being supported
+# via FEAT_TWED, this flag takes the delay value to be set in the
+# SCR_EL3.TWEDEL(4bit) field, when FEAT_TWED is implemented.
+# By default it takes 0, and need to be updated by the platforms.
+TWED_DELAY				?=	0
+
+# Disable MTPMU if FEAT_MTPMU is supported.
+DISABLE_MTPMU				?=	0
+
+#----
+# 8.9
+#----
+
+# Flag to enable NoTagAccess memory region attribute for stage 2 of translation.
+ENABLE_FEAT_MTE_PERM			?=	0
+
+# Flag to enable access to Stage 2 Permission Indirection (FEAT_S2PIE).
+ENABLE_FEAT_S2PIE			?=	0
+
+# Flag to enable access to Stage 1 Permission Indirection (FEAT_S1PIE).
+ENABLE_FEAT_S1PIE			?=	0
+
+# Flag to enable access to Stage 2 Permission Overlay (FEAT_S2POE).
+ENABLE_FEAT_S2POE			?=	0
+
+# Flag to enable access to Stage 1 Permission Overlay (FEAT_S1POE).
+ENABLE_FEAT_S1POE			?=	0
+
+#----
+# 9.0
+#----
+
+# Flag to enable Realm Management Extension (FEAT_RME).
+ENABLE_RME				?=	0
+
+# Scalable Matrix Extension for non-secure world.
+ENABLE_SME_FOR_NS			?=	0
+
+# Scalable Vector Extension for secure world.
+ENABLE_SVE_FOR_SWD			?=	0
+
+# By default, disable access of trace buffer control registers from NS
+# lower ELs  i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused
+# if FEAT_TRBE is implemented.
+# Note FEAT_TRBE is only supported on AArch64 - therefore do not enable in
+# AArch32.
+ifeq (${ARCH},aarch64)
+	ENABLE_TRBE_FOR_NS		?=	0
+else ifeq (${ARCH},aarch32)
+	ifdef ENABLE_TRBE_FOR_NS
+		$(error ENABLE_TRBE_FOR_NS is not supported for AArch32)
+	else
+		ENABLE_TRBE_FOR_NS 	:=	0
+	endif
+endif
+
+#----
+# 9.2
+#----
+
+# Scalable Matrix Extension version 2 for non-secure world.
+ENABLE_SME2_FOR_NS			?=	0
+
+# Scalable Matrix Extension for secure world.
+ENABLE_SME_FOR_SWD			?=	0
+
+# By default, disable access to branch record buffer control registers from NS
+# lower ELs i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused
+# if FEAT_BRBE is implemented.
+ENABLE_BRBE_FOR_NS			?=	0
+
+#----
+#9.4
+#----
+
+# Flag to enable access to Guarded Control Stack (FEAT_GCS).
+ENABLE_FEAT_GCS				?=	0
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 964e0f9..b7e6f99 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -63,16 +63,6 @@
 # Include FP registers in cpu context
 CTX_INCLUDE_FPREGS		:= 0
 
-# Include pointer authentication (ARMv8.3-PAuth) registers in cpu context. This
-# must be set to 1 if the platform wants to use this feature in the Secure
-# world. It is not needed to use it in the Non-secure world.
-CTX_INCLUDE_PAUTH_REGS		:= 0
-
-# Include Nested virtualization control (Armv8.4-NV) registers in cpu context.
-# This must be set to 1 if architecture implements Nested Virtualization
-# Extension and platform wants to use this feature in the Secure world
-CTX_INCLUDE_NEVE_REGS		:= 0
-
 # Debug build
 DEBUG				:= 0
 
@@ -85,17 +75,10 @@
 # Disable the generation of the binary image (ELF only).
 DISABLE_BIN_GENERATION		:= 0
 
-# Disable MTPMU if FEAT_MTPMU is supported. Default is 0 to keep backwards
-# compatibility.
-DISABLE_MTPMU			:= 0
-
 # Enable capability to disable authentication dynamically. Only meant for
 # development platforms.
 DYN_DISABLE_AUTH		:= 0
 
-# Build option to enable MPAM for lower ELs
-ENABLE_MPAM_FOR_LOWER_ELS	:= 0
-
 # Enable the Maximum Power Mitigation Mechanism on supporting cores.
 ENABLE_MPMM			:= 0
 
@@ -111,9 +94,6 @@
 # Flag to enable PSCI STATs functionality
 ENABLE_PSCI_STAT		:= 0
 
-# Flag to enable Realm Management Extension (FEAT_RME)
-ENABLE_RME			:= 0
-
 # Flag to enable runtime instrumentation using PMF
 ENABLE_RUNTIME_INSTRUMENTATION	:= 0
 
@@ -123,77 +103,6 @@
 # Flag to enable exception handling in EL3
 EL3_EXCEPTION_HANDLING		:= 0
 
-# Flag to enable Branch Target Identification.
-# Internal flag not meant for direct setting.
-# Use BRANCH_PROTECTION to enable BTI.
-ENABLE_BTI			:= 0
-
-# Flag to enable Pointer Authentication.
-# Internal flag not meant for direct setting.
-# Use BRANCH_PROTECTION to enable PAUTH.
-ENABLE_PAUTH			:= 0
-
-# Flag to enable AMUv1p1 extension.
-ENABLE_FEAT_AMUv1p1		:= 0
-
-# Flag to enable CSV2_2 extension.
-ENABLE_FEAT_CSV2_2 		:= 0
-
-# Flag to enable access to the HCRX_EL2 register by setting SCR_EL3.HXEn.
-ENABLE_FEAT_HCX			:= 0
-
-# Flag to enable access to the HDFGRTR_EL2 register
-ENABLE_FEAT_FGT			:= 0
-
-# Flag to enable access to the CNTPOFF_EL2 register
-ENABLE_FEAT_ECV			:= 0
-
-# Flag to enable use of the DIT feature.
-ENABLE_FEAT_DIT			:= 0
-
-# Flag to enable access to Privileged Access Never bit of PSTATE.
-ENABLE_FEAT_PAN			:= 0
-
-# Flag to enable access to the Random Number Generator registers
-ENABLE_FEAT_RNG			:= 0
-
-# Flag to enable support for EL3 trapping of reads of the RNDR and RNDRRS
-# registers, by setting SCR_EL3.TRNDR.
-ENABLE_FEAT_RNG_TRAP		:= 0
-
-# Flag to enable Speculation Barrier Instruction
-ENABLE_FEAT_SB			:= 0
-
-# Flag to enable Secure EL-2 feature.
-ENABLE_FEAT_SEL2		:= 0
-
-# Flag to enable Virtualization Host Extensions
-ENABLE_FEAT_VHE 		:= 0
-
-# 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
-
-# Flag to enable access to Stage 2 Permission Indirection (FEAT_S2PIE)
-ENABLE_FEAT_S2PIE		:= 0
-
-# Flag to enable access to Stage 1 Permission Indirection (FEAT_S1PIE)
-ENABLE_FEAT_S1PIE		:= 0
-
-# Flag to enable access to Stage 2 Permission Overlay (FEAT_S2POE)
-ENABLE_FEAT_S2POE		:= 0
-
-# Flag to enable access to Stage 1 Permission Overlay (FEAT_S1POE)
-ENABLE_FEAT_S1POE		:= 0
-
-# Flag to enable access to Guarded Control Stack (FEAT_GCS)
-ENABLE_FEAT_GCS			:= 0
-
-# Flag to enable NoTagAccess memory region attribute for stage 2 of translation.
-ENABLE_FEAT_MTE_PERM		:= 0
-
 # By default BL31 encryption disabled
 ENCRYPT_BL31			:= 0
 
@@ -238,6 +147,9 @@
 # by lower ELs.
 HANDLE_EA_EL3_FIRST_NS		:= 0
 
+# Enable Handoff protocol using transfer lists
+TRANSFER_LIST			:= 0
+
 # Secure hash algorithm flag, accepts 3 values: sha256, sha384 and sha512.
 # The default value is sha256.
 HASH_ALG			:= sha256
@@ -279,8 +191,7 @@
 # Enable PSCI OS-initiated mode support
 PSCI_OS_INIT_MODE		:= 0
 
-# Enable RAS Support
-ENABLE_FEAT_RAS			:= 0
+# Enable RAS Firmware First Handling Support
 RAS_FFH_SUPPORT			:= 0
 
 # By default, BL1 acts as the reset handler, not BL31
@@ -379,40 +290,9 @@
 # platforms).
 WARMBOOT_ENABLE_DCACHE_EARLY	:= 0
 
-# Build option to enable/disable the Statistical Profiling Extensions
-ENABLE_SPE_FOR_NS		:= 2
-
-# SPE is only supported on AArch64 so disable it on AArch32.
-ifeq (${ARCH},aarch32)
-	override ENABLE_SPE_FOR_NS := 0
-endif
-
-# Include Memory Tagging Extension registers in cpu context. This must be set
-# to 1 if the platform wants to use this feature in the Secure world and MTE is
-# enabled at ELX.
-CTX_INCLUDE_MTE_REGS		:= 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		:= 2
-# SVE is only supported on AArch64 so disable it on AArch32.
-ifeq (${ARCH},aarch32)
-	override ENABLE_SVE_FOR_NS	:= 0
-endif
-ENABLE_SVE_FOR_SWD		:= 0
-
 # Default SVE vector length to maximum architected value
 SVE_VECTOR_LEN			:= 2048
 
-# SME defaults to disabled
-ENABLE_SME_FOR_NS		:= 0
-ENABLE_SME_FOR_SWD		:= 0
-ENABLE_SME2_FOR_NS		:= 0
-
 SANITIZE_UB := off
 
 # For ARMv8.1 (AArch64) platforms, enabling this option selects the spinlock
@@ -467,38 +347,6 @@
 # Disable Firmware update support by default
 PSA_FWU_SUPPORT			:= 0
 
-# By default, disable access of trace buffer control registers from NS
-# lower ELs  i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused
-# if FEAT_TRBE is implemented.
-# Note FEAT_TRBE is only supported on AArch64 - therefore do not enable in
-# AArch32.
-ifneq (${ARCH},aarch32)
-	ENABLE_TRBE_FOR_NS		:= 0
-else
-	override ENABLE_TRBE_FOR_NS	:= 0
-endif
-
-# By default, disable access to branch record buffer control registers from NS
-# lower ELs i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused
-# if FEAT_BRBE is implemented.
-ENABLE_BRBE_FOR_NS		:= 0
-
-# By default, disable access of trace system registers from NS lower
-# ELs  i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused if
-# system register trace is implemented.
-ENABLE_SYS_REG_TRACE_FOR_NS	:= 0
-
-# By default, disable trace filter control registers access to NS
-# lower ELs, i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused
-# if FEAT_TRF is implemented.
-ENABLE_TRF_FOR_NS		:= 0
-
-# In v8.6+ platforms with delayed trapping of WFE being supported
-# via FEAT_TWED, this flag takes the delay value to be set in the
-# SCR_EL3.TWEDEL(4bit) field, when FEAT_TWED is implemented.
-# By default it takes 0, and need to be updated by the platforms.
-TWED_DELAY			:= 0
-
 # By default, disable the mocking of RSS provided services
 PLAT_RSS_NOT_SUPPORTED		:= 0
 
diff --git a/plat/arm/board/a5ds/platform.mk b/plat/arm/board/a5ds/platform.mk
index 3ed7a63..dd82a10 100644
--- a/plat/arm/board/a5ds/platform.mk
+++ b/plat/arm/board/a5ds/platform.mk
@@ -102,8 +102,6 @@
     $(error Variable AARCH32_SP has to be set for AArch32)
 endif
 
-MULTI_CONSOLE_API		:=	1
-
 ARM_DISABLE_TRUSTED_WDOG	:=	1
 
 PLAT_BL_COMMON_SOURCES	+=	lib/xlat_tables/aarch32/nonlpae_tables.c
diff --git a/plat/arm/board/corstone1000/platform.mk b/plat/arm/board/corstone1000/platform.mk
index 3edffe0..dcd0df8 100644
--- a/plat/arm/board/corstone1000/platform.mk
+++ b/plat/arm/board/corstone1000/platform.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
 #
@@ -43,6 +43,7 @@
 				plat/arm/board/corstone1000/common/corstone1000_err.c		\
 				plat/arm/board/corstone1000/common/corstone1000_trusted_boot.c	\
 				lib/utils/mem_region.c					\
+				lib/cpus/aarch64/cpu_helpers.S \
 				plat/arm/board/corstone1000/common/corstone1000_helpers.S		\
 				plat/arm/board/corstone1000/common/corstone1000_plat.c		\
 				plat/arm/board/corstone1000/common/corstone1000_bl2_mem_params_desc.c \
diff --git a/plat/arm/board/fvp/fvp_spmd_logical_sp.c b/plat/arm/board/fvp/fvp_spmd_logical_sp.c
index 37b4466..8841fc1 100644
--- a/plat/arm/board/fvp/fvp_spmd_logical_sp.c
+++ b/plat/arm/board/fvp/fvp_spmd_logical_sp.c
@@ -32,7 +32,7 @@
 		panic();
 	}
 
-	num_partitions = ffa_partition_info_regs_get_last_idx(ret) + 1;
+	num_partitions = ffa_partition_info_regs_get_last_idx(&ret) + 1;
 	if (num_partitions > SPMD_LP_MAX_SUPPORTED_SP) {
 		panic();
 	}
@@ -41,7 +41,7 @@
 
 	for (uint16_t i = 0; i < num_partitions; i++) {
 		INFO("***Start Partition***\n");
-		if (!ffa_partition_info_regs_get_part_info(ret, i, &part_info[i]))
+		if (!ffa_partition_info_regs_get_part_info(&ret, i, &part_info[i]))
 			panic();
 		INFO("\tPartition ID: 0x%x\n", part_info[i].ep_id);
 		INFO("\tvCPU count:0x%x\n", part_info[i].execution_ctx_count);
diff --git a/plat/aspeed/ast2700/include/platform_reg.h b/plat/aspeed/ast2700/include/platform_reg.h
index 20ae32a..7f26865 100644
--- a/plat/aspeed/ast2700/include/platform_reg.h
+++ b/plat/aspeed/ast2700/include/platform_reg.h
@@ -18,11 +18,10 @@
 #define UART12_BASE	(UART_BASE + 0xb00)
 
 /* CPU-die SCU */
-#define SCU_CPU_BASE		U(0x12c02000)
-#define SCU_CPU_SMP_READY	(SCU_CPU_BASE + 0x780)
-#define SCU_CPU_SMP_EP1		(SCU_CPU_BASE + 0x788)
-#define SCU_CPU_SMP_EP2		(SCU_CPU_BASE + 0x790)
-#define SCU_CPU_SMP_EP3		(SCU_CPU_BASE + 0x798)
-#define SCU_CPU_SMP_POLLINSN	(SCU_CPU_BASE + 0x7a0)
+#define SCU_CPU_BASE	U(0x12c02000)
+#define SCU_CPU_SMP_EP0	(SCU_CPU_BASE + 0x780)
+#define SCU_CPU_SMP_EP1	(SCU_CPU_BASE + 0x788)
+#define SCU_CPU_SMP_EP2	(SCU_CPU_BASE + 0x790)
+#define SCU_CPU_SMP_EP3	(SCU_CPU_BASE + 0x798)
 
 #endif /* PLATFORM_REG_H */
diff --git a/plat/aspeed/ast2700/plat_bl31_setup.c b/plat/aspeed/ast2700/plat_bl31_setup.c
index 36e7338..fde5dbb 100644
--- a/plat/aspeed/ast2700/plat_bl31_setup.c
+++ b/plat/aspeed/ast2700/plat_bl31_setup.c
@@ -10,6 +10,7 @@
 #include <drivers/arm/gicv3.h>
 #include <drivers/console.h>
 #include <drivers/ti/uart/uart_16550.h>
+#include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
 #include <platform_def.h>
@@ -55,7 +56,14 @@
 
 	console_set_scope(&console, CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
 
-	bl31_params_parse_helper(arg0, &bl32_ep_info, &bl33_ep_info);
+	SET_PARAM_HEAD(&bl32_ep_info, PARAM_EP, VERSION_2, 0);
+	bl32_ep_info.pc = BL32_BASE;
+	SET_SECURITY_STATE(bl32_ep_info.h.attr, SECURE);
+
+	SET_PARAM_HEAD(&bl33_ep_info, PARAM_EP, VERSION_2, 0);
+	bl33_ep_info.pc = mmio_read_64(SCU_CPU_SMP_EP0);
+	bl33_ep_info.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+	SET_SECURITY_STATE(bl33_ep_info.h.attr, NON_SECURE);
 }
 
 void bl31_plat_arch_setup(void)
diff --git a/plat/aspeed/ast2700/plat_helpers.S b/plat/aspeed/ast2700/plat_helpers.S
index 1457692..c6d987e 100644
--- a/plat/aspeed/ast2700/plat_helpers.S
+++ b/plat/aspeed/ast2700/plat_helpers.S
@@ -10,6 +10,7 @@
 #include <cortex_a35.h>
 #include <platform_def.h>
 
+	.globl	platform_mem_init
 	.globl	plat_is_my_cpu_primary
 	.globl	plat_my_core_pos
 	.globl	plat_secondary_cold_boot_setup
@@ -18,6 +19,12 @@
 	.globl	plat_crash_console_putc
 	.globl	plat_crash_console_flush
 
+/* void platform_mem_init(void); */
+func platform_mem_init
+	/* DRAM init. is done by preceding MCU */
+	ret
+endfunc platform_mem_init
+
 /* unsigned int plat_is_my_cpu_primary(void); */
 func plat_is_my_cpu_primary
 	mrs	x0, mpidr_el1
@@ -37,6 +44,21 @@
 	ret
 endfunc plat_my_core_pos
 
+/* void plat_secondary_cold_boot_setup (void); */
+func plat_secondary_cold_boot_setup
+	mov	x0, xzr
+	bl	plat_my_core_pos
+	mov_imm	x1, SCU_CPU_SMP_EP0
+	add	x1, x1, x0, lsl #3
+
+poll_smp_mbox_go:
+	wfe
+	ldr	x0, [x1]
+	cmp	x0, xzr
+	beq	poll_smp_mbox_go
+	br	x0
+endfunc plat_secondary_cold_boot_setup
+
 /* unsigned int plat_get_syscnt_freq2(void); */
 func plat_get_syscnt_freq2
 	mov_imm	w0, PLAT_SYSCNT_CLKIN_HZ
diff --git a/plat/aspeed/ast2700/platform.mk b/plat/aspeed/ast2700/platform.mk
index 16ecf0a..873c60e 100644
--- a/plat/aspeed/ast2700/platform.mk
+++ b/plat/aspeed/ast2700/platform.mk
@@ -25,8 +25,10 @@
 	${GICV3_SOURCES}			\
 	${XLAT_TABLES_LIB_SRCS}
 
+RESET_TO_BL31 := 1
+
 PROGRAMMABLE_RESET_ADDRESS := 1
 
-COLD_BOOT_SINGLE_CPU := 1
+COLD_BOOT_SINGLE_CPU := 0
 
 ENABLE_SVE_FOR_NS := 0
diff --git a/plat/common/plat_gicv2.c b/plat/common/plat_gicv2.c
index 0f988dc..f78d2df 100644
--- a/plat/common/plat_gicv2.c
+++ b/plat/common/plat_gicv2.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  * Portions copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -193,9 +193,9 @@
 	gicv2_set_interrupt_priority(id, priority);
 }
 
-int plat_ic_has_interrupt_type(unsigned int type)
+bool plat_ic_has_interrupt_type(unsigned int type)
 {
-	int has_interrupt_type = 0;
+	bool has_interrupt_type = false;
 
 	switch (type) {
 #if GICV2_G0_FOR_EL3
@@ -204,7 +204,7 @@
 	case INTR_TYPE_S_EL1:
 #endif
 	case INTR_TYPE_NS:
-		has_interrupt_type = 1;
+		has_interrupt_type = true;
 		break;
 	default:
 		/* Do nothing in default case */
@@ -216,7 +216,7 @@
 
 void plat_ic_set_interrupt_type(unsigned int id, unsigned int type)
 {
-	unsigned int gicv2_type = 0U;
+	unsigned int gicv2_group = 0U;
 
 	/* Map canonical interrupt type to GICv2 type */
 	switch (type) {
@@ -225,17 +225,17 @@
 #else
 	case INTR_TYPE_S_EL1:
 #endif
-		gicv2_type = GICV2_INTR_GROUP0;
+		gicv2_group = GICV2_INTR_GROUP0;
 		break;
 	case INTR_TYPE_NS:
-		gicv2_type = GICV2_INTR_GROUP1;
+		gicv2_group = GICV2_INTR_GROUP1;
 		break;
 	default:
-		assert(0); /* Unreachable */
+		assert(false); /* Unreachable */
 		break;
 	}
 
-	gicv2_set_interrupt_type(id, gicv2_type);
+	gicv2_set_interrupt_group(id, gicv2_group);
 }
 
 void plat_ic_raise_el3_sgi(int sgi_num, u_register_t target)
diff --git a/plat/common/plat_gicv3.c b/plat/common/plat_gicv3.c
index e1420bb..baa70e0 100644
--- a/plat/common/plat_gicv3.c
+++ b/plat/common/plat_gicv3.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  * Portions copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -47,10 +47,6 @@
 #pragma weak plat_ic_set_interrupt_pending
 #pragma weak plat_ic_clear_interrupt_pending
 
-CASSERT((INTR_TYPE_S_EL1 == INTR_GROUP1S) &&
-	(INTR_TYPE_NS == INTR_GROUP1NS) &&
-	(INTR_TYPE_EL3 == INTR_GROUP0), assert_interrupt_type_mismatch);
-
 /*
  * This function returns the highest priority pending interrupt at
  * the Interrupt controller
@@ -116,12 +112,26 @@
 
 /*
  * This function returns the type of the interrupt `id`, depending on how
- * the interrupt has been configured in the interrupt controller
+ * the interrupt has been configured in the interrupt controller.
  */
 uint32_t plat_ic_get_interrupt_type(uint32_t id)
 {
+	unsigned int group;
+
 	assert(IS_IN_EL3());
-	return gicv3_get_interrupt_type(id, plat_my_core_pos());
+	group = gicv3_get_interrupt_group(id, plat_my_core_pos());
+
+	switch (group) {
+	case INTR_GROUP0:
+		return INTR_TYPE_EL3;
+	case INTR_GROUP1S:
+		return INTR_TYPE_S_EL1;
+	case INTR_GROUP1NS:
+		return INTR_TYPE_NS;
+	default:
+		assert(false); /* Unreachable */
+		return INTR_TYPE_EL3;
+	}
 }
 
 /*
@@ -225,16 +235,37 @@
 	gicv3_set_interrupt_priority(id, plat_my_core_pos(), priority);
 }
 
-int plat_ic_has_interrupt_type(unsigned int type)
+bool plat_ic_has_interrupt_type(unsigned int type)
 {
-	assert((type == INTR_TYPE_EL3) || (type == INTR_TYPE_S_EL1) ||
-			(type == INTR_TYPE_NS));
-	return 1;
+	if ((type == INTR_TYPE_EL3) || (type == INTR_TYPE_S_EL1) ||
+			(type == INTR_TYPE_NS)) {
+		return true;
+	}
+
+	return false;
 }
 
 void plat_ic_set_interrupt_type(unsigned int id, unsigned int type)
 {
-	gicv3_set_interrupt_type(id, plat_my_core_pos(), type);
+	unsigned int group;
+
+	switch (type) {
+	case INTR_TYPE_EL3:
+		group = INTR_GROUP0;
+		break;
+	case INTR_TYPE_S_EL1:
+		group = INTR_GROUP1S;
+		break;
+	case INTR_TYPE_NS:
+		group = INTR_GROUP1NS;
+		break;
+	default:
+		assert(false); /* Unreachable */
+		group = INTR_GROUP0;
+		break;
+	}
+
+	gicv3_set_interrupt_group(id, plat_my_core_pos(), group);
 }
 
 void plat_ic_raise_el3_sgi(int sgi_num, u_register_t target)
diff --git a/plat/imx/imx7/picopi/platform.mk b/plat/imx/imx7/picopi/platform.mk
index 0267a8b..c599675 100644
--- a/plat/imx/imx7/picopi/platform.mk
+++ b/plat/imx/imx7/picopi/platform.mk
@@ -34,7 +34,6 @@
 USE_COHERENT_MEM		:= 1
 
 # Use multi console API
-MULTI_CONSOLE_API		:= 1
 
 PLAT_PICOPI_UART		:=5
 $(eval $(call add_define,PLAT_PICOPI_UART))
diff --git a/plat/intel/soc/agilex/platform.mk b/plat/intel/soc/agilex/platform.mk
index e9fa666..5c92f72 100644
--- a/plat/intel/soc/agilex/platform.mk
+++ b/plat/intel/soc/agilex/platform.mk
@@ -79,5 +79,4 @@
 PROGRAMMABLE_RESET_ADDRESS	:= 0
 RESET_TO_BL2			:= 1
 BL2_INV_DCACHE			:= 0
-MULTI_CONSOLE_API		:= 1
 USE_COHERENT_MEM		:= 1
diff --git a/plat/intel/soc/agilex5/platform.mk b/plat/intel/soc/agilex5/platform.mk
index 779c629..546bc2e 100644
--- a/plat/intel/soc/agilex5/platform.mk
+++ b/plat/intel/soc/agilex5/platform.mk
@@ -104,4 +104,3 @@
 PROGRAMMABLE_RESET_ADDRESS	:= 0
 RESET_TO_BL2			:= 1
 BL2_INV_DCACHE			:= 0
-MULTI_CONSOLE_API		:= 1
diff --git a/plat/intel/soc/n5x/platform.mk b/plat/intel/soc/n5x/platform.mk
index 7afeb74..95f076f 100644
--- a/plat/intel/soc/n5x/platform.mk
+++ b/plat/intel/soc/n5x/platform.mk
@@ -49,5 +49,4 @@
 PROGRAMMABLE_RESET_ADDRESS	:= 0
 RESET_TO_BL2			:= 1
 BL2_INV_DCACHE			:= 0
-MULTI_CONSOLE_API		:= 1
 USE_COHERENT_MEM		:= 1
diff --git a/plat/mediatek/common/common_config.mk b/plat/mediatek/common/common_config.mk
index 31a61e0..300242b 100644
--- a/plat/mediatek/common/common_config.mk
+++ b/plat/mediatek/common/common_config.mk
@@ -6,7 +6,6 @@
 
 # indicate the reset vector address can be programmed
 PROGRAMMABLE_RESET_ADDRESS := 1
-MULTI_CONSOLE_API := 1
 COLD_BOOT_SINGLE_CPU := 1
 # Build flag to include AArch32 registers in cpu context save and restore during
 # world switch. This flag must be set to 0 for AArch64-only platforms.
diff --git a/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c b/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c
index 7eeadec..8810be3 100644
--- a/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c
+++ b/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c
@@ -118,12 +118,7 @@
 				     u_register_t x3, u_register_t x4,
 				     void *handle, struct smccc_res *smccc_ret)
 {
-	int ret;
-
-	ret = emi_mpu_optee_handler(x1, x2, x3);
-	SMC_RET2(handle, ret, 0U);
-
-	return 0;
+	return (u_register_t) emi_mpu_optee_handler(x1, x2, x3);
 }
 DECLARE_SMC_HANDLER(MTK_SIP_TEE_MPU_PERM_SET, mtk_emi_mpu_sip_handler);
 
diff --git a/plat/mediatek/mt8173/platform.mk b/plat/mediatek/mt8173/platform.mk
index 6bf1aa7..4d5a100 100644
--- a/plat/mediatek/mt8173/platform.mk
+++ b/plat/mediatek/mt8173/platform.mk
@@ -71,5 +71,3 @@
 
 # Do not enable SVE
 ENABLE_SVE_FOR_NS		:=	0
-
-MULTI_CONSOLE_API		:=	1
diff --git a/plat/mediatek/mt8183/platform.mk b/plat/mediatek/mt8183/platform.mk
index a737d24..55c49ff 100644
--- a/plat/mediatek/mt8183/platform.mk
+++ b/plat/mediatek/mt8183/platform.mk
@@ -81,8 +81,6 @@
 
 COLD_BOOT_SINGLE_CPU := 1
 
-MULTI_CONSOLE_API := 1
-
 MACH_MT8183 := 1
 $(eval $(call add_define,MACH_MT8183))
 
diff --git a/plat/qemu/common/common.mk b/plat/qemu/common/common.mk
index 618e6c9..b23f7fd 100644
--- a/plat/qemu/common/common.mk
+++ b/plat/qemu/common/common.mk
@@ -25,6 +25,7 @@
 				lib/cpus/aarch64/neoverse_n_common.S	\
 				lib/cpus/aarch64/neoverse_n1.S		\
 				lib/cpus/aarch64/neoverse_v1.S		\
+				lib/cpus/aarch64/neoverse_n2.S		\
 				lib/cpus/aarch64/qemu_max.S
 
 PLAT_INCLUDES		+=	-Iinclude/plat/arm/common/${ARCH}
@@ -33,7 +34,7 @@
 # v8.0: a53, a57, a72
 # v8.2: a76, n1
 # v8.4: v1
-# v9.0: a710
+# v9.0: a710, n2
 #
 # let treat v9.0 as v8.5 as they share cpu features
 # https://developer.arm.com/documentation/102378/0201/Armv8-x-and-Armv9-x-extensions-and-features
diff --git a/plat/qemu/common/qemu_bl2_setup.c b/plat/qemu/common/qemu_bl2_setup.c
index c4d235e..231f23a 100644
--- a/plat/qemu/common/qemu_bl2_setup.c
+++ b/plat/qemu/common/qemu_bl2_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,6 +18,9 @@
 #include <common/fdt_fixup.h>
 #include <common/fdt_wrappers.h>
 #include <lib/optee_utils.h>
+#if TRANSFER_LIST
+#include <lib/transfer_list.h>
+#endif
 #include <lib/utils.h>
 #include <plat/common/platform.h>
 
@@ -48,6 +51,9 @@
 
 /* Data structure which holds the extents of the trusted SRAM for BL2 */
 static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
+#if TRANSFER_LIST
+static struct transfer_list_header *bl2_tl;
+#endif
 
 void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 			       u_register_t arg2, u_register_t arg3)
@@ -73,6 +79,9 @@
 
 static void update_dt(void)
 {
+#if TRANSFER_LIST
+	struct transfer_list_entry *te;
+#endif
 	int ret;
 	void *fdt = (void *)(uintptr_t)ARM_PRELOADED_DTB_BASE;
 
@@ -95,16 +104,40 @@
 	ret = fdt_pack(fdt);
 	if (ret < 0)
 		ERROR("Failed to pack Device Tree at %p: error %d\n", fdt, ret);
+
+#if TRANSFER_LIST
+	// create a TE
+	te = transfer_list_add(bl2_tl, TL_TAG_FDT, fdt_totalsize(fdt), fdt);
+	if (!te) {
+		ERROR("Failed to add FDT entry to Transfer List\n");
+		return;
+	}
+#endif
 }
 
 void bl2_platform_setup(void)
 {
+#if TRANSFER_LIST
+	bl2_tl = transfer_list_init((void *)(uintptr_t)FW_HANDOFF_BASE,
+				    FW_HANDOFF_SIZE);
+	if (!bl2_tl) {
+		ERROR("Failed to initialize Transfer List at 0x%lx\n",
+		      (unsigned long)FW_HANDOFF_BASE);
+	}
+#endif
 	security_setup();
 	update_dt();
 
 	/* TODO Initialize timer */
 }
 
+void qemu_bl2_sync_transfer_list(void)
+{
+#if TRANSFER_LIST
+	transfer_list_update_checksum(bl2_tl);
+#endif
+}
+
 void bl2_plat_arch_setup(void)
 {
 	const mmap_region_t bl_regions[] = {
@@ -221,6 +254,10 @@
 #if defined(SPD_spmd)
 	bl_mem_params_node_t *bl32_mem_params = NULL;
 #endif
+#if TRANSFER_LIST
+	struct transfer_list_header *ns_tl = NULL;
+	struct transfer_list_entry *te = NULL;
+#endif
 
 	assert(bl_mem_params);
 
@@ -275,6 +312,8 @@
 		pager_mem_params->ep_info.lr_svc = bl_mem_params->ep_info.pc;
 #endif
 
+		bl_mem_params->ep_info.spsr = qemu_get_spsr_for_bl33_entry();
+
 #if ARM_LINUX_KERNEL_AS_BL33
 		/*
 		 * According to the file ``Documentation/arm64/booting.txt`` of
@@ -287,12 +326,49 @@
 		bl_mem_params->ep_info.args.arg1 = 0U;
 		bl_mem_params->ep_info.args.arg2 = 0U;
 		bl_mem_params->ep_info.args.arg3 = 0U;
+#elif TRANSFER_LIST
+		if (bl2_tl) {
+			// relocate the tl to pre-allocate NS memory
+			ns_tl = transfer_list_relocate(bl2_tl,
+					(void *)(uintptr_t)FW_NS_HANDOFF_BASE,
+					bl2_tl->max_size);
+			if (!ns_tl) {
+				ERROR("Relocate TL to 0x%lx failed\n",
+					(unsigned long)FW_NS_HANDOFF_BASE);
+				return -1;
+			}
+			NOTICE("Transfer list handoff to BL33\n");
+			transfer_list_dump(ns_tl);
+
+			te = transfer_list_find(ns_tl, TL_TAG_FDT);
+
+			bl_mem_params->ep_info.args.arg1 =
+				TRANSFER_LIST_SIGNATURE |
+				REGISTER_CONVENTION_VERSION_MASK;
+			bl_mem_params->ep_info.args.arg3 = (uintptr_t)ns_tl;
+
+			if (GET_RW(bl_mem_params->ep_info.spsr) == MODE_RW_32) {
+				// aarch32
+				bl_mem_params->ep_info.args.arg0 = 0;
+				bl_mem_params->ep_info.args.arg2 = te ?
+					(uintptr_t)transfer_list_entry_data(te)
+					: 0;
+			} else {
+				// aarch64
+				bl_mem_params->ep_info.args.arg0 = te ?
+					(uintptr_t)transfer_list_entry_data(te)
+					: 0;
+				bl_mem_params->ep_info.args.arg2 = 0;
+			}
+		} else {
+			// Legacy handoff
+			bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
+		}
 #else
 		/* BL33 expects to receive the primary CPU MPID (through r0) */
 		bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
-#endif
+#endif // ARM_LINUX_KERNEL_AS_BL33
 
-		bl_mem_params->ep_info.spsr = qemu_get_spsr_for_bl33_entry();
 		break;
 #ifdef SPD_spmd
 #if SPMD_SPM_AT_SEL2
diff --git a/plat/qemu/common/qemu_common.c b/plat/qemu/common/qemu_common.c
index 98be491..d4488a4 100644
--- a/plat/qemu/common/qemu_common.c
+++ b/plat/qemu/common/qemu_common.c
@@ -47,6 +47,14 @@
 #define MAP_FLASH1	MAP_REGION_FLAT(QEMU_FLASH1_BASE, QEMU_FLASH1_SIZE, \
 					MT_MEMORY | MT_RO | MT_SECURE)
 
+#ifdef FW_HANDOFF_BASE
+#define MAP_FW_HANDOFF MAP_REGION_FLAT(FW_HANDOFF_BASE, FW_HANDOFF_SIZE, \
+				       MT_MEMORY | MT_RW | MT_SECURE)
+#endif
+#ifdef FW_NS_HANDOFF_BASE
+#define MAP_FW_NS_HANDOFF MAP_REGION_FLAT(FW_NS_HANDOFF_BASE, FW_HANDOFF_SIZE, \
+					  MT_MEMORY | MT_RW | MT_NS)
+#endif
 /*
  * Table of regions for various BL stages to map using the MMU.
  * This doesn't include TZRAM as the 'mem_layout' argument passed to
@@ -85,6 +93,9 @@
 #else
 	MAP_BL32_MEM,
 #endif
+#ifdef MAP_FW_HANDOFF
+	MAP_FW_HANDOFF,
+#endif
 	{0}
 };
 #endif
@@ -98,6 +109,12 @@
 #ifdef MAP_DEVICE2
 	MAP_DEVICE2,
 #endif
+#ifdef MAP_FW_HANDOFF
+	MAP_FW_HANDOFF,
+#endif
+#ifdef MAP_FW_NS_HANDOFF
+	MAP_FW_NS_HANDOFF,
+#endif
 #if SPM_MM
 	MAP_NS_DRAM0,
 	QEMU_SPM_BUF_EL3_MMAP,
diff --git a/plat/qemu/common/qemu_image_load.c b/plat/qemu/common/qemu_image_load.c
index 9970d1d..2b02a67 100644
--- a/plat/qemu/common/qemu_image_load.c
+++ b/plat/qemu/common/qemu_image_load.c
@@ -1,11 +1,13 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <common/desc_image_load.h>
 
+#include "qemu_private.h"
+
 /*******************************************************************************
  * This function is a wrapper of a common function which flushes the data
  * structures so that they are visible in memory for the next BL image.
@@ -13,6 +15,7 @@
 void plat_flush_next_bl_params(void)
 {
 	flush_bl_params_desc();
+	qemu_bl2_sync_transfer_list();
 }
 
 /*******************************************************************************
diff --git a/plat/qemu/common/qemu_private.h b/plat/qemu/common/qemu_private.h
index e80a88d..c8912b2 100644
--- a/plat/qemu/common/qemu_private.h
+++ b/plat/qemu/common/qemu_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -40,4 +40,6 @@
 			size_t log_size,
 			uintptr_t *ns_log_addr);
 
+void qemu_bl2_sync_transfer_list(void);
+
 #endif /* QEMU_PRIVATE_H */
diff --git a/plat/qemu/qemu/include/platform_def.h b/plat/qemu/qemu/include/platform_def.h
index 93a3ce8..903c809 100644
--- a/plat/qemu/qemu/include/platform_def.h
+++ b/plat/qemu/qemu/include/platform_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
  */
@@ -151,9 +151,17 @@
  * current BL3-1 debug size plus a little space for growth.
  */
 #define BL31_BASE			(BL31_LIMIT - 0x60000)
-#define BL31_LIMIT			(BL_RAM_BASE + BL_RAM_SIZE)
+#define BL31_LIMIT			(BL_RAM_BASE + BL_RAM_SIZE - FW_HANDOFF_SIZE)
 #define BL31_PROGBITS_LIMIT		BL1_RW_BASE
 
+#if TRANSFER_LIST
+#define FW_HANDOFF_BASE			BL31_LIMIT
+#define FW_HANDOFF_LIMIT		(FW_HANDOFF_BASE + FW_HANDOFF_SIZE)
+#define FW_HANDOFF_SIZE			0x4000
+#else
+#define FW_HANDOFF_SIZE			0
+#endif
+
 
 /*
  * BL3-2 specific defines.
@@ -172,16 +180,20 @@
 # define BL32_MEM_BASE			BL_RAM_BASE
 # define BL32_MEM_SIZE			BL_RAM_SIZE
 # define BL32_BASE			BL32_SRAM_BASE
-# define BL32_LIMIT			BL32_SRAM_LIMIT
+# define BL32_LIMIT			(BL32_SRAM_LIMIT - FW_HANDOFF_SIZE)
 #elif BL32_RAM_LOCATION_ID == SEC_DRAM_ID
 # define BL32_MEM_BASE			SEC_DRAM_BASE
 # define BL32_MEM_SIZE			SEC_DRAM_SIZE
 # define BL32_BASE			BL32_DRAM_BASE
-# define BL32_LIMIT			BL32_DRAM_LIMIT
+# define BL32_LIMIT			(BL32_DRAM_LIMIT - FW_HANDOFF_SIZE)
 #else
 # error "Unsupported BL32_RAM_LOCATION_ID value"
 #endif
 
+#if TRANSFER_LIST
+#define FW_NS_HANDOFF_BASE		(NS_IMAGE_OFFSET - FW_HANDOFF_SIZE)
+#endif
+
 #define NS_IMAGE_OFFSET			(NS_DRAM0_BASE + 0x20000000)
 #define NS_IMAGE_MAX_SIZE		(NS_DRAM0_SIZE - 0x20000000)
 
diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk
index 16e89c1..e902c12 100644
--- a/plat/qemu/qemu/platform.mk
+++ b/plat/qemu/qemu/platform.mk
@@ -39,6 +39,10 @@
 add-lib-optee 		:= 	yes
 endif
 
+ifeq (${TRANSFER_LIST},1)
+include lib/transfer_list/transfer_list.mk
+endif
+
 ifeq ($(NEED_BL32),yes)
 $(eval $(call add_define,QEMU_LOAD_BL32))
 endif
diff --git a/plat/qemu/qemu_sbsa/include/platform_def.h b/plat/qemu/qemu_sbsa/include/platform_def.h
index deaf16e..14030e3 100644
--- a/plat/qemu/qemu_sbsa/include/platform_def.h
+++ b/plat/qemu/qemu_sbsa/include/platform_def.h
@@ -199,7 +199,7 @@
 #define QEMU_FLASH1_BASE		0x10000000
 #define QEMU_FLASH1_SIZE		0x10000000
 
-#define PLAT_QEMU_FIP_BASE		0x00008000
+#define PLAT_QEMU_FIP_BASE		BL1_SIZE
 #define PLAT_QEMU_FIP_MAX_SIZE		0x00400000
 
 /* This is map from GIC_DIST up to last CPU (255) GIC_REDISTR */
diff --git a/plat/qemu/qemu_sbsa/platform.mk b/plat/qemu/qemu_sbsa/platform.mk
index 4a8df46..1b147ce 100644
--- a/plat/qemu/qemu_sbsa/platform.mk
+++ b/plat/qemu/qemu_sbsa/platform.mk
@@ -7,7 +7,6 @@
 PLAT_QEMU_PATH		:=	plat/qemu/qemu_sbsa
 PLAT_QEMU_COMMON_PATH	:=	plat/qemu/common
 
-MULTI_CONSOLE_API	:= 1
 CRASH_REPORTING		:= 1
 
 # Disable the PSCI platform compatibility layer
diff --git a/plat/qti/sc7180/platform.mk b/plat/qti/sc7180/platform.mk
index 41a08ca..b576649 100644
--- a/plat/qti/sc7180/platform.mk
+++ b/plat/qti/sc7180/platform.mk
@@ -32,8 +32,6 @@
 
 RESET_TO_BL31			:=	0
 
-MULTI_CONSOLE_API		:=	1
-
 QTI_SDI_BUILD := 0
 $(eval $(call assert_boolean,QTI_SDI_BUILD))
 $(eval $(call add_define,QTI_SDI_BUILD))
diff --git a/plat/qti/sc7280/platform.mk b/plat/qti/sc7280/platform.mk
index 528a1d4..3d7d728 100644
--- a/plat/qti/sc7280/platform.mk
+++ b/plat/qti/sc7280/platform.mk
@@ -35,8 +35,6 @@
 
 RESET_TO_BL31			:=	0
 
-MULTI_CONSOLE_API		:=	1
-
 QTI_SDI_BUILD := 0
 $(eval $(call assert_boolean,QTI_SDI_BUILD))
 $(eval $(call add_define,QTI_SDI_BUILD))
diff --git a/plat/renesas/common/common.mk b/plat/renesas/common/common.mk
index 25fbb2f..f769be7 100644
--- a/plat/renesas/common/common.mk
+++ b/plat/renesas/common/common.mk
@@ -12,7 +12,6 @@
 GENERATE_COT			:= 1
 RESET_TO_BL2			:= 1
 ENABLE_SVE_FOR_NS		:= 0
-MULTI_CONSOLE_API		:= 1
 
 CRASH_REPORTING			:= 1
 HANDLE_EA_EL3_FIRST_NS		:= 1
diff --git a/plat/rockchip/px30/platform.mk b/plat/rockchip/px30/platform.mk
index d14ffc4..72e12b1 100644
--- a/plat/rockchip/px30/platform.mk
+++ b/plat/rockchip/px30/platform.mk
@@ -64,7 +64,6 @@
 endif
 
 ENABLE_PLAT_COMPAT	:=	0
-MULTI_CONSOLE_API	:=	1
 
 include lib/libfdt/libfdt.mk
 
diff --git a/plat/rockchip/rk3288/platform.mk b/plat/rockchip/rk3288/platform.mk
index e6f78cf..fec4ebb 100644
--- a/plat/rockchip/rk3288/platform.mk
+++ b/plat/rockchip/rk3288/platform.mk
@@ -56,8 +56,6 @@
 				${RK_PLAT_SOC}/drivers/secure/secure.c		\
 				${RK_PLAT_SOC}/drivers/soc/soc.c		\
 
-MULTI_CONSOLE_API	:=	1
-
 include lib/coreboot/coreboot.mk
 include lib/libfdt/libfdt.mk
 
diff --git a/plat/rpi/rpi3/platform.mk b/plat/rpi/rpi3/platform.mk
index 53c97e2..06393e4 100644
--- a/plat/rpi/rpi3/platform.mk
+++ b/plat/rpi/rpi3/platform.mk
@@ -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
 #
@@ -44,6 +44,7 @@
 				plat/rpi/common/rpi3_io_storage.c
 
 BL31_SOURCES		+=	lib/cpus/aarch64/cortex_a53.S		\
+				plat/common/plat_gicv2.c		\
 				plat/common/plat_psci_common.c		\
 				plat/rpi/rpi3/rpi3_bl31_setup.c		\
 				plat/rpi/common/rpi3_pm.c		\
diff --git a/plat/xilinx/versal/bl31_versal_setup.c b/plat/xilinx/versal/bl31_versal_setup.c
index c50f06f..566415f 100644
--- a/plat/xilinx/versal/bl31_versal_setup.c
+++ b/plat/xilinx/versal/bl31_versal_setup.c
@@ -74,27 +74,27 @@
 	enum pm_ret_status ret_status;
 	uint64_t addr[HANDOFF_PARAMS_MAX_SIZE];
 
-	if (VERSAL_CONSOLE_IS(pl011) || (VERSAL_CONSOLE_IS(pl011_1))) {
+	if (CONSOLE_IS(pl011) || (CONSOLE_IS(pl011_1))) {
 		static console_t versal_runtime_console;
 		/* Initialize the console to provide early debug support */
-		int32_t rc = console_pl011_register((uintptr_t)VERSAL_UART_BASE,
-						(uint32_t)VERSAL_UART_CLOCK,
-						(uint32_t)VERSAL_UART_BAUDRATE,
+		int32_t rc = console_pl011_register((uintptr_t)UART_BASE,
+						(uint32_t)UART_CLOCK,
+						(uint32_t)UART_BAUDRATE,
 						&versal_runtime_console);
 		if (rc == 0) {
 			panic();
 		}
 
 		console_set_scope(&versal_runtime_console, (uint32_t)(CONSOLE_FLAG_BOOT |
-				  CONSOLE_FLAG_RUNTIME));
-	} else if (VERSAL_CONSOLE_IS(dcc)) {
+				  CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH));
+	} else if (CONSOLE_IS(dcc)) {
 		/* Initialize the dcc console for debug */
 		int32_t rc = console_dcc_register();
 		if (rc == 0) {
 			panic();
 		}
 	} else {
-		NOTICE("BL31: Did not register for any console.\n");
+		/* No console device found. */
 	}
 
 	/* Initialize the platform config for future decision making */
diff --git a/plat/xilinx/versal/include/versal_def.h b/plat/xilinx/versal/include/versal_def.h
index a8cf0df..0ac76b5 100644
--- a/plat/xilinx/versal/include/versal_def.h
+++ b/plat/xilinx/versal/include/versal_def.h
@@ -23,7 +23,7 @@
 #define VERSAL_CONSOLE_ID_pl011_1	2
 #define VERSAL_CONSOLE_ID_dcc		3
 
-#define VERSAL_CONSOLE_IS(con)	(VERSAL_CONSOLE_ID_ ## con == VERSAL_CONSOLE)
+#define CONSOLE_IS(con)	(VERSAL_CONSOLE_ID_ ## con == VERSAL_CONSOLE)
 
 /* List all supported platforms */
 #define VERSAL_PLATFORM_ID_versal_virt	1
@@ -63,40 +63,36 @@
 #define VERSAL_UART0_BASE		0xFF000000
 #define VERSAL_UART1_BASE		0xFF010000
 
-#if VERSAL_CONSOLE_IS(pl011) || VERSAL_CONSOLE_IS(dcc)
-# define VERSAL_UART_BASE	VERSAL_UART0_BASE
-#elif VERSAL_CONSOLE_IS(pl011_1)
-# define VERSAL_UART_BASE	VERSAL_UART1_BASE
+#if CONSOLE_IS(pl011) || CONSOLE_IS(dcc)
+# define UART_BASE	VERSAL_UART0_BASE
+#elif CONSOLE_IS(pl011_1)
+# define UART_BASE	VERSAL_UART1_BASE
 #else
 # error "invalid VERSAL_CONSOLE"
 #endif
 
-#define PLAT_VERSAL_CRASH_UART_BASE		VERSAL_UART_BASE
-#define PLAT_VERSAL_CRASH_UART_CLK_IN_HZ	VERSAL_UART_CLOCK
-#define VERSAL_CONSOLE_BAUDRATE			VERSAL_UART_BAUDRATE
-
 /*******************************************************************************
  * Platform related constants
  ******************************************************************************/
 #if VERSAL_PLATFORM_IS(versal_virt)
 # define PLATFORM_NAME		"Versal Virt"
-# define VERSAL_UART_CLOCK	25000000
-# define VERSAL_UART_BAUDRATE	115200
+# define UART_CLOCK	25000000
+# define UART_BAUDRATE	115200
 # define VERSAL_CPU_CLOCK	2720000
 #elif VERSAL_PLATFORM_IS(silicon)
 # define PLATFORM_NAME		"Versal Silicon"
-# define VERSAL_UART_CLOCK	100000000
-# define VERSAL_UART_BAUDRATE	115200
+# define UART_CLOCK	100000000
+# define UART_BAUDRATE	115200
 # define VERSAL_CPU_CLOCK	100000000
 #elif VERSAL_PLATFORM_IS(spp_itr6)
 # define PLATFORM_NAME		"SPP ITR6"
-# define VERSAL_UART_CLOCK	25000000
-# define VERSAL_UART_BAUDRATE	115200
+# define UART_CLOCK	25000000
+# define UART_BAUDRATE	115200
 # define VERSAL_CPU_CLOCK	2720000
 #elif VERSAL_PLATFORM_IS(emu_itr6)
 # define PLATFORM_NAME		"EMU ITR6"
-# define VERSAL_UART_CLOCK	212000
-# define VERSAL_UART_BAUDRATE	9600
+# define UART_CLOCK	212000
+# define UART_BAUDRATE	9600
 # define VERSAL_CPU_CLOCK	212000
 #endif
 
diff --git a/plat/xilinx/versal_net/aarch64/versal_net_helpers.S b/plat/xilinx/versal_net/aarch64/versal_net_helpers.S
index ccebff2..dab8717 100644
--- a/plat/xilinx/versal_net/aarch64/versal_net_helpers.S
+++ b/plat/xilinx/versal_net/aarch64/versal_net_helpers.S
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,9 +16,6 @@
 	.globl	plat_is_my_cpu_primary
 	.globl	platform_mem_init
 	.globl	plat_my_core_pos
-	.globl	plat_crash_console_init
-	.globl	plat_crash_console_putc
-	.globl	plat_crash_console_flush
 
 	/* -----------------------------------------------------
 	 * void plat_secondary_cold_boot_setup (void);
@@ -69,43 +66,3 @@
 func platform_mem_init
 	ret
 endfunc platform_mem_init
-
-
-	/* ---------------------------------------------
-	 * int plat_crash_console_init(void)
-	 * Function to initialize the crash console
-	 * without a C Runtime to print crash report.
-	 * Clobber list : x0, x1, x2
-	 * ---------------------------------------------
-	 */
-func plat_crash_console_init
-/*	mov_imm	x0, PLAT_VERSAL_NET_CRASH_UART_BASE
-	mov_imm	x1, PLAT_VERSAL_NET_CRASH_UART_CLK_IN_HZ
-	mov_imm	x2, VERSAL_NET_CONSOLE_BAUDRATE
-	b	console_pl011_core_init */
-endfunc plat_crash_console_init
-
-	/* ---------------------------------------------
-	 * int plat_crash_console_putc(int c)
-	 * Function to print a character on the crash
-	 * console without a C Runtime.
-	 * Clobber list : x1, x2
-	 * ---------------------------------------------
-	 */
-func plat_crash_console_putc
-	mov_imm	x1, PLAT_VERSAL_NET_CRASH_UART_BASE
-	b	console_pl011_core_putc
-endfunc plat_crash_console_putc
-
-	/* ---------------------------------------------
-	 * void plat_crash_console_flush()
-	 * Function to force a write of all buffered
-	 * data that hasn't been output.
-	 * Out : void.
-	 * Clobber list : x0, x1
-	 * ---------------------------------------------
-	 */
-func plat_crash_console_flush
-	mov_imm	x0, PLAT_VERSAL_NET_CRASH_UART_BASE
-	b	console_pl011_core_flush
-endfunc plat_crash_console_flush
diff --git a/plat/xilinx/versal_net/bl31_versal_net_setup.c b/plat/xilinx/versal_net/bl31_versal_net_setup.c
index d2b6c7b..aa60bbf 100644
--- a/plat/xilinx/versal_net/bl31_versal_net_setup.c
+++ b/plat/xilinx/versal_net/bl31_versal_net_setup.c
@@ -101,20 +101,20 @@
 		panic();
 	}
 
-	if (VERSAL_NET_CONSOLE_IS(pl011_0) || VERSAL_NET_CONSOLE_IS(pl011_1)) {
+	if (CONSOLE_IS(pl011_0) || 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,
+		rc = console_pl011_register(UART_BASE, uart_clock,
+				    UART_BAUDATE,
 				    &versal_net_runtime_console);
 		if (rc == 0) {
 			panic();
 		}
 
 		console_set_scope(&versal_net_runtime_console, CONSOLE_FLAG_BOOT |
-				CONSOLE_FLAG_RUNTIME);
-	} else if (VERSAL_NET_CONSOLE_IS(dcc)) {
+				CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
+	} else if (CONSOLE_IS(dcc)) {
 		/* Initialize the dcc console for debug.
 		 * dcc is over jtag and does not configures uart0 or uart1.
 		 */
@@ -122,6 +122,8 @@
 		if (rc == 0) {
 			panic();
 		}
+	} else {
+		/* No console device found. */
 	}
 
 	NOTICE("TF-A running on %s %d.%d\n", board_name_decode(),
diff --git a/plat/xilinx/versal_net/include/versal_net_def.h b/plat/xilinx/versal_net/include/versal_net_def.h
index 758882c..c242263 100644
--- a/plat/xilinx/versal_net/include/versal_net_def.h
+++ b/plat/xilinx/versal_net/include/versal_net_def.h
@@ -20,7 +20,7 @@
 #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)
+#define CONSOLE_IS(con)	(VERSAL_NET_CONSOLE_ID_ ## con == VERSAL_NET_CONSOLE)
 
 /* List all platforms */
 #define VERSAL_NET_SILICON		U(0)
@@ -135,19 +135,15 @@
 #define VERSAL_NET_UART0_BASE		U(0xF1920000)
 #define VERSAL_NET_UART1_BASE		U(0xF1930000)
 
-#define VERSAL_NET_UART_BAUDRATE	115200
+#define UART_BAUDATE	115200
 
-#if VERSAL_NET_CONSOLE_IS(pl011_1)
-#define VERSAL_NET_UART_BASE		VERSAL_NET_UART1_BASE
+#if CONSOLE_IS(pl011_1)
+#define UART_BASE		VERSAL_NET_UART1_BASE
 #else
 /* Default console is UART0 */
-#define VERSAL_NET_UART_BASE            VERSAL_NET_UART0_BASE
+#define UART_BASE            VERSAL_NET_UART0_BASE
 #endif
 
-#define PLAT_VERSAL_NET_CRASH_UART_BASE		VERSAL_NET_UART_BASE
-#define PLAT_VERSAL_NET_CRASH_UART_CLK_IN_HZ	VERSAL_NET_UART_CLOCK
-#define VERSAL_NET_CONSOLE_BAUDRATE		VERSAL_NET_UART_BAUDRATE
-
 /* Processor core device IDs */
 #define PM_DEV_CLUSTER0_ACPU_0	(0x1810C0AFU)
 #define PM_DEV_CLUSTER0_ACPU_1	(0x1810C0B0U)
diff --git a/plat/xilinx/versal_net/platform.mk b/plat/xilinx/versal_net/platform.mk
index 9c4cfa0..9fa16fd 100644
--- a/plat/xilinx/versal_net/platform.mk
+++ b/plat/xilinx/versal_net/platform.mk
@@ -86,6 +86,7 @@
 				drivers/delay_timer/generic_delay_timer.c	\
 				${GICV3_SOURCES}				\
 				drivers/arm/pl011/aarch64/pl011_console.S	\
+				plat/common/aarch64/crash_console_helpers.S	\
 				plat/arm/common/arm_common.c			\
 				plat/common/plat_gicv3.c			\
 				${PLAT_PATH}/aarch64/versal_net_helpers.S	\
diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
index b584031..e1c8ee8 100644
--- a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
+++ b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
@@ -48,7 +48,7 @@
 	return ver;
 }
 
-uint32_t zynqmp_get_uart_clk(void)
+uint32_t get_uart_clk(void)
 {
 	unsigned int ver = zynqmp_get_silicon_ver();
 
diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
index 56d402f..7bdaf18 100644
--- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
+++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
@@ -73,23 +73,24 @@
 {
 	uint64_t tfa_handoff_addr;
 
-	if (ZYNQMP_CONSOLE_IS(cadence) || (ZYNQMP_CONSOLE_IS(cadence1))) {
+	if (CONSOLE_IS(cadence) || (CONSOLE_IS(cadence1))) {
 		/* Register the console to provide early debug support */
 		static console_t bl31_boot_console;
-		(void)console_cdns_register(ZYNQMP_UART_BASE,
-					       zynqmp_get_uart_clk(),
-					       ZYNQMP_UART_BAUDRATE,
+		(void)console_cdns_register(UART_BASE,
+					       get_uart_clk(),
+					       UART_BAUDRATE,
 					       &bl31_boot_console);
 		console_set_scope(&bl31_boot_console,
-				  CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_BOOT);
-	} else if (ZYNQMP_CONSOLE_IS(dcc)) {
+				  CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_BOOT |
+				  CONSOLE_FLAG_CRASH);
+	} else if (CONSOLE_IS(dcc)) {
 		/* Initialize the dcc console for debug */
 		int32_t rc = console_dcc_register();
 		if (rc == 0) {
 			panic();
 		}
 	} else {
-		ERROR("BL31: No console device found.\n");
+		/* No console device found. */
 	}
 	/* Initialize the platform config for future decision making */
 	zynqmp_config_setup();
diff --git a/plat/xilinx/zynqmp/include/plat_private.h b/plat/xilinx/zynqmp/include/plat_private.h
index 3526b94..dda005a 100644
--- a/plat/xilinx/zynqmp/include/plat_private.h
+++ b/plat/xilinx/zynqmp/include/plat_private.h
@@ -19,7 +19,7 @@
 uint32_t zynqmp_calc_core_pos(u_register_t mpidr);
 
 /* ZynqMP specific functions */
-uint32_t zynqmp_get_uart_clk(void);
+uint32_t get_uart_clk(void);
 uint32_t zynqmp_get_bootmode(void);
 
 #if ZYNQMP_WDT_RESTART
diff --git a/plat/xilinx/zynqmp/include/zynqmp_def.h b/plat/xilinx/zynqmp/include/zynqmp_def.h
index c9f555a..38f2d9b 100644
--- a/plat/xilinx/zynqmp/include/zynqmp_def.h
+++ b/plat/xilinx/zynqmp/include/zynqmp_def.h
@@ -15,7 +15,7 @@
 #define ZYNQMP_CONSOLE_ID_cadence1	2
 #define ZYNQMP_CONSOLE_ID_dcc		3
 
-#define ZYNQMP_CONSOLE_IS(con)	(ZYNQMP_CONSOLE_ID_ ## con == ZYNQMP_CONSOLE)
+#define CONSOLE_IS(con)	(ZYNQMP_CONSOLE_ID_ ## con == ZYNQMP_CONSOLE)
 
 /* Default counter frequency */
 #define ZYNQMP_DEFAULT_COUNTER_FREQ	0U
@@ -144,19 +144,16 @@
 #define ZYNQMP_UART0_BASE		U(0xFF000000)
 #define ZYNQMP_UART1_BASE		U(0xFF010000)
 
-#if ZYNQMP_CONSOLE_IS(cadence) || ZYNQMP_CONSOLE_IS(dcc)
-# define ZYNQMP_UART_BASE	ZYNQMP_UART0_BASE
-#elif ZYNQMP_CONSOLE_IS(cadence1)
-# define ZYNQMP_UART_BASE	ZYNQMP_UART1_BASE
+#if CONSOLE_IS(cadence) || CONSOLE_IS(dcc)
+# define UART_BASE	ZYNQMP_UART0_BASE
+#elif CONSOLE_IS(cadence1)
+# define UART_BASE	ZYNQMP_UART1_BASE
 #else
 # error "invalid ZYNQMP_CONSOLE"
 #endif
 
-#define ZYNQMP_CRASH_UART_BASE		ZYNQMP_UART_BASE
-/* impossible to call C routine how it is done now - hardcode any value */
-#define ZYNQMP_CRASH_UART_CLK_IN_HZ	100000000 /* FIXME */
 /* Must be non zero */
-#define ZYNQMP_UART_BAUDRATE		115200
+#define UART_BAUDRATE		115200
 
 /* Silicon version detection */
 #define ZYNQMP_SILICON_VER_MASK		0xF000
diff --git a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
index 02d0b23..a9f2dbd 100644
--- a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
+++ b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
@@ -22,9 +22,9 @@
 	 * messages from TSP
 	 */
 	static console_t tsp_boot_console;
-	(void)console_cdns_register(ZYNQMP_UART_BASE,
-				       zynqmp_get_uart_clk(),
-				       ZYNQMP_UART_BAUDRATE,
+	(void)console_cdns_register(UART_BASE,
+				       get_uart_clk(),
+				       UART_BAUDRATE,
 				       &tsp_boot_console);
 	console_set_scope(&tsp_boot_console,
 			  CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_BOOT);
diff --git a/services/std_svc/errata_abi/errata_abi_main.c b/services/std_svc/errata_abi/errata_abi_main.c
index 8fee6ac..ca66396 100644
--- a/services/std_svc/errata_abi/errata_abi_main.c
+++ b/services/std_svc/errata_abi/errata_abi_main.c
@@ -310,7 +310,7 @@
 		[1] = {2008768, 0x00, 0x20, ERRATA_A710_2008768},
 		[2] = {2017096, 0x00, 0x20, ERRATA_A710_2017096},
 		[3] = {2055002, 0x10, 0x20, ERRATA_A710_2055002},
-		[4] = {2058056, 0x00, 0x10, ERRATA_A710_2058056},
+		[4] = {2058056, 0x00, 0x20, ERRATA_A710_2058056},
 		[5] = {2081180, 0x00, 0x20, ERRATA_A710_2081180},
 		[6] = {2083908, 0x20, 0x20, ERRATA_A710_2083908},
 		[7] = {2136059, 0x00, 0x20, ERRATA_A710_2136059},
@@ -322,7 +322,8 @@
 		[13] = {2371105, 0x00, 0x20, ERRATA_A710_2371105},
 		[14] = {2701952, 0x00, 0x21, ERRATA_A710_2701952, \
 			ERRATA_NON_ARM_INTERCONNECT},
-		[15] = {2768515, 0x00, 0x21, ERRATA_A710_2768515}
+		[15] = {2768515, 0x00, 0x21, ERRATA_A710_2768515},
+		[16 ... ERRATA_LIST_END] = UNDEF_ERRATA,
 	}
 },
 #endif /* CORTEX_A710_H_INC */
@@ -400,10 +401,14 @@
 {
 	.cpu_partnumber = NEOVERSE_V2_MIDR,
 	.cpu_errata_list = {
-		[0] = {2719103, 0x00, 0x01, ERRATA_V2_2719103, \
+		[0] = {2331132, 0x00, 0x02, ERRATA_V2_2331132},
+		[1] = {2719103, 0x00, 0x01, ERRATA_V2_2719103, \
 			ERRATA_NON_ARM_INTERCONNECT},
-		[1] = {2801372, 0x00, 0x01, ERRATA_V2_2801372},
-		[2 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+		[2] = {2719105, 0x00, 0x01, ERRATA_V2_2719105},
+		[3] = {2743011, 0x00, 0x01, ERRATA_V2_2743011},
+		[4] = {2779510, 0x00, 0x01, ERRATA_V2_2779510},
+		[5] = {2801372, 0x00, 0x01, ERRATA_V2_2801372},
+		[6 ... ERRATA_LIST_END] = UNDEF_ERRATA,
 	}
 },
 #endif /* NEOVERSE_V2_H_INC */
diff --git a/services/std_svc/spmd/spmd_logical_sp.c b/services/std_svc/spmd/spmd_logical_sp.c
index 964b36b..d992187 100644
--- a/services/std_svc/spmd/spmd_logical_sp.c
+++ b/services/std_svc/spmd/spmd_logical_sp.c
@@ -356,7 +356,7 @@
  * other code to consume.
  */
 bool ffa_partition_info_regs_get_part_info(
-	struct ffa_value args, uint8_t idx,
+	struct ffa_value *args, uint8_t idx,
 	struct ffa_partition_info_v1_1 *partition_info)
 {
 	uint64_t *arg_ptrs;
@@ -375,7 +375,7 @@
 	 * function, arg1 is reserved, arg2 encodes indices. arg3 and greater
 	 * values reflect partition properties.
 	 */
-	arg_ptrs = (uint64_t *)&args + ((idx * 3) + 3);
+	arg_ptrs = (uint64_t *)args + ((idx * 3) + 3);
 	info = *arg_ptrs;
 
 	arg_ptrs++;
diff --git a/tools/cert_create/src/cca/cot.c b/tools/cert_create/src/cca/cot.c
index e39b036..372d908 100644
--- a/tools/cert_create/src/cca/cot.c
+++ b/tools/cert_create/src/cca/cot.c
@@ -414,35 +414,35 @@
 	[ROT_KEY] = {
 		.id = ROT_KEY,
 		.opt = "rot-key",
-		.help_msg = "Root Of Trust key (input/output file)",
+		.help_msg = "Root Of Trust key file or PKCS11 URI",
 		.desc = "Root Of Trust key"
 	},
 
 	[SWD_ROT_KEY] = {
 		.id = SWD_ROT_KEY,
 		.opt = "swd-rot-key",
-		.help_msg = "Secure World Root of Trust key",
+		.help_msg = "Secure World Root of Trust key file or PKCS11 URI",
 		.desc = "Secure World Root of Trust key"
 	},
 
 	[CORE_SWD_KEY] = {
 		.id = CORE_SWD_KEY,
 		.opt = "core-swd-key",
-		.help_msg = "Core Secure World key",
+		.help_msg = "Core Secure World key file or PKCS11 URI",
 		.desc = "Core Secure World key"
 	},
 
 	[PROT_KEY] = {
 		.id = PROT_KEY,
 		.opt = "prot-key",
-		.help_msg = "Platform Root of Trust key",
+		.help_msg = "Platform Root of Trust key file or PKCS11 URI",
 		.desc = "Platform Root of Trust key"
 	},
 
 	[PLAT_KEY] = {
 		.id = PLAT_KEY,
 		.opt = "plat-key",
-		.help_msg = "Platform key",
+		.help_msg = "Platform key file or PKCS11 URI",
 		.desc = "Platform key"
 	},
 };
diff --git a/tools/cert_create/src/dualroot/cot.c b/tools/cert_create/src/dualroot/cot.c
index 4dd4cf0..81a7d75 100644
--- a/tools/cert_create/src/dualroot/cot.c
+++ b/tools/cert_create/src/dualroot/cot.c
@@ -540,42 +540,42 @@
 	[ROT_KEY] = {
 		.id = ROT_KEY,
 		.opt = "rot-key",
-		.help_msg = "Root Of Trust key (input/output file)",
+		.help_msg = "Root Of Trust key file or PKCS11 URI",
 		.desc = "Root Of Trust key"
 	},
 
 	[TRUSTED_WORLD_KEY] = {
 		.id = TRUSTED_WORLD_KEY,
 		.opt = "trusted-world-key",
-		.help_msg = "Trusted World key (input/output file)",
+		.help_msg = "Trusted World key file or PKCS11 URI",
 		.desc = "Trusted World key"
 	},
 
 	[SCP_FW_CONTENT_CERT_KEY] = {
 		.id = SCP_FW_CONTENT_CERT_KEY,
 		.opt = "scp-fw-key",
-		.help_msg = "SCP Firmware Content Certificate key (input/output file)",
+		.help_msg = "SCP Firmware Content Certificate key file or PKCS11 URI",
 		.desc = "SCP Firmware Content Certificate key"
 	},
 
 	[SOC_FW_CONTENT_CERT_KEY] = {
 		.id = SOC_FW_CONTENT_CERT_KEY,
 		.opt = "soc-fw-key",
-		.help_msg = "SoC Firmware Content Certificate key (input/output file)",
+		.help_msg = "SoC Firmware Content Certificate key file or PKCS11 URI",
 		.desc = "SoC Firmware Content Certificate key"
 	},
 
 	[TRUSTED_OS_FW_CONTENT_CERT_KEY] = {
 		.id = TRUSTED_OS_FW_CONTENT_CERT_KEY,
 		.opt = "tos-fw-key",
-		.help_msg = "Trusted OS Firmware Content Certificate key (input/output file)",
+		.help_msg = "Trusted OS Firmware Content Certificate key file or PKCS11 URI",
 		.desc = "Trusted OS Firmware Content Certificate key"
 	},
 
 	[PROT_KEY] = {
 		.id = PROT_KEY,
 		.opt = "prot-key",
-		.help_msg = "Platform Root of Trust key",
+		.help_msg = "Platform Root of Trust key file or PKCS11 URI",
 		.desc = "Platform Root of Trust key"
 	},
 };
diff --git a/tools/cert_create/src/key.c b/tools/cert_create/src/key.c
index 27ec979..32229d1 100644
--- a/tools/cert_create/src/key.c
+++ b/tools/cert_create/src/key.c
@@ -9,7 +9,11 @@
 #include <stdlib.h>
 #include <string.h>
 
+/* Suppress OpenSSL engine deprecation warnings */
+#define OPENSSL_SUPPRESS_DEPRECATED
+
 #include <openssl/conf.h>
+#include <openssl/engine.h>
 #include <openssl/evp.h>
 #include <openssl/pem.h>
 
@@ -189,30 +193,69 @@
 	return 0;
 }
 
+static EVP_PKEY *key_load_pkcs11(const char *uri)
+{
+	char *key_pass;
+	EVP_PKEY *pkey;
+	ENGINE *e;
+
+	ENGINE_load_builtin_engines();
+	e = ENGINE_by_id("pkcs11");
+	if (!e) {
+		fprintf(stderr, "Cannot Load PKCS#11 ENGINE\n");
+		return NULL;
+	}
+
+	if (!ENGINE_init(e)) {
+		fprintf(stderr, "Cannot ENGINE_init\n");
+		goto err;
+	}
+
+	key_pass = getenv("PKCS11_PIN");
+	if (key_pass) {
+		if (!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0)) {
+			fprintf(stderr, "Cannot Set PKCS#11 PIN\n");
+			goto err;
+		}
+	}
+
+	pkey = ENGINE_load_private_key(e, uri, NULL, NULL);
+	if (pkey)
+		return pkey;
+err:
+	ENGINE_free(e);
+	return NULL;
+
+}
+
 int key_load(key_t *key, unsigned int *err_code)
 {
 	FILE *fp;
-	EVP_PKEY *k;
 
 	if (key->fn) {
-		/* Load key from file */
-		fp = fopen(key->fn, "r");
-		if (fp) {
-			k = PEM_read_PrivateKey(fp, &key->key, NULL, NULL);
-			fclose(fp);
-			if (k) {
-				*err_code = KEY_ERR_NONE;
-				return 1;
+		if (!strncmp(key->fn, "pkcs11:", 7)) {
+			/* Load key through pkcs11 */
+			key->key = key_load_pkcs11(key->fn);
+		} else {
+			/* Load key from file */
+			fp = fopen(key->fn, "r");
+			if (fp) {
+				key->key = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
+				fclose(fp);
 			} else {
-				ERROR("Cannot load key from %s\n", key->fn);
-				*err_code = KEY_ERR_LOAD;
+				WARN("Cannot open file %s\n", key->fn);
+				*err_code = KEY_ERR_OPEN;
 			}
+		}
+		if (key->key) {
+			*err_code = KEY_ERR_NONE;
+			return 1;
 		} else {
-			WARN("Cannot open file %s\n", key->fn);
-			*err_code = KEY_ERR_OPEN;
+			ERROR("Cannot load key from %s\n", key->fn);
+			*err_code = KEY_ERR_LOAD;
 		}
 	} else {
-		VERBOSE("Key filename not specified\n");
+		VERBOSE("Key not specified\n");
 		*err_code = KEY_ERR_FILENAME;
 	}
 
@@ -224,6 +267,10 @@
 	FILE *fp;
 
 	if (key->fn) {
+		if (!strncmp(key->fn, "pkcs11:", 7)) {
+			ERROR("PKCS11 URI provided instead of a file");
+			return 0;
+		}
 		fp = fopen(key->fn, "w");
 		if (fp) {
 			PEM_write_PrivateKey(fp, key->key,
diff --git a/tools/cert_create/src/tbbr/tbb_key.c b/tools/cert_create/src/tbbr/tbb_key.c
index a81f0e4..5b84b6e 100644
--- a/tools/cert_create/src/tbbr/tbb_key.c
+++ b/tools/cert_create/src/tbbr/tbb_key.c
@@ -15,43 +15,43 @@
 	[ROT_KEY] = {
 		.id = ROT_KEY,
 		.opt = "rot-key",
-		.help_msg = "Root Of Trust key (input/output file)",
+		.help_msg = "Root Of Trust key file or PKCS11 URI",
 		.desc = "Root Of Trust key"
 	},
 	[TRUSTED_WORLD_KEY] = {
 		.id = TRUSTED_WORLD_KEY,
 		.opt = "trusted-world-key",
-		.help_msg = "Trusted World key (input/output file)",
+		.help_msg = "Trusted World key file or PKCS11 URI",
 		.desc = "Trusted World key"
 	},
 	[NON_TRUSTED_WORLD_KEY] = {
 		.id = NON_TRUSTED_WORLD_KEY,
 		.opt = "non-trusted-world-key",
-		.help_msg = "Non Trusted World key (input/output file)",
+		.help_msg = "Non Trusted World key file or PKCS11 URI",
 		.desc = "Non Trusted World key"
 	},
 	[SCP_FW_CONTENT_CERT_KEY] = {
 		.id = SCP_FW_CONTENT_CERT_KEY,
 		.opt = "scp-fw-key",
-		.help_msg = "SCP Firmware Content Certificate key (input/output file)",
+		.help_msg = "SCP Firmware Content Certificate key file or PKCS11 URI",
 		.desc = "SCP Firmware Content Certificate key"
 	},
 	[SOC_FW_CONTENT_CERT_KEY] = {
 		.id = SOC_FW_CONTENT_CERT_KEY,
 		.opt = "soc-fw-key",
-		.help_msg = "SoC Firmware Content Certificate key (input/output file)",
+		.help_msg = "SoC Firmware Content Certificate key file or PKCS11 URI",
 		.desc = "SoC Firmware Content Certificate key"
 	},
 	[TRUSTED_OS_FW_CONTENT_CERT_KEY] = {
 		.id = TRUSTED_OS_FW_CONTENT_CERT_KEY,
 		.opt = "tos-fw-key",
-		.help_msg = "Trusted OS Firmware Content Certificate key (input/output file)",
+		.help_msg = "Trusted OS Firmware Content Certificate key file or PKCS11 URI",
 		.desc = "Trusted OS Firmware Content Certificate key"
 	},
 	[NON_TRUSTED_FW_CONTENT_CERT_KEY] = {
 		.id = NON_TRUSTED_FW_CONTENT_CERT_KEY,
 		.opt = "nt-fw-key",
-		.help_msg = "Non Trusted Firmware Content Certificate key (input/output file)",
+		.help_msg = "Non Trusted Firmware Content Certificate key file or PKCS11 URI",
 		.desc = "Non Trusted Firmware Content Certificate key"
 	}
 };
diff --git a/tools/fiptool/Makefile b/tools/fiptool/Makefile
index 4bdebd9..fda7c77 100644
--- a/tools/fiptool/Makefile
+++ b/tools/fiptool/Makefile
@@ -13,8 +13,7 @@
 PROJECT := $(notdir ${FIPTOOL})
 OBJECTS := fiptool.o tbbr_config.o
 V ?= 0
-OPENSSL_DIR := /usr
-
+STATIC ?= 0
 
 override CPPFLAGS += -D_GNU_SOURCE -D_XOPEN_SOURCE=700
 HOSTCCFLAGS := -Wall -Werror -pedantic -std=c99
@@ -24,14 +23,22 @@
   HOSTCCFLAGS += -O2
 endif
 
+INCLUDE_PATHS := -I../../include/tools_share
+
+DEFINES += -DSTATIC=$(STATIC)
+
+ifeq (${STATIC},1)
+LDOPTS := -static
+else
+OPENSSL_DIR := /usr
+
 # Select OpenSSL version flag according to the OpenSSL build selected
 # from setting the OPENSSL_DIR path.
 $(eval $(call SELECT_OPENSSL_API_VERSION))
 
-HOSTCCFLAGS += ${DEFINES}
 # USING_OPENSSL3 flag will be added to the HOSTCCFLAGS variable with the proper
 # computed value.
-HOSTCCFLAGS += -DUSING_OPENSSL3=$(USING_OPENSSL3)
+DEFINES += -DUSING_OPENSSL3=$(USING_OPENSSL3)
 
 # Include library directories where OpenSSL library files are located.
 # For a normal installation (i.e.: when ${OPENSSL_DIR} = /usr or
@@ -39,7 +46,11 @@
 # directory. However, for a local build of OpenSSL, the built binaries are
 # located under the main project directory (i.e.: ${OPENSSL_DIR}, not
 # ${OPENSSL_DIR}/lib/).
-LDLIBS := -L${OPENSSL_DIR}/lib -L${OPENSSL_DIR} -lcrypto
+LDOPTS := -L${OPENSSL_DIR}/lib -L${OPENSSL_DIR} -lcrypto
+INCLUDE_PATHS += -I${OPENSSL_DIR}/include
+endif # STATIC
+
+HOSTCCFLAGS += ${DEFINES}
 
 ifeq (${V},0)
   Q := @
@@ -47,8 +58,6 @@
   Q :=
 endif
 
-INCLUDE_PATHS := -I../../include/tools_share  -I${OPENSSL_DIR}/include
-
 HOSTCC ?= gcc
 
 ifneq (${PLAT},)
@@ -72,7 +81,7 @@
 
 ${PROJECT}: ${OBJECTS} Makefile
 	@echo "  HOSTLD  $@"
-	${Q}${HOSTCC} ${OBJECTS} -o $@ ${LDLIBS}
+	${Q}${HOSTCC} ${OBJECTS} -o $@ $(LDOPTS)
 	@${ECHO_BLANK_LINE}
 	@echo "Built $@ successfully"
 	@${ECHO_BLANK_LINE}
@@ -84,10 +93,11 @@
 -include $(DEPS)
 
 --openssl:
+ifeq ($(STATIC),0)
 ifeq ($(DEBUG),1)
 	@echo "Selected OpenSSL version: ${OPENSSL_CURRENT_VER}"
 endif
-
+endif # STATIC
 
 clean:
 	$(call SHELL_DELETE_ALL, ${PROJECT} ${OBJECTS} $(DEPS))
diff --git a/tools/fiptool/fiptool.c b/tools/fiptool/fiptool.c
index fadf319..6c566ef 100644
--- a/tools/fiptool/fiptool.c
+++ b/tools/fiptool/fiptool.c
@@ -460,6 +460,7 @@
 	return opts;
 }
 
+#if !STATIC
 static void md_print(const unsigned char *md, size_t len)
 {
 	size_t i;
@@ -467,6 +468,7 @@
 	for (i = 0; i < len; i++)
 		printf("%02x", md[i]);
 }
+#endif
 
 static int info_cmd(int argc, char *argv[])
 {
@@ -498,7 +500,13 @@
 		       (unsigned long long)image->toc_e.offset_address,
 		       (unsigned long long)image->toc_e.size,
 		       desc->cmdline_name);
-#ifndef _MSC_VER	/* We don't have SHA256 for Visual Studio. */
+
+		/*
+		 * Omit this informative code portion for:
+		 * Visual Studio missing SHA256.
+		 * Statically linked builds.
+		 */
+#if !defined(_MSC_VER) && !STATIC
 		if (verbose) {
 			unsigned char md[SHA256_DIGEST_LENGTH];