Merge changes from topic "dcc-console" into integration

* changes:
  fix(dcc): enable DCC also for crash console
  build(changelog): add new scope for DCC
diff --git a/.versionrc.js b/.versionrc.js
index 3a21ded..c7ee4a2 100644
--- a/.versionrc.js
+++ b/.versionrc.js
@@ -129,16 +129,19 @@
                 "readVersion": function (contents) {
                     const major = contents.match(/^VERSION_MAJOR\s*:=\s*(\d+?)$/m)[1];
                     const minor = contents.match(/^VERSION_MINOR\s*:=\s*(\d+?)$/m)[1];
+                    const patch = contents.match(/^VERSION_PATCH\s*:=\s*(\d+?)$/m)[1];
 
-                    return `${major}.${minor}.0`;
+                    return `${major}.${minor}.${patch}`;
                 },
 
                 "writeVersion": function (contents, version) {
                     const major = version.split(".")[0];
                     const minor = version.split(".")[1];
+                    const patch = version.split(".")[2];
 
                     contents = contents.replace(/^(VERSION_MAJOR\s*:=\s*)(\d+?)$/m, `$1${major}`);
                     contents = contents.replace(/^(VERSION_MINOR\s*:=\s*)(\d+?)$/m, `$1${minor}`);
+                    contents = contents.replace(/^(VERSION_PATCH\s*:=\s*)(\d+?)$/m, `$1${patch}`);
 
                     return contents;
                 }
diff --git a/Makefile b/Makefile
index 1cce234..907ae21 100644
--- a/Makefile
+++ b/Makefile
@@ -9,7 +9,8 @@
 #
 VERSION_MAJOR			:= 2
 VERSION_MINOR			:= 9
-VERSION				:= ${VERSION_MAJOR}.${VERSION_MINOR}
+VERSION_PATCH			:= 0
+VERSION				:= ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}
 
 # Default goal is build all images
 .DEFAULT_GOAL			:= all
@@ -598,6 +599,12 @@
 		ifneq ($(SP_LAYOUT_FILE),)
 		BL2_ENABLE_SP_LOAD := 1
 		endif
+
+		ifeq ($(SPMC_AT_EL3_SEL0_SP),1)
+			ifneq ($(SPMC_AT_EL3),1)
+			$(error SEL0 SP cannot be enabled without SPMC at EL3)
+			endif
+		endif
 	else
 		# All other SPDs in spd directory
 		SPD_DIR := spd
@@ -979,13 +986,6 @@
 	endif
 endif #(ARCH=aarch32)
 
-# Ensure ENABLE_RME is not used with SME
-ifeq (${ENABLE_RME},1)
-	ifneq (${ENABLE_SME_FOR_NS},0)
-                $(error "ENABLE_SME_FOR_NS cannot be used with ENABLE_RME")
-	endif
-endif
-
 ifneq (${ENABLE_SME_FOR_NS},0)
 	ifeq (${ENABLE_SVE_FOR_NS},0)
                 $(error "ENABLE_SME_FOR_NS requires ENABLE_SVE_FOR_NS")
@@ -1027,6 +1027,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`)
@@ -1039,6 +1043,10 @@
 # Determine if FEAT_SB is supported
 ENABLE_FEAT_SB		=	$(if $(findstring sb,${arch-features}),1,0)
 
+ifeq ($(PSA_CRYPTO),1)
+        $(info PSA_CRYPTO is an experimental feature)
+endif
+
 ################################################################################
 # Process platform overrideable behaviour
 ################################################################################
@@ -1189,8 +1197,10 @@
 	SPIN_ON_BL1_EXIT \
 	SPM_MM \
 	SPMC_AT_EL3 \
+	SPMC_AT_EL3_SEL0_SP \
 	SPMD_SPM_AT_SEL2 \
 	ENABLE_SPMD_LP \
+	TRANSFER_LIST \
 	TRUSTED_BOARD_BOOT \
 	USE_COHERENT_MEM \
 	USE_DEBUGFS \
@@ -1219,6 +1229,8 @@
 	ERRATA_NON_ARM_INTERCONNECT \
 	CONDITIONAL_CMO \
 	RAS_FFH_SUPPORT \
+	PSA_CRYPTO	\
+	ENABLE_CONSOLE_GETC \
 )))
 
 # Numeric_Flags
@@ -1350,7 +1362,9 @@
 	SPIN_ON_BL1_EXIT \
 	SPM_MM \
 	SPMC_AT_EL3 \
+	SPMC_AT_EL3_SEL0_SP \
 	SPMD_SPM_AT_SEL2 \
+	TRANSFER_LIST \
 	TRUSTED_BOARD_BOOT \
 	CRYPTO_SUPPORT \
 	TRNG_SUPPORT \
@@ -1408,6 +1422,8 @@
 	IMPDEF_SYSREG_TRAP \
 	SVE_VECTOR_LEN \
 	ENABLE_SPMD_LP \
+	PSA_CRYPTO	\
+	ENABLE_CONSOLE_GETC \
 )))
 
 ifeq (${SANITIZE_UB},trap)
diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S
index 7a8c41a..773b41d 100644
--- a/bl31/bl31.ld.S
+++ b/bl31/bl31.ld.S
@@ -101,7 +101,7 @@
     ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
         "cpu_ops not defined for this platform.")
 
-#if SPM_MM
+#if SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)
 #   ifndef SPM_SHIM_EXCEPTIONS_VMA
 #       define SPM_SHIM_EXCEPTIONS_VMA RAM
 #   endif /* SPM_SHIM_EXCEPTIONS_VMA */
@@ -128,7 +128,7 @@
     PROVIDE(__SPM_SHIM_EXCEPTIONS_LMA__ = LOADADDR(.spm_shim_exceptions));
 
     . = LOADADDR(.spm_shim_exceptions) + SIZEOF(.spm_shim_exceptions);
-#endif /* SPM_MM */
+#endif /* SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP) */
 
     __RW_START__ = .;
 
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 cdb0182..33e5e8c 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -790,6 +790,9 @@
       - title: Semihosting
         scope: semihosting
 
+      - title: Firmware Handoff
+        scope: handoff
+
   - title: Drivers
 
     subsections:
@@ -809,6 +812,9 @@
           - title: mbedTLS
             scope: mbedtls
 
+          - title: mbedTLS-PSA
+            scope: mbedtls-psa
+
       - title: Console
         scope: console
 
@@ -905,6 +911,9 @@
                   - title: GIC-600AE
                     scope: gic600ae
 
+              - title: GICv2
+                scope: gicv2
+
           - title: SMMU
             scope: smmu
 
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/components/secure-partition-manager.rst b/docs/components/secure-partition-manager.rst
index d4f0b00..5d3adec 100644
--- a/docs/components/secure-partition-manager.rst
+++ b/docs/components/secure-partition-manager.rst
@@ -152,6 +152,8 @@
   exception level is set to S-EL1.
   ``SPMD_SPM_AT_SEL2`` is enabled. The context save/restore routine
   and exhaustive list of registers is visible at `[4]`_.
+- **SPMC_AT_EL3_SEL0_SP**: this option enables the support to load SEL0 SP
+  when SPMC at EL3 support is enabled.
 - **SP_LAYOUT_FILE**: this option specifies a text description file
   providing paths to SP binary images and manifests in DTS format
   (see `Describing secure partitions`_). It
@@ -257,6 +259,22 @@
     PLAT=fvp \
     all fip
 
+Sample TF-A build command line when the SPMC is located at EL3 and SEL0 SP is
+enabled:
+
+.. code:: shell
+
+    make \
+    CROSS_COMPILE=aarch64-none-elf- \
+    SPD=spmd \
+    SPMD_SPM_AT_SEL2=0 \
+    SPMC_AT_EL3=1 \
+    SPMC_AT_EL3_SEL0_SP=1 \
+    BL32=<path-to-tee-binary> \
+    BL33=<path-to-bl33-binary> \
+    PLAT=fvp \
+    all fip
+
 FVP model invocation
 ====================
 
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index bf04558..ad05a50 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -726,6 +726,10 @@
 
 For Cortex-X3, the following errata build flags are defined :
 
+- ``ERRATA_X3_2070301``: This applies errata 2070301 workaround to the Cortex-X3
+  CPU. This needs to be enabled only for revisions r0p0, r1p0, r1p1 and r1p2 of
+  the CPU and is still open.
+
 - ``ERRATA_X3_2313909``: This applies errata 2313909 workaround to
   Cortex-X3 CPU. This needs to be enabled only for revisions r0p0 and r1p0
   of the CPU, it is fixed in r1p1.
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 1da2738..cd70a22 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -452,9 +452,9 @@
    world to trap to EL3. Requires ``ENABLE_SVE_FOR_NS`` to be set as SME is a
    superset of SVE. SME is an optional architectural feature for AArch64
    and TF-A support is experimental. At this time, this build option cannot be
-   used on systems that have SPD=spmd/SPM_MM or ENABLE_RME, and attempting to
-   build with these options will fail. This flag can take the values 0 to 2, to
-   align with the ``FEATURE_DETECTION`` mechanism. Default is 0.
+   used on systems that have SPD=spmd/SPM_MM and atempting to build with this
+   option will fail. This flag can take the values 0 to 2, to align with the
+   ``FEATURE_DETECTION`` mechanism. Default is 0.
 
 -  ``ENABLE_SME2_FOR_NS``: Numeric value to enable Scalable Matrix Extension
    version 2 (SME2) for the non-secure world only. SME2 is an optional
@@ -692,7 +692,7 @@
    +===========================+====================================+
    |           rsa             | 1024 , 2048 (default), 3072, 4096* |
    +---------------------------+------------------------------------+
-   |          ecdsa            |            unavailable             |
+   |          ecdsa            |         256 (default), 384         |
    +---------------------------+------------------------------------+
    |  ecdsa-brainpool-regular  |            unavailable             |
    +---------------------------+------------------------------------+
@@ -900,6 +900,10 @@
    disabled). This configuration supports pre-Armv8.4 platforms (aka not
    implementing the ``FEAT_SEL2`` extension). This is an experimental feature.
 
+-  ``SPMC_AT_EL3_SEL0_SP`` : Boolean option to enable SEL0 SP load support when
+   ``SPMC_AT_EL3`` is enabled. The default value if ``0`` (disabled). This
+   option cannot be enabled (``1``) when (``SPMC_AT_EL3``) is disabled.
+
 -  ``SPMC_OPTEE`` : This boolean option is used jointly with the SPM
    Dispatcher option (``SPD=spmd``) and with ``SPMD_SPM_AT_SEL2=0`` to
    indicate that the SPMC at S-EL1 is OP-TEE and an OP-TEE specific loading
@@ -945,6 +949,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``.
 
@@ -1180,6 +1189,18 @@
   errata mitigation for platforms with a non-arm interconnect using the errata
   ABI. By default its disabled (``0``).
 
+- ``PSA_CRYPTO``: Boolean option for enabling MbedTLS PSA crypto APIs support.
+  The platform will use PSA compliant Crypto APIs during authentication and
+  image measurement process by enabling this option. It uses APIs defined as
+  per the `PSA Crypto API specification`_. This feature is only supported if
+  using MbedTLS 3.x version. By default it is disabled (``0``).
+
+- ``ENABLE_CONSOLE_GETC``: Boolean option to enable `getc()` feature in console
+  driver(s). By default it is disabled (``0``) because it constitutes an attack
+  vector into TF-A by potentially allowing an attacker to inject arbitrary data.
+  This option should only be enabled on a need basis if there is a use case for
+  reading characters from the console.
+
 GICv3 driver options
 --------------------
 
@@ -1300,3 +1321,5 @@
 .. _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
+.. _PSA Crypto API specification: https://armmbed.github.io/mbed-crypto/html/
diff --git a/docs/getting_started/prerequisites.rst b/docs/getting_started/prerequisites.rst
index 332ed58..573abdf 100644
--- a/docs/getting_started/prerequisites.rst
+++ b/docs/getting_started/prerequisites.rst
@@ -26,7 +26,7 @@
 |TF-A| can be built with any of the following *cross-compiler* toolchains that
 target the Armv7-A or Armv8-A architectures:
 
-- GCC >= 12.2.Rel1 (from the `Arm Developer website`_)
+- TF-A has been tested with version 12.3.Rel1 (gcc 12.3) from the `Arm Developer website`_
 
    You will need the targets ``arm-none-eabi`` and ``aarch64-none-elf`` for
    AArch32 and AArch64 builds respectively.
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/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/process/faq.rst b/docs/process/faq.rst
index daab198..0f33bc0 100644
--- a/docs/process/faq.rst
+++ b/docs/process/faq.rst
@@ -67,9 +67,11 @@
 What are these strange comments in my changes?
 ----------------------------------------------
 
-All the comments from ``ci-bot-user`` are associated with Continuous Integration
-infrastructure. The links published on the comment are not currently accessible,
-but would be after the CI has been transitioned to `trustedfirmware.org`_.
+All the comments from ``TrustedFirmware Code Review`` user (email:
+``ci@trustedfirmware.org``) are associated with Continuous Integration (CI)
+infrastructure. The links published on the comments redirect to the CI web
+interface at http://ci.trustedfirmware.org, where details of the tests failures,
+if any, can be examined.
 
 --------------
 
@@ -77,4 +79,3 @@
 
 .. _Gerrit Upload Patch Set documentation: https://review.trustedfirmware.org/Documentation/intro-user.html#upload-patch-set
 .. _Gerrit Replace Changes documentation: https://review.trustedfirmware.org/Documentation/user-upload.html#push_replace
-.. _trustedfirmware.org: https://www.trustedfirmware.org/
diff --git a/docs/process/security-hardening.rst b/docs/process/security-hardening.rst
index f9618db..eace467 100644
--- a/docs/process/security-hardening.rst
+++ b/docs/process/security-hardening.rst
@@ -135,6 +135,16 @@
   it is recommended to develop against ``W=2`` (which will eventually become the
   default).
 
+Additional guidelines are provided below for some security-related build
+options:
+
+- The ``ENABLE_CONSOLE_GETC`` build flag should be set to 0 to disable the
+  `getc()` feature, which allows the firmware to read characters from the
+  console. Keeping this feature enabled is considered dangerous from a security
+  point of view because it potentially allows an attacker to inject arbitrary
+  data into the firmware. It should only be enabled on a need basis if there is
+  a use case for it, for example in a testing or factory environment.
+
 .. rubric:: References
 
 -  `Arm ARM`_
diff --git a/drivers/amlogic/console/aarch64/meson_console.S b/drivers/amlogic/console/aarch64/meson_console.S
index 6d0a2d6..d955d83 100644
--- a/drivers/amlogic/console/aarch64/meson_console.S
+++ b/drivers/amlogic/console/aarch64/meson_console.S
@@ -69,7 +69,7 @@
 
 	mov	x0, x6
 	mov	x30, x7
-	finish_console_register meson putc=1, getc=1, flush=1
+	finish_console_register meson putc=1, getc=ENABLE_CONSOLE_GETC, flush=1
 
 register_fail:
 	ret	x7
diff --git a/drivers/arm/dcc/dcc_console.c b/drivers/arm/dcc/dcc_console.c
index 599f471..19c3450 100644
--- a/drivers/arm/dcc/dcc_console.c
+++ b/drivers/arm/dcc/dcc_console.c
@@ -53,6 +53,7 @@
 	return read_mdccsr_el0();
 }
 
+#if ENABLE_CONSOLE_GETC
 static inline char __dcc_getchar(void)
 {
 	char c;
@@ -61,6 +62,7 @@
 
 	return c;
 }
+#endif
 
 static inline void __dcc_putchar(char c)
 {
@@ -102,6 +104,7 @@
 	return ch;
 }
 
+#if ENABLE_CONSOLE_GETC
 static int32_t dcc_console_getc(struct console *console)
 {
 	unsigned int status;
@@ -113,12 +116,7 @@
 
 	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 */
-}
+#endif
 
 /**
  * dcc_console_flush() - Function to force a write of all buffered data
@@ -142,7 +140,9 @@
 			CONSOLE_FLAG_RUNTIME |
 			CONSOLE_FLAG_CRASH,
 		.putc = dcc_console_putc,
+#if ENABLE_CONSOLE_GETC
 		.getc = dcc_console_getc,
+#endif
 		.flush = dcc_console_flush,
 	},
 };
@@ -151,3 +151,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/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/arm/pl011/aarch32/pl011_console.S b/drivers/arm/pl011/aarch32/pl011_console.S
index 9caeb0c..b7d1747 100644
--- a/drivers/arm/pl011/aarch32/pl011_console.S
+++ b/drivers/arm/pl011/aarch32/pl011_console.S
@@ -116,7 +116,7 @@
 
 	mov	r0, r4
 	pop	{r4, lr}
-	finish_console_register pl011 putc=1, getc=1, flush=1
+	finish_console_register pl011 putc=1, getc=ENABLE_CONSOLE_GETC, flush=1
 
 register_fail:
 	pop	{r4, pc}
diff --git a/drivers/arm/pl011/aarch64/pl011_console.S b/drivers/arm/pl011/aarch64/pl011_console.S
index 861d2ed..8cb0122 100644
--- a/drivers/arm/pl011/aarch64/pl011_console.S
+++ b/drivers/arm/pl011/aarch64/pl011_console.S
@@ -103,7 +103,7 @@
 
 	mov	x0, x6
 	mov	x30, x7
-	finish_console_register pl011 putc=1, getc=1, flush=1
+	finish_console_register pl011 putc=1, getc=ENABLE_CONSOLE_GETC, flush=1
 
 register_fail:
 	ret	x7
diff --git a/drivers/auth/mbedtls/mbedtls_common.mk b/drivers/auth/mbedtls/mbedtls_common.mk
index 79c4512..e380c86 100644
--- a/drivers/auth/mbedtls/mbedtls_common.mk
+++ b/drivers/auth/mbedtls/mbedtls_common.mk
@@ -23,7 +23,11 @@
 ifeq (${MBEDTLS_MAJOR}, 2)
 	MBEDTLS_CONFIG_FILE	?=	"<drivers/auth/mbedtls/mbedtls_config-2.h>"
 else ifeq (${MBEDTLS_MAJOR}, 3)
-	MBEDTLS_CONFIG_FILE	?=	"<drivers/auth/mbedtls/mbedtls_config-3.h>"
+	ifeq (${PSA_CRYPTO},1)
+		MBEDTLS_CONFIG_FILE     ?=      "<drivers/auth/mbedtls/psa_mbedtls_config.h>"
+	else
+		MBEDTLS_CONFIG_FILE	?=	"<drivers/auth/mbedtls/mbedtls_config-3.h>"
+	endif
 endif
 
 $(eval $(call add_define,MBEDTLS_CONFIG_FILE))
@@ -77,6 +81,18 @@
 	LIBMBEDTLS_CFLAGS += -Wno-error=redundant-decls
 endif
 
+ifeq (${PSA_CRYPTO},1)
+LIBMBEDTLS_SRCS         += $(addprefix ${MBEDTLS_DIR}/library/,    	\
+					psa_crypto.c                   	\
+					psa_crypto_client.c            	\
+					psa_crypto_driver_wrappers.c   	\
+					psa_crypto_hash.c              	\
+					psa_crypto_rsa.c               	\
+					psa_crypto_ecp.c               	\
+					psa_crypto_slot_management.c   	\
+					)
+endif
+
 # The platform may define the variable 'TF_MBEDTLS_KEY_ALG' to select the key
 # algorithm to use. If the variable is not defined, select it based on
 # algorithm used for key generation `KEY_ALG`. If `KEY_ALG` is not defined,
@@ -91,11 +107,21 @@
 
 ifeq (${TF_MBEDTLS_KEY_SIZE},)
     ifneq ($(findstring rsa,${TF_MBEDTLS_KEY_ALG}),)
-	ifeq (${KEY_SIZE},)
+        ifeq (${KEY_SIZE},)
             TF_MBEDTLS_KEY_SIZE		:=	2048
-	else
+        else ifneq ($(filter $(KEY_SIZE), 1024 2048 3072 4096),)
             TF_MBEDTLS_KEY_SIZE		:=	${KEY_SIZE}
-	endif
+        else
+            $(error "Invalid value for KEY_SIZE: ${KEY_SIZE}")
+        endif
+    else ifneq ($(findstring ecdsa,${TF_MBEDTLS_KEY_ALG}),)
+        ifeq (${KEY_SIZE},)
+            TF_MBEDTLS_KEY_SIZE		:=	256
+        else ifneq ($(filter $(KEY_SIZE), 256 384),)
+            TF_MBEDTLS_KEY_SIZE		:=	${KEY_SIZE}
+        else
+            $(error "Invalid value for KEY_SIZE: ${KEY_SIZE}")
+        endif
     endif
 endif
 
diff --git a/drivers/auth/mbedtls/mbedtls_crypto.mk b/drivers/auth/mbedtls/mbedtls_crypto.mk
index 2a9fbbf..bd36730 100644
--- a/drivers/auth/mbedtls/mbedtls_crypto.mk
+++ b/drivers/auth/mbedtls/mbedtls_crypto.mk
@@ -1,11 +1,16 @@
 #
-# Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
 include drivers/auth/mbedtls/mbedtls_common.mk
 
-MBEDTLS_SOURCES	+=		drivers/auth/mbedtls/mbedtls_crypto.c
-
-
+ifeq (${PSA_CRYPTO},1)
+	# Some of the PSA functions are declared in multiple header files
+	# that triggers this warning.
+	TF_CFLAGS      	+=     	-Wno-error=redundant-decls
+	MBEDTLS_SOURCES +=	drivers/auth/mbedtls/mbedtls_psa_crypto.c
+else
+	MBEDTLS_SOURCES +=	drivers/auth/mbedtls/mbedtls_crypto.c
+endif
diff --git a/drivers/auth/mbedtls/mbedtls_psa_crypto.c b/drivers/auth/mbedtls/mbedtls_psa_crypto.c
new file mode 100644
index 0000000..2fa8e63
--- /dev/null
+++ b/drivers/auth/mbedtls/mbedtls_psa_crypto.c
@@ -0,0 +1,499 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stddef.h>
+#include <string.h>
+
+/* mbed TLS headers */
+#include <mbedtls/gcm.h>
+#include <mbedtls/md.h>
+#include <mbedtls/memory_buffer_alloc.h>
+#include <mbedtls/oid.h>
+#include <mbedtls/platform.h>
+#include <mbedtls/version.h>
+#include <mbedtls/x509.h>
+#include <psa/crypto.h>
+#include <psa/crypto_platform.h>
+#include <psa/crypto_types.h>
+#include <psa/crypto_values.h>
+
+#include <common/debug.h>
+#include <drivers/auth/crypto_mod.h>
+#include <drivers/auth/mbedtls/mbedtls_common.h>
+#include <plat/common/platform.h>
+
+#define LIB_NAME		"mbed TLS PSA"
+
+#if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
+CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
+/*
+ * CRYPTO_MD_MAX_SIZE value is as per current stronger algorithm available
+ * so make sure that mbed TLS MD maximum size must be lesser than this.
+ */
+CASSERT(CRYPTO_MD_MAX_SIZE >= MBEDTLS_MD_MAX_SIZE,
+	assert_mbedtls_md_size_overflow);
+
+#endif /*
+	* CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
+	* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
+	*/
+
+static inline psa_algorithm_t mbedtls_md_psa_alg_from_type(
+						mbedtls_md_type_t md_type)
+{
+	assert((md_type == MBEDTLS_MD_SHA256) ||
+	       (md_type == MBEDTLS_MD_SHA384) ||
+	       (md_type == MBEDTLS_MD_SHA512));
+
+	return PSA_ALG_CATEGORY_HASH | (psa_algorithm_t) (md_type + 0x5);
+}
+
+/*
+ * AlgorithmIdentifier  ::=  SEQUENCE  {
+ *     algorithm               OBJECT IDENTIFIER,
+ *     parameters              ANY DEFINED BY algorithm OPTIONAL
+ * }
+ *
+ * SubjectPublicKeyInfo  ::=  SEQUENCE  {
+ *     algorithm            AlgorithmIdentifier,
+ *     subjectPublicKey     BIT STRING
+ * }
+ *
+ * DigestInfo ::= SEQUENCE {
+ *     digestAlgorithm AlgorithmIdentifier,
+ *     digest OCTET STRING
+ * }
+ */
+
+/*
+ * We pretend using an external RNG (through MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
+ * mbedTLS config option) so we need to provide an implementation of
+ * mbedtls_psa_external_get_random(). Provide a fake one, since we do not
+ * actually have any external RNG and TF-A itself doesn't engage in
+ * cryptographic operations that demands randomness.
+ */
+psa_status_t mbedtls_psa_external_get_random(
+			mbedtls_psa_external_random_context_t *context,
+			uint8_t *output, size_t output_size,
+			size_t *output_length)
+{
+	return PSA_ERROR_INSUFFICIENT_ENTROPY;
+}
+
+/*
+ * Initialize the library and export the descriptor
+ */
+static void init(void)
+{
+	/* Initialize mbed TLS */
+	mbedtls_init();
+
+	/* Initialise PSA mbedTLS */
+	psa_status_t status = psa_crypto_init();
+
+	if (status != PSA_SUCCESS) {
+		ERROR("Failed to initialize %s crypto (%d).\n", LIB_NAME, status);
+		panic();
+	}
+
+	INFO("PSA crypto initialized successfully!\n");
+}
+
+#if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
+CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
+
+static void construct_psa_key_alg_and_type(mbedtls_pk_type_t pk_alg,
+					   mbedtls_md_type_t md_alg,
+					   psa_algorithm_t *psa_alg,
+					   psa_key_type_t *psa_key_type)
+{
+	psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg);
+
+	switch (pk_alg) {
+	case MBEDTLS_PK_RSASSA_PSS:
+		*psa_alg = PSA_ALG_RSA_PSS(psa_md_alg);
+		*psa_key_type = PSA_KEY_TYPE_RSA_PUBLIC_KEY;
+		break;
+	default:
+		*psa_alg = PSA_ALG_NONE;
+		*psa_key_type = PSA_KEY_TYPE_NONE;
+		break;
+	}
+}
+
+/*
+ * Verify a signature.
+ *
+ * Parameters are passed using the DER encoding format following the ASN.1
+ * structures detailed above.
+ */
+static int verify_signature(void *data_ptr, unsigned int data_len,
+			    void *sig_ptr, unsigned int sig_len,
+			    void *sig_alg, unsigned int sig_alg_len,
+			    void *pk_ptr, unsigned int pk_len)
+{
+	mbedtls_asn1_buf sig_oid, sig_params;
+	mbedtls_asn1_buf signature;
+	mbedtls_md_type_t md_alg;
+	mbedtls_pk_type_t pk_alg;
+	int rc;
+	void *sig_opts = NULL;
+	unsigned char *p, *end;
+
+	/* construct PSA key algo and type */
+	psa_status_t status = PSA_SUCCESS;
+	psa_key_attributes_t psa_key_attr = PSA_KEY_ATTRIBUTES_INIT;
+	psa_key_id_t psa_key_id = PSA_KEY_ID_NULL;
+	psa_key_type_t psa_key_type;
+	psa_algorithm_t psa_alg;
+
+	/* Get pointers to signature OID and parameters */
+	p = (unsigned char *)sig_alg;
+	end = (unsigned char *)(p + sig_alg_len);
+	rc = mbedtls_asn1_get_alg(&p, end, &sig_oid, &sig_params);
+	if (rc != 0) {
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	/* Get the actual signature algorithm (MD + PK) */
+	rc = mbedtls_x509_get_sig_alg(&sig_oid, &sig_params, &md_alg, &pk_alg, &sig_opts);
+	if (rc != 0) {
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	/* Get the signature (bitstring) */
+	p = (unsigned char *)sig_ptr;
+	end = (unsigned char *)(p + sig_len);
+	signature.tag = *p;
+	rc = mbedtls_asn1_get_bitstring_null(&p, end, &signature.len);
+	if ((rc != 0) || ((size_t)(end - p) != signature.len)) {
+		rc = CRYPTO_ERR_SIGNATURE;
+		goto end2;
+	}
+	signature.p = p;
+
+	/* Convert this pk_alg and md_alg to PSA key type and key algorithm */
+	construct_psa_key_alg_and_type(pk_alg, md_alg,
+				       &psa_alg, &psa_key_type);
+
+
+	if ((psa_alg == PSA_ALG_NONE) || (psa_key_type == PSA_KEY_TYPE_NONE)) {
+		rc = CRYPTO_ERR_SIGNATURE;
+		goto end2;
+	}
+
+	/* filled-in key_attributes */
+	psa_set_key_algorithm(&psa_key_attr, psa_alg);
+	psa_set_key_type(&psa_key_attr, psa_key_type);
+	psa_set_key_usage_flags(&psa_key_attr, PSA_KEY_USAGE_VERIFY_MESSAGE);
+
+	/* Get the key_id using import API */
+	status = psa_import_key(&psa_key_attr,
+				pk_ptr,
+				(size_t)pk_len,
+				&psa_key_id);
+
+	if (status != PSA_SUCCESS) {
+		rc = CRYPTO_ERR_SIGNATURE;
+		goto end2;
+	}
+
+	/*
+	 * Hash calculation and Signature verification of the given data payload
+	 * is wrapped under the psa_verify_message function.
+	 */
+	status = psa_verify_message(psa_key_id, psa_alg,
+				    data_ptr, data_len,
+				    signature.p, signature.len);
+
+	if (status != PSA_SUCCESS) {
+		rc = CRYPTO_ERR_SIGNATURE;
+		goto end1;
+	}
+
+	/* Signature verification success */
+	rc = CRYPTO_SUCCESS;
+
+end1:
+	/*
+	 * Destroy the key if it is created successfully
+	 */
+	psa_destroy_key(psa_key_id);
+end2:
+	mbedtls_free(sig_opts);
+	return rc;
+}
+
+/*
+ * Match a hash
+ *
+ * Digest info is passed in DER format following the ASN.1 structure detailed
+ * above.
+ */
+static int verify_hash(void *data_ptr, unsigned int data_len,
+		       void *digest_info_ptr, unsigned int digest_info_len)
+{
+	mbedtls_asn1_buf hash_oid, params;
+	mbedtls_md_type_t md_alg;
+	unsigned char *p, *end, *hash;
+	size_t len;
+	int rc;
+	psa_status_t status;
+	psa_algorithm_t psa_md_alg;
+
+	/*
+	 * Digest info should be an MBEDTLS_ASN1_SEQUENCE, but padding after
+	 * it is allowed.  This is necessary to support multiple hash
+	 * algorithms.
+	 */
+	p = (unsigned char *)digest_info_ptr;
+	end = p + digest_info_len;
+	rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
+				  MBEDTLS_ASN1_SEQUENCE);
+	if (rc != 0) {
+		return CRYPTO_ERR_HASH;
+	}
+
+	end = p + len;
+
+	/* Get the hash algorithm */
+	rc = mbedtls_asn1_get_alg(&p, end, &hash_oid, &params);
+	if (rc != 0) {
+		return CRYPTO_ERR_HASH;
+	}
+
+	/* Hash should be octet string type and consume all bytes */
+	rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING);
+	if ((rc != 0) || ((size_t)(end - p) != len)) {
+		return CRYPTO_ERR_HASH;
+	}
+	hash = p;
+
+	rc = mbedtls_oid_get_md_alg(&hash_oid, &md_alg);
+	if (rc != 0) {
+		return CRYPTO_ERR_HASH;
+	}
+
+	/* convert the md_alg to psa_algo */
+	psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg);
+
+	/* Length of hash must match the algorithm's size */
+	if (len != PSA_HASH_LENGTH(psa_md_alg)) {
+		return CRYPTO_ERR_HASH;
+	}
+
+	/*
+	 * Calculate Hash and compare it against the retrieved hash from
+	 * the certificate (one shot API).
+	 */
+	status = psa_hash_compare(psa_md_alg,
+				  data_ptr, (size_t)data_len,
+				  (const uint8_t *)hash, len);
+
+	if (status != PSA_SUCCESS) {
+		return CRYPTO_ERR_HASH;
+	}
+
+	return CRYPTO_SUCCESS;
+}
+#endif /*
+	* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
+	* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
+	*/
+
+#if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
+CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
+/*
+ * Map a generic crypto message digest algorithm to the corresponding macro used
+ * by Mbed TLS.
+ */
+static inline mbedtls_md_type_t md_type(enum crypto_md_algo algo)
+{
+	switch (algo) {
+	case CRYPTO_MD_SHA512:
+		return MBEDTLS_MD_SHA512;
+	case CRYPTO_MD_SHA384:
+		return MBEDTLS_MD_SHA384;
+	case CRYPTO_MD_SHA256:
+		return MBEDTLS_MD_SHA256;
+	default:
+		/* Invalid hash algorithm. */
+		return MBEDTLS_MD_NONE;
+	}
+}
+
+/*
+ * Calculate a hash
+ *
+ * output points to the computed hash
+ */
+static int calc_hash(enum crypto_md_algo md_algo, void *data_ptr,
+		     unsigned int data_len,
+		     unsigned char output[CRYPTO_MD_MAX_SIZE])
+{
+	size_t hash_length;
+	psa_status_t status;
+	psa_algorithm_t psa_md_alg;
+
+	/* convert the md_alg to psa_algo */
+	psa_md_alg = mbedtls_md_psa_alg_from_type(md_type(md_algo));
+
+	/*
+	 * Calculate the hash of the data, it is safe to pass the
+	 * 'output' hash buffer pointer considering its size is always
+	 * bigger than or equal to MBEDTLS_MD_MAX_SIZE.
+	 */
+	status = psa_hash_compute(psa_md_alg, data_ptr, (size_t)data_len,
+				  (uint8_t *)output, CRYPTO_MD_MAX_SIZE,
+				  &hash_length);
+	if (status != PSA_SUCCESS) {
+		return CRYPTO_ERR_HASH;
+	}
+
+	return CRYPTO_SUCCESS;
+}
+#endif /*
+	* CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
+	* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
+	*/
+
+#if TF_MBEDTLS_USE_AES_GCM
+/*
+ * Stack based buffer allocation for decryption operation. It could
+ * be configured to balance stack usage vs execution speed.
+ */
+#define DEC_OP_BUF_SIZE		128
+
+static int aes_gcm_decrypt(void *data_ptr, size_t len, const void *key,
+			   unsigned int key_len, const void *iv,
+			   unsigned int iv_len, const void *tag,
+			   unsigned int tag_len)
+{
+	mbedtls_gcm_context ctx;
+	mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
+	unsigned char buf[DEC_OP_BUF_SIZE];
+	unsigned char tag_buf[CRYPTO_MAX_TAG_SIZE];
+	unsigned char *pt = data_ptr;
+	size_t dec_len;
+	int diff, i, rc;
+	size_t output_length __unused;
+
+	mbedtls_gcm_init(&ctx);
+
+	rc = mbedtls_gcm_setkey(&ctx, cipher, key, key_len * 8);
+	if (rc != 0) {
+		rc = CRYPTO_ERR_DECRYPTION;
+		goto exit_gcm;
+	}
+
+#if (MBEDTLS_VERSION_MAJOR < 3)
+	rc = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT, iv, iv_len, NULL, 0);
+#else
+	rc = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT, iv, iv_len);
+#endif
+	if (rc != 0) {
+		rc = CRYPTO_ERR_DECRYPTION;
+		goto exit_gcm;
+	}
+
+	while (len > 0) {
+		dec_len = MIN(sizeof(buf), len);
+
+#if (MBEDTLS_VERSION_MAJOR < 3)
+		rc = mbedtls_gcm_update(&ctx, dec_len, pt, buf);
+#else
+		rc = mbedtls_gcm_update(&ctx, pt, dec_len, buf, sizeof(buf), &output_length);
+#endif
+
+		if (rc != 0) {
+			rc = CRYPTO_ERR_DECRYPTION;
+			goto exit_gcm;
+		}
+
+		memcpy(pt, buf, dec_len);
+		pt += dec_len;
+		len -= dec_len;
+	}
+
+#if (MBEDTLS_VERSION_MAJOR < 3)
+	rc = mbedtls_gcm_finish(&ctx, tag_buf, sizeof(tag_buf));
+#else
+	rc = mbedtls_gcm_finish(&ctx, NULL, 0, &output_length, tag_buf, sizeof(tag_buf));
+#endif
+
+	if (rc != 0) {
+		rc = CRYPTO_ERR_DECRYPTION;
+		goto exit_gcm;
+	}
+
+	/* Check tag in "constant-time" */
+	for (diff = 0, i = 0; i < tag_len; i++)
+		diff |= ((const unsigned char *)tag)[i] ^ tag_buf[i];
+
+	if (diff != 0) {
+		rc = CRYPTO_ERR_DECRYPTION;
+		goto exit_gcm;
+	}
+
+	/* GCM decryption success */
+	rc = CRYPTO_SUCCESS;
+
+exit_gcm:
+	mbedtls_gcm_free(&ctx);
+	return rc;
+}
+
+/*
+ * Authenticated decryption of an image
+ */
+static int auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr,
+			size_t len, const void *key, unsigned int key_len,
+			unsigned int key_flags, const void *iv,
+			unsigned int iv_len, const void *tag,
+			unsigned int tag_len)
+{
+	int rc;
+
+	assert((key_flags & ENC_KEY_IS_IDENTIFIER) == 0);
+
+	switch (dec_algo) {
+	case CRYPTO_GCM_DECRYPT:
+		rc = aes_gcm_decrypt(data_ptr, len, key, key_len, iv, iv_len,
+				     tag, tag_len);
+		if (rc != 0)
+			return rc;
+		break;
+	default:
+		return CRYPTO_ERR_DECRYPTION;
+	}
+
+	return CRYPTO_SUCCESS;
+}
+#endif /* TF_MBEDTLS_USE_AES_GCM */
+
+/*
+ * Register crypto library descriptor
+ */
+#if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
+#if TF_MBEDTLS_USE_AES_GCM
+REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash,
+		    auth_decrypt, NULL);
+#else
+REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash,
+		    NULL, NULL);
+#endif
+#elif CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY
+#if TF_MBEDTLS_USE_AES_GCM
+REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL,
+		    auth_decrypt, NULL);
+#else
+REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL,
+		    NULL, NULL);
+#endif
+#elif CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY
+REGISTER_CRYPTO_LIB(LIB_NAME, init, NULL, NULL, calc_hash, NULL, NULL);
+#endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
diff --git a/drivers/cadence/uart/aarch64/cdns_console.S b/drivers/cadence/uart/aarch64/cdns_console.S
index 1bdaa48..d2dd0a8 100644
--- a/drivers/cadence/uart/aarch64/cdns_console.S
+++ b/drivers/cadence/uart/aarch64/cdns_console.S
@@ -79,7 +79,7 @@
 
 	mov	x0, x6
 	mov	x30, x7
-	finish_console_register cdns putc=1, getc=1, flush=1
+	finish_console_register cdns putc=1, getc=ENABLE_CONSOLE_GETC, flush=1
 
 register_fail:
 	ret	x7
diff --git a/drivers/console/aarch32/skeleton_console.S b/drivers/console/aarch32/skeleton_console.S
index a9e13ec..05a5985 100644
--- a/drivers/console/aarch32/skeleton_console.S
+++ b/drivers/console/aarch32/skeleton_console.S
@@ -63,7 +63,7 @@
 	 * If any of the argument is unspecified, then the corresponding
 	 * entry in console_t is set to 0.
 	 */
-	finish_console_register xxx putc=1, getc=1, flush=1
+	finish_console_register xxx putc=1, getc=ENABLE_CONSOLE_GETC, flush=1
 
 	/* Jump here if hardware init fails or parameters are invalid. */
 register_fail:
diff --git a/drivers/console/aarch64/skeleton_console.S b/drivers/console/aarch64/skeleton_console.S
index 7ea2eec..3310d28 100644
--- a/drivers/console/aarch64/skeleton_console.S
+++ b/drivers/console/aarch64/skeleton_console.S
@@ -63,7 +63,7 @@
 	 * If any of the argument is unspecified, then the corresponding
 	 * entry in console_t is set to 0.
 	 */
-	finish_console_register xxx putc=1, getc=1, flush=1
+	finish_console_register xxx putc=1, getc=ENABLE_CONSOLE_GETC, flush=1
 
 	/* Jump here if hardware init fails or parameters are invalid. */
 register_fail:
diff --git a/drivers/console/multi_console.c b/drivers/console/multi_console.c
index 93c38d8..e962fff 100644
--- a/drivers/console/multi_console.c
+++ b/drivers/console/multi_console.c
@@ -108,6 +108,7 @@
 		return EOF;
 }
 
+#if ENABLE_CONSOLE_GETC
 int console_getc(void)
 {
 	int err = ERROR_NO_VALID_CONSOLE;
@@ -127,6 +128,7 @@
 
 	return err;
 }
+#endif
 
 void console_flush(void)
 {
diff --git a/drivers/marvell/uart/a3700_console.S b/drivers/marvell/uart/a3700_console.S
index c7eb165..a1eacbc 100644
--- a/drivers/marvell/uart/a3700_console.S
+++ b/drivers/marvell/uart/a3700_console.S
@@ -140,7 +140,7 @@
 
 	mov	x0, x6
 	mov	x30, x7
-	finish_console_register a3700, putc=1, getc=1, flush=1
+	finish_console_register a3700, putc=1, getc=ENABLE_CONSOLE_GETC, flush=1
 
 register_fail:
 	ret	x7
diff --git a/drivers/mtd/nand/raw_nand.c b/drivers/mtd/nand/raw_nand.c
index 021e30b..3595c21 100644
--- a/drivers/mtd/nand/raw_nand.c
+++ b/drivers/mtd/nand/raw_nand.c
@@ -218,6 +218,18 @@
 	return -ETIMEDOUT;
 }
 
+static int nand_reset(void)
+{
+	int ret;
+
+	ret = nand_send_cmd(NAND_CMD_RESET, NAND_TWB_MAX);
+	if (ret != 0) {
+		return ret;
+	}
+
+	return nand_send_wait(PSEC_TO_MSEC(NAND_TRST_MAX), 0U);
+}
+
 #if NAND_ONFI_DETECT
 static uint16_t nand_check_crc(uint16_t crc, uint8_t *data_in,
 			       unsigned int data_len)
@@ -265,18 +277,6 @@
 	return nand_read_data(id, size, true);
 }
 
-static int nand_reset(void)
-{
-	int ret;
-
-	ret = nand_send_cmd(NAND_CMD_RESET, NAND_TWB_MAX);
-	if (ret != 0) {
-		return ret;
-	}
-
-	return nand_send_wait(PSEC_TO_MSEC(NAND_TRST_MAX), 0U);
-}
-
 static int nand_read_param_page(void)
 {
 	struct nand_param_page page;
@@ -346,11 +346,6 @@
 	int ret;
 	char id[4];
 
-	ret = nand_reset();
-	if (ret != 0) {
-		return ret;
-	}
-
 	ret = nand_read_id(ONFI_SIGNATURE_ADDR, (uint8_t *)id, sizeof(id));
 	if (ret != 0) {
 		return ret;
@@ -406,6 +401,8 @@
 
 int nand_raw_init(unsigned long long *size, unsigned int *erase_size)
 {
+	int ret;
+
 	rawnand_dev.nand_dev = get_nand_device();
 	if (rawnand_dev.nand_dev == NULL) {
 		return -EINVAL;
@@ -420,6 +417,11 @@
 		return -ENODEV;
 	}
 
+	ret = nand_reset();
+	if (ret != 0) {
+		return ret;
+	}
+
 #if NAND_ONFI_DETECT
 	if (detect_onfi() != 0) {
 		WARN("Detect ONFI failed\n");
diff --git a/drivers/nxp/console/16550_console.S b/drivers/nxp/console/16550_console.S
index 044d3d0..b5617a3 100644
--- a/drivers/nxp/console/16550_console.S
+++ b/drivers/nxp/console/16550_console.S
@@ -167,7 +167,7 @@
 register_16550:
 	mov	x0, x6
 	mov	x30, x7
-	finish_console_register 16550 putc=1, getc=1, flush=1
+	finish_console_register 16550 putc=1, getc=ENABLE_CONSOLE_GETC, flush=1
 
 register_fail:
 	ret	x7
diff --git a/drivers/st/crypto/stm32_pka.c b/drivers/st/crypto/stm32_pka.c
index 9124cf2..3054577 100644
--- a/drivers/st/crypto/stm32_pka.c
+++ b/drivers/st/crypto/stm32_pka.c
@@ -56,7 +56,7 @@
 #define _PKA_IPIDR			0x1FF8U
 
 /* PKA control register fields */
-#define _PKA_CR_MODE_MASK		GENMASK(13, 8)
+#define _PKA_CR_MODE_MASK		GENMASK_32(13, 8)
 #define _PKA_CR_MODE_SHIFT		8U
 #define _PKA_CR_MODE_ADD		0x9U
 #define _PKA_CR_MODE_ECDSA_VERIF	0x26U
@@ -69,7 +69,7 @@
 #define _PKA_SR_INITOK			BIT(0)
 
 /* PKA it flag fields (used in CR, SR and CLRFR) */
-#define _PKA_IT_MASK			(GENMASK(21, 19) | BIT(17))
+#define _PKA_IT_MASK			(GENMASK_32(21, 19) | BIT(17))
 #define _PKA_IT_SHIFT			17U
 #define _PKA_IT_OPERR			BIT(21)
 #define _PKA_IT_ADDRERR			BIT(20)
@@ -77,9 +77,9 @@
 #define _PKA_IT_PROCEND			BIT(17)
 
 /* PKA version register fields */
-#define _PKA_VERR_MAJREV_MASK		GENMASK(7, 4)
+#define _PKA_VERR_MAJREV_MASK		GENMASK_32(7, 4)
 #define _PKA_VERR_MAJREV_SHIFT		4U
-#define _PKA_VERR_MINREV_MASK		GENMASK(3, 0)
+#define _PKA_VERR_MINREV_MASK		GENMASK_32(3, 0)
 #define _PKA_VERR_MINREV_SHIFT		0U
 
 /* RAM magic offset */
diff --git a/drivers/st/crypto/stm32_rng.c b/drivers/st/crypto/stm32_rng.c
index a9dc43f..1342fd4 100644
--- a/drivers/st/crypto/stm32_rng.c
+++ b/drivers/st/crypto/stm32_rng.c
@@ -187,6 +187,10 @@
 
 		count = 4U;
 		while (len != 0U) {
+			if ((mmio_read_32(stm32_rng.base + RNG_SR) & RNG_SR_DRDY) == 0U) {
+				break;
+			}
+
 			data32 = mmio_read_32(stm32_rng.base + RNG_DR);
 			count--;
 
diff --git a/drivers/ti/uart/aarch32/16550_console.S b/drivers/ti/uart/aarch32/16550_console.S
index 0429f87..898a68d 100644
--- a/drivers/ti/uart/aarch32/16550_console.S
+++ b/drivers/ti/uart/aarch32/16550_console.S
@@ -124,7 +124,7 @@
 register_16550:
 	mov	r0, r4
 	pop	{r4, lr}
-	finish_console_register 16550 putc=1, getc=1, flush=1
+	finish_console_register 16550 putc=1, getc=ENABLE_CONSOLE_GETC, flush=1
 
 register_fail:
 	pop	{r4, pc}
diff --git a/drivers/ti/uart/aarch64/16550_console.S b/drivers/ti/uart/aarch64/16550_console.S
index cb21512..2b1b5a9 100644
--- a/drivers/ti/uart/aarch64/16550_console.S
+++ b/drivers/ti/uart/aarch64/16550_console.S
@@ -118,7 +118,7 @@
 register_16550:
 	mov	x0, x6
 	mov	x30, x7
-	finish_console_register 16550 putc=1, getc=1, flush=1
+	finish_console_register 16550 putc=1, getc=ENABLE_CONSOLE_GETC, flush=1
 
 register_fail:
 	ret	x7
diff --git a/fdts/stm32mp135f-dk.dts b/fdts/stm32mp135f-dk.dts
index 0f06b67..1204692 100644
--- a/fdts/stm32mp135f-dk.dts
+++ b/fdts/stm32mp135f-dk.dts
@@ -223,20 +223,20 @@
 		};
 
 		pll2_vco_1066Mhz: pll2-vco-1066Mhz {
-			src = < CLK_PLL12_HSE >;
-			divmn = < 2 65 >;
-			frac = < 0x1400 >;
+			src = <CLK_PLL12_HSE>;
+			divmn = <2 65>;
+			frac = <0x1400>;
 		};
 
-		pll3_vco_417_8Mhz: pll3-vco-417_8Mhz {
-			src = < CLK_PLL3_HSE >;
-			divmn = < 1 33 >;
-			frac = < 0x1a04 >;
+		pll3_vco_417Mhz: pll3-vco-417Mhz {
+			src = <CLK_PLL3_HSE>;
+			divmn = <1 33>;
+			frac = <0x1a04>;
 		};
 
 		pll4_vco_600Mhz: pll4-vco-600Mhz {
-			src = < CLK_PLL4_HSE >;
-			divmn = < 1 49 >;
+			src = <CLK_PLL4_HSE>;
+			divmn = <1 49>;
 		};
 	};
 
@@ -258,11 +258,11 @@
 		compatible = "st,stm32mp1-pll";
 		reg = <1>;
 
-		st,pll = < &pll2_cfg1 >;
+		st,pll = <&pll2_cfg1>;
 
 		pll2_cfg1: pll2_cfg1 {
-			st,pll_vco = < &pll2_vco_1066Mhz >;
-			st,pll_div_pqr = < 1 1 0 >;
+			st,pll_vco = <&pll2_vco_1066Mhz>;
+			st,pll_div_pqr = <1 1 0>;
 		};
 	};
 
@@ -271,11 +271,11 @@
 		compatible = "st,stm32mp1-pll";
 		reg = <2>;
 
-		st,pll = < &pll3_cfg1 >;
+		st,pll = <&pll3_cfg1>;
 
 		pll3_cfg1: pll3_cfg1 {
-			st,pll_vco = < &pll3_vco_417_8Mhz >;
-			st,pll_div_pqr = < 1 16 1 >;
+			st,pll_vco = <&pll3_vco_417Mhz>;
+			st,pll_div_pqr = <1 16 1>;
 		};
 	};
 
@@ -284,11 +284,11 @@
 		compatible = "st,stm32mp1-pll";
 		reg = <3>;
 
-		st,pll = < &pll4_cfg1 >;
+		st,pll = <&pll4_cfg1>;
 
 		pll4_cfg1: pll4_cfg1 {
-			st,pll_vco = < &pll4_vco_600Mhz >;
-			st,pll_div_pqr = < 11 59 5 >;
+			st,pll_vco = <&pll4_vco_600Mhz>;
+			st,pll_div_pqr = <11 59 5>;
 		};
 	};
 };
diff --git a/include/arch/aarch32/console_macros.S b/include/arch/aarch32/console_macros.S
index 996cb32..726b281 100644
--- a/include/arch/aarch32/console_macros.S
+++ b/include/arch/aarch32/console_macros.S
@@ -29,12 +29,20 @@
 	.endif
 	str	r1, [r0, #CONSOLE_T_PUTC]
 
+	/*
+	 * If ENABLE_CONSOLE_GETC support is disabled, but a getc callback is
+	 * specified nonetheless, the assembler will abort on encountering the
+	 * CONSOLE_T_GETC macro, which is undefined.
+	 */
 	.ifne \getc
 	  ldr	r1, =console_\_driver\()_getc
+	  str	r1, [r0, #CONSOLE_T_GETC]
 	.else
+#if ENABLE_CONSOLE_GETC
 	  mov	r1, #0
+	  str	r1, [r0, #CONSOLE_T_GETC]
+#endif
 	.endif
-	str	r1, [r0, #CONSOLE_T_GETC]
 
 	.ifne \flush
 	  ldr	r1, =console_\_driver\()_flush
diff --git a/include/arch/aarch64/console_macros.S b/include/arch/aarch64/console_macros.S
index 3285d85..8adb9cd 100644
--- a/include/arch/aarch64/console_macros.S
+++ b/include/arch/aarch64/console_macros.S
@@ -30,12 +30,19 @@
 	  str	xzr, [x0, #CONSOLE_T_PUTC]
 	.endif
 
+	/*
+	 * If ENABLE_CONSOLE_GETC support is disabled, but a getc callback is
+	 * specified nonetheless, the assembler will abort on encountering the
+	 * CONSOLE_T_GETC macro, which is undefined.
+	 */
 	.ifne \getc
 	  adrp	x1, console_\_driver\()_getc
 	  add	x1, x1, :lo12:console_\_driver\()_getc
 	  str	x1, [x0, #CONSOLE_T_GETC]
 	.else
+#if ENABLE_CONSOLE_GETC
 	  str	xzr, [x0, #CONSOLE_T_GETC]
+#endif
 	.endif
 
 	.ifne \flush
diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S
index fa9310e..536d807 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -59,43 +59,14 @@
 	 * zero here but are updated ahead of transitioning to a lower EL in the
 	 * function cm_init_context_common().
 	 *
-	 * SCR_EL3.TWE: Set to zero so that execution of WFE instructions at
-	 *  EL2, EL1 and EL0 are not trapped to EL3.
-	 *
-	 * SCR_EL3.TWI: Set to zero so that execution of WFI instructions at
-	 *  EL2, EL1 and EL0 are not trapped to EL3.
-	 *
 	 * SCR_EL3.SIF: Set to one to disable instruction fetches from
 	 *  Non-secure memory.
 	 *
-	 * SCR_EL3.SMD: Set to zero to enable SMC calls at EL1 and above, from
-	 *  both Security states and both Execution states.
-	 *
 	 * SCR_EL3.EA: Set to one to route External Aborts and SError Interrupts
 	 *  to EL3 when executing at any EL.
-	 *
-	 * SCR_EL3.{API,APK}: For Armv8.3 pointer authentication feature,
-	 * disable traps to EL3 when accessing key registers or using pointer
-	 * authentication instructions from lower ELs.
 	 * ---------------------------------------------------------------------
 	 */
-	mov_imm	x0, ((SCR_RESET_VAL | SCR_EA_BIT | SCR_SIF_BIT) \
-			& ~(SCR_TWE_BIT | SCR_TWI_BIT | SCR_SMD_BIT))
-#if CTX_INCLUDE_PAUTH_REGS
-	/*
-	 * If the pointer authentication registers are saved during world
-	 * switches, enable pointer authentication everywhere, as it is safe to
-	 * do so.
-	 */
-	orr	x0, x0, #(SCR_API_BIT | SCR_APK_BIT)
-#endif
-#if ENABLE_RME
-	/*
-	 * TODO: Settting the EEL2 bit to allow EL3 access to secure only registers
-	 * in context management. This will need to be refactored.
-	 */
-	orr	x0, x0, #SCR_EEL2_BIT
-#endif
+	mov_imm	x0, (SCR_RESET_VAL | SCR_EA_BIT | SCR_SIF_BIT)
 	msr	scr_el3, x0
 
 	/* ---------------------------------------------------------------------
@@ -132,25 +103,9 @@
 	/* ---------------------------------------------------------------------
 	 * Initialise CPTR_EL3, setting all fields rather than relying on hw.
 	 * All fields are architecturally UNKNOWN on reset.
-	 *
-	 * CPTR_EL3.TCPAC: Set to zero so that any accesses to CPACR_EL1,
-	 *  CPTR_EL2, CPACR, or HCPTR do not trap to EL3.
-	 *
-	 * CPTR_EL3.TFP: Set to zero so that accesses to the V- or Z- registers
-	 *  by Advanced SIMD, floating-point or SVE instructions (if implemented)
-	 *  do not trap to EL3.
-	 *
-	 * CPTR_EL3.TAM: Set to one so that Activity Monitor access is
-	 *  trapped to EL3 by default.
-	 *
-	 * CPTR_EL3.EZ: Set to zero so that all SVE functionality is trapped
-	 *  to EL3 by default.
-	 *
-	 * CPTR_EL3.ESM: Set to zero so that all SME functionality is trapped
-	 *  to EL3 by default.
+	 * ---------------------------------------------------------------------
 	 */
-
-	mov_imm x0, (CPTR_EL3_RESET_VAL & ~(TCPAC_BIT | TFP_BIT))
+	mov_imm x0, CPTR_EL3_RESET_VAL
 	msr	cptr_el3, x0
 
 	/*
diff --git a/include/common/tbbr/cot_def.h b/include/common/tbbr/cot_def.h
index 822c474..1d28772 100644
--- a/include/common/tbbr/cot_def.h
+++ b/include/common/tbbr/cot_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -46,7 +46,13 @@
 #error "Invalid value for TF_MBEDTLS_KEY_SIZE"
 #endif
 #else /* Only using ECDSA keys. */
+#if TF_MBEDTLS_KEY_SIZE == 384
+#define PK_DER_LEN                      120
+#elif TF_MBEDTLS_KEY_SIZE == 256
 #define PK_DER_LEN                      92
+#else
+#error "Invalid value for TF_MBEDTLS_KEY_SIZE"
+#endif
 #endif
 
 #if TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA256
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/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/auth/mbedtls/mbedtls_config-3.h b/include/drivers/auth/mbedtls/mbedtls_config-3.h
index ba936a3..923fc54 100644
--- a/include/drivers/auth/mbedtls/mbedtls_config-3.h
+++ b/include/drivers/auth/mbedtls/mbedtls_config-3.h
@@ -62,8 +62,12 @@
 #if TF_MBEDTLS_USE_ECDSA
 #define MBEDTLS_ECDSA_C
 #define MBEDTLS_ECP_C
+#if TF_MBEDTLS_KEY_SIZE == 384
+#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
+#else
 #define MBEDTLS_ECP_DP_SECP256R1_ENABLED
 #endif
+#endif
 #if TF_MBEDTLS_USE_RSA
 #define MBEDTLS_RSA_C
 #define MBEDTLS_X509_RSASSA_PSS_SUPPORT
diff --git a/include/drivers/auth/mbedtls/psa_mbedtls_config.h b/include/drivers/auth/mbedtls/psa_mbedtls_config.h
new file mode 100644
index 0000000..ad825f0
--- /dev/null
+++ b/include/drivers/auth/mbedtls/psa_mbedtls_config.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2023, Arm Ltd. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PSA_MBEDTLS_CONFIG_H
+#define PSA_MBEDTLS_CONFIG_H
+
+#include "mbedtls_config-3.h"
+
+#define MBEDTLS_PSA_CRYPTO_C
+
+/*
+ * Using PSA crypto API requires an RNG right now. If we don't define the macro
+ * below then we get build errors.
+ *
+ * This is a functionality gap in mbedTLS. The technical limitation is that
+ * psa_crypto_init() is all-or-nothing, and fixing that would require separate
+ * initialization of the keystore, the RNG, etc.
+ *
+ * By defining MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG, we pretend using an external
+ * RNG. As a result, the PSA crypto init code does nothing when it comes to
+ * initializing the RNG, as we are supposed to take care of that ourselves.
+ */
+#define MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
+
+#endif /* PSA_MBEDTLS_CONFIG_H */
diff --git a/include/drivers/console.h b/include/drivers/console.h
index f499571..fa4eb94 100644
--- a/include/drivers/console.h
+++ b/include/drivers/console.h
@@ -12,10 +12,16 @@
 #define CONSOLE_T_NEXT			(U(0) * REGSZ)
 #define CONSOLE_T_FLAGS			(U(1) * REGSZ)
 #define CONSOLE_T_PUTC			(U(2) * REGSZ)
+#if ENABLE_CONSOLE_GETC
 #define CONSOLE_T_GETC			(U(3) * REGSZ)
 #define CONSOLE_T_FLUSH			(U(4) * REGSZ)
 #define CONSOLE_T_BASE			(U(5) * REGSZ)
 #define CONSOLE_T_DRVDATA		(U(6) * REGSZ)
+#else
+#define CONSOLE_T_FLUSH			(U(3) * REGSZ)
+#define CONSOLE_T_BASE			(U(4) * REGSZ)
+#define CONSOLE_T_DRVDATA		(U(5) * REGSZ)
+#endif
 
 #define CONSOLE_FLAG_BOOT		(U(1) << 0)
 #define CONSOLE_FLAG_RUNTIME		(U(1) << 1)
@@ -42,7 +48,9 @@
 	 */
 	u_register_t flags;
 	int (*const putc)(int character, struct console *console);
+#if ENABLE_CONSOLE_GETC
 	int (*const getc)(struct console *console);
+#endif
 	void (*const flush)(struct console *console);
 	uintptr_t base;
 	/* Additional private driver data may follow here. */
@@ -75,8 +83,10 @@
 void console_switch_state(unsigned int new_state);
 /* Output a character on all consoles registered for the current state. */
 int console_putc(int c);
+#if ENABLE_CONSOLE_GETC
 /* Read a character (blocking) from any console registered for current state. */
 int console_getc(void);
+#endif
 /* Flush all consoles registered for the current state. */
 void console_flush(void);
 
diff --git a/include/drivers/console_assertions.h b/include/drivers/console_assertions.h
index 00caa31..9f06573 100644
--- a/include/drivers/console_assertions.h
+++ b/include/drivers/console_assertions.h
@@ -19,8 +19,10 @@
 	assert_console_t_flags_offset_mismatch);
 CASSERT(CONSOLE_T_PUTC == __builtin_offsetof(console_t, putc),
 	assert_console_t_putc_offset_mismatch);
+#if ENABLE_CONSOLE_GETC
 CASSERT(CONSOLE_T_GETC == __builtin_offsetof(console_t, getc),
 	assert_console_t_getc_offset_mismatch);
+#endif
 CASSERT(CONSOLE_T_FLUSH == __builtin_offsetof(console_t, flush),
 	assert_console_t_flush_offset_mismatch);
 CASSERT(CONSOLE_T_DRVDATA == sizeof(console_t),
diff --git a/include/lib/cpus/aarch64/cortex_x3.h b/include/lib/cpus/aarch64/cortex_x3.h
index e648734..04548ea 100644
--- a/include/lib/cpus/aarch64/cortex_x3.h
+++ b/include/lib/cpus/aarch64/cortex_x3.h
@@ -38,4 +38,13 @@
 #define CORTEX_X3_CPUACTLR5_EL1_BIT_55		(ULL(1) << 55)
 #define CORTEX_X3_CPUACTLR5_EL1_BIT_56		(ULL(1) << 56)
 
+/*******************************************************************************
+ * CPU Extended Control register 2 specific definitions.
+ ******************************************************************************/
+#define CORTEX_X3_CPUECTLR2_EL1			S3_0_C15_C1_5
+
+#define CORTEX_X3_CPUECTLR2_EL1_PF_MODE_LSB	U(11)
+#define CORTEX_X3_CPUECTLR2_EL1_PF_MODE_WIDTH	U(4)
+#define CORTEX_X3_CPUECTLR2_EL1_PF_MODE_CNSRV	ULL(0x9)
+
 #endif /* CORTEX_X3_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/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index 0ab0e82..314eb93 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -24,8 +24,6 @@
  */
 #define ARM_ROTPK_HEADER_LEN		19
 #define ARM_ROTPK_HASH_LEN		32
-/* ARM_ROTPK_KEY_LEN includes DER header + raw key material */
-#define ARM_ROTPK_KEY_LEN		294
 
 /* Special value used to verify platform parameters from BL2 to BL31 */
 #define ARM_BL31_PLAT_PARAM_VAL		ULL(0x0f1e2d3c4b5a6978)
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 2fdbfb7..0fb06a6 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -53,7 +53,7 @@
 		PLAT_ARM_TZC_NS_DEV_ACCESS}
 #endif
 
-#if SPM_MM
+#if SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)
 #define ARM_TZC_REGIONS_DEF						\
 	{ARM_AP_TZC_DRAM1_BASE, ARM_EL3_TZC_DRAM1_END + ARM_L1_GPT_SIZE,\
 		TZC_REGION_S_RDWR, 0},					\
@@ -176,10 +176,17 @@
 #define STATE_SW_E_DENIED		(-3)
 
 /* plat_get_rotpk_info() flags */
-#define ARM_ROTPK_REGS_ID		1
-#define ARM_ROTPK_DEVEL_RSA_ID		2
-#define ARM_ROTPK_DEVEL_ECDSA_ID	3
+#define ARM_ROTPK_REGS_ID			1
+#define ARM_ROTPK_DEVEL_RSA_ID			2
+#define ARM_ROTPK_DEVEL_ECDSA_ID		3
 #define ARM_ROTPK_DEVEL_FULL_DEV_RSA_KEY_ID	4
+#define ARM_ROTPK_DEVEL_FULL_DEV_ECDSA_KEY_ID	5
+
+#define ARM_USE_DEVEL_ROTPK							\
+	(ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) ||			\
+	(ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) ||			\
+	(ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_FULL_DEV_RSA_KEY_ID) ||	\
+	(ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_FULL_DEV_ECDSA_KEY_ID)
 
 /* IO storage utility functions */
 int arm_io_setup(void);
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_x3.S b/lib/cpus/aarch64/cortex_x3.S
index 98d148e..0cb3b97 100644
--- a/lib/cpus/aarch64/cortex_x3.S
+++ b/lib/cpus/aarch64/cortex_x3.S
@@ -26,6 +26,13 @@
 	wa_cve_2022_23960_bhb_vector_table CORTEX_X3_BHB_LOOP_COUNT, cortex_x3
 #endif /* WORKAROUND_CVE_2022_23960 */
 
+workaround_reset_start cortex_x3, ERRATUM(2070301), ERRATA_X3_2070301
+	sysreg_bitfield_insert CORTEX_X3_CPUECTLR2_EL1, CORTEX_X3_CPUECTLR2_EL1_PF_MODE_CNSRV, \
+	CORTEX_X3_CPUECTLR2_EL1_PF_MODE_LSB, CORTEX_X3_CPUECTLR2_EL1_PF_MODE_WIDTH
+workaround_reset_end cortex_x3, ERRATUM(2070301)
+
+check_erratum_ls cortex_x3, ERRATUM(2070301), CPU_REV(1, 2)
+
 workaround_runtime_start cortex_x3, ERRATUM(2313909), ERRATA_X3_2313909
 	sysreg_bit_set	CORTEX_X3_CPUACTLR2_EL1, CORTEX_X3_CPUACTLR2_EL1_BIT_36
 workaround_runtime_end cortex_x3, ERRATUM(2313909), NO_ISB
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 77cc41e..e12795f 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -734,6 +734,11 @@
 # still open.
 CPU_FLAG_LIST += ERRATA_X2_2768515
 
+# Flag to apply erratum 2070301 workaround on reset. This erratum applies
+# to revisions r0p0, r1p0, r1p1 and r1p2 of the Cortex-X3 cpu and is
+# still open.
+CPU_FLAG_LIST += ERRATA_X3_2070301
+
 # Flag to apply erratum 2313909 workaround on powerdown. This erratum applies
 # to revisions r0p0 and r1p0 of the Cortex-X3 cpu, it is fixed in r1p1.
 CPU_FLAG_LIST += ERRATA_X3_2313909
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index f47e779..290a93a 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -557,7 +557,6 @@
 	msr	spsel, #MODE_SP_ELX
 	str	x17, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
 
-#if IMAGE_BL31
 	/* ----------------------------------------------------------
 	 * Restore CPTR_EL3.
 	 * ZCR is only restored if SVE is supported and enabled.
@@ -567,6 +566,7 @@
 	ldp	x19, x20, [sp, #CTX_EL3STATE_OFFSET + CTX_CPTR_EL3]
 	msr	cptr_el3, x19
 
+#if IMAGE_BL31
 	ands	x19, x19, #CPTR_EZ_BIT
 	beq	sve_not_enabled
 
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index b16c113..3a7e50f 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -135,16 +135,6 @@
 	}
 #endif /* CTX_INCLUDE_MTE_REGS */
 
-	/* Enable S-EL2 if the next EL is EL2 and S-EL2 is present */
-	if ((GET_EL(ep->spsr) == MODE_EL2) && is_feat_sel2_supported()) {
-		if (GET_RW(ep->spsr) != MODE_RW_64) {
-			ERROR("S-EL2 can not be used in AArch32\n.");
-			panic();
-		}
-
-		scr_el3 |= SCR_EEL2_BIT;
-	}
-
 	write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
 
 	/*
@@ -197,21 +187,33 @@
 	/* SCR_NS: Set the NS bit */
 	scr_el3 |= SCR_NS_BIT;
 
+	/* Allow access to Allocation Tags when MTE is implemented. */
+	scr_el3 |= SCR_ATA_BIT;
+
 #if !CTX_INCLUDE_PAUTH_REGS
 	/*
-	 * If the pointer authentication registers aren't saved during world
-	 * switches the value of the registers can be leaked from the Secure to
-	 * the Non-secure world. To prevent this, rather than enabling pointer
-	 * authentication everywhere, we only enable it in the Non-secure world.
+	 * Pointer Authentication feature, if present, is always enabled by default
+	 * for Non secure lower exception levels. We do not have an explicit
+	 * flag to set it.
+	 * CTX_INCLUDE_PAUTH_REGS flag, is explicitly used to enable for lower
+	 * exception levels of secure and realm worlds.
 	 *
-	 * If the Secure world wants to use pointer authentication,
-	 * CTX_INCLUDE_PAUTH_REGS must be set to 1.
+	 * To prevent the leakage between the worlds during world switch,
+	 * we enable it only for the non-secure world.
+	 *
+	 * If the Secure/realm world wants to use pointer authentication,
+	 * CTX_INCLUDE_PAUTH_REGS must be explicitly set to 1, in which case
+	 * it will be enabled globally for all the contexts.
+	 *
+	 * SCR_EL3.API: Set to one to not trap any PAuth instructions at ELs
+	 *  other than EL3
+	 *
+	 * SCR_EL3.APK: Set to one to not trap any PAuth key values at ELs other
+	 *  than EL3
 	 */
 	scr_el3 |= SCR_API_BIT | SCR_APK_BIT;
-#endif /* !CTX_INCLUDE_PAUTH_REGS */
 
-	/* Allow access to Allocation Tags when MTE is implemented. */
-	scr_el3 |= SCR_ATA_BIT;
+#endif /* CTX_INCLUDE_PAUTH_REGS */
 
 #if HANDLE_EA_EL3_FIRST_NS
 	/* SCR_EL3.EA: Route External Abort and SError Interrupt to EL3. */
@@ -258,15 +260,6 @@
 	write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_SCTLR_EL2,
 			sctlr_el2);
 
-	/*
-	 * Program the ICC_SRE_EL2 to make sure the correct bits are set
-	 * when restoring NS context.
-	 */
-	u_register_t icc_sre_el2 = ICC_SRE_DIB_BIT | ICC_SRE_DFB_BIT |
-				   ICC_SRE_EN_BIT | ICC_SRE_SRE_BIT;
-	write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_ICC_SRE_EL2,
-			icc_sre_el2);
-
 	if (is_feat_hcx_supported()) {
 		/*
 		 * Initialize register HCRX_EL2 with its init value.
@@ -308,25 +301,53 @@
  ******************************************************************************/
 static void setup_context_common(cpu_context_t *ctx, const entry_point_info_t *ep)
 {
+	u_register_t cptr_el3;
 	u_register_t scr_el3;
 	el3_state_t *state;
 	gp_regs_t *gp_regs;
 
+	state = get_el3state_ctx(ctx);
+
 	/* Clear any residual register values from the context */
 	zeromem(ctx, sizeof(*ctx));
 
 	/*
+	 * The lower-EL context is zeroed so that no stale values leak to a world.
+	 * It is assumed that an all-zero lower-EL context is good enough for it
+	 * to boot correctly. However, there are very few registers where this
+	 * is not true and some values need to be recreated.
+	 */
+#if CTX_INCLUDE_EL2_REGS
+	el2_sysregs_t *el2_ctx = get_el2_sysregs_ctx(ctx);
+
+	/*
+	 * These bits are set in the gicv3 driver. Losing them (especially the
+	 * SRE bit) is problematic for all worlds. Henceforth recreate them.
+	 */
+	u_register_t icc_sre_el2 = ICC_SRE_DIB_BIT | ICC_SRE_DFB_BIT |
+				   ICC_SRE_EN_BIT | ICC_SRE_SRE_BIT;
+	write_ctx_reg(el2_ctx, CTX_ICC_SRE_EL2, icc_sre_el2);
+#endif /* CTX_INCLUDE_EL2_REGS */
+
+	/* Start with a clean SCR_EL3 copy as all relevant values are set */
+	scr_el3 = SCR_RESET_VAL;
+
+	/*
-	 * SCR_EL3 was initialised during reset sequence in macro
-	 * el3_arch_init_common. This code modifies the SCR_EL3 fields that
-	 * affect the next EL.
+	 * SCR_EL3.TWE: Set to zero so that execution of WFE instructions at
+	 *  EL2, EL1 and EL0 are not trapped to EL3.
 	 *
-	 * The following fields are initially set to zero and then updated to
-	 * the required value depending on the state of the SPSR_EL3 and the
-	 * Security state and entrypoint attributes of the next EL.
+	 * SCR_EL3.TWI: Set to zero so that execution of WFI instructions at
+	 *  EL2, EL1 and EL0 are not trapped to EL3.
+	 *
+	 * SCR_EL3.SMD: Set to zero to enable SMC calls at EL1 and above, from
+	 *  both Security states and both Execution states.
+	 *
+	 * SCR_EL3.SIF: Set to one to disable secure instruction execution from
+	 *  Non-secure memory.
 	 */
-	scr_el3 = read_scr();
-	scr_el3 &= ~(SCR_NS_BIT | SCR_RW_BIT | SCR_EA_BIT | SCR_FIQ_BIT | SCR_IRQ_BIT |
-			SCR_ST_BIT | SCR_HCE_BIT | SCR_NSE_BIT);
+	scr_el3 &= ~(SCR_TWE_BIT | SCR_TWI_BIT | SCR_SMD_BIT);
+
+	scr_el3 |= SCR_SIF_BIT;
 
 	/*
 	 * SCR_EL3.RW: Set the execution state, AArch32 or AArch64, for next
@@ -368,6 +389,19 @@
 	scr_el3 |= SCR_FIEN_BIT;
 #endif
 
+#if CTX_INCLUDE_PAUTH_REGS
+	/*
+	 * Enable Pointer Authentication globally for all the worlds.
+	 *
+	 * SCR_EL3.API: Set to one to not trap any PAuth instructions at ELs
+	 *  other than EL3
+	 *
+	 * SCR_EL3.APK: Set to one to not trap any PAuth key values at ELs other
+	 *  than EL3
+	 */
+	scr_el3 |= SCR_API_BIT | SCR_APK_BIT;
+#endif /* CTX_INCLUDE_PAUTH_REGS */
+
 	/*
 	 * SCR_EL3.TCR2EN: Enable access to TCR2_ELx for AArch64 if present.
 	 */
@@ -391,10 +425,19 @@
 	}
 
 	/*
-	 * CPTR_EL3 was initialized out of reset, copy that value to the
-	 * context register.
+	 * Initialise CPTR_EL3, setting all fields rather than relying on hw.
+	 * All fields are architecturally UNKNOWN on reset.
+	 *
+	 * CPTR_EL3.TFP: Set to zero so that accesses to the V- or Z- registers
+	 *  by Advanced SIMD, floating-point or SVE instructions (if
+	 *  implemented) do not trap to EL3.
+	 *
+	 * CPTR_EL3.TCPAC: Set to zero so that accesses to CPACR_EL1,
+	 *  CPTR_EL2,CPACR, or HCPTR do not trap to EL3.
 	 */
-	write_ctx_reg(get_el3state_ctx(ctx), CTX_CPTR_EL3, read_cptr_el3());
+	cptr_el3 = CPTR_EL3_RESET_VAL & ~(TFP_BIT | TCPAC_BIT);
+
+	write_ctx_reg(state, CTX_CPTR_EL3, cptr_el3);
 
 	/*
 	 * SCR_EL3.HCE: Enable HVC instructions if next execution state is
@@ -431,12 +474,18 @@
 		/* Enable WFE delay */
 		scr_el3 |= SCR_TWEDEn_BIT;
 	}
+
+#if IMAGE_BL31 && defined(SPD_spmd) && SPMD_SPM_AT_SEL2
+	/* Enable S-EL2 if FEAT_SEL2 is implemented for all the contexts. */
+	if (is_feat_sel2_supported()) {
+		scr_el3 |= SCR_EEL2_BIT;
+	}
+#endif /* (IMAGE_BL31 && defined(SPD_spmd) && SPMD_SPM_AT_SEL2) */
 
 	/*
 	 * Populate EL3 state so that we've the right context
 	 * before doing ERET
 	 */
-	state = get_el3state_ctx(ctx);
 	write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
 	write_ctx_reg(state, CTX_ELR_EL3, ep->pc);
 	write_ctx_reg(state, CTX_SPSR_EL3, ep->spsr);
@@ -1032,7 +1081,20 @@
 	write_ctx_reg(ctx, CTX_HCR_EL2, read_hcr_el2());
 	write_ctx_reg(ctx, CTX_HPFAR_EL2, read_hpfar_el2());
 	write_ctx_reg(ctx, CTX_HSTR_EL2, read_hstr_el2());
+
+	/*
+	 * Set the NS bit to be able to access the ICC_SRE_EL2 register
+	 * TODO: remove with root context
+	 */
+	u_register_t scr_el3 = read_scr_el3();
+
+	write_scr_el3(scr_el3 | SCR_NS_BIT);
+	isb();
 	write_ctx_reg(ctx, CTX_ICC_SRE_EL2, read_icc_sre_el2());
+
+	write_scr_el3(scr_el3);
+	isb();
+
 	write_ctx_reg(ctx, CTX_ICH_HCR_EL2, read_ich_hcr_el2());
 	write_ctx_reg(ctx, CTX_ICH_VMCR_EL2, read_ich_vmcr_el2());
 	write_ctx_reg(ctx, CTX_MAIR_EL2, read_mair_el2());
@@ -1069,7 +1131,20 @@
 	write_hcr_el2(read_ctx_reg(ctx, CTX_HCR_EL2));
 	write_hpfar_el2(read_ctx_reg(ctx, CTX_HPFAR_EL2));
 	write_hstr_el2(read_ctx_reg(ctx, CTX_HSTR_EL2));
+
+	/*
+	 * Set the NS bit to be able to access the ICC_SRE_EL2 register
+	 * TODO: remove with root context
+	 */
+	u_register_t scr_el3 = read_scr_el3();
+
+	write_scr_el3(scr_el3 | SCR_NS_BIT);
+	isb();
 	write_icc_sre_el2(read_ctx_reg(ctx, CTX_ICC_SRE_EL2));
+
+	write_scr_el3(scr_el3);
+	isb();
+
 	write_ich_hcr_el2(read_ctx_reg(ctx, CTX_ICH_HCR_EL2));
 	write_ich_vmcr_el2(read_ctx_reg(ctx, CTX_ICH_VMCR_EL2));
 	write_mair_el2(read_ctx_reg(ctx, CTX_MAIR_EL2));
@@ -1092,87 +1167,71 @@
  ******************************************************************************/
 void cm_el2_sysregs_context_save(uint32_t security_state)
 {
-	u_register_t scr_el3 = read_scr();
-
-	/*
-	 * Always save the non-secure and realm EL2 context, only save the
-	 * S-EL2 context if S-EL2 is enabled.
-	 */
-	if ((security_state != SECURE) ||
-	    ((security_state == SECURE) && ((scr_el3 & SCR_EEL2_BIT) != 0U))) {
-		cpu_context_t *ctx;
-		el2_sysregs_t *el2_sysregs_ctx;
+	cpu_context_t *ctx;
+	el2_sysregs_t *el2_sysregs_ctx;
 
-		ctx = cm_get_context(security_state);
-		assert(ctx != NULL);
+	ctx = cm_get_context(security_state);
+	assert(ctx != NULL);
 
-		el2_sysregs_ctx = get_el2_sysregs_ctx(ctx);
+	el2_sysregs_ctx = get_el2_sysregs_ctx(ctx);
 
-		el2_sysregs_context_save_common(el2_sysregs_ctx);
+	el2_sysregs_context_save_common(el2_sysregs_ctx);
 #if CTX_INCLUDE_MTE_REGS
-		write_ctx_reg(el2_sysregs_ctx, CTX_TFSR_EL2, read_tfsr_el2());
+	write_ctx_reg(el2_sysregs_ctx, CTX_TFSR_EL2, read_tfsr_el2());
 #endif
-		if (is_feat_mpam_supported()) {
-			el2_sysregs_context_save_mpam(el2_sysregs_ctx);
-		}
+	if (is_feat_mpam_supported()) {
+		el2_sysregs_context_save_mpam(el2_sysregs_ctx);
+	}
 
-		if (is_feat_fgt_supported()) {
-			el2_sysregs_context_save_fgt(el2_sysregs_ctx);
-		}
+	if (is_feat_fgt_supported()) {
+		el2_sysregs_context_save_fgt(el2_sysregs_ctx);
+	}
 
-		if (is_feat_ecv_v2_supported()) {
-			write_ctx_reg(el2_sysregs_ctx, CTX_CNTPOFF_EL2,
-				      read_cntpoff_el2());
-		}
+	if (is_feat_ecv_v2_supported()) {
+		write_ctx_reg(el2_sysregs_ctx, CTX_CNTPOFF_EL2, read_cntpoff_el2());
+	}
 
-		if (is_feat_vhe_supported()) {
-			write_ctx_reg(el2_sysregs_ctx, CTX_CONTEXTIDR_EL2,
-				      read_contextidr_el2());
-			write_ctx_reg(el2_sysregs_ctx, CTX_TTBR1_EL2,
-				      read_ttbr1_el2());
-		}
+	if (is_feat_vhe_supported()) {
+		write_ctx_reg(el2_sysregs_ctx, CTX_CONTEXTIDR_EL2, read_contextidr_el2());
+		write_ctx_reg(el2_sysregs_ctx, CTX_TTBR1_EL2, read_ttbr1_el2());
+	}
 
-		if (is_feat_ras_supported()) {
-			write_ctx_reg(el2_sysregs_ctx, CTX_VDISR_EL2,
-				      read_vdisr_el2());
-			write_ctx_reg(el2_sysregs_ctx, CTX_VSESR_EL2,
-				      read_vsesr_el2());
-		}
+	if (is_feat_ras_supported()) {
+		write_ctx_reg(el2_sysregs_ctx, CTX_VDISR_EL2, read_vdisr_el2());
+		write_ctx_reg(el2_sysregs_ctx, CTX_VSESR_EL2, read_vsesr_el2());
+	}
 
-		if (is_feat_nv2_supported()) {
-			write_ctx_reg(el2_sysregs_ctx, CTX_VNCR_EL2,
-				      read_vncr_el2());
-		}
+	if (is_feat_nv2_supported()) {
+		write_ctx_reg(el2_sysregs_ctx, CTX_VNCR_EL2, read_vncr_el2());
+	}
 
-		if (is_feat_trf_supported()) {
-			write_ctx_reg(el2_sysregs_ctx, CTX_TRFCR_EL2, read_trfcr_el2());
-		}
+	if (is_feat_trf_supported()) {
+		write_ctx_reg(el2_sysregs_ctx, CTX_TRFCR_EL2, read_trfcr_el2());
+	}
 
-		if (is_feat_csv2_2_supported()) {
-			write_ctx_reg(el2_sysregs_ctx, CTX_SCXTNUM_EL2,
-				      read_scxtnum_el2());
-		}
+	if (is_feat_csv2_2_supported()) {
+		write_ctx_reg(el2_sysregs_ctx, CTX_SCXTNUM_EL2, read_scxtnum_el2());
+	}
 
-		if (is_feat_hcx_supported()) {
-			write_ctx_reg(el2_sysregs_ctx, CTX_HCRX_EL2, read_hcrx_el2());
-		}
-		if (is_feat_tcr2_supported()) {
-			write_ctx_reg(el2_sysregs_ctx, CTX_TCR2_EL2, read_tcr2_el2());
-		}
-		if (is_feat_sxpie_supported()) {
-			write_ctx_reg(el2_sysregs_ctx, CTX_PIRE0_EL2, read_pire0_el2());
-			write_ctx_reg(el2_sysregs_ctx, CTX_PIR_EL2, read_pir_el2());
-		}
-		if (is_feat_s2pie_supported()) {
-			write_ctx_reg(el2_sysregs_ctx, CTX_S2PIR_EL2, read_s2pir_el2());
-		}
-		if (is_feat_sxpoe_supported()) {
-			write_ctx_reg(el2_sysregs_ctx, CTX_POR_EL2, read_por_el2());
-		}
-		if (is_feat_gcs_supported()) {
-			write_ctx_reg(el2_sysregs_ctx, CTX_GCSPR_EL2, read_gcspr_el2());
-			write_ctx_reg(el2_sysregs_ctx, CTX_GCSCR_EL2, read_gcscr_el2());
-		}
+	if (is_feat_hcx_supported()) {
+		write_ctx_reg(el2_sysregs_ctx, CTX_HCRX_EL2, read_hcrx_el2());
+	}
+	if (is_feat_tcr2_supported()) {
+		write_ctx_reg(el2_sysregs_ctx, CTX_TCR2_EL2, read_tcr2_el2());
+	}
+	if (is_feat_sxpie_supported()) {
+		write_ctx_reg(el2_sysregs_ctx, CTX_PIRE0_EL2, read_pire0_el2());
+		write_ctx_reg(el2_sysregs_ctx, CTX_PIR_EL2, read_pir_el2());
+	}
+	if (is_feat_s2pie_supported()) {
+		write_ctx_reg(el2_sysregs_ctx, CTX_S2PIR_EL2, read_s2pir_el2());
+	}
+	if (is_feat_sxpoe_supported()) {
+		write_ctx_reg(el2_sysregs_ctx, CTX_POR_EL2, read_por_el2());
+	}
+	if (is_feat_gcs_supported()) {
+		write_ctx_reg(el2_sysregs_ctx, CTX_GCSPR_EL2, read_gcspr_el2());
+		write_ctx_reg(el2_sysregs_ctx, CTX_GCSCR_EL2, read_gcscr_el2());
 	}
 }
 
@@ -1181,81 +1240,70 @@
  ******************************************************************************/
 void cm_el2_sysregs_context_restore(uint32_t security_state)
 {
-	u_register_t scr_el3 = read_scr();
-
-	/*
-	 * Always restore the non-secure and realm EL2 context, only restore the
-	 * S-EL2 context if S-EL2 is enabled.
-	 */
-	if ((security_state != SECURE) ||
-	    ((security_state == SECURE) && ((scr_el3 & SCR_EEL2_BIT) != 0U))) {
-		cpu_context_t *ctx;
-		el2_sysregs_t *el2_sysregs_ctx;
+	cpu_context_t *ctx;
+	el2_sysregs_t *el2_sysregs_ctx;
 
-		ctx = cm_get_context(security_state);
-		assert(ctx != NULL);
+	ctx = cm_get_context(security_state);
+	assert(ctx != NULL);
 
-		el2_sysregs_ctx = get_el2_sysregs_ctx(ctx);
+	el2_sysregs_ctx = get_el2_sysregs_ctx(ctx);
 
-		el2_sysregs_context_restore_common(el2_sysregs_ctx);
+	el2_sysregs_context_restore_common(el2_sysregs_ctx);
 #if CTX_INCLUDE_MTE_REGS
-		write_tfsr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TFSR_EL2));
+	write_tfsr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TFSR_EL2));
 #endif
-		if (is_feat_mpam_supported()) {
-			el2_sysregs_context_restore_mpam(el2_sysregs_ctx);
-		}
+	if (is_feat_mpam_supported()) {
+		el2_sysregs_context_restore_mpam(el2_sysregs_ctx);
+	}
 
-		if (is_feat_fgt_supported()) {
-			el2_sysregs_context_restore_fgt(el2_sysregs_ctx);
-		}
+	if (is_feat_fgt_supported()) {
+		el2_sysregs_context_restore_fgt(el2_sysregs_ctx);
+	}
 
-		if (is_feat_ecv_v2_supported()) {
-			write_cntpoff_el2(read_ctx_reg(el2_sysregs_ctx,
-						       CTX_CNTPOFF_EL2));
-		}
+	if (is_feat_ecv_v2_supported()) {
+		write_cntpoff_el2(read_ctx_reg(el2_sysregs_ctx, CTX_CNTPOFF_EL2));
+	}
 
-		if (is_feat_vhe_supported()) {
-			write_contextidr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_CONTEXTIDR_EL2));
-			write_ttbr1_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TTBR1_EL2));
-		}
+	if (is_feat_vhe_supported()) {
+		write_contextidr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_CONTEXTIDR_EL2));
+		write_ttbr1_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TTBR1_EL2));
+	}
 
-		if (is_feat_ras_supported()) {
-			write_vdisr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_VDISR_EL2));
-			write_vsesr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_VSESR_EL2));
-		}
+	if (is_feat_ras_supported()) {
+		write_vdisr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_VDISR_EL2));
+		write_vsesr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_VSESR_EL2));
+	}
 
-		if (is_feat_nv2_supported()) {
-			write_vncr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_VNCR_EL2));
-		}
-		if (is_feat_trf_supported()) {
-			write_trfcr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TRFCR_EL2));
-		}
+	if (is_feat_nv2_supported()) {
+		write_vncr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_VNCR_EL2));
+	}
+	if (is_feat_trf_supported()) {
+		write_trfcr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TRFCR_EL2));
+	}
 
-		if (is_feat_csv2_2_supported()) {
-			write_scxtnum_el2(read_ctx_reg(el2_sysregs_ctx,
-						       CTX_SCXTNUM_EL2));
-		}
+	if (is_feat_csv2_2_supported()) {
+		write_scxtnum_el2(read_ctx_reg(el2_sysregs_ctx, CTX_SCXTNUM_EL2));
+	}
 
-		if (is_feat_hcx_supported()) {
-			write_hcrx_el2(read_ctx_reg(el2_sysregs_ctx, CTX_HCRX_EL2));
-		}
-		if (is_feat_tcr2_supported()) {
-			write_tcr2_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TCR2_EL2));
-		}
-		if (is_feat_sxpie_supported()) {
-			write_pire0_el2(read_ctx_reg(el2_sysregs_ctx, CTX_PIRE0_EL2));
-			write_pir_el2(read_ctx_reg(el2_sysregs_ctx, CTX_PIR_EL2));
-		}
-		if (is_feat_s2pie_supported()) {
-			write_s2pir_el2(read_ctx_reg(el2_sysregs_ctx, CTX_S2PIR_EL2));
-		}
-		if (is_feat_sxpoe_supported()) {
-			write_por_el2(read_ctx_reg(el2_sysregs_ctx, CTX_POR_EL2));
-		}
-		if (is_feat_gcs_supported()) {
-			write_gcscr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_GCSCR_EL2));
-			write_gcspr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_GCSPR_EL2));
-		}
+	if (is_feat_hcx_supported()) {
+		write_hcrx_el2(read_ctx_reg(el2_sysregs_ctx, CTX_HCRX_EL2));
+	}
+	if (is_feat_tcr2_supported()) {
+		write_tcr2_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TCR2_EL2));
+	}
+	if (is_feat_sxpie_supported()) {
+		write_pire0_el2(read_ctx_reg(el2_sysregs_ctx, CTX_PIRE0_EL2));
+		write_pir_el2(read_ctx_reg(el2_sysregs_ctx, CTX_PIR_EL2));
+	}
+	if (is_feat_s2pie_supported()) {
+		write_s2pir_el2(read_ctx_reg(el2_sysregs_ctx, CTX_S2PIR_EL2));
+	}
+	if (is_feat_sxpoe_supported()) {
+		write_por_el2(read_ctx_reg(el2_sysregs_ctx, CTX_POR_EL2));
+	}
+	if (is_feat_gcs_supported()) {
+		write_gcscr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_GCSCR_EL2));
+		write_gcspr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_GCSPR_EL2));
 	}
 }
 #endif /* CTX_INCLUDE_EL2_REGS */
@@ -1279,18 +1327,6 @@
 			(el_implemented(2U) != EL_IMPL_NONE));
 #endif /* ENABLE_ASSERTIONS */
 
-	/*
-	 * Set the NS bit to be able to access the ICC_SRE_EL2
-	 * register when restoring context.
-	 */
-	write_scr_el3(read_scr_el3() | SCR_NS_BIT);
-
-	/*
-	 * Ensure the NS bit change is committed before the EL2/EL1
-	 * state restoration.
-	 */
-	isb();
-
 	/* Restore EL2 and EL1 sysreg contexts */
 	cm_el2_sysregs_context_restore(NON_SECURE);
 	cm_el1_sysregs_context_restore(NON_SECURE);
diff --git a/lib/extensions/amu/aarch64/amu.c b/lib/extensions/amu/aarch64/amu.c
index 8c5ef0b..53bdb55 100644
--- a/lib/extensions/amu/aarch64/amu.c
+++ b/lib/extensions/amu/aarch64/amu.c
@@ -69,16 +69,6 @@
 		((value << CPTR_EL2_TAM_SHIFT) & CPTR_EL2_TAM_BIT));
 }
 
-static inline __unused void ctx_write_cptr_el3_tam(cpu_context_t *ctx, uint64_t tam)
-{
-	uint64_t value = read_ctx_reg(get_el3state_ctx(ctx), CTX_CPTR_EL3);
-
-	value &= ~TAM_BIT;
-	value |= (tam << TAM_SHIFT) & TAM_BIT;
-
-	write_ctx_reg(get_el3state_ctx(ctx), CTX_CPTR_EL3, value);
-}
-
 static inline __unused void ctx_write_scr_el3_amvoffen(cpu_context_t *ctx, uint64_t amvoffen)
 {
 	uint64_t value = read_ctx_reg(get_el3state_ctx(ctx), CTX_SCR_EL3);
@@ -194,7 +184,10 @@
 	 * Set CPTR_EL3.TAM to zero so that any accesses to the Activity Monitor
 	 * registers do not trap to EL3.
 	 */
-	ctx_write_cptr_el3_tam(ctx, 0U);
+	u_register_t cptr_el3 = read_ctx_reg(get_el3state_ctx(ctx), CTX_CPTR_EL3);
+
+	cptr_el3 &= ~TAM_BIT;
+	write_ctx_reg(get_el3state_ctx(ctx), CTX_CPTR_EL3, cptr_el3);
 
 	/* Initialize FEAT_AMUv1p1 features if present. */
 	if (is_feat_amuv1p1_supported()) {
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/defaults.mk b/make_helpers/defaults.mk
index aaabb27..ea22655 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -147,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
@@ -237,6 +240,9 @@
 # Use the FF-A SPMC implementation in EL3.
 SPMC_AT_EL3			:= 0
 
+# Enable SEL0 SP when SPMC is enabled at EL3
+SPMC_AT_EL3_SEL0_SP		:=0
+
 # Use SPM at S-EL2 as a default config for SPMD
 SPMD_SPM_AT_SEL2		:= 1
 
@@ -356,3 +362,11 @@
 
 # By default, disable SPMD Logical partitions
 ENABLE_SPMD_LP			:= 0
+
+# By default, disable PSA crypto (use MbedTLS legacy crypto API).
+PSA_CRYPTO			:= 0
+
+# getc() support from the console(s).
+# Disabled by default because it constitutes an attack vector into TF-A. It
+# should only be enabled if there is a use case for it.
+ENABLE_CONSOLE_GETC		:= 0
diff --git a/plat/arm/board/common/board_arm_trusted_boot.c b/plat/arm/board/common/board_arm_trusted_boot.c
index 24d88ee..c4f15dd 100644
--- a/plat/arm/board/common/board_arm_trusted_boot.c
+++ b/plat/arm/board/common/board_arm_trusted_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-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
  */
@@ -94,20 +94,25 @@
 #endif
 
 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
-    (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) || \
-    (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_FULL_DEV_RSA_KEY_ID)
+    (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
 int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len,
 			unsigned int *flags)
 {
-	if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_FULL_DEV_RSA_KEY_ID) {
-		*key_ptr = arm_rotpk_key;
-		*key_len = arm_rotpk_key_end - arm_rotpk_key;
-		*flags = 0;
-	} else {
-		*key_ptr = arm_rotpk_header;
-		*key_len = arm_rotpk_hash_end - arm_rotpk_header;
-		*flags = ROTPK_IS_HASH;
-	}
+	*key_ptr = arm_rotpk_header;
+	*key_len = arm_rotpk_hash_end - arm_rotpk_header;
+	*flags = ROTPK_IS_HASH;
+	return 0;
+}
+#endif
+
+#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_FULL_DEV_RSA_KEY_ID) || \
+    (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_FULL_DEV_ECDSA_KEY_ID)
+int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len,
+			unsigned int *flags)
+{
+	*key_ptr = arm_rotpk_key;
+	*key_len = arm_rotpk_key_end - arm_rotpk_key;
+	*flags = 0;
 	return 0;
 }
 #endif
@@ -144,9 +149,7 @@
 	return arm_get_rotpk_info_cc(key_ptr, key_len, flags);
 #else
 
-#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
-    (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) || \
-    (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_FULL_DEV_RSA_KEY_ID)
+#if ARM_USE_DEVEL_ROTPK
 	return arm_get_rotpk_info_dev(key_ptr, key_len, flags);
 #elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
 	return arm_get_rotpk_info_regs(key_ptr, key_len, flags);
diff --git a/plat/arm/board/common/board_common.mk b/plat/arm/board/common/board_common.mk
index 4665827..cbdbf70 100644
--- a/plat/arm/board/common/board_common.mk
+++ b/plat/arm/board/common/board_common.mk
@@ -39,6 +39,16 @@
 	ARM_ROTPK_S = plat/arm/board/common/rotpk/arm_full_dev_rsa_rotpk.S
 $(warning Development keys support for FVP is deprecated. Use `regs` \
 option instead)
+else ifeq (${ARM_ROTPK_LOCATION}, devel_full_dev_ecdsa_key)
+	CRYPTO_ALG=ec
+	ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_FULL_DEV_ECDSA_KEY_ID
+ifeq (${KEY_SIZE},384)
+	ARM_ROTPK_S = plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p384_rotpk.S
+else
+	ARM_ROTPK_S = plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p256_rotpk.S
+endif
+$(warning Development keys support for FVP is deprecated. Use `regs` \
+option instead)
 else
 $(error "Unsupported ARM_ROTPK_LOCATION value")
 endif
diff --git a/plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p256_rotpk.S b/plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p256_rotpk.S
new file mode 100644
index 0000000..690bdbc
--- /dev/null
+++ b/plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p256_rotpk.S
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+	.global arm_rotpk_key
+	.global arm_rotpk_key_end
+
+	.section .rodata.arm_rotpk_key, "a"
+
+/* Derived from arm_rotprivk_ecdsa.pem private key file. */
+arm_rotpk_key:
+	.byte 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D
+	.byte 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01
+	.byte 0x07, 0x03, 0x42, 0x00, 0x04, 0x9B, 0xE6, 0x48, 0xBD, 0x34, 0x38
+	.byte 0xE1, 0xA2, 0xA4, 0xF3, 0x70, 0xE1, 0x54, 0xBB, 0x2F, 0xB0, 0x5A
+	.byte 0x4A, 0x0C, 0xFF, 0xC2, 0x87, 0xDB, 0xC0, 0xFB, 0x81, 0xE9, 0xF9
+	.byte 0xF9, 0x95, 0x7D, 0x7E, 0xA0, 0x0C, 0x7F, 0x0A, 0xD4, 0xE0, 0x62
+	.byte 0x4A, 0x94, 0x5F, 0xEC, 0x52, 0x7D, 0x44, 0x63, 0xC8, 0x9F, 0x61
+	.byte 0xFA, 0xC6, 0xCB, 0x7E, 0x6B, 0x53, 0xAD, 0x2C, 0xC5, 0x94, 0x0D
+	.byte 0x1A, 0x86, 0x91
+arm_rotpk_key_end:
diff --git a/plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p384_rotpk.S b/plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p384_rotpk.S
new file mode 100644
index 0000000..eaf2de4
--- /dev/null
+++ b/plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p384_rotpk.S
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+	.global arm_rotpk_key
+	.global arm_rotpk_key_end
+
+	.section .rodata.arm_rotpk_key, "a"
+
+/* Derived from arm_rotprivk_ecdsa_secp384r1.pem private key file. */
+arm_rotpk_key:
+	.byte 0x30, 0x76, 0x30, 0x10, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D
+	.byte 0x02, 0x01, 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22, 0x03, 0x62
+	.byte 0x00, 0x04, 0xB8, 0xB0, 0xC7, 0xC4, 0x57, 0x19, 0xB7, 0x5A, 0x06
+	.byte 0x36, 0xC5, 0xD8, 0x3C, 0x4E, 0xC3, 0xB5, 0xE1, 0x15, 0x60, 0x0E
+	.byte 0x63, 0xD8, 0xAF, 0x22, 0x2C, 0x6D, 0x79, 0x29, 0xDF, 0x46, 0xA9
+	.byte 0x30, 0x12, 0x16, 0x2D, 0x4F, 0x0F, 0x96, 0x6B, 0x1F, 0x87, 0x06
+	.byte 0xDB, 0x8F, 0xD7, 0x08, 0x46, 0xE4, 0x4C, 0x22, 0xF3, 0xDE, 0xCE
+	.byte 0x0F, 0x72, 0x27, 0x00, 0xAA, 0xD8, 0xC3, 0x79, 0x80, 0x5E, 0xF1
+	.byte 0x35, 0x1B, 0x33, 0xB6, 0x31, 0xC4, 0x59, 0xD4, 0xE9, 0x65, 0x91
+	.byte 0x22, 0x58, 0x2F, 0x87, 0xF1, 0x6C, 0x27, 0xBE, 0x99, 0x6F, 0x5F
+	.byte 0x6C, 0x14, 0xC5, 0x37, 0x0C, 0x73, 0xB4, 0xE4, 0x8A, 0x63
+arm_rotpk_key_end:
diff --git a/plat/arm/board/common/rotpk/arm_full_dev_rsa_rotpk.S b/plat/arm/board/common/rotpk/arm_full_dev_rsa_rotpk.S
index 4bb04dc..4532e53 100644
--- a/plat/arm/board/common/rotpk/arm_full_dev_rsa_rotpk.S
+++ b/plat/arm/board/common/rotpk/arm_full_dev_rsa_rotpk.S
@@ -1,32 +1,40 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-/* corstone1000 platform provides custom values for the macros defined in
- * arm_def.h , so only platform_def.h needs to be included
- */
-#if !defined(TARGET_PLATFORM_FVP) && !defined(TARGET_PLATFORM_FPGA)
-#include "plat/arm/common/arm_def.h"
-#else
-#include <platform_def.h>
-#endif
-
 	.global arm_rotpk_key
 	.global arm_rotpk_key_end
 
 	.section .rodata.arm_rotpk_key, "a"
 
 arm_rotpk_key:
-	.byte 0x30, 0x82, 0x01, 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01
-	.byte 0x05, 0x00, 0x03, 0x82, 0x01, 0x0F, 0x00, 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01
-	.byte 0x00, 0xCB, 0x2C, 0x60, 0xD5, 0x8D, 0x63, 0xD4, 0x07, 0x79, 0x7E, 0xC7, 0x16, 0x96, 0xBD, 0x4D, 0x24, 0x4E, 0xAC, 0x86, 0xE6, 0xB7, 0x71, 0xE3, 0xC5, 0x54, 0x0B, 0xE7, 0x14, 0x1C, 0xBD, 0x29, 0x1A, 0xC1, 0x3F, 0x7A, 0xB6, 0x02, 0xAA, 0xAB, 0x36, 0xC4, 0xD9, 0x36, 0x69, 0x6C, 0xE2, 0x65, 0xC3, 0x9B, 0xB1, 0xBF, 0x3D, 0xA8, 0x56, 0x26, 0xCB, 0xFD, 0x04, 0x01, 0xBA, 0xAC, 0x3E, 0x54, 0x32, 0xCA, 0x79, 0x5E, 0xBB, 0xB2, 0x05, 0xEA, 0x06, 0x58, 0xF2, 0x74, 0xBA, 0xE1, 0xF4, 0x87, 0xC0, 0x19, 0x0A, 0x1F, 0x66, 0x07, 0x77, 0x84, 0x83, 0xA1, 0x1C, 0xEF, 0xFF, 0x28, 0x59, 0xE7, 0xC3, 0x68, 0x7D, 0x26, 0x20, 0x43, 0xEB, 0x56, 0x63, 0xF3, 0x39, 0x31, 0xD8, 0x2B, 0x51, 0xA9, 0xBC, 0x4F, 0xD0, 0xF6, 0xDE, 0x95, 0xDC, 0x5F, 0x5B, 0xC1, 0xED, 0x90, 0x6F, 0xEC, 0x28, 0x91, 0x7E, 0x17, 0xED, 0x78, 0x90, 0xF4, 0x60, 0xA7, 0xC4, 0xC7, 0x4F, 0x50, 0xED, 0x5D, 0x13, 0x3A, 0x21, 0x2B, 0x70, 0xC5, 0x61, 0x7B, 0x08, 0x21, 0x65, 0x3A, 0xCD, 0x82, 0x56, 0x8C, 0x7A, 0x47, 0xAC, 0x89, 0xE8, 0xA5, 0x48, 0x48
-	.byte 0x31, 0xD9, 0x1D, 0x46, 0xE5, 0x85, 0x86, 0x98, 0xA0, 0xE5, 0xC0, 0xA6, 0x6A, 0xBD, 0x07, 0xE4, 0x92, 0x57, 0x61, 0x07, 0x8F, 0x7D, 0x5A, 0x4D, 0xCA, 0xAE, 0x36, 0xB9, 0x56, 0x04, 0x10, 0xF2, 0x6C, 0xBE, 0xF6, 0x3B, 0x6C, 0x80, 0x3E, 0xBE , 0x0E, 0xA3, 0x4D , 0xC7 , 0xD4, 0x7E , 0xA7  , 0x49, 0xD4, 0xF2, 0xD2, 0xBC, 0xCF, 0x30, 0xA8, 0xE7, 0x74, 0x8F, 0x64, 0xDF, 0xBC, 0x5C, 0x47, 0x68, 0xCC, 0x40, 0x4C, 0xF8, 0x83, 0xCC, 0xCB, 0x40, 0x35, 0x04, 0x60, 0xCA, 0xB3, 0xA4, 0x17, 0x9F, 0x03, 0xCA, 0x1D, 0x5A, 0xFA, 0xD1, 0xAF, 0x21, 0x57, 0x10, 0xD3, 0x02, 0x03, 0x01, 0x00, 0x01
-
+	.byte 0x30, 0x82, 0x01, 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48
+	.byte 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01
+	.byte 0x0F, 0x00, 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, 0x00
+	.byte 0xCB, 0x2C, 0x60, 0xD5, 0x8D, 0x63, 0xD4, 0x07, 0x79, 0x7E, 0xC7
+	.byte 0x16, 0x96, 0xBD, 0x4D, 0x24, 0x4E, 0xAC, 0x86, 0xE6, 0xB7, 0x71
+	.byte 0xE3, 0xC5, 0x54, 0x0B, 0xE7, 0x14, 0x1C, 0xBD, 0x29, 0x1A, 0xC1
+	.byte 0x3F, 0x7A, 0xB6, 0x02, 0xAA, 0xAB, 0x36, 0xC4, 0xD9, 0x36, 0x69
+	.byte 0x6C, 0xE2, 0x65, 0xC3, 0x9B, 0xB1, 0xBF, 0x3D, 0xA8, 0x56, 0x26
+	.byte 0xCB, 0xFD, 0x04, 0x01, 0xBA, 0xAC, 0x3E, 0x54, 0x32, 0xCA, 0x79
+	.byte 0x5E, 0xBB, 0xB2, 0x05, 0xEA, 0x06, 0x58, 0xF2, 0x74, 0xBA, 0xE1
+	.byte 0xF4, 0x87, 0xC0, 0x19, 0x0A, 0x1F, 0x66, 0x07, 0x77, 0x84, 0x83
+	.byte 0xA1, 0x1C, 0xEF, 0xFF, 0x28, 0x59, 0xE7, 0xC3, 0x68, 0x7D, 0x26
+	.byte 0x20, 0x43, 0xEB, 0x56, 0x63, 0xF3, 0x39, 0x31, 0xD8, 0x2B, 0x51
+	.byte 0xA9, 0xBC, 0x4F, 0xD0, 0xF6, 0xDE, 0x95, 0xDC, 0x5F, 0x5B, 0xC1
+	.byte 0xED, 0x90, 0x6F, 0xEC, 0x28, 0x91, 0x7E, 0x17, 0xED, 0x78, 0x90
+	.byte 0xF4, 0x60, 0xA7, 0xC4, 0xC7, 0x4F, 0x50, 0xED, 0x5D, 0x13, 0x3A
+	.byte 0x21, 0x2B, 0x70, 0xC5, 0x61, 0x7B, 0x08, 0x21, 0x65, 0x3A, 0xCD
+	.byte 0x82, 0x56, 0x8C, 0x7A, 0x47, 0xAC, 0x89, 0xE8, 0xA5, 0x48, 0x48
+	.byte 0x31, 0xD9, 0x1D, 0x46, 0xE5, 0x85, 0x86, 0x98, 0xA0, 0xE5, 0xC0
+	.byte 0xA6, 0x6A, 0xBD, 0x07, 0xE4, 0x92, 0x57, 0x61, 0x07, 0x8F, 0x7D
+	.byte 0x5A, 0x4D, 0xCA, 0xAE, 0x36, 0xB9, 0x56, 0x04, 0x10, 0xF2, 0x6C
+	.byte 0xBE, 0xF6, 0x3B, 0x6C, 0x80, 0x3E, 0xBE, 0x0E, 0xA3, 0x4D, 0xC7
+	.byte 0xD4, 0x7E, 0xA7, 0x49, 0xD4, 0xF2, 0xD2, 0xBC, 0xCF, 0x30, 0xA8
+	.byte 0xE7, 0x74, 0x8F, 0x64, 0xDF, 0xBC, 0x5C, 0x47, 0x68, 0xCC, 0x40
+	.byte 0x4C, 0xF8, 0x83, 0xCC, 0xCB, 0x40, 0x35, 0x04, 0x60, 0xCA, 0xB3
+	.byte 0xA4, 0x17, 0x9F, 0x03, 0xCA, 0x1D, 0x5A, 0xFA, 0xD1, 0xAF, 0x21
+	.byte 0x57, 0x10, 0xD3, 0x02, 0x03, 0x01, 0x00, 0x01
 arm_rotpk_key_end:
-
-.if ARM_ROTPK_KEY_LEN != arm_rotpk_key_end - arm_rotpk_key
-.error "Invalid ROTPK length."
-.endif
-
diff --git a/plat/arm/board/common/rotpk/arm_rotprivk_ecdsa_secp384r1.pem b/plat/arm/board/common/rotpk/arm_rotprivk_ecdsa_secp384r1.pem
new file mode 100644
index 0000000..d40fc05
--- /dev/null
+++ b/plat/arm/board/common/rotpk/arm_rotprivk_ecdsa_secp384r1.pem
@@ -0,0 +1,6 @@
+-----BEGIN PRIVATE KEY-----
+MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDAWrGXulAoVCrH3oRMC
+/AGvn2LA6+VI0xtd9eCWCzIcOSt+AC+/kULZnypuC8bdGJOhZANiAAS4sMfEVxm3
+WgY2xdg8TsO14RVgDmPYryIsbXkp30apMBIWLU8Plmsfhwbbj9cIRuRMIvPezg9y
+JwCq2MN5gF7xNRsztjHEWdTpZZEiWC+H8WwnvplvX2wUxTcMc7TkimM=
+-----END PRIVATE KEY-----
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/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 4803f35..3c02485 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -58,7 +58,6 @@
 ifeq (${ARCH}, aarch64)
 ifneq (${SPD}, spmd)
 ifeq (${SPM_MM}, 0)
-ifeq (${ENABLE_RME}, 0)
 ifeq (${CTX_INCLUDE_FPREGS}, 0)
 	ENABLE_SME_FOR_NS		:= 2
 	ENABLE_SME2_FOR_NS		:= 2
@@ -67,7 +66,6 @@
 endif
 endif
 endif
-endif
 
 # enable unconditionally for all builds
 ifeq (${ARCH}, aarch64)
diff --git a/plat/arm/board/rdn2/include/platform_def.h b/plat/arm/board/rdn2/include/platform_def.h
index ff1a437..2391b72 100644
--- a/plat/arm/board/rdn2/include/platform_def.h
+++ b/plat/arm/board/rdn2/include/platform_def.h
@@ -102,4 +102,25 @@
 #define PLAT_REBOOT_PRI		GIC_HIGHEST_SEC_PRIORITY
 #define PLAT_EHF_DESC		EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_REBOOT_PRI)
 
+/*
+ * Number of Secure Partitions supported.
+ * SPMC at EL3, uses this count to configure the maximum number of supported
+ * secure partitions.
+ */
+#define SECURE_PARTITION_COUNT          1
+
+/*
+ * Number of NWd Partitions supported.
+ * SPMC at EL3, uses this count to configure the maximum number of supported
+ * nwld partitions.
+ */
+#define NS_PARTITION_COUNT              1
+
+/*
+ * Number of Logical Partitions supported.
+ * SPMC at EL3, uses this count to configure the maximum number of supported
+ * logical partitions.
+ */
+#define MAX_EL3_LP_DESCS_COUNT		1
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/rdn2/rdn2_plat.c b/plat/arm/board/rdn2/rdn2_plat.c
index e8a967e..f117456 100644
--- a/plat/arm/board/rdn2/rdn2_plat.c
+++ b/plat/arm/board/rdn2/rdn2_plat.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,6 +8,7 @@
 #include <drivers/arm/gic600_multichip.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
+#include <services/el3_spmc_ffa_memory.h>
 #include <rdn2_ras.h>
 #include <sgi_soc_platform_def_v2.h>
 #include <sgi_plat.h>
@@ -141,3 +142,41 @@
 #endif
 }
 #endif /* IMAGE_BL31 */
+
+#if SPMC_AT_EL3
+
+#define DATASTORE_SIZE 1024
+
+__section("arm_el3_tzc_dram") uint8_t plat_spmc_shmem_datastore[DATASTORE_SIZE];
+
+int plat_spmc_shmem_datastore_get(uint8_t **datastore, size_t *size)
+{
+	*datastore = plat_spmc_shmem_datastore;
+	*size = DATASTORE_SIZE;
+	return 0;
+}
+
+/*
+ * Add dummy implementations of memory management related platform hooks.
+ * Memory share/lend operation are not required on RdN2 platform.
+ */
+int plat_spmc_shmem_begin(struct ffa_mtd *desc)
+{
+	return 0;
+}
+
+int plat_spmc_shmem_reclaim(struct ffa_mtd *desc)
+{
+	return 0;
+}
+
+int plat_spmd_handle_group0_interrupt(uint32_t intid)
+{
+	/*
+	 * As of now, there are no sources of Group0 secure interrupt enabled
+	 * for RDN2.
+	 */
+	(void)intid;
+	return -1;
+}
+#endif
diff --git a/plat/arm/css/sgi/include/sgi_base_platform_def.h b/plat/arm/css/sgi/include/sgi_base_platform_def.h
index b9c785f..8a13bf3 100644
--- a/plat/arm/css/sgi/include/sgi_base_platform_def.h
+++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -33,7 +33,7 @@
  * chips are accessed - secure ram, css device and soc device regions.
  */
 #if defined(IMAGE_BL31)
-# if SPM_MM
+# if SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)
 #  define PLAT_ARM_MMAP_ENTRIES		(9  + ((CSS_SGI_CHIP_COUNT - 1) * 3))
 #  define MAX_XLAT_TABLES		(7  + ((CSS_SGI_CHIP_COUNT - 1) * 3))
 #  define PLAT_SP_IMAGE_MMAP_REGIONS	10
@@ -210,7 +210,7 @@
 #define PLAT_SP_PRI				0x10
 #endif
 
-#if SPM_MM && RAS_FFH_SUPPORT
+#if (SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)) && RAS_FFH_SUPPORT
 /*
  * CPER buffer memory of 128KB is reserved and it is placed adjacent to the
  * memory shared between EL3 and S-EL0.
@@ -232,7 +232,7 @@
 #define PLAT_ARM_SP_IMAGE_STACK_BASE		(PLAT_SP_IMAGE_NS_BUF_BASE +   \
 						 PLAT_SP_IMAGE_NS_BUF_SIZE +   \
 						 CSS_SGI_SP_CPER_BUF_SIZE)
-#elif SPM_MM
+#elif (SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP))
 /*
  * Secure partition stack follows right after the memory region that is shared
  * between EL3 and S-EL0.
diff --git a/plat/arm/css/sgi/sgi_plat_v2.c b/plat/arm/css/sgi/sgi_plat_v2.c
index 8de0efe..85f99d4 100644
--- a/plat/arm/css/sgi/sgi_plat_v2.c
+++ b/plat/arm/css/sgi/sgi_plat_v2.c
@@ -54,7 +54,7 @@
 #if ARM_BL31_IN_DRAM
 	ARM_MAP_BL31_SEC_DRAM,
 #endif
-#if SPM_MM
+#if SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)
 	ARM_SP_IMAGE_MMAP,
 #endif
 #if TRUSTED_BOARD_BOOT && !RESET_TO_BL2
@@ -73,7 +73,7 @@
 	CSS_SGI_MAP_DEVICE,
 	SOC_PLATFORM_PERIPH_MAP_DEVICE,
 	SOC_SYSTEM_PERIPH_MAP_DEVICE,
-#if SPM_MM
+#if SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)
 	ARM_SPM_BUF_EL3_MMAP,
 #endif
 	{0}
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/aarch64/plat_ehf.c b/plat/common/aarch64/plat_ehf.c
index be0fac1..41b175d 100644
--- a/plat/common/aarch64/plat_ehf.c
+++ b/plat/common/aarch64/plat_ehf.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2020, Broadcom
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -25,7 +25,7 @@
 	EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SDEI_NORMAL_PRI),
 #endif
 
-#if SPM_MM
+#if SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)
 #if RAS_FFH_SUPPORT
 #if (PLAT_SP_PRI != PLAT_RAS_PRI)
 	EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SP_PRI),
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/common/aarch32/imx_uart_console.S b/plat/imx/common/aarch32/imx_uart_console.S
index 1a1229a..2a35b5e 100644
--- a/plat/imx/common/aarch32/imx_uart_console.S
+++ b/plat/imx/common/aarch32/imx_uart_console.S
@@ -28,7 +28,7 @@
 
 	mov	r0, r4
 	pop	{r4, lr}
-	finish_console_register imx_uart putc=1, getc=1, flush=1
+	finish_console_register imx_uart putc=1, getc=ENABLE_CONSOLE_GETC, flush=1
 
 register_fail:
 	pop	{r4, pc}
diff --git a/plat/imx/common/imx_uart_console.S b/plat/imx/common/imx_uart_console.S
index 4d17288..560db15 100644
--- a/plat/imx/common/imx_uart_console.S
+++ b/plat/imx/common/imx_uart_console.S
@@ -33,7 +33,7 @@
 
 	mov	x0, x6
 	mov	x30, x7
-	finish_console_register imx_uart putc=1, getc=1, flush=1
+	finish_console_register imx_uart putc=1, getc=ENABLE_CONSOLE_GETC, flush=1
 
 register_fail:
 	ret	x7
diff --git a/plat/imx/common/lpuart_console.S b/plat/imx/common/lpuart_console.S
index ff01e35..7acf773 100644
--- a/plat/imx/common/lpuart_console.S
+++ b/plat/imx/common/lpuart_console.S
@@ -27,7 +27,7 @@
 
 	mov	x0, x6
 	mov	x30, x7
-	finish_console_register lpuart putc=1, getc=1, flush=1
+	finish_console_register lpuart putc=1, getc=ENABLE_CONSOLE_GETC, flush=1
 
 register_fail:
 	ret	x7
diff --git a/plat/imx/imx8m/imx8m_snvs.c b/plat/imx/imx8m/imx8m_snvs.c
new file mode 100644
index 0000000..7874a68
--- /dev/null
+++ b/plat/imx/imx8m/imx8m_snvs.c
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2022-2023 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#define SNVS_HPCOMR		U(0x04)
+#define SNVS_NPSWA_EN		BIT(31)
+
+void enable_snvs_privileged_access(void)
+{
+	unsigned int val;
+
+	val = mmio_read_32(IMX_SNVS_BASE + SNVS_HPCOMR);
+	mmio_write_32(IMX_SNVS_BASE + SNVS_HPCOMR, val | SNVS_NPSWA_EN);
+}
diff --git a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
index c8a3adf..dc9dd59 100644
--- a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
@@ -29,6 +29,7 @@
 #include <imx8m_caam.h>
 #include <imx8m_ccm.h>
 #include <imx8m_csu.h>
+#include <imx8m_snvs.h>
 #include <plat_imx8.h>
 
 #define TRUSTY_PARAMS_LEN_BYTES      (4096*2)
@@ -187,6 +188,10 @@
 #endif
 #endif
 
+#if !defined(SPD_opteed) && !defined(SPD_trusty)
+	enable_snvs_privileged_access();
+#endif
+
 	bl31_tzc380_setup();
 }
 
@@ -208,8 +213,10 @@
 #if USE_COHERENT_MEM
 		MAP_COHERENT_MEM,
 #endif
+#if defined(SPD_opteed) || defined(SPD_trusty)
 		/* Map TEE memory */
 		MAP_BL32_TOTAL,
+#endif
 		{0}
 	};
 
diff --git a/plat/imx/imx8m/imx8mm/platform.mk b/plat/imx/imx8m/imx8mm/platform.mk
index 6f6daf8..97f4f24 100644
--- a/plat/imx/imx8m/imx8mm/platform.mk
+++ b/plat/imx/imx8m/imx8mm/platform.mk
@@ -39,6 +39,7 @@
 				plat/imx/imx8m/imx8m_caam.c			\
 				plat/imx/imx8m/imx8m_ccm.c			\
 				plat/imx/imx8m/imx8m_psci_common.c		\
+				plat/imx/imx8m/imx8m_snvs.c			\
 				plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c	\
 				plat/imx/imx8m/imx8mm/imx8mm_psci.c		\
 				plat/imx/imx8m/imx8mm/gpc.c			\
diff --git a/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
index 147249e..f9e430b 100644
--- a/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
@@ -27,6 +27,7 @@
 #include <imx8m_caam.h>
 #include <imx8m_ccm.h>
 #include <imx8m_csu.h>
+#include <imx8m_snvs.h>
 #include <platform_def.h>
 #include <plat_imx8.h>
 
@@ -138,6 +139,13 @@
 
 	imx_csu_init(csu_cfg);
 
+	/*
+	 * Configure the force_incr programmable bit in GPV_5 of PL301_display, which fixes
+	 * partial write issue. The AXI2AHB bridge is used for masters that access the TCM
+	 * through system bus. Please refer to errata ERR050362 for more information.
+	 */
+	mmio_setbits_32((GPV5_BASE_ADDR + FORCE_INCR_OFFSET), FORCE_INCR_BIT_MASK);
+
 	/* config the ocram memory range for secure access */
 	mmio_write_32(IMX_IOMUX_GPR_BASE + 0x2c, 0x4c1);
 	val = mmio_read_32(IMX_IOMUX_GPR_BASE + 0x2c);
@@ -184,6 +192,10 @@
 #endif
 #endif
 
+#if !defined(SPD_opteed) && !defined(SPD_trusty)
+	enable_snvs_privileged_access();
+#endif
+
 	bl31_tzc380_setup();
 }
 
@@ -205,8 +217,10 @@
 #if USE_COHERENT_MEM
 		MAP_COHERENT_MEM,
 #endif
+#if defined(SPD_opteed) || defined(SPD_trusty)
 		/* Map TEE memory */
 		MAP_BL32_TOTAL,
+#endif
 		{0}
 	};
 
diff --git a/plat/imx/imx8m/imx8mn/include/platform_def.h b/plat/imx/imx8m/imx8mn/include/platform_def.h
index c75e250..d5176dd 100644
--- a/plat/imx/imx8m/imx8mn/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mn/include/platform_def.h
@@ -141,6 +141,10 @@
 
 #define COUNTER_FREQUENCY		8000000 /* 8MHz */
 
+#define GPV5_BASE_ADDR			U(0x32500000)
+#define FORCE_INCR_OFFSET		U(0x4044)
+#define FORCE_INCR_BIT_MASK		U(0x2)
+
 #define IMX_WDOG_B_RESET
 
 #define GIC_MAP		MAP_REGION_FLAT(IMX_GIC_BASE, IMX_GIC_SIZE, MT_DEVICE | MT_RW)
diff --git a/plat/imx/imx8m/imx8mn/platform.mk b/plat/imx/imx8m/imx8mn/platform.mk
index a6b43f2..e0826e2 100644
--- a/plat/imx/imx8m/imx8mn/platform.mk
+++ b/plat/imx/imx8m/imx8mn/platform.mk
@@ -34,6 +34,7 @@
 				plat/imx/imx8m/imx8m_ccm.c			\
 				plat/imx/imx8m/imx8m_csu.c			\
 				plat/imx/imx8m/imx8m_psci_common.c		\
+				plat/imx/imx8m/imx8m_snvs.c			\
 				plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c	\
 				plat/imx/imx8m/imx8mn/imx8mn_psci.c		\
 				plat/imx/imx8m/imx8mn/gpc.c			\
diff --git a/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
index b0a41c7..43fa064 100644
--- a/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
@@ -27,6 +27,7 @@
 #include <imx8m_caam.h>
 #include <imx8m_ccm.h>
 #include <imx8m_csu.h>
+#include <imx8m_snvs.h>
 #include <platform_def.h>
 #include <plat_imx8.h>
 
@@ -180,6 +181,10 @@
 #endif
 #endif
 
+#if !defined(SPD_opteed) && !defined(SPD_trusty)
+	enable_snvs_privileged_access();
+#endif
+
 	bl31_tzc380_setup();
 }
 
@@ -201,8 +206,10 @@
 #if USE_COHERENT_MEM
 		MAP_COHERENT_MEM,
 #endif
+#if defined(SPD_opteed) || defined(SPD_trusty)
 		/* Map TEE memory */
 		MAP_BL32_TOTAL,
+#endif
 		{0}
 	};
 
diff --git a/plat/imx/imx8m/imx8mp/platform.mk b/plat/imx/imx8m/imx8mp/platform.mk
index a8400a4..ce69071 100644
--- a/plat/imx/imx8m/imx8mp/platform.mk
+++ b/plat/imx/imx8m/imx8mp/platform.mk
@@ -35,6 +35,7 @@
 				plat/imx/imx8m/imx8m_ccm.c			\
 				plat/imx/imx8m/imx8m_csu.c			\
 				plat/imx/imx8m/imx8m_psci_common.c		\
+				plat/imx/imx8m/imx8m_snvs.c			\
 				plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c	\
 				plat/imx/imx8m/imx8mp/imx8mp_psci.c		\
 				plat/imx/imx8m/imx8mp/gpc.c			\
diff --git a/plat/imx/imx8m/include/imx8m_snvs.h b/plat/imx/imx8m/include/imx8m_snvs.h
new file mode 100644
index 0000000..799e1d5
--- /dev/null
+++ b/plat/imx/imx8m/include/imx8m_snvs.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright 2022-2023 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IMX8M_SNVS_H
+#define IMX8M_SNVS_H
+
+void enable_snvs_privileged_access(void);
+
+#endif
diff --git a/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.c b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.c
index c1b3de0..86c4b81 100644
--- a/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.c
+++ b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.c
@@ -88,6 +88,7 @@
 
 	mmio_write_32(MD32_SYS_CTRL, MD32_SYS_CTRL_RST);
 
+	dsb();
 	udelay(RESET_DEALY_US);
 
 	mmio_write_32(MD32_SYS_CTRL, MD32_G2B_CG_EN | MD32_DBG_EN | MD32_DM_AWUSER_IOMMU_EN |
diff --git a/plat/mediatek/drivers/apusys/mt8188/apusys_power.c b/plat/mediatek/drivers/apusys/mt8188/apusys_power.c
index cdfc133..0a2781b 100644
--- a/plat/mediatek/drivers/apusys/mt8188/apusys_power.c
+++ b/plat/mediatek/drivers/apusys/mt8188/apusys_power.c
@@ -37,7 +37,6 @@
 		if ((reg_val & mask) == value) {
 			return 0;
 		}
-
 		udelay(APU_POLL_STEP_US);
 	} while (--count);
 
@@ -169,15 +168,19 @@
 static void apu_sleep_rpc_rcx(void)
 {
 	mmio_write_32(APU_RPC_BASE + APU_RPC_TOP_CON, REG_WAKEUP_CLR);
+	dsb();
 	udelay(10);
 
 	mmio_setbits_32(APU_RPC_BASE + APU_RPC_TOP_SEL, (RPC_CTRL | RSV10));
+	dsb();
 	udelay(10);
 
 	mmio_setbits_32(APU_RPC_BASE + APU_RPC_TOP_CON, CLR_IRQ);
+	dsb();
 	udelay(10);
 
 	mmio_setbits_32(APU_RPC_BASE + APU_RPC_TOP_CON, SLEEP_REQ);
+	dsb();
 	udelay(100);
 }
 
@@ -313,12 +316,15 @@
 static void apu_buck_off_cfg(void)
 {
 	mmio_write_32(APU_RPC_BASE + APU_RPC_HW_CON, BUCK_PROT_REQ_SET);
+	dsb();
 	udelay(10);
 
 	mmio_write_32(APU_RPC_BASE + APU_RPC_HW_CON, BUCK_ELS_EN_SET);
+	dsb();
 	udelay(10);
 
 	mmio_write_32(APU_RPC_BASE + APU_RPC_HW_CON, BUCK_AO_RST_B_CLR);
+	dsb();
 	udelay(10);
 }
 
@@ -425,15 +431,19 @@
 {
 	mmio_clrbits_32(SPM_BASE + APUSYS_BUCK_ISOLATION, IPU_EXT_BUCK_ISO);
 	mmio_write_32(APU_RPC_BASE + APU_RPC_HW_CON, BUCK_ELS_EN_CLR);
+	dsb();
 	udelay(10);
 
 	mmio_write_32(APU_RPC_BASE + APU_RPC_HW_CON, BUCK_AO_RST_B_SET);
+	dsb();
 	udelay(10);
 
 	mmio_write_32(APU_RPC_BASE + APU_RPC_HW_CON, BUCK_PROT_REQ_CLR);
+	dsb();
 	udelay(10);
 
 	mmio_write_32(APU_RPC_BASE + APU_RPC_HW_CON, SRAM_AOC_ISO_CLR);
+	dsb();
 	udelay(10);
 }
 
diff --git a/plat/nvidia/tegra/drivers/spe/shared_console.S b/plat/nvidia/tegra/drivers/spe/shared_console.S
index d1b18dd..5ad4eb8 100644
--- a/plat/nvidia/tegra/drivers/spe/shared_console.S
+++ b/plat/nvidia/tegra/drivers/spe/shared_console.S
@@ -71,7 +71,7 @@
 	cbz	x3, register_fail
 	str	x0, [x3, #CONSOLE_T_BASE]
 	mov	x0, x3
-	finish_console_register spe putc=1, getc=1, flush=1
+	finish_console_register spe putc=1, getc=ENABLE_CONSOLE_GETC, flush=1
 
 register_fail:
 	mov	w0, wzr
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/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/socionext/uniphier/uniphier_console_setup.c b/plat/socionext/uniphier/uniphier_console_setup.c
index 9fda26e..9268f5d 100644
--- a/plat/socionext/uniphier/uniphier_console_setup.c
+++ b/plat/socionext/uniphier/uniphier_console_setup.c
@@ -30,7 +30,9 @@
 		 CONSOLE_FLAG_CRASH |
 		 CONSOLE_FLAG_TRANSLATE_CRLF,
 	.putc = uniphier_console_putc,
+#if ENABLE_CONSOLE_GETC
 	.getc = uniphier_console_getc,
+#endif
 	.flush = uniphier_console_flush,
 };
 
diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c
index 0bcfece..86795d7 100644
--- a/plat/st/common/bl2_io_storage.c
+++ b/plat/st/common/bl2_io_storage.c
@@ -56,7 +56,7 @@
 #if STM32MP_SDMMC || STM32MP_EMMC
 static struct mmc_device_info mmc_info;
 
-static uint32_t block_buffer[MMC_BLOCK_SIZE] __aligned(MMC_BLOCK_SIZE);
+static uint8_t block_buffer[MMC_BLOCK_SIZE] __aligned(MMC_BLOCK_SIZE);
 
 static io_block_dev_spec_t mmc_block_dev_spec = {
 	/* It's used as temp buffer in block driver */
diff --git a/plat/st/common/common.mk b/plat/st/common/common.mk
index d10f185..7f93961 100644
--- a/plat/st/common/common.mk
+++ b/plat/st/common/common.mk
@@ -165,7 +165,6 @@
 ifeq (${GENERATE_COT},1)
 TFW_NVCTR_VAL			:=	0
 NTFW_NVCTR_VAL			:=	0
-KEY_SIZE			:=
 KEY_ALG				:=	ecdsa
 HASH_ALG			:=	sha256
 
@@ -178,6 +177,7 @@
 
 endif
 TF_MBEDTLS_KEY_ALG		:=	ecdsa
+KEY_SIZE			:=	256
 
 ifneq (${MBEDTLS_DIR},)
 MBEDTLS_MAJOR=$(shell grep -hP "define MBEDTLS_VERSION_MAJOR" \
diff --git a/plat/st/common/include/stm32mp_dt.h b/plat/st/common/include/stm32mp_dt.h
index b7bf1d0..2d11653 100644
--- a/plat/st/common/include/stm32mp_dt.h
+++ b/plat/st/common/include/stm32mp_dt.h
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2020-2022, STMicroelectronics - All Rights Reserved
- * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -35,7 +35,7 @@
 int dt_get_node(struct dt_node_info *info, int offset, const char *compat);
 int dt_get_stdout_uart_info(struct dt_node_info *info);
 int dt_match_instance_by_compatible(const char *compatible, uintptr_t address);
-uint32_t dt_get_ddr_size(void);
+size_t dt_get_ddr_size(void);
 uint32_t dt_get_pwr_vdd_voltage(void);
 struct rdev *dt_get_vdd_regulator(void);
 struct rdev *dt_get_cpu_regulator(void);
diff --git a/plat/st/common/stm32cubeprogrammer_uart.c b/plat/st/common/stm32cubeprogrammer_uart.c
index e4a5338..0916099 100644
--- a/plat/st/common/stm32cubeprogrammer_uart.c
+++ b/plat/st/common/stm32cubeprogrammer_uart.c
@@ -409,7 +409,7 @@
 	handle.addr = (uint8_t *)buffer;
 	handle.len = length;
 
-	INFO("UART: read phase %u at 0x%lx size 0x%x\n",
+	INFO("UART: read phase %u at 0x%lx size 0x%zx\n",
 	     id, buffer, length);
 	while (!start_done) {
 		ret = uart_receive_command(&command);
diff --git a/plat/st/common/stm32mp_crypto_lib.c b/plat/st/common/stm32mp_crypto_lib.c
index ea2b8db..e282115 100644
--- a/plat/st/common/stm32mp_crypto_lib.c
+++ b/plat/st/common/stm32mp_crypto_lib.c
@@ -80,7 +80,7 @@
 }
 
 static int get_plain_pk_from_asn1(void *pk_ptr, unsigned int pk_len, void **plain_pk,
-			   unsigned int *len, int *pk_alg)
+				  size_t *len, int *pk_alg)
 {
 	int ret;
 	mbedtls_pk_context mbedtls_pk = {0};
@@ -170,7 +170,15 @@
 static int crypto_convert_pk(void *full_pk_ptr, unsigned int full_pk_len,
 			     void **hashed_pk_ptr, unsigned int *hashed_pk_len)
 {
-	return get_plain_pk_from_asn1(full_pk_ptr, full_pk_len, hashed_pk_ptr, hashed_pk_len, NULL);
+	size_t len;
+	int ret;
+
+	ret = get_plain_pk_from_asn1(full_pk_ptr, full_pk_len, hashed_pk_ptr, &len, NULL);
+	if (ret == 0) {
+		*hashed_pk_len = (unsigned int)len;
+	}
+
+	return ret;
 }
 #else /* STM32MP_CRYPTO_ROM_LIB*/
 static uint32_t verify_signature(uint8_t *hash_in, uint8_t *pubkey_in,
@@ -226,7 +234,7 @@
 	static uint8_t st_pk[CRYPTO_PUBKEY_MAX_SIZE + sizeof(uint32_t)];
 	int ret;
 	void *plain_pk;
-	unsigned int len;
+	size_t len;
 	int curve_id;
 	uint32_t cid;
 
@@ -241,7 +249,7 @@
 	memcpy(st_pk + sizeof(cid), plain_pk, len);
 
 	*hashed_pk_ptr = st_pk;
-	*hashed_pk_len = len + sizeof(cid);
+	*hashed_pk_len = (unsigned int)(len + sizeof(cid));
 
 	return 0;
 }
@@ -339,15 +347,15 @@
 		return CRYPTO_ERR_SIGNATURE;
 	}
 
-	ret = get_plain_pk_from_asn1(pk_ptr, pk_len, &pk_ptr, &pk_len, &curve_id);
+	ret = get_plain_pk_from_asn1(pk_ptr, pk_len, &pk_ptr, &len, &curve_id);
 	if (ret != 0) {
 		VERBOSE("%s: get_plain_pk_from_asn1 (%d)\n", __func__, ret);
 		return CRYPTO_ERR_SIGNATURE;
 	}
 
 	/* We expect a known pk_len */
-	if (pk_len != sizeof(my_pk)) {
-		VERBOSE("%s: pk_len=%u sizeof(my_pk)=%zu)\n", __func__, pk_len, sizeof(my_pk));
+	if (len != sizeof(my_pk)) {
+		VERBOSE("%s: pk_len=%zu sizeof(my_pk)=%zu)\n", __func__, len, sizeof(my_pk));
 		return CRYPTO_ERR_SIGNATURE;
 	}
 
@@ -483,7 +491,7 @@
 	/*
 	 * Not a real derivation yet
 	 *
-	 * But we expect a 32 bytes key, and OTP is only 16 bytes
+	 * We expect a 32 bytes key, if OTP is only 16 bytes
 	 *   => duplicate.
 	 */
 	for (i = 0U, j = len; j < 32U;
@@ -517,7 +525,7 @@
 	}
 
 	if (otp_len > (*key_len * CHAR_BIT)) {
-		VERBOSE("%s: length Error otp_len=%u key_len=%u\n", __func__,
+		VERBOSE("%s: length Error otp_len=%u key_len=%zu\n", __func__,
 			otp_len, *key_len * CHAR_BIT);
 		return -EINVAL;
 	}
diff --git a/plat/st/common/stm32mp_dt.c b/plat/st/common/stm32mp_dt.c
index 34d52e1..1cbf51b 100644
--- a/plat/st/common/stm32mp_dt.c
+++ b/plat/st/common/stm32mp_dt.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
  */
@@ -228,9 +228,9 @@
  * This function gets DDR size information from the DT.
  * Returns value in bytes on success, and 0 on failure.
  ******************************************************************************/
-uint32_t dt_get_ddr_size(void)
+size_t dt_get_ddr_size(void)
 {
-	static uint32_t size;
+	static size_t size;
 	int node;
 
 	if (size != 0U) {
@@ -240,12 +240,12 @@
 	node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT);
 	if (node < 0) {
 		INFO("%s: Cannot read DDR node in DT\n", __func__);
-		return 0;
+		return 0U;
 	}
 
-	size = fdt_read_uint32_default(fdt, node, "st,mem-size", 0U);
+	size = (size_t)fdt_read_uint32_default(fdt, node, "st,mem-size", 0U);
 
-	flush_dcache_range((uintptr_t)&size, sizeof(uint32_t));
+	flush_dcache_range((uintptr_t)&size, sizeof(size_t));
 
 	return size;
 }
diff --git a/plat/st/common/stm32mp_trusted_boot.c b/plat/st/common/stm32mp_trusted_boot.c
index 051d6fc..6d89290 100644
--- a/plat/st/common/stm32mp_trusted_boot.c
+++ b/plat/st/common/stm32mp_trusted_boot.c
@@ -10,6 +10,7 @@
 
 #include <common/debug.h>
 #include <common/tbbr/cot_def.h>
+#include <drivers/clk.h>
 #include <drivers/st/stm32_hash.h>
 #include <lib/fconf/fconf.h>
 #include <lib/fconf/fconf_dyn_cfg_getter.h>
@@ -171,16 +172,20 @@
 
 int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
 {
+	clk_enable(TAMP_BKP_REG_CLK);
 	*nv_ctr = mmio_read_32(TAMP_BASE + TAMP_COUNTR);
+	clk_disable(TAMP_BKP_REG_CLK);
 
 	return 0;
 }
 
 int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
 {
+	clk_enable(TAMP_BKP_REG_CLK);
 	while (mmio_read_32(TAMP_BASE + TAMP_COUNTR) != nv_ctr) {
 		mmio_write_32(TAMP_BASE + TAMP_COUNTR, 1U);
 	}
+	clk_disable(TAMP_BKP_REG_CLK);
 
 	return 0;
 }
diff --git a/plat/xilinx/common/plat_fdt.c b/plat/xilinx/common/plat_fdt.c
index 911f664..de5d1a1 100644
--- a/plat/xilinx/common/plat_fdt.c
+++ b/plat/xilinx/common/plat_fdt.c
@@ -15,61 +15,84 @@
 
 void prepare_dtb(void)
 {
+#if defined(XILINX_OF_BOARD_DTB_ADDR)
 	void *dtb;
-	int ret;
-#if !defined(XILINX_OF_BOARD_DTB_ADDR)
-	return;
-#else
+	int map_ret = 0;
+	int ret = 0;
+
 	dtb = (void *)XILINX_OF_BOARD_DTB_ADDR;
-#endif
-	if (IS_TFA_IN_OCM(BL31_BASE))
-		return;
+
+	if (!IS_TFA_IN_OCM(BL31_BASE)) {
 
 #if defined(PLAT_XLAT_TABLES_DYNAMIC)
-	ret = mmap_add_dynamic_region((unsigned long long)dtb,
-				      (uintptr_t)dtb,
-				      XILINX_OF_BOARD_DTB_MAX_SIZE,
-				      MT_MEMORY | MT_RW | MT_NS);
-	if (ret != 0) {
-		WARN("Failed to add dynamic region for dtb: error %d\n", ret);
-		return;
-	}
+		map_ret = mmap_add_dynamic_region((unsigned long long)dtb,
+						 (uintptr_t)dtb,
+						 XILINX_OF_BOARD_DTB_MAX_SIZE,
+						 MT_MEMORY | MT_RW | MT_NS);
+		if (map_ret != 0) {
+			WARN("Failed to add dynamic region for dtb: error %d\n",
+			     map_ret);
+		}
 #endif
 
-	/* Return if no device tree is detected */
-	if (fdt_check_header(dtb) != 0) {
-		NOTICE("Can't read DT at %p\n", dtb);
-		return;
-	}
+		if (!map_ret) {
+			/* Return if no device tree is detected */
+			if (fdt_check_header(dtb) != 0) {
+				NOTICE("Can't read DT at %p\n", dtb);
+			} else {
+				ret = fdt_open_into(dtb, dtb, XILINX_OF_BOARD_DTB_MAX_SIZE);
 
-	ret = fdt_open_into(dtb, dtb, XILINX_OF_BOARD_DTB_MAX_SIZE);
-	if (ret < 0) {
-		ERROR("Invalid Device Tree at %p: error %d\n", dtb, ret);
-		return;
-	}
+				if (ret < 0) {
+					ERROR("Invalid Device Tree at %p: error %d\n",
+					      dtb, ret);
+				} else {
 
-	/* Reserve memory used by Trusted Firmware. */
-	if (fdt_add_reserved_memory(dtb, "tf-a", BL31_BASE, BL31_LIMIT - BL31_BASE)) {
-		WARN("Failed to add reserved memory nodes for BL31 to DT.\n");
-		return;
-	}
+					if (dt_add_psci_node(dtb)) {
+						WARN("Failed to add PSCI Device Tree node\n");
+					}
 
-	ret = fdt_pack(dtb);
-	if (ret < 0) {
-		ERROR("Failed to pack Device Tree at %p: error %d\n", dtb, ret);
-		return;
-	}
+					if (dt_add_psci_cpu_enable_methods(dtb)) {
+						WARN("Failed to add PSCI cpu enable methods in DT\n");
+					}
 
-	flush_dcache_range((uintptr_t)dtb, fdt_blob_size(dtb));
+					/* Reserve memory used by Trusted Firmware. */
+					ret = fdt_add_reserved_memory(dtb,
+								     "tf-a",
+								     BL31_BASE,
+								     BL31_LIMIT
+								     -
+								     BL31_BASE);
+					if (ret < 0) {
+						WARN("Failed to add reserved memory nodes for BL31 to DT.\n");
+					}
+
+					ret = fdt_pack(dtb);
+					if (ret < 0) {
+						WARN("Failed to pack dtb at %p: error %d\n",
+						     dtb, ret);
+					}
+					flush_dcache_range((uintptr_t)dtb,
+							   fdt_blob_size(dtb));
+
+					INFO("Changed device tree to advertise PSCI and reserved memories.\n");
+
+				}
+			}
+
+		}
+
 
 #if defined(PLAT_XLAT_TABLES_DYNAMIC)
-	ret = mmap_remove_dynamic_region((uintptr_t)dtb,
+		if (!map_ret) {
+			ret = mmap_remove_dynamic_region((uintptr_t)dtb,
 					 XILINX_OF_BOARD_DTB_MAX_SIZE);
-	if (ret != 0) {
-		WARN("Failed to remove dynamic region for dtb: error %d\n", ret);
-		return;
-	}
+			if (ret != 0) {
+				WARN("Failed to remove dynamic region for dtb:error %d\n",
+					ret);
+			}
+		}
 #endif
+	}
 
-	INFO("Changed device tree to advertise PSCI and reserved memories.\n");
+#endif
 }
diff --git a/plat/xilinx/versal/bl31_versal_setup.c b/plat/xilinx/versal/bl31_versal_setup.c
index 99797b5..566415f 100644
--- a/plat/xilinx/versal/bl31_versal_setup.c
+++ b/plat/xilinx/versal/bl31_versal_setup.c
@@ -74,12 +74,12 @@
 	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();
@@ -87,14 +87,14 @@
 
 		console_set_scope(&versal_runtime_console, (uint32_t)(CONSOLE_FLAG_BOOT |
 				  CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH));
-	} else if (VERSAL_CONSOLE_IS(dcc)) {
+	} 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/bl31_versal_net_setup.c b/plat/xilinx/versal_net/bl31_versal_net_setup.c
index 91f9a46..a70095d 100644
--- a/plat/xilinx/versal_net/bl31_versal_net_setup.c
+++ b/plat/xilinx/versal_net/bl31_versal_net_setup.c
@@ -101,12 +101,12 @@
 		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_BAUDRATE,
 				    &versal_net_runtime_console);
 		if (rc == 0) {
 			panic();
@@ -114,7 +114,7 @@
 
 		console_set_scope(&versal_net_runtime_console, CONSOLE_FLAG_BOOT |
 				CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
-	} else if (VERSAL_NET_CONSOLE_IS(dcc)) {
+	} 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 53eb2cd..a53cad9 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,17 +135,15 @@
 #define VERSAL_NET_UART0_BASE		U(0xF1920000)
 #define VERSAL_NET_UART1_BASE		U(0xF1930000)
 
-#define VERSAL_NET_UART_BAUDRATE	115200
+#define UART_BAUDRATE	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 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/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 f408992..32bb982 100644
--- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
+++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
@@ -21,6 +21,7 @@
 #include <plat/common/platform.h>
 
 #include <custom_svc.h>
+#include <plat_fdt.h>
 #include <plat_private.h>
 #include <plat_startup.h>
 #include <zynqmp_def.h>
@@ -73,24 +74,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 |
 				  CONSOLE_FLAG_CRASH);
-	} else if (ZYNQMP_CONSOLE_IS(dcc)) {
+	} 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();
@@ -183,55 +184,9 @@
 }
 #endif
 
-#if (defined(XILINX_OF_BOARD_DTB_ADDR) && !IS_TFA_IN_OCM(BL31_BASE))
-static void prepare_dtb(void)
-{
-	void *dtb = (void *)XILINX_OF_BOARD_DTB_ADDR;
-	int ret;
-
-	/* Return if no device tree is detected */
-	if (fdt_check_header(dtb) != 0) {
-		NOTICE("Can't read DT at %p\n", dtb);
-		return;
-	}
-
-	ret = fdt_open_into(dtb, dtb, XILINX_OF_BOARD_DTB_MAX_SIZE);
-	if (ret < 0) {
-		ERROR("Invalid Device Tree at %p: error %d\n", dtb, ret);
-		return;
-	}
-
-	if (dt_add_psci_node(dtb)) {
-		ERROR("Failed to add PSCI Device Tree node\n");
-		return;
-	}
-
-	if (dt_add_psci_cpu_enable_methods(dtb)) {
-		ERROR("Failed to add PSCI cpu enable methods in Device Tree\n");
-		return;
-	}
-
-	/* Reserve memory used by Trusted Firmware. */
-	if (fdt_add_reserved_memory(dtb, "tf-a", BL31_BASE,
-				   (size_t) (BL31_LIMIT - BL31_BASE))) {
-		WARN("Failed to add reserved memory nodes for BL31 to DT.\n");
-	}
-
-	ret = fdt_pack(dtb);
-	if (ret < 0) {
-		ERROR("Failed to pack Device Tree at %p: error %d\n", dtb, ret);
-	}
-
-	clean_dcache_range((uintptr_t)dtb, fdt_blob_size(dtb));
-	INFO("Changed device tree to advertise PSCI and reserved memories.\n");
-}
-#endif
-
 void bl31_platform_setup(void)
 {
-#if (defined(XILINX_OF_BOARD_DTB_ADDR) && !IS_TFA_IN_OCM(BL31_BASE))
 	prepare_dtb();
-#endif
 
 	/* Initialize the gic cpu and distributor interfaces */
 	plat_arm_gic_driver_init();
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/platform.mk b/plat/xilinx/zynqmp/platform.mk
index 9c79855..e20cb22 100644
--- a/plat/xilinx/zynqmp/platform.mk
+++ b/plat/xilinx/zynqmp/platform.mk
@@ -127,6 +127,7 @@
 				${LIBFDT_SRCS}					\
 				plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c \
 				plat/xilinx/common/plat_startup.c		\
+				plat/xilinx/common/plat_fdt.c			\
 				plat/xilinx/zynqmp/bl31_zynqmp_setup.c		\
 				plat/xilinx/zynqmp/plat_psci.c			\
 				plat/xilinx/zynqmp/plat_zynqmp.c		\
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 ca66396..c0a089b 100644
--- a/services/std_svc/errata_abi/errata_abi_main.c
+++ b/services/std_svc/errata_abi/errata_abi_main.c
@@ -428,10 +428,11 @@
 {
 	.cpu_partnumber = CORTEX_X3_MIDR,
 	.cpu_errata_list = {
-		[0] = {2313909, 0x00, 0x10, ERRATA_X3_2313909},
-		[1] = {2615812, 0x00, 0x11, ERRATA_X3_2615812},
-		[2] = {2742421, 0x00, 0x11, ERRATA_X3_2742421},
-		[3 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+		[0] = {2070301, 0x00, 0x12, ERRATA_X3_2070301},
+		[1] = {2313909, 0x00, 0x10, ERRATA_X3_2313909},
+		[2] = {2615812, 0x00, 0x11, ERRATA_X3_2615812},
+		[3] = {2742421, 0x00, 0x11, ERRATA_X3_2742421},
+		[4 ... ERRATA_LIST_END] = UNDEF_ERRATA,
 	}
 },
 #endif /* CORTEX_X3_H_INC */
diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c
index a929ea2..fa24a91 100644
--- a/services/std_svc/rmmd/rmmd_main.c
+++ b/services/std_svc/rmmd/rmmd_main.c
@@ -30,6 +30,7 @@
 #include <platform_def.h>
 #include <services/rmmd_svc.h>
 #include <smccc_helpers.h>
+#include <lib/extensions/sme.h>
 #include <lib/extensions/sve.h>
 #include "rmmd_initial_context.h"
 #include "rmmd_private.h"
@@ -134,6 +135,16 @@
 	}
 
 	pmuv3_enable(ctx);
+
+	/*
+	 * If SME/SME2 is supported and enabled for NS world, then enables SME
+	 * for Realm world. RMM will save/restore required registers that are
+	 * shared with SVE/FPU so that Realm can use FPU or SVE.
+	 */
+	if (is_feat_sme_supported()) {
+		/* sme_enable() also enables SME2 if supported by hardware */
+		sme_enable(ctx);
+	}
 }
 
 /*******************************************************************************
@@ -309,6 +320,14 @@
 	 * is.
 	 */
 	if (src_sec_state == SMC_FROM_NON_SECURE) {
+		/*
+		 * If SVE hint bit is set in the flags then update the SMC
+		 * function id and pass it on to the lower EL.
+		 */
+		if (is_sve_hint_set(flags)) {
+			smc_fid |= (FUNCID_SVE_HINT_MASK <<
+				    FUNCID_SVE_HINT_SHIFT);
+		}
 		VERBOSE("RMMD: RMI call from non-secure world.\n");
 		return rmmd_smc_forward(NON_SECURE, REALM, smc_fid,
 					x1, x2, x3, x4, handle);
diff --git a/services/std_svc/spm/spm_mm/aarch64/spm_mm_shim_exceptions.S b/services/std_svc/spm/common/aarch64/spm_shim_exceptions.S
similarity index 100%
rename from services/std_svc/spm/spm_mm/aarch64/spm_mm_shim_exceptions.S
rename to services/std_svc/spm/common/aarch64/spm_shim_exceptions.S
diff --git a/services/std_svc/spm/common/include/spm_common.h b/services/std_svc/spm/common/include/spm_common.h
index 68805fc..c736919 100644
--- a/services/std_svc/spm/common/include/spm_common.h
+++ b/services/std_svc/spm/common/include/spm_common.h
@@ -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
  */
@@ -32,11 +32,15 @@
 #ifndef __ASSEMBLER__
 
 #include <stdint.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
 
 /* Assembly helpers */
 uint64_t spm_secure_partition_enter(uint64_t *c_rt_ctx);
 void __dead2 spm_secure_partition_exit(uint64_t c_rt_ctx, uint64_t ret);
 
+/* Helper to obtain a reference to the SP's translation table context */
+xlat_ctx_t *spm_get_sp_xlat_context(void);
+
 #endif /* __ASSEMBLER__ */
 
 #endif /* SPM_COMMON_H */
diff --git a/services/std_svc/spm/spm_mm/spm_mm_shim_private.h b/services/std_svc/spm/common/include/spm_shim_private.h
similarity index 75%
rename from services/std_svc/spm/spm_mm/spm_mm_shim_private.h
rename to services/std_svc/spm/common/include/spm_shim_private.h
index f69c748..bcb1147 100644
--- a/services/std_svc/spm/spm_mm/spm_mm_shim_private.h
+++ b/services/std_svc/spm/common/include/spm_shim_private.h
@@ -1,11 +1,11 @@
 /*
- * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef SPM_MM_SHIM_PRIVATE_H
-#define SPM_MM_SHIM_PRIVATE_H
+#ifndef SPM_SHIM_PRIVATE_H
+#define SPM_SHIM_PRIVATE_H
 
 #include <stdint.h>
 
@@ -23,4 +23,4 @@
 #define SPM_SHIM_EXCEPTIONS_SIZE	\
 	(SPM_SHIM_EXCEPTIONS_END - SPM_SHIM_EXCEPTIONS_START)
 
-#endif /* SPM_MM_SHIM_PRIVATE_H */
+#endif /* SPM_SHIM_PRIVATE_H */
diff --git a/services/std_svc/spm/common/spm.mk b/services/std_svc/spm/common/spm.mk
index 9aa96be..65fd72a 100644
--- a/services/std_svc/spm/common/spm.mk
+++ b/services/std_svc/spm/common/spm.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2022-2023, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -10,8 +10,14 @@
 
 INCLUDES	+=	-Iservices/std_svc/spm/common/include
 
-SPM_SOURCES	:=	$(addprefix services/std_svc/spm/common/,\
-			${ARCH}/spm_helpers.S)
+SPM_SOURCES	:=	$(addprefix services/std_svc/spm/common/,	\
+			${ARCH}/spm_helpers.S				\
+			${ARCH}/spm_shim_exceptions.S)
+
+ifeq (1, $(filter 1, ${SPM_MM} ${SPMC_AT_EL3_SEL0_SP}))
+SPM_SOURCES	+=	$(addprefix services/std_svc/spm/common/,       \
+			spm_xlat_common.c)
+endif
 
 # Let the top-level Makefile know that we intend to include a BL32 image
 NEED_BL32		:=	yes
diff --git a/services/std_svc/spm/common/spm_xlat_common.c b/services/std_svc/spm/common/spm_xlat_common.c
new file mode 100644
index 0000000..a463c8b
--- /dev/null
+++ b/services/std_svc/spm/common/spm_xlat_common.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <platform_def.h>
+
+/* Place translation tables by default along with the ones used by BL31. */
+#ifndef PLAT_SP_IMAGE_XLAT_SECTION_NAME
+#define PLAT_SP_IMAGE_XLAT_SECTION_NAME	".xlat_table"
+#endif
+#ifndef PLAT_SP_IMAGE_BASE_XLAT_SECTION_NAME
+#define PLAT_SP_IMAGE_BASE_XLAT_SECTION_NAME	".bss"
+#endif
+
+/* Allocate and initialise the translation context for the secure partitions. */
+REGISTER_XLAT_CONTEXT2(sp,
+		       PLAT_SP_IMAGE_MMAP_REGIONS,
+		       PLAT_SP_IMAGE_MAX_XLAT_TABLES,
+		       PLAT_VIRT_ADDR_SPACE_SIZE, PLAT_PHY_ADDR_SPACE_SIZE,
+		       EL1_EL0_REGIME, PLAT_SP_IMAGE_XLAT_SECTION_NAME,
+		       PLAT_SP_IMAGE_BASE_XLAT_SECTION_NAME);
+
+/* Get handle of Secure Partition translation context */
+xlat_ctx_t *spm_get_sp_xlat_context(void)
+{
+	return &sp_xlat_ctx;
+};
diff --git a/services/std_svc/spm/spm_mm/spm_mm.mk b/services/std_svc/spm/spm_mm/spm_mm.mk
index 513e8ef..cbc7940 100644
--- a/services/std_svc/spm/spm_mm/spm_mm.mk
+++ b/services/std_svc/spm/spm_mm/spm_mm.mk
@@ -21,7 +21,6 @@
 endif
 
 SPM_MM_SOURCES	:=	$(addprefix services/std_svc/spm/spm_mm/,	\
-			${ARCH}/spm_mm_shim_exceptions.S		\
 			spm_mm_main.c					\
 			spm_mm_setup.c					\
 			spm_mm_xlat.c)
diff --git a/services/std_svc/spm/spm_mm/spm_mm_private.h b/services/std_svc/spm/spm_mm/spm_mm_private.h
index 0eff1c0..3a52a3e 100644
--- a/services/std_svc/spm/spm_mm/spm_mm_private.h
+++ b/services/std_svc/spm/spm_mm/spm_mm_private.h
@@ -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
  */
@@ -55,8 +55,6 @@
 
 void spm_sp_setup(sp_context_t *sp_ctx);
 
-xlat_ctx_t *spm_get_sp_xlat_context(void);
-
 int32_t spm_memory_attributes_get_smc_handler(sp_context_t *sp_ctx,
 					      uintptr_t base_va);
 int spm_memory_attributes_set_smc_handler(sp_context_t *sp_ctx,
diff --git a/services/std_svc/spm/spm_mm/spm_mm_setup.c b/services/std_svc/spm/spm_mm/spm_mm_setup.c
index 04dc212..4e65c9c 100644
--- a/services/std_svc/spm/spm_mm/spm_mm_setup.c
+++ b/services/std_svc/spm/spm_mm/spm_mm_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -21,7 +21,7 @@
 
 #include "spm_common.h"
 #include "spm_mm_private.h"
-#include "spm_mm_shim_private.h"
+#include "spm_shim_private.h"
 
 /* Setup context of the Secure Partition */
 void spm_sp_setup(sp_context_t *sp_ctx)
diff --git a/services/std_svc/spm/spm_mm/spm_mm_xlat.c b/services/std_svc/spm/spm_mm/spm_mm_xlat.c
index b1ca55a..01d95c7 100644
--- a/services/std_svc/spm/spm_mm/spm_mm_xlat.c
+++ b/services/std_svc/spm/spm_mm/spm_mm_xlat.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,33 +15,11 @@
 #include <services/spm_mm_svc.h>
 
 #include "spm_mm_private.h"
-#include "spm_mm_shim_private.h"
-
-/* Place translation tables by default along with the ones used by BL31. */
-#ifndef PLAT_SP_IMAGE_XLAT_SECTION_NAME
-#define PLAT_SP_IMAGE_XLAT_SECTION_NAME	".xlat_table"
-#endif
-#ifndef PLAT_SP_IMAGE_BASE_XLAT_SECTION_NAME
-#define PLAT_SP_IMAGE_BASE_XLAT_SECTION_NAME	".bss"
-#endif
-
-/* Allocate and initialise the translation context for the secure partitions. */
-REGISTER_XLAT_CONTEXT2(sp,
-		       PLAT_SP_IMAGE_MMAP_REGIONS,
-		       PLAT_SP_IMAGE_MAX_XLAT_TABLES,
-		       PLAT_VIRT_ADDR_SPACE_SIZE, PLAT_PHY_ADDR_SPACE_SIZE,
-		       EL1_EL0_REGIME, PLAT_SP_IMAGE_XLAT_SECTION_NAME,
-		       PLAT_SP_IMAGE_BASE_XLAT_SECTION_NAME);
+#include "spm_shim_private.h"
 
 /* Lock used for SP_MEMORY_ATTRIBUTES_GET and SP_MEMORY_ATTRIBUTES_SET */
 static spinlock_t mem_attr_smc_lock;
 
-/* Get handle of Secure Partition translation context */
-xlat_ctx_t *spm_get_sp_xlat_context(void)
-{
-	return &sp_xlat_ctx;
-};
-
 /*
  * Attributes are encoded using a different format in the SMC interface than in
  * the Trusted Firmware, where the mmap_attr_t enum type is used. This function
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/include/key.h b/tools/cert_create/include/key.h
index 312575b..56f1c21 100644
--- a/tools/cert_create/include/key.h
+++ b/tools/cert_create/include/key.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
  */
@@ -44,7 +44,7 @@
 static const unsigned int KEY_SIZES[KEY_ALG_MAX_NUM][KEY_SIZE_MAX_NUM] = {
 	{ 2048, 1024, 3072, 4096 },	/* KEY_ALG_RSA */
 #ifndef OPENSSL_NO_EC
-	{},				/* KEY_ALG_ECDSA_NIST */
+	{ 256, 384 },			/* KEY_ALG_ECDSA_NIST */
 	{},				/* KEY_ALG_ECDSA_BRAINPOOL_R */
 	{}				/* KEY_ALG_ECDSA_BRAINPOOL_T */
 #endif /* OPENSSL_NO_EC */
diff --git a/tools/cert_create/src/key.c b/tools/cert_create/src/key.c
index 32229d1..14c8e18 100644
--- a/tools/cert_create/src/key.c
+++ b/tools/cert_create/src/key.c
@@ -1,9 +1,10 @@
 /*
- * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <assert.h>
 #include <getopt.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -112,7 +113,12 @@
 
 static int key_create_ecdsa_nist(key_t *key, int key_bits)
 {
-	return key_create_ecdsa(key, key_bits, "prime256v1");
+	if (key_bits == 384) {
+		return key_create_ecdsa(key, key_bits, "secp384r1");
+	} else {
+		assert(key_bits == 256);
+		return key_create_ecdsa(key, key_bits, "prime256v1");
+	}
 }
 
 static int key_create_ecdsa_brainpool_r(key_t *key, int key_bits)
@@ -154,7 +160,12 @@
 
 static int key_create_ecdsa_nist(key_t *key, int key_bits)
 {
-	return key_create_ecdsa(key, key_bits, NID_X9_62_prime256v1);
+	if (key_bits == 384) {
+		return key_create_ecdsa(key, key_bits, NID_secp384r1);
+	} else {
+		assert(key_bits == 256);
+		return key_create_ecdsa(key, key_bits, NID_X9_62_prime256v1);
+	}
 }
 
 static int key_create_ecdsa_brainpool_r(key_t *key, int key_bits)