Merge "fix(qemu-sbsa): enable FGT" into integration
diff --git a/Makefile b/Makefile
index 5306ddf..2870a46 100644
--- a/Makefile
+++ b/Makefile
@@ -414,6 +414,10 @@
 WARNINGS	+=		-Wunused-but-set-variable -Wmaybe-uninitialized	\
 				-Wpacked-bitfield-compat -Wshift-overflow=2 \
 				-Wlogical-op
+
+# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105523
+TF_CFLAGS		+= 	$(call cc_option, --param=min-pagesize=0)
+
 else
 # using clang
 WARNINGS	+=		-Wshift-overflow -Wshift-sign-overflow \
@@ -861,8 +865,12 @@
     $(info FEATURE_DETECTION is an experimental feature)
 endif
 
-ifneq ($(ENABLE_SME_FOR_NS), 0)
-    $(info ENABLE_SME_FOR_NS is an experimental feature)
+ifneq ($(ENABLE_SME2_FOR_NS), 0)
+    ifeq (${ENABLE_SME_FOR_NS}, 0)
+        $(warning "ENABLE_SME2_FOR_NS requires ENABLE_SME_FOR_NS also to be set")
+        $(warning "Forced ENABLE_SME_FOR_NS=1")
+        override ENABLE_SME_FOR_NS	:= 1
+    endif
 endif
 
 ifeq (${ARM_XLAT_TABLES_LIB_V1}, 1)
@@ -884,6 +892,7 @@
     ifneq (${ENABLE_SME_FOR_NS},0)
         $(error "ENABLE_SME_FOR_NS cannot be used with ARCH=aarch32")
     endif
+
     ifeq (${ENABLE_SVE_FOR_NS},1)
         # Warning instead of error due to CI dependency on this
         $(error "ENABLE_SVE_FOR_NS cannot be used with ARCH=aarch32")
@@ -907,11 +916,20 @@
     endif
 endif
 
+ifneq (${ENABLE_SME_FOR_NS},0)
+    ifeq (${ENABLE_SVE_FOR_NS},0)
+        $(error "ENABLE_SME_FOR_NS requires ENABLE_SVE_FOR_NS")
+    endif
+endif
+
 # Secure SME/SVE requires the non-secure component as well
 ifeq (${ENABLE_SME_FOR_SWD},1)
     ifeq (${ENABLE_SME_FOR_NS},0)
         $(error "ENABLE_SME_FOR_SWD requires ENABLE_SME_FOR_NS")
     endif
+    ifeq (${ENABLE_SVE_FOR_SWD},0)
+        $(error "ENABLE_SME_FOR_SWD requires ENABLE_SVE_FOR_SWD")
+    endif
 endif
 ifeq (${ENABLE_SVE_FOR_SWD},1)
     ifeq (${ENABLE_SVE_FOR_NS},0)
@@ -925,6 +943,7 @@
     ifneq (${ENABLE_SME_FOR_NS},0)
         $(error "ENABLE_SME_FOR_NS cannot be used with CTX_INCLUDE_FPREGS")
     endif
+
     ifeq (${ENABLE_SVE_FOR_NS},1)
         # Warning instead of error due to CI dependency on this
         $(warning "ENABLE_SVE_FOR_NS cannot be used with CTX_INCLUDE_FPREGS")
@@ -1052,6 +1071,7 @@
 # Variables for use with PRINT_MEMORY_MAP
 PRINT_MEMORY_MAP_PATH		?=	tools/memory
 PRINT_MEMORY_MAP		?=	${PRINT_MEMORY_MAP_PATH}/print_memory_map.py
+INVERTED_MEMMAP			?=	0
 
 # Variables for use with documentation build using Sphinx tool
 DOCS_PATH		?=	docs
@@ -1196,6 +1216,7 @@
         ENABLE_SPE_FOR_NS \
         ENABLE_SYS_REG_TRACE_FOR_NS \
         ENABLE_SME_FOR_NS \
+        ENABLE_SME2_FOR_NS \
         ENABLE_SVE_FOR_NS \
         ENABLE_TRF_FOR_NS \
         FW_ENC_STATUS \
@@ -1205,6 +1226,7 @@
         TWED_DELAY \
         ENABLE_FEAT_TWED \
         SVE_VECTOR_LEN \
+	IMPDEF_SYSREG_TRAP \
 )))
 
 ifdef KEY_SIZE
@@ -1251,6 +1273,7 @@
         ENABLE_RME \
         ENABLE_RUNTIME_INSTRUMENTATION \
         ENABLE_SME_FOR_NS \
+        ENABLE_SME2_FOR_NS \
         ENABLE_SME_FOR_SWD \
         ENABLE_SPE_FOR_NS \
         ENABLE_SVE_FOR_NS \
@@ -1335,6 +1358,7 @@
         TWED_DELAY \
         ENABLE_FEAT_TWED \
 	CONDITIONAL_CMO \
+	IMPDEF_SYSREG_TRAP \
 )))
 
 ifeq (${SANITIZE_UB},trap)
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index 9b5cf55..b16b4e7 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -101,12 +101,10 @@
 
 ifneq (${ENABLE_SME_FOR_NS},0)
 BL31_SOURCES		+=	lib/extensions/sme/sme.c
-BL31_SOURCES		+=	lib/extensions/sve/sve.c
-else
+endif
 ifneq (${ENABLE_SVE_FOR_NS},0)
 BL31_SOURCES		+=	lib/extensions/sve/sve.c
 endif
-endif
 
 ifneq (${ENABLE_MPAM_FOR_LOWER_ELS},0)
 BL31_SOURCES		+=	lib/extensions/mpam/mpam.c
diff --git a/bl31/bl31_traps.c b/bl31/bl31_traps.c
index b12185d..2cfe14a 100644
--- a/bl31/bl31_traps.c
+++ b/bl31/bl31_traps.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2022, ARM Limited. All rights reserved.
+ * Copyright (c) 2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -11,13 +12,19 @@
 
 int handle_sysreg_trap(uint64_t esr_el3, cpu_context_t *ctx)
 {
-	switch (esr_el3 & ISS_SYSREG_OPCODE_MASK) {
+	uint64_t __unused opcode = esr_el3 & ISS_SYSREG_OPCODE_MASK;
+
 #if ENABLE_FEAT_RNG_TRAP
-	case ISS_SYSREG_OPCODE_RNDR:
-	case ISS_SYSREG_OPCODE_RNDRRS:
+	if ((opcode == ISS_SYSREG_OPCODE_RNDR) || (opcode == ISS_SYSREG_OPCODE_RNDRRS)) {
 		return plat_handle_rng_trap(esr_el3, ctx);
+	}
 #endif
-	default:
-		return TRAP_RET_UNHANDLED;
+
+#if IMPDEF_SYSREG_TRAP
+	if ((opcode & ISS_SYSREG_OPCODE_IMPDEF) == ISS_SYSREG_OPCODE_IMPDEF) {
+		return plat_handle_impdef_trap(esr_el3, ctx);
 	}
+#endif
+
+	return TRAP_RET_UNHANDLED;
 }
diff --git a/changelog.yaml b/changelog.yaml
index d54c62b..c969b2c 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -128,7 +128,7 @@
       - title: Trapping support for RNDR/RNDRRS (FEAT_RNG_TRAP)
         scope: rng-trap
 
-      - title: Scalable Matrix Extension (FEAT_SME)
+      - title: Scalable Matrix Extension (FEAT_SME, FEAT_SME2)
         scope: sme
 
       - title: Statistical profiling Extension (FEAT_SPE)
@@ -877,6 +877,9 @@
                 deprecated:
                   - drivers/tzc380
 
+          - title: SBSA
+            scope: sbsa
+
       - title: Marvell
         scope: marvell-drivers
 
diff --git a/common/feat_detect.c b/common/feat_detect.c
index c8a0703..eb4db95 100644
--- a/common/feat_detect.c
+++ b/common/feat_detect.c
@@ -218,6 +218,8 @@
 	/* v9.2 features */
 	check_feature(ENABLE_SME_FOR_NS, read_feat_sme_id_field(),
 		      "SME", 1, 2);
+	check_feature(ENABLE_SME2_FOR_NS, read_feat_sme_id_field(),
+		      "SME2", 2, 2);
 
 	/* v9.4 features */
 	check_feature(ENABLE_FEAT_GCS, read_feat_gcs_id_field(), "GCS", 1, 1);
diff --git a/docs/about/release-information.rst b/docs/about/release-information.rst
index cd52460..0ba0a7a 100644
--- a/docs/about/release-information.rst
+++ b/docs/about/release-information.rst
@@ -67,7 +67,7 @@
 |                                | Date        | after   |                                                         |
 |                                |             | Release |                                                         |
 +================================+=============+=========+=========================================================+
-| plat_convert_pk() function     |   Nov'22    |   2.9   | Platform conversion to manage specific PK hash          |
+| None at this time              |             |         |                                                         |
 +--------------------------------+-------------+---------+---------------------------------------------------------+
 
 Removal of Deprecated Drivers
@@ -82,8 +82,6 @@
 |                                | Date        | after   |                                                         |
 |                                |             | Release |                                                         |
 +================================+=============+=========+=========================================================+
-| io_dummy driver                |   Nov'22    |   2.9   | No more used by any upstream platform                   |
-+--------------------------------+-------------+---------+---------------------------------------------------------+
 | CryptoCell-712                 |     2.9     |   3.0   | No longer maintained.                                   |
 +--------------------------------+-------------+---------+---------------------------------------------------------+
 | CryptoCell-713                 |     2.9     |   3.0   | No longer maintained.                                   |
diff --git a/docs/components/secure-partition-manager.rst b/docs/components/secure-partition-manager.rst
index f0caf89..8dc1c61 100644
--- a/docs/components/secure-partition-manager.rst
+++ b/docs/components/secure-partition-manager.rst
@@ -1318,6 +1318,25 @@
        direct request to SP2 by invoking FFA_RUN.
   - 9) SPMC resumes the pre-empted vCPU of SP2.
 
+EL3 interrupt handling
+~~~~~~~~~~~~~~~~~~~~~~
+
+In GICv3 based systems, EL3 interrupts are configured as Group0 secure
+interrupts. Execution traps to SPMC when a Group0 interrupt triggers while an
+SP is running. Further, SPMC running at S-EL2 uses FFA_EL3_INTR_HANDLE ABI to
+request EL3 platform firmware to handle a pending Group0 interrupt.
+Similarly, SPMD registers a handler with interrupt management framework to
+delegate handling of Group0 interrupt to the platform if the interrupt triggers
+in normal world.
+
+ - Platform hook
+
+   - plat_spmd_handle_group0_interrupt
+
+     SPMD provides platform hook to handle Group0 secure interrupts. In the
+     current design, SPMD expects the platform not to delegate handling to the
+     NWd (such as through SDEI) while processing Group0 interrupts.
+
 Power management
 ----------------
 
@@ -1557,4 +1576,4 @@
 
 --------------
 
-*Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst
index 97f3550..2c9b76a 100644
--- a/docs/design/firmware-design.rst
+++ b/docs/design/firmware-design.rst
@@ -1759,6 +1759,10 @@
 
                    DRAM
     0xffffffff +----------+
+               | EL3 TZC  |
+    0xffe00000 |----------| (secure)
+               | AP TZC   |
+    0xff000000 +----------+
                :          :
     0x82100000 |----------|
                |HW_CONFIG |
@@ -1800,6 +1804,10 @@
 
                      DRAM
     0xffffffff +--------------+
+               |   EL3 TZC    |
+    0xffe00000 |--------------|  (secure)
+               |   AP TZC     |
+    0xff000000 +--------------+
                :              :
     0x82100000 |--------------|
                |  HW_CONFIG   |
@@ -1840,7 +1848,10 @@
 
                    DRAM
     0xffffffff +----------+
-               |  BL32    |  (secure)
+               |  EL3 TZC |
+    0xffe00000 |----------|  (secure)
+               |  AP TZC  |
+               |  (BL32)  |
     0xff000000 +----------+
                |          |
     0x82100000 |----------|
@@ -1880,6 +1891,20 @@
 
 ::
 
+                  DRAM
+    0xFFFFFFFF +----------+
+               |  SCP TZC |
+    0xFFE00000 |----------|
+               |  EL3 TZC |
+    0xFFC00000 |----------|  (secure)
+               |  AP TZC  |
+    0xFF000000 +----------+
+               |          |
+               :          :  (non-secure)
+               |          |
+    0x80000000 +----------+
+
+
                   Flash0
     0x0C000000 +----------+
                :          :
@@ -1909,9 +1934,14 @@
 ::
 
                    DRAM
-    0xFFE00000 +----------+
-               |  BL32    |  (secure)
-    0xFF000000 |----------|
+    0xFFFFFFFF +----------+
+               |  SCP TZC |
+    0xFFE00000 |----------|
+               |  EL3 TZC |
+    0xFFC00000 |----------|  (secure)
+               |  AP TZC  |
+               |  (BL32)  |
+    0xFF000000 +----------+
                |          |
                :          :  (non-secure)
                |          |
diff --git a/docs/design_documents/measured_boot_poc.rst b/docs/design_documents/measured_boot_poc.rst
index 2e25057..7f73d7e 100644
--- a/docs/design_documents/measured_boot_poc.rst
+++ b/docs/design_documents/measured_boot_poc.rst
@@ -135,11 +135,11 @@
 
 (4) Now, you should be able to continue with step 5 in "`Get and build the solution`_"
     instructions. In order to enable support for Measured Boot, you need to
-    set the ``MEASURED_BOOT`` build option:
+    set the following build options:
 
     .. code:: shell
 
-       $ MEASURED_BOOT=y make -j `nproc`
+       $ MEASURED_BOOT=y MEASURED_BOOT_FTPM=y make -j `nproc`
 
     .. note::
        The build process will likely take a long time. It is strongly recommended to
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index d2f463f..ffde0a4 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -436,17 +436,24 @@
    (SME), SVE, and FPU/SIMD for the non-secure world only. These features share
    registers so are enabled together. Using this option without
    ENABLE_SME_FOR_SWD=1 will cause SME, SVE, and FPU/SIMD instructions in secure
-   world to trap to EL3. SME is an optional architectural feature for AArch64
+   world to trap to EL3. Requires ``ENABLE_SVE_FOR_NS`` to be set as SME is a
+   superset of SVE. SME is an optional architectural feature for AArch64
    and TF-A support is experimental. At this time, this build option cannot be
    used on systems that have SPD=spmd/SPM_MM or ENABLE_RME, and attempting to
    build with these options will fail. This flag can take the values 0 to 2, to
    align with the ``FEATURE_DETECTION`` mechanism. Default is 0.
 
+-  ``ENABLE_SME2_FOR_NS``: Numeric value to enable Scalable Matrix Extension
+   version 2 (SME2) for the non-secure world only. SME2 is an optional
+   architectural feature for AArch64 and TF-A support is experimental.
+   This should be set along with ENABLE_SME_FOR_NS=1, if not, the default SME
+   accesses will still be trapped. This flag can take the values 0 to 2, to
+   align with the ``FEATURE_DETECTION`` mechanism. Default is 0.
+
 -  ``ENABLE_SME_FOR_SWD``: Boolean option to enable the Scalable Matrix
-   Extension for secure world use along with SVE and FPU/SIMD, ENABLE_SME_FOR_NS
-   must also be set to use this. If enabling this, the secure world MUST
-   handle context switching for SME, SVE, and FPU/SIMD registers to ensure that
-   no data is leaked to non-secure world. This is experimental. Default is 0.
+   Extension for secure world. Used along with SVE and FPU/SIMD.
+   ENABLE_SME_FOR_NS and ENABLE_SVE_FOR_SWD must also be set to use this.
+   This is experimental. Default is 0.
 
 -  ``ENABLE_SPE_FOR_NS`` : Numeric value to enable Statistical Profiling
    extensions. This is an optional architectural feature for AArch64.
@@ -462,17 +469,15 @@
    This is to avoid corruption of the Non-secure world data in the Z-registers
    which are aliased by the SIMD and FP registers. The build option is not
    compatible with the ``CTX_INCLUDE_FPREGS`` build option, and will raise an
-   assert on platforms where SVE is implemented and ``ENABLE_SVE_FOR_NS`` enabled.
-   This flag can take the values 0 to 2, to align with the ``FEATURE_DETECTION``
-   mechanism. The default is 2 but is automatically disabled when
-   ENABLE_SME_FOR_NS is enabled ( set to 1 or 2) since SME encompasses SVE.
-   At this time, this build option cannot be used on systems that have SPM_MM
-   enabled.
+   assert on platforms where SVE is implemented and ``ENABLE_SVE_FOR_NS``
+   enabled.  This flag can take the values 0 to 2, to align with the
+   ``FEATURE_DETECTION`` mechanism. At this time, this build option cannot be
+   used on systems that have SPM_MM enabled. The default is 1.
 
 -  ``ENABLE_SVE_FOR_SWD``: Boolean option to enable SVE for the Secure world.
    SVE is an optional architectural feature for AArch64. Note that this option
-   requires ENABLE_SVE_FOR_NS to be enabled. The default is 0 and it
-   is automatically disabled when the target architecture is AArch32.
+   requires ENABLE_SVE_FOR_NS to be enabled. The default is 0 and it is
+   automatically disabled when the target architecture is AArch32.
 
 -  ``ENABLE_STACK_PROTECTOR``: String option to enable the stack protection
    checks in GCC. Allowed values are "all", "strong", "default" and "none". The
@@ -633,6 +638,10 @@
    translation library (xlat tables v2) must be used; version 1 of translation
    library is not supported.
 
+-  ``IMPDEF_SYSREG_TRAP``: Numeric value to enable the handling traps for
+   implementation defined system register accesses from lower ELs. Default
+   value is ``0``.
+
 -  ``INVERTED_MEMMAP``: memmap tool print by default lower addresses at the
    bottom, higher addresses at the top. This build flag can be set to '1' to
    invert this behavior. Lower addresses will be printed at the top and higher
diff --git a/docs/getting_started/prerequisites.rst b/docs/getting_started/prerequisites.rst
index bf10ecf..a3f8cc8 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 >= 11.3.Rel1 (from the `Arm Developer website`_)
+- GCC >= 12.2.Rel1 (from the `Arm Developer website`_)
 
    You will need the targets ``arm-none-eabi`` and ``aarch64-none-elf`` for
    AArch32 and AArch64 builds respectively.
diff --git a/docs/glossary.rst b/docs/glossary.rst
index 57fde2d..12c6ab7 100644
--- a/docs/glossary.rst
+++ b/docs/glossary.rst
@@ -229,7 +229,7 @@
       Trusted Platform Module
 
    TRNG
-      True Randon Number Generator (hardware based)
+      True Random Number Generator (hardware based)
 
    TSP
       Test Secure Payload
diff --git a/docs/plat/allwinner.rst b/docs/plat/allwinner.rst
index 3e9ce51..8e967dc 100644
--- a/docs/plat/allwinner.rst
+++ b/docs/plat/allwinner.rst
@@ -23,6 +23,8 @@
 +------+-------------------+
 | H313 | sun50i_h616       |
 +------+-------------------+
+| T507 | sun50i_h616       |
++------+-------------------+
 | R329 | sun50i_r329       |
 +------+-------------------+
 
diff --git a/docs/plat/arm/juno/index.rst b/docs/plat/arm/juno/index.rst
index 1f15a73..ea7d11c 100644
--- a/docs/plat/arm/juno/index.rst
+++ b/docs/plat/arm/juno/index.rst
@@ -56,7 +56,7 @@
 
 #. Obtain SCP binaries (Juno)
 
-   This version of TF-A is tested with SCP version 2.8.0 on Juno. You can
+   This version of TF-A is tested with SCP version 2.12.0 on Juno. You can
    download pre-built SCP binaries (``scp_bl1.bin`` and ``scp_bl2.bin``)
    from `TF-A downloads page`_. Alternatively, you can `build
    the binaries from source`_.
diff --git a/docs/plat/index.rst b/docs/plat/index.rst
index a4e2067..57c7303 100644
--- a/docs/plat/index.rst
+++ b/docs/plat/index.rst
@@ -76,7 +76,9 @@
 +----------------+----------------+--------------------+--------------------+
 |    tc0         |      Arm       |        2.8         |       3.0          |
 +----------------+----------------+--------------------+--------------------+
+|    rde1edge    |      Arm       |        2.9         |       3.1          |
++----------------+----------------+--------------------+--------------------+
 
 --------------
 
-*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2023, Arm Limited. All rights reserved.*
diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst
index 25b55e8..1225a9f 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -2785,6 +2785,22 @@
 by the ``MPIDR`` (first argument). The generic code expects the platform to
 return PSCI_E_SUCCESS on success or PSCI_E_INTERN_FAIL for any failure.
 
+plat_psci_ops.pwr_domain_off_early() [optional]
+...............................................
+
+This optional function performs the platform specific actions to check if
+powering off the calling CPU and its higher parent power domain levels as
+indicated by the ``target_state`` (first argument) is possible or allowed.
+
+The ``target_state`` encodes the platform coordinated target local power states
+for the CPU power domain and its parent power domain levels.
+
+For this handler, the local power state for the CPU power domain will be a
+power down state where as it could be either power down, retention or run state
+for the higher power domain levels depending on the result of state
+coordination. The generic code expects PSCI_E_DENIED return code if the
+platform thinks that CPU_OFF should not proceed on the calling CPU.
+
 plat_psci_ops.pwr_domain_off()
 ..............................
 
@@ -3502,6 +3518,38 @@
 
 This function needs to be implemented by a platform if it enables FEAT_RNG_TRAP.
 
+Function : plat_handle_impdef_trap
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : uint64_t
+    Argument : cpu_context_t *
+    Return   : int
+
+This function is invoked by BL31's exception handler when there is a synchronous
+system register trap caused by access to the implementation defined registers.
+It allows platforms enabling ``IMPDEF_SYSREG_TRAP`` to emulate those system
+registers choosing to program bits of their choice.
+
+The first parameter (``uint64_t esr_el3``) contains the content of the ESR_EL3
+syndrome register, which encodes the instruction that was trapped.
+
+The second parameter (``cpu_context_t *ctx``) represents the CPU state in the
+lower exception level, at the time when the execution of the ``mrs`` instruction
+was trapped.
+
+The return value indicates how to proceed:
+
+-  When returning ``TRAP_RET_UNHANDLED`` (-1), the machine will panic.
+-  When returning ``TRAP_RET_REPEAT`` (0), the exception handler will return
+   to the same instruction, so its execution will be repeated.
+-  When returning ``TRAP_RET_CONTINUE`` (1), the exception handler will return
+   to the next instruction.
+
+This function needs to be implemented by a platform if it enables
+IMPDEF_SYSREG_TRAP.
+
 Build flags
 -----------
 
diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c
index 168d0eb..2c74800 100644
--- a/drivers/arm/gic/v3/gicv3_main.c
+++ b/drivers/arm/gic/v3/gicv3_main.c
@@ -330,6 +330,8 @@
 	/* Enable Group1 Secure interrupts */
 	write_icc_igrpen1_el3(read_icc_igrpen1_el3() |
 				IGRPEN1_EL3_ENABLE_G1S_BIT);
+	/* and restore the original */
+	write_scr_el3(scr_el3);
 	isb();
 	/* Add DSB to ensure visibility of System register writes */
 	dsb();
diff --git a/drivers/arm/sbsa/sbsa.c b/drivers/arm/sbsa/sbsa.c
index 79c6f26..a88e20c 100644
--- a/drivers/arm/sbsa/sbsa.c
+++ b/drivers/arm/sbsa/sbsa.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -40,3 +40,9 @@
 {
 	mmio_write_32(base + SBSA_WDOG_WCS_OFFSET, (0x0));
 }
+
+/* Refresh the secure watchdog timer explicitly */
+void sbsa_wdog_refresh(uintptr_t refresh_base)
+{
+	mmio_write_32(refresh_base + SBSA_WDOG_WRR_OFFSET, SBSA_WDOG_WRR_REFRESH);
+}
diff --git a/drivers/io/io_dummy.c b/drivers/io/io_dummy.c
deleted file mode 100644
index 4f0cda6..0000000
--- a/drivers/io/io_dummy.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <string.h>
-
-#include <common/debug.h>
-#include <drivers/io/io_driver.h>
-#include <drivers/io/io_dummy.h>
-#include <drivers/io/io_storage.h>
-
-struct file_state {
-	int in_use;
-	size_t size;
-};
-
-static struct file_state current_file = {0};
-
-/* Identify the device type as dummy */
-static io_type_t device_type_dummy(void)
-{
-	return IO_TYPE_DUMMY;
-}
-
-/* Dummy device functions */
-static int dummy_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info);
-static int dummy_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
-			     io_entity_t *entity);
-static int dummy_block_len(io_entity_t *entity, size_t *length);
-static int dummy_block_read(io_entity_t *entity, uintptr_t buffer,
-			     size_t length, size_t *length_read);
-static int dummy_block_close(io_entity_t *entity);
-static int dummy_dev_close(io_dev_info_t *dev_info);
-
-
-static const io_dev_connector_t dummy_dev_connector = {
-	.dev_open = dummy_dev_open
-};
-
-
-static const io_dev_funcs_t dummy_dev_funcs = {
-	.type = device_type_dummy,
-	.open = dummy_block_open,
-	.seek = NULL,
-	.size = dummy_block_len,
-	.read = dummy_block_read,
-	.write = NULL,
-	.close = dummy_block_close,
-	.dev_init = NULL,
-	.dev_close = dummy_dev_close,
-};
-
-
-static const io_dev_info_t dummy_dev_info = {
-	.funcs = &dummy_dev_funcs,
-	.info = (uintptr_t)NULL
-};
-
-
-/* Open a connection to the dummy device */
-static int dummy_dev_open(const uintptr_t dev_spec __attribute__((unused)),
-			   io_dev_info_t **dev_info)
-{
-	assert(dev_info != NULL);
-	*dev_info = (io_dev_info_t *)&dummy_dev_info;
-
-	return 0;
-}
-
-
-/* Close a connection to the dummy device */
-static int dummy_dev_close(io_dev_info_t *dev_info)
-{
-	return 0;
-}
-
-
-/* Open a file on the dummy device */
-static int dummy_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
-			     io_entity_t *entity)
-{
-	int result;
-	const io_block_spec_t *block_spec = (io_block_spec_t *)spec;
-
-	if (current_file.in_use == 0) {
-		assert(block_spec != NULL);
-		assert(entity != NULL);
-
-		current_file.in_use = 1;
-		current_file.size = block_spec->length;
-		entity->info = (uintptr_t)&current_file;
-		result = 0;
-	} else {
-		WARN("A Dummy device is already active. Close first.\n");
-		result = -ENOMEM;
-	}
-
-	return result;
-}
-
-
-/* Return the size of a file on the dummy device */
-static int dummy_block_len(io_entity_t *entity, size_t *length)
-{
-	assert(entity != NULL);
-	assert(length != NULL);
-
-	*length =  ((struct file_state *)entity->info)->size;
-
-	return 0;
-}
-
-
-/* Read data from a file on the dummy device */
-static int dummy_block_read(io_entity_t *entity, uintptr_t buffer,
-			     size_t length, size_t *length_read)
-{
-	assert(length_read != NULL);
-
-	*length_read = length;
-
-	return 0;
-}
-
-
-/* Close a file on the dummy device */
-static int dummy_block_close(io_entity_t *entity)
-{
-	assert(entity != NULL);
-
-	entity->info = 0;
-	current_file.in_use = 0;
-
-	return 0;
-}
-
-
-/* Exported functions */
-
-/* Register the dummy driver with the IO abstraction */
-int register_io_dev_dummy(const io_dev_connector_t **dev_con)
-{
-	int result;
-
-	assert(dev_con != NULL);
-
-	result = io_register_device(&dummy_dev_info);
-	if (result == 0)
-		*dev_con = &dummy_dev_connector;
-
-	return result;
-}
diff --git a/drivers/st/crypto/stm32_pka.c b/drivers/st/crypto/stm32_pka.c
index 2bbb31d..5dfad9a 100644
--- a/drivers/st/crypto/stm32_pka.c
+++ b/drivers/st/crypto/stm32_pka.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2022-2023, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,6 +19,11 @@
 
 #include <platform_def.h>
 
+#if !PKA_USE_NIST_P256 && !PKA_USE_BRAINPOOL_P256R1 && !PKA_USE_BRAINPOOL_P256T1 && \
+	!PKA_USE_NIST_P521
+#error "At least one ECDSA curve needs to be selected"
+#endif
+
 /*
  * For our comprehension in this file
  *  _len are in BITs
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 9e061bf..ac5eae2 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -412,6 +412,7 @@
 #define ID_AA64PFR1_EL1_SME_MASK		ULL(0xf)
 #define ID_AA64PFR1_EL1_SME_NOT_SUPPORTED	ULL(0x0)
 #define ID_AA64PFR1_EL1_SME_SUPPORTED		ULL(0x1)
+#define ID_AA64PFR1_EL1_SME2_SUPPORTED		ULL(0x2)
 
 /* ID_PFR1_EL1 definitions */
 #define ID_PFR1_VIRTEXT_SHIFT	U(12)
@@ -519,6 +520,8 @@
 #define CPACR_EL1_FP_TRAP_EL0	UL(0x1)
 #define CPACR_EL1_FP_TRAP_ALL	UL(0x2)
 #define CPACR_EL1_FP_TRAP_NONE	UL(0x3)
+#define CPACR_EL1_SMEN_SHIFT	U(24)
+#define CPACR_EL1_SMEN_MASK	ULL(0x3)
 
 /* SCR definitions */
 #define SCR_RES1_BITS		((U(1) << 4) | (U(1) << 5))
@@ -1026,11 +1029,16 @@
 #define ID_AA64SMFR0_EL1_SME_FA64_SHIFT		U(63)
 #define ID_AA64SMFR0_EL1_SME_FA64_MASK		U(0x1)
 #define ID_AA64SMFR0_EL1_SME_FA64_SUPPORTED	U(0x1)
+#define ID_AA64SMFR0_EL1_SME_VER_SHIFT		U(55)
+#define ID_AA64SMFR0_EL1_SME_VER_MASK		ULL(0xf)
+#define ID_AA64SMFR0_EL1_SME_INST_SUPPORTED	ULL(0x0)
+#define ID_AA64SMFR0_EL1_SME2_INST_SUPPORTED	ULL(0x1)
 
 /* SMCR_ELx definitions */
 #define SMCR_ELX_LEN_SHIFT		U(0)
-#define SMCR_ELX_LEN_MASK		U(0x1ff)
+#define SMCR_ELX_LEN_MAX		U(0x1ff)
 #define SMCR_ELX_FA64_BIT		(U(1) << 31)
+#define SMCR_ELX_EZT0_BIT		(U(1) << 30)
 
 /*******************************************************************************
  * Definitions of MAIR encodings for device and normal memory
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index 40ab82f..a0141de 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -657,4 +657,17 @@
 	return read_feat_sme_id_field() >= ID_AA64PFR1_EL1_SME_SUPPORTED;
 }
 
+static inline bool is_feat_sme2_supported(void)
+{
+	if (ENABLE_SME2_FOR_NS == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_SME2_FOR_NS == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_sme_id_field() >= ID_AA64PFR1_EL1_SME2_SUPPORTED;
+}
+
 #endif /* ARCH_FEATURES_H */
diff --git a/include/arch/aarch64/asm_macros.S b/include/arch/aarch64/asm_macros.S
index b4dab08..7d1407a 100644
--- a/include/arch/aarch64/asm_macros.S
+++ b/include/arch/aarch64/asm_macros.S
@@ -186,11 +186,12 @@
 	.space	SPINLOCK_ASM_SIZE
 	.endm
 
-#if RAS_EXTENSION
+	/*
+	 * With RAS extension executes esb instruction, else NOP
+	 */
 	.macro esb
 	.inst	0xd503221f
 	.endm
-#endif
 
 	/*
 	 * Helper macro to read system register value into x0
diff --git a/include/bl31/sync_handle.h b/include/bl31/sync_handle.h
index e211575..1ac4f98 100644
--- a/include/bl31/sync_handle.h
+++ b/include/bl31/sync_handle.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2022, ARM Limited. All rights reserved.
+ * Copyright (c) 2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,6 +17,7 @@
 #define ISS_SYSREG_DIRECTION_MASK	0x000001UL
 
 #define ISS_SYSREG_OPCODE_RNDR		0x30c808U
+#define ISS_SYSREG_OPCODE_IMPDEF	0x303c00U
 #define ISS_SYSREG_OPCODE_RNDRRS	0x32c808U
 
 #define TRAP_RET_UNHANDLED		-1
@@ -54,6 +56,7 @@
 int handle_sysreg_trap(uint64_t esr_el3, cpu_context_t *ctx);
 
 /* Prototypes for system register emulation handlers provided by platforms. */
+int plat_handle_impdef_trap(uint64_t esr_el3, cpu_context_t *ctx);
 int plat_handle_rng_trap(uint64_t esr_el3, cpu_context_t *ctx);
 
 #endif /* __ASSEMBLER__ */
diff --git a/include/drivers/arm/sbsa.h b/include/drivers/arm/sbsa.h
index 9403634..4ca7194 100644
--- a/include/drivers/arm/sbsa.h
+++ b/include/drivers/arm/sbsa.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,7 +9,12 @@
 
 #include <stdint.h>
 
-/* Register Offsets */
+/* SBSA Secure Watchdog Register Offsets */
+/* Refresh frame */
+#define SBSA_WDOG_WRR_OFFSET		UL(0x000)
+#define SBSA_WDOG_WRR_REFRESH		UL(0x1)
+
+/* Control and status frame */
 #define SBSA_WDOG_WCS_OFFSET		UL(0x000)
 #define SBSA_WDOG_WOR_LOW_OFFSET	UL(0x008)
 #define SBSA_WDOG_WOR_HIGH_OFFSET	UL(0x00C)
@@ -20,5 +25,6 @@
 
 void sbsa_wdog_start(uintptr_t base, uint64_t ms);
 void sbsa_wdog_stop(uintptr_t base);
+void sbsa_wdog_refresh(uintptr_t refresh_base);
 
 #endif /* SBSA_H */
diff --git a/include/drivers/io/io_dummy.h b/include/drivers/io/io_dummy.h
deleted file mode 100644
index edfc699..0000000
--- a/include/drivers/io/io_dummy.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef IO_DUMMY_H
-#define IO_DUMMY_H
-
-int register_io_dev_dummy(const struct io_dev_connector **dev_con);
-
-#endif /* IO_DUMMY_H */
diff --git a/include/drivers/io/io_storage.h b/include/drivers/io/io_storage.h
index 8f30ed0..3179383 100644
--- a/include/drivers/io/io_storage.h
+++ b/include/drivers/io/io_storage.h
@@ -19,7 +19,6 @@
 	IO_TYPE_INVALID,
 	IO_TYPE_SEMIHOSTING,
 	IO_TYPE_MEMMAP,
-	IO_TYPE_DUMMY,
 	IO_TYPE_FIRMWARE_IMAGE_PACKAGE,
 	IO_TYPE_BLOCK,
 	IO_TYPE_MTD,
diff --git a/include/drivers/st/stm32_pka.h b/include/drivers/st/stm32_pka.h
index ad4690a..34b3f6b 100644
--- a/include/drivers/st/stm32_pka.h
+++ b/include/drivers/st/stm32_pka.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2022-2023, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,24 +9,11 @@
 
 #include <stdint.h>
 
-#if !PKA_USE_NIST_P256 && !PKA_USE_BRAINPOOL_P256R1 && !PKA_USE_BRAINPOOL_P256T1 && \
-	!PKA_USE_NIST_P521
-#error "At least one ECDSA curve needs to be selected"
-#endif
-
 enum stm32_pka_ecdsa_curve_id {
-#if PKA_USE_NIST_P256
 	PKA_NIST_P256,
-#endif
-#if PKA_USE_BRAINPOOL_P256R1
 	PKA_BRAINPOOL_P256R1,
-#endif
-#if PKA_USE_BRAINPOOL_P256T1
 	PKA_BRAINPOOL_P256T1,
-#endif
-#if PKA_USE_NIST_P521
 	PKA_NIST_P521,
-#endif
 };
 
 struct stm32_pka_platdata {
diff --git a/include/lib/psci/psci.h b/include/lib/psci/psci.h
index 6d27b7b..4d7e58e 100644
--- a/include/lib/psci/psci.h
+++ b/include/lib/psci/psci.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -317,6 +318,7 @@
 	void (*cpu_standby)(plat_local_state_t cpu_state);
 	int (*pwr_domain_on)(u_register_t mpidr);
 	void (*pwr_domain_off)(const psci_power_state_t *target_state);
+	int (*pwr_domain_off_early)(const psci_power_state_t *target_state);
 	void (*pwr_domain_suspend_pwrdown_early)(
 				const psci_power_state_t *target_state);
 #if PSCI_OS_INIT_MODE
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index ffbd4ca..e8461f5 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -364,6 +364,7 @@
 /* secure watchdog */
 void plat_arm_secure_wdt_start(void);
 void plat_arm_secure_wdt_stop(void);
+void plat_arm_secure_wdt_refresh(void);
 
 /* Get SOC-ID of ARM platform */
 uint32_t plat_arm_get_soc_id(void);
diff --git a/include/plat/arm/css/common/css_def.h b/include/plat/arm/css/common/css_def.h
index dde174c..f87f857 100644
--- a/include/plat/arm/css/common/css_def.h
+++ b/include/plat/arm/css/common/css_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -52,18 +52,21 @@
  * terminology. On a GICv2 system or mode, the interrupts will be treated as
  * Group 0 interrupts.
  */
-#define CSS_G1S_IRQ_PROPS(grp) \
+#define CSS_G1S_INT_PROPS(grp) \
 	INTR_PROP_DESC(CSS_IRQ_MHU, GIC_HIGHEST_SEC_PRIORITY, grp, \
 			GIC_INTR_CFG_LEVEL), \
 	INTR_PROP_DESC(CSS_IRQ_GPU_SMMU_0, GIC_HIGHEST_SEC_PRIORITY, grp, \
 			GIC_INTR_CFG_LEVEL), \
 	INTR_PROP_DESC(CSS_IRQ_TZC, GIC_HIGHEST_SEC_PRIORITY, grp, \
 			GIC_INTR_CFG_LEVEL), \
-	INTR_PROP_DESC(CSS_IRQ_TZ_WDOG, GIC_HIGHEST_SEC_PRIORITY, grp, \
-			GIC_INTR_CFG_LEVEL), \
 	INTR_PROP_DESC(CSS_IRQ_SEC_SYS_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
 			GIC_INTR_CFG_LEVEL)
 
+#define CSS_G1S_IRQ_PROPS(grp) \
+	CSS_G1S_INT_PROPS(grp), \
+	INTR_PROP_DESC(CSS_IRQ_TZ_WDOG, GIC_HIGHEST_SEC_PRIORITY, grp, \
+			GIC_INTR_CFG_LEVEL)
+
 #if CSS_USE_SCMI_SDS_DRIVER
 /* Memory region for shared data storage */
 #define PLAT_ARM_SDS_MEM_BASE		ARM_SHARED_RAM_BASE
diff --git a/include/services/ffa_svc.h b/include/services/ffa_svc.h
index 8bc911a..64af437 100644
--- a/include/services/ffa_svc.h
+++ b/include/services/ffa_svc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,7 +24,7 @@
 
 /* The macros below are used to identify FFA calls from the SMC function ID */
 #define FFA_FNUM_MIN_VALUE	U(0x60)
-#define FFA_FNUM_MAX_VALUE	U(0x8B)
+#define FFA_FNUM_MAX_VALUE	U(0x8C)
 #define is_ffa_fid(fid) __extension__ ({		\
 	__typeof__(fid) _fid = (fid);			\
 	((GET_SMC_NUM(_fid) >= FFA_FNUM_MIN_VALUE) &&	\
@@ -118,6 +118,7 @@
 #define FFA_FNUM_MSG_SEND2			U(0x86)
 #define FFA_FNUM_SECONDARY_EP_REGISTER		U(0x87)
 #define FFA_FNUM_PARTITION_INFO_GET_REGS	U(0x8B)
+#define FFA_FNUM_EL3_INTR_HANDLE		U(0x8C)
 
 /* FFA SMC32 FIDs */
 #define FFA_ERROR		FFA_FID(SMC_32, FFA_FNUM_ERROR)
@@ -163,6 +164,7 @@
 #define FFA_MEM_FRAG_TX	FFA_FID(SMC_32, FFA_FNUM_MEM_FRAG_TX)
 #define FFA_SPM_ID_GET		FFA_FID(SMC_32, FFA_FNUM_SPM_ID_GET)
 #define FFA_NORMAL_WORLD_RESUME	FFA_FID(SMC_32, FFA_FNUM_NORMAL_WORLD_RESUME)
+#define FFA_EL3_INTR_HANDLE	FFA_FID(SMC_32, FFA_FNUM_EL3_INTR_HANDLE)
 
 /* FFA SMC64 FIDs */
 #define FFA_ERROR_SMC64		FFA_FID(SMC_64, FFA_FNUM_ERROR)
diff --git a/lib/cpus/aarch64/cortex_x1.S b/lib/cpus/aarch64/cortex_x1.S
index 9a7f666..de65365 100644
--- a/lib/cpus/aarch64/cortex_x1.S
+++ b/lib/cpus/aarch64/cortex_x1.S
@@ -37,7 +37,7 @@
 	bl	check_errata_1821534
 	cbz	x0, 1f
 	mrs	x1, CORTEX_X1_ACTLR2_EL1
-	orr	x1, x1, BIT(2)
+	orr	x1, x1, #BIT(2)
 	msr	CORTEX_X1_ACTLR2_EL1, x1
 	isb
 1:
@@ -64,7 +64,7 @@
 	bl	check_errata_1688305
 	cbz	x0, 1f
 	mrs	x0, CORTEX_X1_ACTLR2_EL1
-	orr	x0, x0, BIT(1)
+	orr	x0, x0, #BIT(1)
 	msr	CORTEX_X1_ACTLR2_EL1, x0
 	isb
 
@@ -92,7 +92,7 @@
 	bl	check_errata_1827429
 	cbz	x0, 1f
 	mrs	x0, CORTEX_X1_CPUECTLR_EL1
-	orr	x0, x0, BIT(53)
+	orr	x0, x0, #BIT(53)
 	msr	CORTEX_X1_CPUECTLR_EL1, x0
 	isb
 
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index e38b34d..744e4f9 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -517,12 +517,13 @@
 		amu_enable(el2_unused, ctx);
 	}
 
-	/* Enable SME, SVE, and FPU/SIMD for non-secure world. */
+	/* Enable SVE and FPU/SIMD */
+	if (is_feat_sve_supported()) {
+		sve_enable(ctx);
+	}
+
 	if (is_feat_sme_supported()) {
 		sme_enable(ctx);
-	} else if (is_feat_sve_supported()) {
-		/* Enable SVE and FPU/SIMD for non-secure world. */
-		sve_enable(ctx);
 	}
 
 	if (is_feat_mpam_supported()) {
@@ -553,22 +554,7 @@
 static void manage_extensions_secure(cpu_context_t *ctx)
 {
 #if IMAGE_BL31
-
-	if (is_feat_sme_supported()) {
-		if (ENABLE_SME_FOR_SWD) {
-		/*
-		 * Enable SME, SVE, FPU/SIMD in secure context, secure manager
-		 * must ensure SME, SVE, and FPU/SIMD context properly managed.
-		 */
-			sme_enable(ctx);
-		} else {
-		/*
-		 * Disable SME, SVE, FPU/SIMD in secure context so non-secure
-		 * world can safely use the associated registers.
-		 */
-			sme_disable(ctx);
-		}
-	} else if (is_feat_sve_supported()) {
+	if (is_feat_sve_supported()) {
 		if (ENABLE_SVE_FOR_SWD) {
 		/*
 		 * Enable SVE and FPU in secure context, secure manager must
@@ -585,6 +571,21 @@
 		}
 	}
 
+	if (is_feat_sme_supported()) {
+		if (ENABLE_SME_FOR_SWD) {
+		/*
+		 * Enable SME, SVE, FPU/SIMD in secure context, secure manager
+		 * must ensure SME, SVE, and FPU/SIMD context properly managed.
+		 */
+			sme_enable(ctx);
+		} else {
+		/*
+		 * Disable SME, SVE, FPU/SIMD in secure context so non-secure
+		 * world can safely use the associated registers.
+		 */
+			sme_disable(ctx);
+		}
+	}
 #endif /* IMAGE_BL31 */
 }
 
diff --git a/lib/extensions/sme/sme.c b/lib/extensions/sme/sme.c
index 29034fd..3423dba 100644
--- a/lib/extensions/sme/sme.c
+++ b/lib/extensions/sme/sme.c
@@ -43,19 +43,28 @@
 	 * to be the least restrictive, then lower ELs can restrict as needed
 	 * using SMCR_EL2 and SMCR_EL1.
 	 */
-	reg = SMCR_ELX_LEN_MASK;
+	reg = SMCR_ELX_LEN_MAX;
+
 	if (read_feat_sme_fa64_id_field() != 0U) {
 		VERBOSE("[SME] FA64 enabled\n");
 		reg |= SMCR_ELX_FA64_BIT;
 	}
+
+	/*
+	 * Enable access to ZT0 register.
+	 * Make sure FEAT_SME2 is supported by the hardware before continuing.
+	 * If supported, Set the EZT0 bit in SMCR_EL3 to allow instructions to
+	 * access ZT0 register without trapping.
+	 */
+	if (is_feat_sme2_supported()) {
+		VERBOSE("SME2 enabled\n");
+		reg |= SMCR_ELX_EZT0_BIT;
+	}
 	write_smcr_el3(reg);
 
 	/* Reset CPTR_EL3 value. */
 	write_cptr_el3(cptr_el3);
 	isb();
-
-	/* Enable SVE/FPU in addition to SME. */
-	sve_enable(context);
 }
 
 void sme_disable(cpu_context_t *context)
diff --git a/lib/cpus/aarch64/runtime_errata.S b/lib/psci/aarch64/runtime_errata.S
similarity index 100%
rename from lib/cpus/aarch64/runtime_errata.S
rename to lib/psci/aarch64/runtime_errata.S
diff --git a/lib/psci/psci_lib.mk b/lib/psci/psci_lib.mk
index 6864202..c71580f 100644
--- a/lib/psci/psci_lib.mk
+++ b/lib/psci/psci_lib.mk
@@ -22,7 +22,7 @@
 
 ifeq (${ARCH}, aarch64)
 PSCI_LIB_SOURCES	+=	lib/el3_runtime/aarch64/context.S	\
-				lib/cpus/aarch64/runtime_errata.S
+				lib/psci/aarch64/runtime_errata.S
 endif
 
 ifeq (${USE_COHERENT_MEM}, 1)
diff --git a/lib/psci/psci_off.c b/lib/psci/psci_off.c
index 637adb9..9f36ac7 100644
--- a/lib/psci/psci_off.c
+++ b/lib/psci/psci_off.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -57,6 +58,19 @@
 	psci_set_power_off_state(&state_info);
 
 	/*
+	 * Call the platform provided early CPU_OFF handler to allow
+	 * platforms to perform any housekeeping activities before
+	 * actually powering the CPU off. PSCI_E_DENIED indicates that
+	 * the CPU off sequence should be aborted at this time.
+	 */
+	if (psci_plat_pm_ops->pwr_domain_off_early) {
+		rc = psci_plat_pm_ops->pwr_domain_off_early(&state_info);
+		if (rc == PSCI_E_DENIED) {
+			return rc;
+		}
+	}
+
+	/*
 	 * Get the parent nodes here, this is important to do before we
 	 * initiate the power down sequence as after that point the core may
 	 * have exited coherency and its cache may be disabled, any access to
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index 9ca6bdf..3bce3a5 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -73,6 +73,7 @@
 # Convenience function for verifying option has a boolean value
 # $(eval $(call assert_boolean,FOO)) will assert FOO is 0 or 1
 define assert_boolean
+    $(if $($(1)),,$(error $(1) must not be empty))
     $(if $(filter-out 0 1,$($1)),$(error $1 must be boolean))
 endef
 
@@ -104,6 +105,12 @@
 	$(shell if $(LD) $(1) -v >/dev/null 2>&1; then echo $(1); fi )
 endef
 
+# Convenience function to check for a given compiler option. A call to
+# $(call cc_option, --no-XYZ) will return --no-XYZ if supported by the compiler
+define cc_option
+	$(shell if $(CC) $(1) -c -x c /dev/null -o /dev/null >/dev/null 2>&1; then echo $(1); fi )
+endef
+
 # CREATE_SEQ is a recursive function to create sequence of numbers from 1 to
 # $(2) and assign the sequence to $(1)
 define CREATE_SEQ
@@ -326,7 +333,10 @@
 
 $(eval OBJ := $(1)/$(patsubst %.c,%.o,$(notdir $(2))))
 $(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
-$(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) -DIMAGE_$(call uppercase,$(3)))
+
+$(eval BL_DEFINES := $($(call uppercase,$(3))_DEFINES))
+$(eval BL_INCLUDE_DIRS := $($(call uppercase,$(3))_INCLUDE_DIRS))
+$(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) -DIMAGE_$(call uppercase,$(3)) $(addprefix -D,$(BL_DEFINES)) $(addprefix -I,$(BL_INCLUDE_DIRS)))
 $(eval BL_CFLAGS := $($(call uppercase,$(3))_CFLAGS))
 
 $(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $(3)_dirs
@@ -346,7 +356,10 @@
 
 $(eval OBJ := $(1)/$(patsubst %.S,%.o,$(notdir $(2))))
 $(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
-$(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) -DIMAGE_$(call uppercase,$(3)))
+
+$(eval BL_DEFINES := $($(call uppercase,$(3))_DEFINES))
+$(eval BL_INCLUDE_DIRS := $($(call uppercase,$(3))_INCLUDE_DIRS))
+$(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) -DIMAGE_$(call uppercase,$(3)) $(addprefix -D,$(BL_DEFINES)) $(addprefix -I,$(BL_INCLUDE_DIRS)))
 $(eval BL_ASFLAGS := $($(call uppercase,$(3))_ASFLAGS))
 
 $(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $(3)_dirs
@@ -365,7 +378,10 @@
 define MAKE_LD
 
 $(eval DEP := $(1).d)
-$(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) -DIMAGE_$(call uppercase,$(3)))
+
+$(eval BL_DEFINES := $($(call uppercase,$(3))_DEFINES))
+$(eval BL_INCLUDE_DIRS := $($(call uppercase,$(3))_INCLUDE_DIRS))
+$(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) -DIMAGE_$(call uppercase,$(3)) $(addprefix -D,$(BL_DEFINES)) $(addprefix -I,$(BL_INCLUDE_DIRS)))
 
 $(1): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $(3)_dirs
 	$$(ECHO) "  PP      $$<"
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 34a9bc6..e2a67f7 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -243,6 +243,9 @@
 # operations.
 HW_ASSISTED_COHERENCY		:= 0
 
+# Flag to enable trapping of implementation defined sytem registers
+IMPDEF_SYSREG_TRAP		:= 0
+
 # Set the default algorithm for the generation of Trusted Board Boot keys
 KEY_ALG				:= rsa
 
@@ -398,12 +401,7 @@
 # SME defaults to disabled
 ENABLE_SME_FOR_NS		:= 0
 ENABLE_SME_FOR_SWD		:= 0
-
-# If SME is enabled then force SVE off
-ifneq (${ENABLE_SME_FOR_NS},0)
-	override ENABLE_SVE_FOR_NS	:= 0
-	override ENABLE_SVE_FOR_SWD	:= 0
-endif
+ENABLE_SME2_FOR_NS		:= 0
 
 SANITIZE_UB := off
 
diff --git a/plat/allwinner/common/include/sunxi_cpucfg_ncat.h b/plat/allwinner/common/include/sunxi_cpucfg_ncat.h
new file mode 100644
index 0000000..22828c2
--- /dev/null
+++ b/plat/allwinner/common/include/sunxi_cpucfg_ncat.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SUNXI_CPUCFG_H
+#define SUNXI_CPUCFG_H
+
+#include <sunxi_mmap.h>
+
+/* c = cluster, n = core */
+#define SUNXI_CPUCFG_CLS_CTRL_REG0(c)	(SUNXI_CPUCFG_BASE + 0x0010 + (c) * 0x10)
+#define SUNXI_CPUCFG_CLS_CTRL_REG1(c)	(SUNXI_CPUCFG_BASE + 0x0014 + (c) * 0x10)
+#define SUNXI_CPUCFG_CACHE_CFG_REG	(SUNXI_CPUCFG_BASE + 0x0024)
+/* The T507 datasheet does not mention this register. */
+#define SUNXI_CPUCFG_DBG_REG0		(SUNXI_CPUCFG_BASE + 0x00c0)
+
+#define SUNXI_CPUCFG_RST_CTRL_REG(c)	(SUNXI_CPUCFG_BASE + 0x0000 + (c) * 4)
+#define SUNXI_CPUCFG_RVBAR_LO_REG(n)	(SUNXI_CPUCFG_BASE + 0x0040 + (n) * 8)
+#define SUNXI_CPUCFG_RVBAR_HI_REG(n)	(SUNXI_CPUCFG_BASE + 0x0044 + (n) * 8)
+
+#define SUNXI_C0_CPU_CTRL_REG(n)	(SUNXI_CPUCFG_BASE + 0x0060 + (n) * 4)
+
+#define SUNXI_CPU_CTRL_REG(n)		(SUNXI_CPUSUBSYS_BASE + 0x20 + (n) * 4)
+#define SUNXI_ALT_RVBAR_LO_REG(n)	(SUNXI_CPUSUBSYS_BASE + 0x40 + (n) * 8)
+#define SUNXI_ALT_RVBAR_HI_REG(n)	(SUNXI_CPUSUBSYS_BASE + 0x44 + (n) * 8)
+
+#define SUNXI_POWERON_RST_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0040 + (c) * 4)
+#define SUNXI_POWEROFF_GATING_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0044 + (c) * 4)
+#define SUNXI_CPU_POWER_CLAMP_REG(c, n)	(SUNXI_R_CPUCFG_BASE + 0x0050 + \
+					(c) * 0x10 + (n) * 4)
+#define SUNXI_CPU_UNK_REG(n)		(SUNXI_R_CPUCFG_BASE + 0x0070 + (n) * 4)
+
+#define SUNXI_CPUIDLE_EN_REG		(SUNXI_R_CPUCFG_BASE + 0x0100)
+#define SUNXI_CORE_CLOSE_REG		(SUNXI_R_CPUCFG_BASE + 0x0104)
+#define SUNXI_PWR_SW_DELAY_REG		(SUNXI_R_CPUCFG_BASE + 0x0140)
+#define SUNXI_CONFIG_DELAY_REG		(SUNXI_R_CPUCFG_BASE + 0x0144)
+
+#define SUNXI_AA64nAA32_REG		SUNXI_CPUCFG_CLS_CTRL_REG0
+#define SUNXI_AA64nAA32_OFFSET		24
+
+#endif /* SUNXI_CPUCFG_H */
diff --git a/plat/allwinner/common/include/sunxi_cpucfg_ncat2.h b/plat/allwinner/common/include/sunxi_cpucfg_ncat2.h
new file mode 100644
index 0000000..d4aec19
--- /dev/null
+++ b/plat/allwinner/common/include/sunxi_cpucfg_ncat2.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2021 Sipeed
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SUNXI_CPUCFG_H
+#define SUNXI_CPUCFG_H
+
+#include <sunxi_mmap.h>
+
+/* c = cluster, n = core */
+#define SUNXI_CPUCFG_CLS_CTRL_REG0(c)	(SUNXI_C0_CPUXCFG_BASE + 0x0010)
+#define SUNXI_CPUCFG_CLS_CTRL_REG1(c)	(SUNXI_C0_CPUXCFG_BASE + 0x0014)
+#define SUNXI_CPUCFG_CACHE_CFG_REG	(SUNXI_C0_CPUXCFG_BASE + 0x0024)
+#define SUNXI_CPUCFG_DBG_REG0		(SUNXI_C0_CPUXCFG_BASE + 0x00c0)
+
+#define SUNXI_CPUCFG_RST_CTRL_REG(c)	(SUNXI_C0_CPUXCFG_BASE + 0x0000)
+#define SUNXI_CPUCFG_GEN_CTRL_REG0(c)	(SUNXI_CPUCFG_BASE + 0x0000)
+#define SUNXI_CPUCFG_RVBAR_LO_REG(n)	(SUNXI_CPUCFG_BASE + 0x0040 + (n) * 8)
+#define SUNXI_CPUCFG_RVBAR_HI_REG(n)	(SUNXI_CPUCFG_BASE + 0x0044 + (n) * 8)
+
+#define SUNXI_POWERON_RST_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0040 + (c) * 4)
+#define SUNXI_POWEROFF_GATING_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0044 + (c) * 4)
+#define SUNXI_CPU_POWER_CLAMP_REG(c, n)	(SUNXI_R_CPUCFG_BASE + 0x0050 + \
+					(c) * 0x10 + (n) * 4)
+
+#define SUNXI_AA64nAA32_REG		SUNXI_CPUCFG_GEN_CTRL_REG0
+#define SUNXI_AA64nAA32_OFFSET		4
+
+static inline bool sunxi_cpucfg_has_per_cluster_regs(void)
+{
+	return true;
+}
+
+#endif /* SUNXI_CPUCFG_H */
diff --git a/plat/allwinner/common/include/sunxi_def.h b/plat/allwinner/common/include/sunxi_def.h
index c17ef95..20f6c49 100644
--- a/plat/allwinner/common/include/sunxi_def.h
+++ b/plat/allwinner/common/include/sunxi_def.h
@@ -20,6 +20,7 @@
 #define SUNXI_SOC_H616			0x1823
 #define SUNXI_SOC_R329			0x1851
 
+#define SUNXI_VER_BITS_MASK		0xffU
 #define JEDEC_ALLWINNER_BKID		9U
 #define JEDEC_ALLWINNER_MFID		0x9eU
 
diff --git a/plat/allwinner/common/sunxi_common.c b/plat/allwinner/common/sunxi_common.c
index 092659c..62f4fcb 100644
--- a/plat/allwinner/common/sunxi_common.c
+++ b/plat/allwinner/common/sunxi_common.c
@@ -183,5 +183,5 @@
 {
 	uint32_t reg = mmio_read_32(SRAM_VER_REG);
 
-	return reg & GENMASK_32(7, 0);
+	return reg & SUNXI_VER_BITS_MASK;
 }
diff --git a/plat/allwinner/common/sunxi_cpu_ops.c b/plat/allwinner/common/sunxi_cpu_ops.c
index 46e7090..30841e2 100644
--- a/plat/allwinner/common/sunxi_cpu_ops.c
+++ b/plat/allwinner/common/sunxi_cpu_ops.c
@@ -19,6 +19,12 @@
 #include <sunxi_mmap.h>
 #include <sunxi_private.h>
 
+#ifndef SUNXI_C0_CPU_CTRL_REG
+#define SUNXI_C0_CPU_CTRL_REG(n)	0
+#define SUNXI_CPU_UNK_REG(n)		0
+#define SUNXI_CPU_CTRL_REG(n)		0
+#endif
+
 static void sunxi_cpu_disable_power(unsigned int cluster, unsigned int core)
 {
 	if (mmio_read_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core)) == 0xff)
@@ -53,15 +59,30 @@
 
 	VERBOSE("PSCI: Powering off cluster %d core %d\n", cluster, core);
 
-	/* Deassert DBGPWRDUP */
-	mmio_clrbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core));
-	/* Activate the core output clamps, but not for core 0. */
-	if (core != 0)
-		mmio_setbits_32(SUNXI_POWEROFF_GATING_REG(cluster), BIT(core));
-	/* Assert CPU power-on reset */
-	mmio_clrbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core));
-	/* Remove power from the CPU */
-	sunxi_cpu_disable_power(cluster, core);
+	if (sunxi_cpucfg_has_per_cluster_regs()) {
+		/* Deassert DBGPWRDUP */
+		mmio_clrbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core));
+		/* Activate the core output clamps, but not for core 0. */
+		if (core != 0) {
+			mmio_setbits_32(SUNXI_POWEROFF_GATING_REG(cluster),
+					BIT(core));
+		}
+		/* Assert CPU power-on reset */
+		mmio_clrbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core));
+		/* Remove power from the CPU */
+		sunxi_cpu_disable_power(cluster, core);
+	} else {
+		/* power down(?) debug core */
+		mmio_clrbits_32(SUNXI_C0_CPU_CTRL_REG(core), BIT(8));
+		/* ??? Activate the core output clamps, but not for core 0 */
+		if (core != 0) {
+			mmio_setbits_32(SUNXI_CPU_UNK_REG(core), BIT(1));
+		}
+		/* ??? Assert CPU power-on reset ??? */
+		mmio_clrbits_32(SUNXI_CPU_UNK_REG(core), BIT(0));
+		/* Remove power from the CPU */
+		sunxi_cpu_disable_power(cluster, core);
+	}
 }
 
 void sunxi_cpu_on(u_register_t mpidr)
@@ -71,23 +92,45 @@
 
 	VERBOSE("PSCI: Powering on cluster %d core %d\n", cluster, core);
 
+	if (sunxi_cpucfg_has_per_cluster_regs()) {
+		/* Assert CPU core reset */
+		mmio_clrbits_32(SUNXI_CPUCFG_RST_CTRL_REG(cluster), BIT(core));
+		/* Assert CPU power-on reset */
+		mmio_clrbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core));
+		/* Set CPU to start in AArch64 mode */
+		mmio_setbits_32(SUNXI_AA64nAA32_REG(cluster),
+				BIT(SUNXI_AA64nAA32_OFFSET + core));
+		/* Apply power to the CPU */
+		sunxi_cpu_enable_power(cluster, core);
+		/* Release the core output clamps */
+		mmio_clrbits_32(SUNXI_POWEROFF_GATING_REG(cluster), BIT(core));
+		/* Deassert CPU power-on reset */
+		mmio_setbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core));
+		/* Deassert CPU core reset */
+		mmio_setbits_32(SUNXI_CPUCFG_RST_CTRL_REG(cluster), BIT(core));
+		/* Assert DBGPWRDUP */
+		mmio_setbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core));
+	} else {
+		/* Assert CPU core reset */
+		mmio_clrbits_32(SUNXI_C0_CPU_CTRL_REG(core), BIT(0));
+		/* ??? Assert CPU power-on reset ??? */
+		mmio_clrbits_32(SUNXI_CPU_UNK_REG(core), BIT(0));
+
+		/* Set CPU to start in AArch64 mode */
+		mmio_setbits_32(SUNXI_CPU_CTRL_REG(core), BIT(0));
+
+		/* Apply power to the CPU */
+		sunxi_cpu_enable_power(cluster, core);
+
-	/* Assert CPU core reset */
-	mmio_clrbits_32(SUNXI_CPUCFG_RST_CTRL_REG(cluster), BIT(core));
-	/* Assert CPU power-on reset */
-	mmio_clrbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core));
-	/* Set CPU to start in AArch64 mode */
-	mmio_setbits_32(SUNXI_AA64nAA32_REG(cluster),
-			BIT(SUNXI_AA64nAA32_OFFSET + core));
-	/* Apply power to the CPU */
-	sunxi_cpu_enable_power(cluster, core);
-	/* Release the core output clamps */
-	mmio_clrbits_32(SUNXI_POWEROFF_GATING_REG(cluster), BIT(core));
-	/* Deassert CPU power-on reset */
-	mmio_setbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core));
-	/* Deassert CPU core reset */
-	mmio_setbits_32(SUNXI_CPUCFG_RST_CTRL_REG(cluster), BIT(core));
-	/* Assert DBGPWRDUP */
-	mmio_setbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core));
+		/* ??? Release the core output clamps ??? */
+		mmio_clrbits_32(SUNXI_CPU_UNK_REG(core), BIT(1));
+		/* ??? Deassert CPU power-on reset ??? */
+		mmio_setbits_32(SUNXI_CPU_UNK_REG(core), BIT(0));
+		/* Deassert CPU core reset */
+		mmio_setbits_32(SUNXI_C0_CPU_CTRL_REG(core), BIT(0));
+		/* power up(?) debug core */
+		mmio_setbits_32(SUNXI_C0_CPU_CTRL_REG(core), BIT(8));
+	}
 }
 
 void sunxi_cpu_power_off_others(void)
diff --git a/plat/allwinner/common/sunxi_pm.c b/plat/allwinner/common/sunxi_pm.c
index 3772b4a..ebc406b 100644
--- a/plat/allwinner/common/sunxi_pm.c
+++ b/plat/allwinner/common/sunxi_pm.c
@@ -25,6 +25,11 @@
 }
 #endif
 
+#ifndef SUNXI_ALT_RVBAR_LO_REG
+#define SUNXI_ALT_RVBAR_LO_REG(n)	0
+#define SUNXI_ALT_RVBAR_HI_REG(n)	0
+#endif
+
 int sunxi_validate_ns_entrypoint(uintptr_t ns_entrypoint)
 {
 	/* The non-secure entry point must be in DRAM */
@@ -42,10 +47,17 @@
 
 	/* Program all CPU entry points. */
 	for (unsigned int cpu = 0; cpu < PLATFORM_CORE_COUNT; ++cpu) {
-		mmio_write_32(SUNXI_CPUCFG_RVBAR_LO_REG(cpu),
-			      sec_entrypoint & 0xffffffff);
-		mmio_write_32(SUNXI_CPUCFG_RVBAR_HI_REG(cpu),
-			      sec_entrypoint >> 32);
+		if (sunxi_cpucfg_has_per_cluster_regs()) {
+			mmio_write_32(SUNXI_CPUCFG_RVBAR_LO_REG(cpu),
+				      sec_entrypoint & 0xffffffff);
+			mmio_write_32(SUNXI_CPUCFG_RVBAR_HI_REG(cpu),
+				      sec_entrypoint >> 32);
+		} else {
+			mmio_write_32(SUNXI_ALT_RVBAR_LO_REG(cpu),
+				      sec_entrypoint & 0xffffffff);
+			mmio_write_32(SUNXI_ALT_RVBAR_HI_REG(cpu),
+				      sec_entrypoint >> 32);
+		}
 	}
 
 	if (sunxi_set_scpi_psci_ops(psci_ops) == 0) {
diff --git a/plat/allwinner/sun50i_a64/include/sunxi_cpucfg.h b/plat/allwinner/sun50i_a64/include/sunxi_cpucfg.h
index aed3585..ddd53ba 100644
--- a/plat/allwinner/sun50i_a64/include/sunxi_cpucfg.h
+++ b/plat/allwinner/sun50i_a64/include/sunxi_cpucfg.h
@@ -36,4 +36,9 @@
 #define SUNXI_AA64nAA32_REG		SUNXI_CPUCFG_CLS_CTRL_REG0
 #define SUNXI_AA64nAA32_OFFSET		24
 
+static inline bool sunxi_cpucfg_has_per_cluster_regs(void)
+{
+	return true;
+}
+
 #endif /* SUNXI_CPUCFG_H */
diff --git a/plat/allwinner/sun50i_h6/include/sunxi_cpucfg.h b/plat/allwinner/sun50i_h6/include/sunxi_cpucfg.h
index 5bfda5d..585c51b 100644
--- a/plat/allwinner/sun50i_h6/include/sunxi_cpucfg.h
+++ b/plat/allwinner/sun50i_h6/include/sunxi_cpucfg.h
@@ -1,35 +1,6 @@
-/*
- * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SUNXI_CPUCFG_H
-#define SUNXI_CPUCFG_H
-
-#include <sunxi_mmap.h>
-
-/* c = cluster, n = core */
-#define SUNXI_CPUCFG_CLS_CTRL_REG0(c)	(SUNXI_CPUCFG_BASE + 0x0010 + (c) * 0x10)
-#define SUNXI_CPUCFG_CLS_CTRL_REG1(c)	(SUNXI_CPUCFG_BASE + 0x0014 + (c) * 0x10)
-#define SUNXI_CPUCFG_CACHE_CFG_REG	(SUNXI_CPUCFG_BASE + 0x0024)
-#define SUNXI_CPUCFG_DBG_REG0		(SUNXI_CPUCFG_BASE + 0x00c0)
-
-#define SUNXI_CPUCFG_RST_CTRL_REG(c)	(SUNXI_CPUCFG_BASE + 0x0000 + (c) * 4)
-#define SUNXI_CPUCFG_RVBAR_LO_REG(n)	(SUNXI_CPUCFG_BASE + 0x0040 + (n) * 8)
-#define SUNXI_CPUCFG_RVBAR_HI_REG(n)	(SUNXI_CPUCFG_BASE + 0x0044 + (n) * 8)
-
-#define SUNXI_POWERON_RST_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0040 + (c) * 4)
-#define SUNXI_POWEROFF_GATING_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0044 + (c) * 4)
-#define SUNXI_CPU_POWER_CLAMP_REG(c, n)	(SUNXI_R_CPUCFG_BASE + 0x0050 + \
-					(c) * 0x10 + (n) * 4)
-
-#define SUNXI_CPUIDLE_EN_REG		(SUNXI_R_CPUCFG_BASE + 0x0100)
-#define SUNXI_CORE_CLOSE_REG		(SUNXI_R_CPUCFG_BASE + 0x0104)
-#define SUNXI_PWR_SW_DELAY_REG		(SUNXI_R_CPUCFG_BASE + 0x0140)
-#define SUNXI_CONFIG_DELAY_REG		(SUNXI_R_CPUCFG_BASE + 0x0144)
-
-#define SUNXI_AA64nAA32_REG		SUNXI_CPUCFG_CLS_CTRL_REG0
-#define SUNXI_AA64nAA32_OFFSET		24
+#include <sunxi_cpucfg_ncat.h>
 
-#endif /* SUNXI_CPUCFG_H */
+static inline bool sunxi_cpucfg_has_per_cluster_regs(void)
+{
+	return true;
+}
diff --git a/plat/allwinner/sun50i_h6/include/sunxi_mmap.h b/plat/allwinner/sun50i_h6/include/sunxi_mmap.h
index 58216d8..43133be 100644
--- a/plat/allwinner/sun50i_h6/include/sunxi_mmap.h
+++ b/plat/allwinner/sun50i_h6/include/sunxi_mmap.h
@@ -59,5 +59,6 @@
 #define SUNXI_R_RSB_BASE		0x07083000
 #define SUNXI_R_UART_BASE		0x07080000
 #define SUNXI_R_PIO_BASE		0x07022000
+#define SUNXI_CPUSUBSYS_BASE		0x08100000
 
 #endif /* SUNXI_MMAP_H */
diff --git a/plat/allwinner/sun50i_h616/include/sunxi_cpucfg.h b/plat/allwinner/sun50i_h616/include/sunxi_cpucfg.h
index dab663b..5c590e4 100644
--- a/plat/allwinner/sun50i_h616/include/sunxi_cpucfg.h
+++ b/plat/allwinner/sun50i_h616/include/sunxi_cpucfg.h
@@ -1,35 +1,8 @@
-/*
- * Copyright (c) 2017-2020, ARM Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
+#include <plat/common/platform.h>
 
-#ifndef SUNXI_CPUCFG_H
-#define SUNXI_CPUCFG_H
-
-#include <sunxi_mmap.h>
-
-/* c = cluster, n = core */
-#define SUNXI_CPUCFG_CLS_CTRL_REG0(c)	(SUNXI_CPUCFG_BASE + 0x0010 + (c) * 0x10)
-#define SUNXI_CPUCFG_CLS_CTRL_REG1(c)	(SUNXI_CPUCFG_BASE + 0x0014 + (c) * 0x10)
-#define SUNXI_CPUCFG_CACHE_CFG_REG	(SUNXI_CPUCFG_BASE + 0x0024)
-#define SUNXI_CPUCFG_DBG_REG0		(SUNXI_CPUCFG_BASE + 0x00c0)
-
-#define SUNXI_CPUCFG_RST_CTRL_REG(c)	(SUNXI_CPUCFG_BASE + 0x0000 + (c) * 4)
-#define SUNXI_CPUCFG_RVBAR_LO_REG(n)	(SUNXI_CPUCFG_BASE + 0x0040 + (n) * 8)
-#define SUNXI_CPUCFG_RVBAR_HI_REG(n)	(SUNXI_CPUCFG_BASE + 0x0044 + (n) * 8)
-
-#define SUNXI_POWERON_RST_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0040 + (c) * 4)
-#define SUNXI_POWEROFF_GATING_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0044 + (c) * 4)
-#define SUNXI_CPU_POWER_CLAMP_REG(c, n)	(SUNXI_R_CPUCFG_BASE + 0x0050 + \
-					(c) * 0x10 + (n) * 4)
-
-#define SUNXI_CPUIDLE_EN_REG		(SUNXI_R_CPUCFG_BASE + 0x0100)
-#define SUNXI_CORE_CLOSE_REG		(SUNXI_R_CPUCFG_BASE + 0x0104)
-#define SUNXI_PWR_SW_DELAY_REG		(SUNXI_R_CPUCFG_BASE + 0x0140)
-#define SUNXI_CONFIG_DELAY_REG		(SUNXI_R_CPUCFG_BASE + 0x0144)
-
-#define SUNXI_AA64nAA32_REG		SUNXI_CPUCFG_CLS_CTRL_REG0
-#define SUNXI_AA64nAA32_OFFSET		24
+#include <sunxi_cpucfg_ncat.h>
 
-#endif /* SUNXI_CPUCFG_H */
+static inline bool sunxi_cpucfg_has_per_cluster_regs(void)
+{
+	return (plat_get_soc_revision() != 2);
+}
diff --git a/plat/allwinner/sun50i_h616/include/sunxi_mmap.h b/plat/allwinner/sun50i_h616/include/sunxi_mmap.h
index 3b4f4a0..24a4ba8 100644
--- a/plat/allwinner/sun50i_h616/include/sunxi_mmap.h
+++ b/plat/allwinner/sun50i_h616/include/sunxi_mmap.h
@@ -41,6 +41,7 @@
 #define SUNXI_R_UART_BASE		0x07080000
 #define SUNXI_R_I2C_BASE		0x07081400
 #define SUNXI_R_RSB_BASE		0x07083000
+#define SUNXI_CPUSUBSYS_BASE		0x08100000
 #define SUNXI_CPUCFG_BASE		0x09010000
 
 #endif /* SUNXI_MMAP_H */
diff --git a/plat/allwinner/sun50i_r329/include/sunxi_cpucfg.h b/plat/allwinner/sun50i_r329/include/sunxi_cpucfg.h
index 9478f32..3c3530f 100644
--- a/plat/allwinner/sun50i_r329/include/sunxi_cpucfg.h
+++ b/plat/allwinner/sun50i_r329/include/sunxi_cpucfg.h
@@ -1,31 +1 @@
-/*
- * Copyright (c) 2021 Sipeed
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SUNXI_CPUCFG_H
-#define SUNXI_CPUCFG_H
-
-#include <sunxi_mmap.h>
-
-/* c = cluster, n = core */
-#define SUNXI_CPUCFG_CLS_CTRL_REG0(c)	(SUNXI_C0_CPUXCFG_BASE + 0x0010)
-#define SUNXI_CPUCFG_CLS_CTRL_REG1(c)	(SUNXI_C0_CPUXCFG_BASE + 0x0014)
-#define SUNXI_CPUCFG_CACHE_CFG_REG	(SUNXI_C0_CPUXCFG_BASE + 0x0024)
-#define SUNXI_CPUCFG_DBG_REG0		(SUNXI_C0_CPUXCFG_BASE + 0x00c0)
-
-#define SUNXI_CPUCFG_RST_CTRL_REG(c)	(SUNXI_C0_CPUXCFG_BASE + 0x0000)
-#define SUNXI_CPUCFG_GEN_CTRL_REG0(c)	(SUNXI_CPUCFG_BASE + 0x0000)
-#define SUNXI_CPUCFG_RVBAR_LO_REG(n)	(SUNXI_CPUCFG_BASE + 0x0040 + (n) * 8)
-#define SUNXI_CPUCFG_RVBAR_HI_REG(n)	(SUNXI_CPUCFG_BASE + 0x0044 + (n) * 8)
-
-#define SUNXI_POWERON_RST_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0040 + (c) * 4)
-#define SUNXI_POWEROFF_GATING_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0044 + (c) * 4)
-#define SUNXI_CPU_POWER_CLAMP_REG(c, n)	(SUNXI_R_CPUCFG_BASE + 0x0050 + \
-					(c) * 0x10 + (n) * 4)
-
-#define SUNXI_AA64nAA32_REG		SUNXI_CPUCFG_GEN_CTRL_REG0
-#define SUNXI_AA64nAA32_OFFSET		4
-
-#endif /* SUNXI_CPUCFG_H */
+#include <sunxi_cpucfg_ncat2.h>
diff --git a/plat/arm/board/a5ds/platform.mk b/plat/arm/board/a5ds/platform.mk
index 4f87306..6fcf080 100644
--- a/plat/arm/board/a5ds/platform.mk
+++ b/plat/arm/board/a5ds/platform.mk
@@ -100,6 +100,8 @@
 
 MULTI_CONSOLE_API		:=	1
 
+ARM_DISABLE_TRUSTED_WDOG	:=	1
+
 PLAT_BL_COMMON_SOURCES	+=	lib/xlat_tables/aarch32/nonlpae_tables.c
 
 # Use translation tables library v1 when using Cortex-A5
diff --git a/plat/arm/board/corstone1000/common/corstone1000_bl31_setup.c b/plat/arm/board/corstone1000/common/corstone1000_bl31_setup.c
new file mode 100644
index 0000000..b6765a6
--- /dev/null
+++ b/plat/arm/board/corstone1000/common/corstone1000_bl31_setup.c
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#if defined(SPD_spmd)
+/*
+ * A dummy implementation of the platform handler for Group0 secure interrupt.
+ */
+int plat_spmd_handle_group0_interrupt(uint32_t intid)
+{
+	(void)intid;
+	return -1;
+}
+#endif /*defined(SPD_spmd)*/
diff --git a/plat/arm/board/corstone1000/platform.mk b/plat/arm/board/corstone1000/platform.mk
index d891691..3edffe0 100644
--- a/plat/arm/board/corstone1000/platform.mk
+++ b/plat/arm/board/corstone1000/platform.mk
@@ -56,6 +56,7 @@
 			plat/arm/board/corstone1000/common/corstone1000_security.c		\
 			plat/arm/board/corstone1000/common/corstone1000_plat.c		\
 			plat/arm/board/corstone1000/common/corstone1000_pm.c		\
+			plat/arm/board/corstone1000/common/corstone1000_bl31_setup.c	\
 			${CORSTONE1000_CPU_LIBS}					\
 			${CORSTONE1000_GIC_SOURCES}
 
diff --git a/plat/arm/board/fvp/aarch64/fvp_ea.c b/plat/arm/board/fvp/aarch64/fvp_ea.c
new file mode 100644
index 0000000..07053a9
--- /dev/null
+++ b/plat/arm/board/fvp/aarch64/fvp_ea.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <inttypes.h>
+#include <stdint.h>
+
+#include <arch_helpers.h>
+#include <bl31/ea_handle.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <context.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <plat/common/platform.h>
+
+/*
+ * This source file with custom plat_ea_handler function is compiled only when
+ * building TF-A with compile option PLATFORM_TEST_EA_FFH
+ */
+
+/* Test address(non-existent) used in tftf to cause External aborts */
+#define TEST_ADDRESS	UL(0x7FFFF000)
+
+void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
+		void *handle, uint64_t flags)
+{
+#ifdef PLATFORM_TEST_EA_FFH
+	u_register_t elr_el3;
+	u_register_t fault_address;
+	cpu_context_t *ctx = cm_get_context(NON_SECURE);
+	el3_state_t *el3_ctx = get_el3state_ctx(ctx);
+	gp_regs_t *gpregs_ctx = get_gpregs_ctx(ctx);
+	unsigned int level = (unsigned int)GET_EL(read_spsr_el3());
+
+	fault_address = read_ctx_reg(gpregs_ctx, CTX_GPREG_X0);
+
+	if ((level < MODE_EL3) && (fault_address == TEST_ADDRESS)) {
+		if (ea_reason == ERROR_EA_SYNC) {
+			INFO("Handled sync EA from lower EL at address 0x%lx\n", fault_address);
+			/* To avoid continuous faults, forward return address */
+			elr_el3 = read_ctx_reg(el3_ctx, CTX_ELR_EL3);
+			elr_el3 += 4;
+			write_ctx_reg(el3_ctx, CTX_ELR_EL3, elr_el3);
+			return;
+		} else if (ea_reason == ERROR_EA_ASYNC) {
+			INFO("Handled Serror from lower EL at address 0x%lx\n", fault_address);
+			return;
+		}
+	}
+#endif
+	plat_default_ea_handler(ea_reason, syndrome, cookie, handle, flags);
+}
diff --git a/plat/arm/board/fvp/aarch64/fvp_ras.c b/plat/arm/board/fvp/aarch64/fvp_ras.c
index 759f6d0..f9b9634 100644
--- a/plat/arm/board/fvp/aarch64/fvp_ras.c
+++ b/plat/arm/board/fvp/aarch64/fvp_ras.c
@@ -4,12 +4,63 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <inttypes.h>
+#include <stdint.h>
+
 #include <lib/extensions/ras.h>
+#include <services/sdei.h>
+
+#ifdef PLATFORM_TEST_RAS_FFH
+static int injected_fault_handler(const struct err_record_info *info,
+		int probe_data, const struct err_handler_data *const data)
+{
+	uint64_t status;
+	int ret;
+
+	/*
+	 * The faulting error record is already selected by the SER probe
+	 * function.
+	 */
+	status = read_erxstatus_el1();
+
+	ERROR("Fault reported by system error record %d on 0x%lx: status=0x%" PRIx64 "\n",
+			probe_data, read_mpidr_el1(), status);
+	ERROR(" exception reason=%u syndrome=0x%" PRIx64 "\n", data->ea_reason,
+			data->flags);
+
+	/* Clear error */
+	write_erxstatus_el1(status);
+
+	ret = sdei_dispatch_event(5000);
+	if (ret < 0) {
+		ERROR("Can't dispatch event to SDEI\n");
+		panic();
+	} else {
+		INFO("SDEI event dispatched\n");
+	}
+
+	return 0;
+}
+
+void plat_handle_uncontainable_ea(void)
+{
+	/* Do not change the string, CI expects it. Wait forever */
+	INFO("Injected Uncontainable Error\n");
+	while (true) {
+		wfe();
+	}
+}
+#endif
 
 struct ras_interrupt fvp_ras_interrupts[] = {
 };
 
 struct err_record_info fvp_err_records[] = {
+#ifdef PLATFORM_TEST_RAS_FFH
+	/* Record for injected fault */
+	ERR_RECORD_SYSREG_V1(0, 2, ras_err_ser_probe_sysreg,
+			injected_fault_handler, NULL),
+#endif
 };
 
 REGISTER_ERR_RECORD_INFO(fvp_err_records);
diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
index 4543671..4f97339 100644
--- a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
+++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,7 +15,7 @@
 / {
 	compatible = "arm,ffa-core-manifest-1.0";
 	#address-cells = <2>;
-	#size-cells = <1>;
+	#size-cells = <2>;
 
 	attribute {
 		spmc_id = <0x8000>;
@@ -78,9 +78,17 @@
 		CPU_1
 	};
 
-	memory@6000000 {
+	memory@0 {
 		device_type = "memory";
-		reg = <0x0 0x6000000 0x2000000>; /* Trusted DRAM */
+		reg = <0x0 0xfd000000 0x0 0x2000000>,
+		      <0x0 0x7000000 0x0 0x1000000>,
+		      <0x0 0xff000000 0x0 0x1000000>;
+	};
+
+	memory@1 {
+		device_type = "ns-memory";
+		reg = <0x00008800 0x80000000 0x0 0x7f000000>,
+		      <0x0 0x88000000 0x0 0x10000000>;
 	};
 
 #if MEASURED_BOOT
diff --git a/plat/arm/board/fvp/fvp_spmd.c b/plat/arm/board/fvp/fvp_spmd.c
new file mode 100644
index 0000000..8213e5e
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_spmd.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+int plat_spmd_handle_group0_interrupt(uint32_t intid)
+{
+	/*
+	 * As of now, there are no sources of Group0 secure interrupt enabled
+	 * for FVP.
+	 */
+	(void)intid;
+	return -1;
+}
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index 79d7451..9e72ba0 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -397,7 +397,17 @@
 #define PLAT_SDEI_DP_EVENT_MAX_CNT	ARM_SDEI_DP_EVENT_MAX_CNT
 #define PLAT_SDEI_DS_EVENT_MAX_CNT	ARM_SDEI_DS_EVENT_MAX_CNT
 #else
-#define PLAT_ARM_PRIVATE_SDEI_EVENTS	ARM_SDEI_PRIVATE_EVENTS
+  #if PLATFORM_TEST_RAS_FFH
+  #define PLAT_ARM_PRIVATE_SDEI_EVENTS \
+	ARM_SDEI_PRIVATE_EVENTS, \
+	SDEI_EXPLICIT_EVENT(5000, SDEI_MAPF_NORMAL), \
+	SDEI_EXPLICIT_EVENT(5001, SDEI_MAPF_NORMAL), \
+	SDEI_EXPLICIT_EVENT(5002, SDEI_MAPF_NORMAL), \
+	SDEI_EXPLICIT_EVENT(5003, SDEI_MAPF_CRITICAL), \
+	SDEI_EXPLICIT_EVENT(5004, SDEI_MAPF_CRITICAL)
+  #else
+  #define PLAT_ARM_PRIVATE_SDEI_EVENTS	ARM_SDEI_PRIVATE_EVENTS
+  #endif
 #define PLAT_ARM_SHARED_SDEI_EVENTS	ARM_SDEI_SHARED_EVENTS
 #endif
 
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index a893155..f2df780 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -50,16 +50,19 @@
 	ENABLE_FEAT_RNG			:= 2
 	ENABLE_FEAT_TWED		:= 2
 	ENABLE_FEAT_GCS			:= 2
-ifeq (${ARCH},aarch64)
+ifeq (${ARCH}, aarch64)
+ifneq (${SPD}, spmd)
 ifeq (${SPM_MM}, 0)
 ifeq (${ENABLE_RME}, 0)
 ifeq (${CTX_INCLUDE_FPREGS}, 0)
 	ENABLE_SME_FOR_NS		:= 2
+	ENABLE_SME2_FOR_NS		:= 2
 endif
 endif
 endif
 endif
 endif
+endif
 
 # enable unconditionally for all builds
 ifeq (${ARCH}, aarch64)
@@ -501,3 +504,23 @@
 endif
 
 PSCI_OS_INIT_MODE	:=	1
+
+ifeq (${SPD},spmd)
+BL31_SOURCES	+=	plat/arm/board/fvp/fvp_spmd.c
+endif
+
+# Test specific macros, keep them at bottom of this file
+$(eval $(call add_define,PLATFORM_TEST_EA_FFH))
+ifeq (${PLATFORM_TEST_EA_FFH}, 1)
+    ifeq (${HANDLE_EA_EL3_FIRST_NS}, 0)
+         $(error "PLATFORM_TEST_EA_FFH expects HANDLE_EA_EL3_FIRST_NS to be 1")
+    endif
+BL31_SOURCES	+= plat/arm/board/fvp/aarch64/fvp_ea.c
+endif
+
+$(eval $(call add_define,PLATFORM_TEST_RAS_FFH))
+ifeq (${PLATFORM_TEST_RAS_FFH}, 1)
+    ifeq (${RAS_EXTENSION}, 0)
+         $(error "PLATFORM_TEST_RAS_FFH expects RAS_EXTENSION to be 1")
+    endif
+endif
diff --git a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
index 4941a4b..6809541 100644
--- a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
+++ b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
@@ -159,3 +159,14 @@
 	if ((plat_info.multichip_mode) && (plat_info.remote_ddr_size != 0))
 		remote_dmc_ecc_setup(plat_info.remote_ddr_size);
 }
+
+#if defined(SPD_spmd)
+/*
+ * A dummy implementation of the platform handler for Group0 secure interrupt.
+ */
+int plat_spmd_handle_group0_interrupt(uint32_t intid)
+{
+	(void)intid;
+	return -1;
+}
+#endif /*defined(SPD_spmd)*/
diff --git a/plat/arm/board/rde1edge/platform.mk b/plat/arm/board/rde1edge/platform.mk
index 0f9dd49..4a9a467 100644
--- a/plat/arm/board/rde1edge/platform.mk
+++ b/plat/arm/board/rde1edge/platform.mk
@@ -1,9 +1,12 @@
 #
-# Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2023, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+$(warning Platform ${PLAT} is deprecated. \
+  Some of the features might not work as expected)
+
 include plat/arm/css/sgi/sgi-common.mk
 
 RDE1EDGE_BASE		=	plat/arm/board/rde1edge
diff --git a/plat/arm/board/tc/fdts/tc_spmc_manifest.dts b/plat/arm/board/tc/fdts/tc_spmc_manifest.dts
index d3a5e1a..b64e076 100644
--- a/plat/arm/board/tc/fdts/tc_spmc_manifest.dts
+++ b/plat/arm/board/tc/fdts/tc_spmc_manifest.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,7 +8,7 @@
 / {
 	compatible = "arm,ffa-core-manifest-1.0";
 	#address-cells = <2>;
-	#size-cells = <1>;
+	#size-cells = <2>;
 
 	attribute {
 		spmc_id = <0x8000>;
@@ -117,9 +117,16 @@
 		};
 	};
 
-	/* 32MB of TC_TZC_DRAM1_BASE */
-	memory@fd000000 {
+	memory@0 {
 		device_type = "memory";
-		reg = <0x0 0xfd000000 0x2000000>;
+		reg = <0x0 0xfd000000 0x0 0x2000000>,
+		      <0x0 0x7000000 0x0 0x1000000>,
+		      <0x0 0xff000000 0x0 0x1000000>;
+	};
+
+	memory@1 {
+		device_type = "ns-memory";
+		reg = <0x00008800 0x80000000 0x0 0x7f000000>,
+		      <0x0 0x88000000 0x1 0x00000000>;
 	};
 };
diff --git a/plat/arm/board/tc/include/platform_def.h b/plat/arm/board/tc/include/platform_def.h
index eea1be6..59fff6e 100644
--- a/plat/arm/board/tc/include/platform_def.h
+++ b/plat/arm/board/tc/include/platform_def.h
@@ -212,8 +212,11 @@
 #define PLAT_ARM_DRAM2_SIZE		ULL(0x180000000)
 #define PLAT_ARM_DRAM2_END		(PLAT_ARM_DRAM2_BASE + PLAT_ARM_DRAM2_SIZE - 1ULL)
 
-#define PLAT_ARM_G1S_IRQ_PROPS(grp)	CSS_G1S_IRQ_PROPS(grp)
-#define PLAT_ARM_G0_IRQ_PROPS(grp)	ARM_G0_IRQ_PROPS(grp)
+#define PLAT_ARM_G1S_IRQ_PROPS(grp)	CSS_G1S_INT_PROPS(grp)
+#define PLAT_ARM_G0_IRQ_PROPS(grp)	ARM_G0_IRQ_PROPS(grp),	\
+					INTR_PROP_DESC(SBSA_SECURE_WDOG_INTID,	\
+						GIC_HIGHEST_SEC_PRIORITY, grp, \
+						GIC_INTR_CFG_LEVEL)
 
 #define PLAT_ARM_SP_IMAGE_STACK_BASE	(PLAT_SP_IMAGE_NS_BUF_BASE +	\
 					 PLAT_SP_IMAGE_NS_BUF_SIZE)
@@ -229,9 +232,11 @@
 #define PLAT_ARM_MEM_PROT_ADDR		(V2M_FLASH0_BASE + \
 					 V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
 
-/*Secure Watchdog Constants */
-#define SBSA_SECURE_WDOG_BASE		UL(0x2A480000)
+/* Secure Watchdog Constants */
+#define SBSA_SECURE_WDOG_CONTROL_BASE	UL(0x2A480000)
+#define SBSA_SECURE_WDOG_REFRESH_BASE	UL(0x2A490000)
 #define SBSA_SECURE_WDOG_TIMEOUT	UL(100)
+#define SBSA_SECURE_WDOG_INTID		86
 
 #define PLAT_ARM_SCMI_CHANNEL_COUNT	1
 
diff --git a/plat/arm/board/tc/include/tc_plat.h b/plat/arm/board/tc/include/tc_plat.h
index ba1831f..195366e 100644
--- a/plat/arm/board/tc/include/tc_plat.h
+++ b/plat/arm/board/tc/include/tc_plat.h
@@ -9,8 +9,10 @@
 
 void tc_bl31_common_platform_setup(void);
 
-#ifdef PLATFORM_TEST
+#ifdef PLATFORM_TEST_TFM_TESTSUITE
 void run_platform_tests(void);
+#endif
+#ifdef PLATFORM_TEST_NV_COUNTERS
 void nv_counter_test(void);
 #endif
 
diff --git a/plat/arm/board/tc/plat_fiptool.mk b/plat/arm/board/tc/plat_fiptool.mk
deleted file mode 100644
index 0e13556..0000000
--- a/plat/arm/board/tc/plat_fiptool.mk
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# Copyright (c) 2021, NXP. All rights reserved.
-# Copyright (c) 2022, Arm Limited. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-# Name of the platform defined source file name,
-# which contains platform defined UUID entries populated
-# in the plat_def_toc_entries[].
-PLAT_DEF_UUID_CONFIG_FILE_NAME	:= plat_def_uuid_config
-
-PLAT_DEF_UUID_CONFIG_FILE_PATH := ../../plat/arm/board/tc
-
-PLAT_DEF_UUID := yes
-PLAT_DEF_UUID_OID_CONFIG_PATH := ../../plat/arm/board/tc
-
-
-INCLUDE_PATHS += -I${PLAT_DEF_UUID_OID_CONFIG_PATH} \
-		 -I./
-# Clean the stale object file.
-$(shell rm ${PLAT_DEF_UUID_CONFIG_FILE_PATH}/${PLAT_DEF_UUID_CONFIG_FILE_NAME}.o)
-
-ifeq (${PLAT_DEF_OID},yes)
-HOSTCCFLAGS += -DPLAT_DEF_OID
-endif
-
-ifeq (${PLAT_DEF_UUID},yes)
-HOSTCCFLAGS += -DPLAT_DEF_FIP_UUID
-PLAT_OBJECTS += ${PLAT_DEF_UUID_CONFIG_FILE_PATH}/${PLAT_DEF_UUID_CONFIG_FILE_NAME}.o
-endif
-
-OBJECTS += ${PLAT_OBJECTS}
diff --git a/plat/arm/board/tc/plat_tc_mbedtls_config.h b/plat/arm/board/tc/plat_tc_mbedtls_config.h
index d776b63..f0aa60b 100644
--- a/plat/arm/board/tc/plat_tc_mbedtls_config.h
+++ b/plat/arm/board/tc/plat_tc_mbedtls_config.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Ltd. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Ltd. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,8 +7,8 @@
 #ifndef PLAT_TC_MBEDTLS_CONFIG_H
 #define PLAT_TC_MBEDTLS_CONFIG_H
 
-#include <mbedtls_config.h>
 #include <export/lib/utils_def_exp.h>
+#include <mbedtls_config-3.h>
 
 #ifndef TF_MBEDTLS_HEAP_SIZE
 #error TF_MBEDTLS_HEAP_SIZE is not defined
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index 7fdc4fd..c75507a 100644
--- a/plat/arm/board/tc/platform.mk
+++ b/plat/arm/board/tc/platform.mk
@@ -53,9 +53,6 @@
 # enable trace filter control registers access to NS by default
 ENABLE_TRF_FOR_NS               := 1
 
-# Enable RSS-required FIP UUIDs
-$(shell cp plat/arm/board/tc/plat_fiptool.mk ${PLAT_DIR})
-
 # Include GICv3 driver files
 include drivers/arm/gic/v3/gicv3.mk
 
@@ -121,7 +118,8 @@
 				lib/fconf/fconf_dyn_cfg_getter.c	\
 				drivers/cfi/v2m/v2m_flash.c		\
 				lib/utils/mem_region.c			\
-				plat/arm/common/arm_nor_psci_mem_protect.c
+				plat/arm/common/arm_nor_psci_mem_protect.c	\
+				drivers/arm/sbsa/sbsa.c
 
 BL31_SOURCES		+=	${FDT_WRAPPERS_SOURCES}
 
@@ -209,7 +207,7 @@
 
     PLAT_INCLUDES	+=	-Iinclude/lib/psa
 
-    $(eval $(call add_define,PLATFORM_TEST))
+    $(eval $(call add_define,PLATFORM_TEST_NV_COUNTERS))
 else ifeq (${PLATFORM_TEST},tfm-testsuite)
     # Add this include as first, before arm_common.mk. This is necessary
     # because arm_common.mk builds Mbed TLS, and platform_test.mk can
diff --git a/plat/arm/board/tc/platform_test.mk b/plat/arm/board/tc/platform_test.mk
index 5cdbb86..e974855 100644
--- a/plat/arm/board/tc/platform_test.mk
+++ b/plat/arm/board/tc/platform_test.mk
@@ -76,5 +76,5 @@
     $(eval $(call add_define,MEASURED_BOOT_HASH_ALG))
     $(eval $(call add_define,DELEG_ATTEST_DUMP_TOKEN_AND_KEY))
 
-    $(eval $(call add_define,PLATFORM_TEST))
+    $(eval $(call add_define,PLATFORM_TEST_TFM_TESTSUITE))
 endif
diff --git a/plat/arm/board/tc/tc_bl31_setup.c b/plat/arm/board/tc/tc_bl31_setup.c
index 1c1e2fb..630324f 100644
--- a/plat/arm/board/tc/tc_bl31_setup.c
+++ b/plat/arm/board/tc/tc_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,6 +13,7 @@
 #include <common/debug.h>
 #include <drivers/arm/css/css_mhu_doorbell.h>
 #include <drivers/arm/css/scmi.h>
+#include <drivers/arm/sbsa.h>
 #include <lib/fconf/fconf.h>
 #include <lib/fconf/fconf_dyn_cfg_getter.h>
 #include <plat/arm/common/plat_arm.h>
@@ -53,11 +54,11 @@
 {
 	arm_bl31_platform_setup();
 
-#ifdef PLATFORM_TEST
-#if PLATFORM_TEST == rss-nv-counters
+#if defined(PLATFORM_TEST_NV_COUNTERS) || defined(PLATFORM_TEST_TFM_TESTSUITE)
+#ifdef PLATFORM_TEST_NV_COUNTERS
 	nv_counter_test();
-#elif PLATFORM_TEST == tfm-testsuite
-	run_platform_tests()
+#elif PLATFORM_TEST_TFM_TESTSUITE
+	run_platform_tests();
 #endif
 	/* Suspend booting */
 	plat_error_handler(-1);
@@ -81,3 +82,37 @@
 
 	fconf_populate("HW_CONFIG", hw_config_info->config_addr);
 }
+
+#if defined(SPD_spmd) && (SPMD_SPM_AT_SEL2 == 1)
+void tc_bl31_plat_runtime_setup(void)
+{
+	arm_bl31_plat_runtime_setup();
+
+	/* Start secure watchdog timer. */
+	plat_arm_secure_wdt_start();
+}
+
+void bl31_plat_runtime_setup(void)
+{
+	tc_bl31_plat_runtime_setup();
+}
+
+/*
+ * Platform handler for Group0 secure interrupt.
+ */
+int plat_spmd_handle_group0_interrupt(uint32_t intid)
+{
+	/* Trusted Watchdog timer is the only source of Group0 interrupt now. */
+	if (intid == SBSA_SECURE_WDOG_INTID) {
+		INFO("Watchdog restarted\n");
+		/* Refresh the timer. */
+		plat_arm_secure_wdt_refresh();
+
+		/* Deactivate the corresponding interrupt. */
+		plat_ic_end_of_interrupt(intid);
+		return 0;
+	}
+
+	return -1;
+}
+#endif /*defined(SPD_spmd) && (SPMD_SPM_AT_SEL2 == 1)*/
diff --git a/plat/arm/board/tc/tc_plat.c b/plat/arm/board/tc/tc_plat.c
index 228f2fa..766bfb5 100644
--- a/plat/arm/board/tc/tc_plat.c
+++ b/plat/arm/board/tc/tc_plat.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -147,10 +147,15 @@
 
 void plat_arm_secure_wdt_start(void)
 {
-	sbsa_wdog_start(SBSA_SECURE_WDOG_BASE, SBSA_SECURE_WDOG_TIMEOUT);
+	sbsa_wdog_start(SBSA_SECURE_WDOG_CONTROL_BASE, SBSA_SECURE_WDOG_TIMEOUT);
 }
 
 void plat_arm_secure_wdt_stop(void)
 {
-	sbsa_wdog_stop(SBSA_SECURE_WDOG_BASE);
+	sbsa_wdog_stop(SBSA_SECURE_WDOG_CONTROL_BASE);
+}
+
+void plat_arm_secure_wdt_refresh(void)
+{
+	sbsa_wdog_refresh(SBSA_SECURE_WDOG_REFRESH_BASE);
 }
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index 19efdd3..8c62a9b 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -43,6 +43,7 @@
 #pragma weak bl31_platform_setup
 #pragma weak bl31_plat_arch_setup
 #pragma weak bl31_plat_get_next_image_ep_info
+#pragma weak bl31_plat_runtime_setup
 
 #define MAP_BL31_TOTAL		MAP_REGION_FLAT(			\
 					BL31_START,			\
diff --git a/plat/hisilicon/hikey960/hikey960_bl31_setup.c b/plat/hisilicon/hikey960/hikey960_bl31_setup.c
index 50751ee..1d7bc94 100644
--- a/plat/hisilicon/hikey960/hikey960_bl31_setup.c
+++ b/plat/hisilicon/hikey960/hikey960_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -245,6 +245,15 @@
 
 	return 0;
 }
+#elif defined(SPD_spmd) && (SPMD_SPM_AT_SEL2 == 1)
+/*
+ * A dummy implementation of the platform handler for Group0 secure interrupt.
+ */
+int plat_spmd_handle_group0_interrupt(uint32_t intid)
+{
+	(void)intid;
+	return -1;
+}
 #endif
 
 void bl31_plat_runtime_setup(void)
diff --git a/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_bus26m.c b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_bus26m.c
index 0b792ab..c8a2d4c 100644
--- a/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_bus26m.c
+++ b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_bus26m.c
@@ -53,6 +53,7 @@
 static struct mt_irqremain *refer2remain_irq;
 
 static struct mt_spm_cond_tables cond_bus26m = {
+	.name = "bus26m",
 	.table_cg = {
 		0xFF5DD002,	/* MTCMOS1 */
 		0x0000003C,	/* MTCMOS2 */
@@ -175,7 +176,7 @@
 		(IS_PLAT_SUSPEND_ID(state_id) || (state_id == MT_PLAT_PWR_STATE_SYSTEM_BUS)));
 }
 
-static int update_rc_condition(const void *val)
+static int update_rc_condition(int state_id, const void *val)
 {
 	const struct mt_spm_cond_tables *tlb = (const struct mt_spm_cond_tables *)val;
 	const struct mt_spm_cond_tables *tlb_check =
@@ -185,7 +186,7 @@
 		return MT_RM_STATUS_BAD;
 	}
 
-	status.is_cond_block = mt_spm_cond_check(tlb, tlb_check,
+	status.is_cond_block = mt_spm_cond_check(state_id, tlb, tlb_check,
 						 (status.is_valid & MT_SPM_RC_VALID_COND_LATCH) ?
 						 &cond_bus26m_res : NULL);
 	status.all_pll_dump = mt_spm_dump_all_pll(tlb, tlb_check,
@@ -279,7 +280,7 @@
 
 	switch (type) {
 	case PLAT_RC_UPDATE_CONDITION:
-		res = update_rc_condition(val);
+		res = update_rc_condition(state_id, val);
 		break;
 	case PLAT_RC_UPDATE_REMAIN_IRQS:
 		update_rc_remain_irqs(val);
diff --git a/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_dram.c b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_dram.c
index d1a2435..82b38ad 100644
--- a/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_dram.c
+++ b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_dram.c
@@ -37,6 +37,7 @@
 #define CONSTRAINT_DRAM_RESOURCE_REQ (MT_SPM_SYSPLL | MT_SPM_INFRA | MT_SPM_26M)
 
 static struct mt_spm_cond_tables cond_dram = {
+	.name = "dram",
 	.table_cg = {
 		0xFF5DD002,	/* MTCMOS1 */
 		0x0000003C,	/* MTCMOS2 */
@@ -104,7 +105,7 @@
 		 (state_id == MT_PLAT_PWR_STATE_SYSTEM_BUS)));
 }
 
-static int update_rc_condition(const void *val)
+static int update_rc_condition(int state_id, const void *val)
 {
 	const struct mt_spm_cond_tables *tlb = (const struct mt_spm_cond_tables *)val;
 	const struct mt_spm_cond_tables *tlb_check = (const struct mt_spm_cond_tables *)&cond_dram;
@@ -113,7 +114,7 @@
 		return MT_RM_STATUS_BAD;
 	}
 
-	status.is_cond_block = mt_spm_cond_check(tlb, tlb_check,
+	status.is_cond_block = mt_spm_cond_check(state_id, tlb, tlb_check,
 						 (status.is_valid & MT_SPM_RC_VALID_COND_LATCH) ?
 						  &cond_dram_res : NULL);
 	return MT_RM_STATUS_OK;
@@ -185,7 +186,7 @@
 
 	switch (type) {
 	case PLAT_RC_UPDATE_CONDITION:
-		res = update_rc_condition(val);
+		res = update_rc_condition(state_id, val);
 		break;
 	case PLAT_RC_CLKBUF_STATUS:
 		update_rc_clkbuf_status(val);
diff --git a/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_syspll.c b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_syspll.c
index 700f500..5359c7c 100644
--- a/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_syspll.c
+++ b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_syspll.c
@@ -49,6 +49,7 @@
 static unsigned short ext_status_syspll;
 
 static struct mt_spm_cond_tables cond_syspll = {
+	.name = "syspll",
 	.table_cg = {
 		0xFF5DD002,	/* MTCMOS1 */
 		0x0000003C,	/* MTCMOS2 */
@@ -113,7 +114,7 @@
 		 (state_id == MT_PLAT_PWR_STATE_SYSTEM_BUS)));
 }
 
-static int update_rc_condition(const void *val)
+static int update_rc_condition(int state_id, const void *val)
 {
 	int res = MT_RM_STATUS_OK;
 
@@ -126,7 +127,7 @@
 		return MT_RM_STATUS_BAD;
 	}
 
-	status.is_cond_block = mt_spm_cond_check(tlb, tlb_check,
+	status.is_cond_block = mt_spm_cond_check(state_id, tlb, tlb_check,
 						 (status.is_valid & MT_SPM_RC_VALID_COND_LATCH) ?
 						 &cond_syspll_res : NULL);
 	return res;
@@ -228,7 +229,7 @@
 
 	switch (type) {
 	case PLAT_RC_UPDATE_CONDITION:
-		res = update_rc_condition(val);
+		res = update_rc_condition(state_id, val);
 		break;
 	case PLAT_RC_CLKBUF_STATUS:
 		update_rc_clkbuf_status(val);
diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.c b/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.c
index fe6e598..bed55c9 100644
--- a/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.c
+++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.c
@@ -126,12 +126,14 @@
 #define PLL_APLL4	MT_LP_TZ_APMIXEDSYS(0x404)
 #define PLL_APLL5	MT_LP_TZ_APMIXEDSYS(0x418)
 
-unsigned int mt_spm_cond_check(const struct mt_spm_cond_tables *src,
+unsigned int mt_spm_cond_check(int state_id,
+			       const struct mt_spm_cond_tables *src,
 			       const struct mt_spm_cond_tables *dest,
 			       struct mt_spm_cond_tables *res)
 {
 	unsigned int b_res = 0U;
 	unsigned int i;
+	bool is_system_suspend = IS_PLAT_SUSPEND_ID(state_id);
 
 	if ((src == NULL) || (dest == NULL)) {
 		return SPM_COND_CHECK_FAIL;
@@ -140,6 +142,11 @@
 	for (i = 0; i < PLAT_SPM_COND_MAX; i++) {
 		if (res != NULL) {
 			res->table_cg[i] = (src->table_cg[i] & dest->table_cg[i]);
+			if (is_system_suspend && ((res->table_cg[i]) != 0U)) {
+				INFO("suspend: %s block[%u](0x%lx) = 0x%08x\n",
+				     dest->name, i, idle_cg_info[i].addr,
+				     res->table_cg[i]);
+			}
 
 			if ((res->table_cg[i]) != 0U) {
 				b_res |= BIT(i);
@@ -161,6 +168,10 @@
 		b_res |= SPM_COND_CHECK_BLOCKED_PLL;
 	}
 
+	if (is_system_suspend && ((b_res) != 0U)) {
+		INFO("suspend: %s total blocked = 0x%08x\n", dest->name, b_res);
+	}
+
 	return b_res;
 }
 
diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.h b/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.h
index 793d5e8..d93df57 100644
--- a/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.h
+++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.h
@@ -75,13 +75,15 @@
 #define SPM_COND_CHECK_FAIL		BIT(31)
 
 struct mt_spm_cond_tables {
+	char *name;
 	unsigned int table_cg[PLAT_SPM_COND_MAX];
 	unsigned int table_pll;
 	unsigned int table_all_pll;
 	void *priv;
 };
 
-unsigned int mt_spm_cond_check(const struct mt_spm_cond_tables *src,
+unsigned int mt_spm_cond_check(int state_id,
+			       const struct mt_spm_cond_tables *src,
 			       const struct mt_spm_cond_tables *dest,
 			       struct mt_spm_cond_tables *res);
 unsigned int mt_spm_dump_all_pll(const struct mt_spm_cond_tables *src,
diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_conservation.c b/plat/mediatek/drivers/spm/mt8188/mt_spm_conservation.c
index bcb2df6..395448a 100644
--- a/plat/mediatek/drivers/spm/mt8188/mt_spm_conservation.c
+++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_conservation.c
@@ -61,6 +61,14 @@
 
 	__spm_send_cpu_wakeup_event();
 
+	INFO("cpu%d: wakesrc = 0x%x, settle = 0x%x, sec = %u\n",
+	     cpu, pwrctrl->wake_src, mmio_read_32(SPM_CLK_SETTLE),
+	     (mmio_read_32(PCM_TIMER_VAL) / 32768));
+	INFO("sw_flag = 0x%x 0x%x, req = 0x%x, pwr = 0x%x 0x%x\n",
+	     pwrctrl->pcm_flags, pwrctrl->pcm_flags1,
+	     mmio_read_32(SPM_SRC_REQ), mmio_read_32(PWR_STATUS),
+	     mmio_read_32(PWR_STATUS_2ND));
+
 	return ret;
 }
 
diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.c b/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.c
index b38a6d0..5eb16b3 100644
--- a/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.c
+++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.c
@@ -24,6 +24,7 @@
 
 wake_reason_t __spm_output_wake_reason(const struct wake_status *wakesta)
 {
+	uint32_t bk_vtcxo_dur, spm_26m_off_pct;
 	wake_reason_t wr = WR_UNKNOWN;
 
 	if (wakesta == NULL) {
@@ -46,6 +47,33 @@
 		}
 	}
 
+	INFO("r12 = 0x%x, r12_ext = 0x%x, r13 = 0x%x, debug_flag = 0x%x 0x%x\n",
+	     wakesta->tr.comm.r12, wakesta->r12_ext, wakesta->tr.comm.r13, wakesta->tr.comm.debug_flag,
+	     wakesta->tr.comm.debug_flag1);
+	INFO("raw_sta = 0x%x 0x%x 0x%x, idle_sta = 0x%x, cg_check_sta = 0x%x\n",
+	     wakesta->tr.comm.raw_sta, wakesta->md32pcm_wakeup_sta,
+	     wakesta->md32pcm_event_sta, wakesta->idle_sta,
+	     wakesta->cg_check_sta);
+	INFO("req_sta = 0x%x 0x%x 0x%x 0x%x 0x%x, isr = 0x%x\n",
+	     wakesta->tr.comm.req_sta0, wakesta->tr.comm.req_sta1, wakesta->tr.comm.req_sta2,
+	     wakesta->tr.comm.req_sta3, wakesta->tr.comm.req_sta4, wakesta->isr);
+	INFO("rt_req_sta0 = 0x%x, rt_req_sta1 = 0x%x, rt_req_sta2 = 0x%x\n",
+	     wakesta->rt_req_sta0, wakesta->rt_req_sta1, wakesta->rt_req_sta2);
+	INFO("rt_req_sta3 = 0x%x, dram_sw_con_3 = 0x%x, raw_ext_sta = 0x%x\n",
+	     wakesta->rt_req_sta3, wakesta->rt_req_sta4, wakesta->raw_ext_sta);
+	INFO("wake_misc = 0x%x, pcm_flag = 0x%x 0x%x 0x%x 0x%x, req = 0x%x\n",
+	     wakesta->wake_misc, wakesta->sw_flag0, wakesta->sw_flag1,
+	     wakesta->tr.comm.b_sw_flag0, wakesta->tr.comm.b_sw_flag1, wakesta->src_req);
+	INFO("clk_settle = 0x%x, wlk_cntcv_l = 0x%x, wlk_cntcv_h = 0x%x\n",
+	     wakesta->clk_settle, mmio_read_32(SYS_TIMER_VALUE_L),
+	     mmio_read_32(SYS_TIMER_VALUE_H));
+
+	if (wakesta->tr.comm.timer_out != 0U) {
+		bk_vtcxo_dur = mmio_read_32(SPM_BK_VTCXO_DUR);
+		spm_26m_off_pct = (100 * bk_vtcxo_dur) / wakesta->tr.comm.timer_out;
+		INFO("spm_26m_off_pct = %u\n", spm_26m_off_pct);
+	}
+
 	return wr;
 }
 
@@ -331,6 +359,18 @@
 	wakesta->tr.comm.b_sw_flag0 = mmio_read_32(SPM_SW_RSV_7);	/* SPM_SW_RSV_7 */
 	wakesta->tr.comm.b_sw_flag1 = mmio_read_32(SPM_SW_RSV_8);	/* SPM_SW_RSV_8 */
 
+	/* record below spm info for debug */
+	wakesta->src_req = mmio_read_32(SPM_SRC_REQ);
+
+	/* get HW CG check status */
+	wakesta->cg_check_sta = mmio_read_32(SPM_CG_CHECK_STA);
+
+	wakesta->rt_req_sta0 = mmio_read_32(SPM_SW_RSV_2);
+	wakesta->rt_req_sta1 = mmio_read_32(SPM_SW_RSV_3);
+	wakesta->rt_req_sta2 = mmio_read_32(SPM_SW_RSV_4);
+	wakesta->rt_req_sta3 = mmio_read_32(SPM_SW_RSV_5);
+	wakesta->rt_req_sta4 = mmio_read_32(SPM_SW_RSV_6);
+
 	/* get ISR status */
 	wakesta->isr = mmio_read_32(SPM_IRQ_STA);
 
@@ -338,6 +378,9 @@
 	wakesta->sw_flag0 = mmio_read_32(SPM_SW_FLAG_0);
 	wakesta->sw_flag1 = mmio_read_32(SPM_SW_FLAG_1);
 
+	/* get CLK SETTLE */
+	wakesta->clk_settle = mmio_read_32(SPM_CLK_SETTLE);
+
 	/* check abort */
 	wakesta->is_abort = wakesta->tr.comm.debug_flag & DEBUG_ABORT_MASK;
 	wakesta->is_abort |= wakesta->tr.comm.debug_flag1 & DEBUG_ABORT_MASK_1;
diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.h b/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.h
index c719caf..5e3390f 100644
--- a/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.h
+++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.h
@@ -628,11 +628,19 @@
 	uint32_t md32pcm_event_sta;	/* MD32PCM_EVENT_STA */
 	uint32_t wake_misc;		/* SPM_SW_RSV_5 */
 	uint32_t idle_sta;		/* SUBSYS_IDLE_STA */
+	uint32_t cg_check_sta;		/* SPM_CG_CHECK_STA */
 	uint32_t sw_flag0;		/* SPM_SW_FLAG_0 */
 	uint32_t sw_flag1;		/* SPM_SW_FLAG_1 */
 	uint32_t isr;			/* SPM_IRQ_STA */
+	uint32_t clk_settle;		/* SPM_CLK_SETTLE */
+	uint32_t src_req;		/* SPM_SRC_REQ */
 	uint32_t log_index;
 	uint32_t is_abort;
+	uint32_t rt_req_sta0;		/* SPM_SW_RSV_2 */
+	uint32_t rt_req_sta1;		/* SPM_SW_RSV_3 */
+	uint32_t rt_req_sta2;		/* SPM_SW_RSV_4 */
+	uint32_t rt_req_sta3;		/* SPM_SW_RSV_5 */
+	uint32_t rt_req_sta4;		/* SPM_SW_RSV_6 */
 };
 
 struct spm_lp_scen {
diff --git a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
index 6c8c4f0..72ecd54 100644
--- a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
+++ b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
@@ -125,15 +125,18 @@
 .endm
 
 	/* -----------------------------------------------------
-	 * unsigned int plat_is_my_cpu_primary(void);
+	 * bool plat_is_my_cpu_primary(void);
 	 *
 	 * This function checks if this is the Primary CPU
+	 *
+	 * Registers clobbered: x0, x1
 	 * -----------------------------------------------------
 	 */
 func plat_is_my_cpu_primary
 	mrs	x0, mpidr_el1
-	and	x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
-	cmp	x0, #TEGRA_PRIMARY_CPU
+	adr	x1, tegra_primary_cpu_mpid
+	ldr	x1, [x1]
+	cmp	x0, x1
 	cset	x0, eq
 	ret
 endfunc plat_is_my_cpu_primary
@@ -251,6 +254,14 @@
 	adr	x18, bl31_entrypoint
 	str	x18, [x17]
 
+	/* -----------------------------------
+	 * save the boot CPU MPID value
+	 * -----------------------------------
+	 */
+	mrs	x0, mpidr_el1
+	adr	x1, tegra_primary_cpu_mpid
+	str	x0, [x1]
+
 1:	cpu_init_common
 
 	ret
@@ -426,3 +437,10 @@
 	 */
 tegra_console_base:
 	.quad	0
+
+	/* --------------------------------------------------
+	 * MPID value for the boot CPU
+	 * --------------------------------------------------
+	 */
+tegra_primary_cpu_mpid:
+	.quad	0
diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c
index 6a3eae0..050ef52 100644
--- a/plat/nvidia/tegra/common/tegra_bl31_setup.c
+++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2020-2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -92,21 +92,16 @@
 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 				u_register_t arg2, u_register_t arg3)
 {
-	struct tegra_bl31_params *arg_from_bl2 = (struct tegra_bl31_params *) arg0;
-	plat_params_from_bl2_t *plat_params = (plat_params_from_bl2_t *)arg1;
+	struct tegra_bl31_params *arg_from_bl2 = plat_get_bl31_params();
+	plat_params_from_bl2_t *plat_params = plat_get_bl31_plat_params();
 	int32_t ret;
 
 	/*
-	 * For RESET_TO_BL31 systems, BL31 is the first bootloader to run so
-	 * there's no argument to relay from a previous bootloader. Platforms
-	 * might use custom ways to get arguments.
+	 * Tegra platforms will receive boot parameters through custom
+	 * mechanisms. So, we ignore the input parameters.
 	 */
-	if (arg_from_bl2 == NULL) {
-		arg_from_bl2 = plat_get_bl31_params();
-	}
-	if (plat_params == NULL) {
-		plat_params = plat_get_bl31_plat_params();
-	}
+	(void)arg0;
+	(void)arg1;
 
 	/*
 	 * Copy BL3-3, BL3-2 entry point information.
diff --git a/plat/nvidia/tegra/common/tegra_pm.c b/plat/nvidia/tegra/common/tegra_pm.c
index ec34a85..8edb024 100644
--- a/plat/nvidia/tegra/common/tegra_pm.c
+++ b/plat/nvidia/tegra/common/tegra_pm.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2020-2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -92,6 +92,16 @@
 /*******************************************************************************
  * Handler called when a power domain is about to be turned off. The
  * target_state encodes the power state that each level should transition to.
+ * Return error if CPU off sequence is not allowed for the current core.
+ ******************************************************************************/
+static int tegra_pwr_domain_off_early(const psci_power_state_t *target_state)
+{
+	return tegra_soc_pwr_domain_off_early(target_state);
+}
+
+/*******************************************************************************
+ * Handler called when a power domain is about to be turned off. The
+ * target_state encodes the power state that each level should transition to.
  ******************************************************************************/
 static void tegra_pwr_domain_off(const psci_power_state_t *target_state)
 {
@@ -268,6 +278,7 @@
 static plat_psci_ops_t tegra_plat_psci_ops = {
 	.cpu_standby			= tegra_cpu_standby,
 	.pwr_domain_on			= tegra_pwr_domain_on,
+	.pwr_domain_off_early		= tegra_pwr_domain_off_early,
 	.pwr_domain_off			= tegra_pwr_domain_off,
 	.pwr_domain_suspend_pwrdown_early = tegra_pwr_domain_suspend_pwrdown_early,
 	.pwr_domain_suspend		= tegra_pwr_domain_suspend,
diff --git a/plat/nvidia/tegra/include/platform_def.h b/plat/nvidia/tegra/include/platform_def.h
index 84b3297..958a3f9 100644
--- a/plat/nvidia/tegra/include/platform_def.h
+++ b/plat/nvidia/tegra/include/platform_def.h
@@ -41,8 +41,6 @@
 #define PLATFORM_STACK_SIZE 		U(0x400)
 #endif
 
-#define TEGRA_PRIMARY_CPU		U(0x0)
-
 #define PLAT_MAX_PWR_LVL		MPIDR_AFFLVL2
 #define PLATFORM_CORE_COUNT		(PLATFORM_CLUSTER_COUNT * \
 					 PLATFORM_MAX_CPUS_PER_CLUSTER)
diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h
index cc2ad86..71bea08 100644
--- a/plat/nvidia/tegra/include/tegra_private.h
+++ b/plat/nvidia/tegra/include/tegra_private.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2020-2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -98,6 +98,9 @@
 int32_t tegra_fiq_get_intr_context(void);
 void tegra_fiq_set_ns_entrypoint(uint64_t entrypoint);
 
+/* Declarations for tegra_helpers.S */
+bool plat_is_my_cpu_primary(void);
+
 /* Declarations for tegra_security.c */
 void tegra_security_setup(void);
 void tegra_security_setup_videomem(uintptr_t base, uint64_t size);
@@ -109,6 +112,7 @@
 int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state);
 int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state);
 int32_t tegra_soc_pwr_domain_on(u_register_t mpidr);
+int32_t tegra_soc_pwr_domain_off_early(const psci_power_state_t *target_state);
 int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state);
 int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state);
 int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state);
diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
index af4182e..8f88e28 100644
--- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
@@ -433,6 +433,16 @@
 	return PSCI_E_SUCCESS;
 }
 
+int32_t tegra_soc_pwr_domain_off_early(const psci_power_state_t *target_state)
+{
+	/* Do not power off the boot CPU */
+	if (plat_is_my_cpu_primary()) {
+		return PSCI_E_DENIED;
+	}
+
+	return PSCI_E_SUCCESS;
+}
+
 int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
 {
 	uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) & (uint64_t)MIDR_IMPL_MASK;
diff --git a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
index 41a85ee..83d815a 100644
--- a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
@@ -463,6 +463,16 @@
 	return PSCI_E_SUCCESS;
 }
 
+int32_t tegra_soc_pwr_domain_off_early(const psci_power_state_t *target_state)
+{
+	/* Do not power off the boot CPU */
+	if (plat_is_my_cpu_primary()) {
+		return PSCI_E_DENIED;
+	}
+
+	return PSCI_E_SUCCESS;
+}
+
 int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
 {
 	uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
diff --git a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
index 7f73ea5..2ec044c 100644
--- a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
@@ -575,6 +575,16 @@
 	return PSCI_E_SUCCESS;
 }
 
+int32_t tegra_soc_pwr_domain_off_early(const psci_power_state_t *target_state)
+{
+	/* Do not power off the boot CPU */
+	if (plat_is_my_cpu_primary()) {
+		return PSCI_E_DENIED;
+	}
+
+	return PSCI_E_SUCCESS;
+}
+
 int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
 {
 	tegra_fc_cpu_off(read_mpidr() & MPIDR_CPU_MASK);
diff --git a/plat/nxp/common/fip_handler/ddr_fip/ddr_fip_io.mk b/plat/nxp/common/fip_handler/ddr_fip/ddr_fip_io.mk
index 7d673ba..36c07b7 100644
--- a/plat/nxp/common/fip_handler/ddr_fip/ddr_fip_io.mk
+++ b/plat/nxp/common/fip_handler/ddr_fip/ddr_fip_io.mk
@@ -1,5 +1,6 @@
 #
 # Copyright 2020 NXP
+# Copyright (c) 2023, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -22,8 +23,6 @@
 
 DDR_FIP_IO_SOURCES	+= $(DDR_FIP_IO_STORAGE_PATH)/ddr_io_storage.c
 
-$(shell cp tools/nxp/plat_fiptool/plat_fiptool.mk ${PLAT_DIR})
-
 ifeq (${BL_COMM_DDR_FIP_IO_NEEDED},yes)
 BL_COMMON_SOURCES	+= ${DDR_FIP_IO_SOURCES}
 else
diff --git a/plat/nxp/common/fip_handler/fuse_fip/fuse.mk b/plat/nxp/common/fip_handler/fuse_fip/fuse.mk
index d8f5ae6..4e84d02 100644
--- a/plat/nxp/common/fip_handler/fuse_fip/fuse.mk
+++ b/plat/nxp/common/fip_handler/fuse_fip/fuse.mk
@@ -1,5 +1,6 @@
 #
 # Copyright 2018-2020 NXP
+# Copyright (c) 2023, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -29,8 +30,6 @@
 
 ifeq (${FUSE_PROV_FILE},)
 
-$(shell cp tools/nxp/plat_fiptool/plat_fiptool.mk ${PLAT_DIR})
-
 else
 ifeq (${TRUSTED_BOARD_BOOT},1)
 FUSE_PROV_FILE_SB = $(notdir ${FUSE_PROV_FILE})_prov.sb
diff --git a/plat/qemu/common/qemu_common.c b/plat/qemu/common/qemu_common.c
index 935ba7a..9aec213 100644
--- a/plat/qemu/common/qemu_common.c
+++ b/plat/qemu/common/qemu_common.c
@@ -1,6 +1,6 @@
 
 /*
- * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -162,3 +162,14 @@
 	return 0;
 }
 #endif
+
+#if defined(SPD_spmd) && (SPMD_SPM_AT_SEL2 == 1)
+/*
+ * A dummy implementation of the platform handler for Group0 secure interrupt.
+ */
+int plat_spmd_handle_group0_interrupt(uint32_t intid)
+{
+	(void)intid;
+	return -1;
+}
+#endif /*defined(SPD_spmd) && (SPMD_SPM_AT_SEL2 == 1)*/
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index 1d93983..55423ae 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -73,6 +73,9 @@
 endif
 endif
 
+PKA_USE_NIST_P256	?=	0
+PKA_USE_BRAINPOOL_P256T1 ?=	0
+
 ifeq ($(AARCH32_SP),sp_min)
 # Disable Neon support: sp_min runtime may conflict with non-secure world
 TF_CFLAGS		+=	-mfloat-abi=soft
@@ -158,7 +161,6 @@
 	$(sort \
 		PKA_USE_BRAINPOOL_P256T1 \
 		PKA_USE_NIST_P256 \
-		PLAT_TBBR_IMG_DEF \
 		STM32MP_CRYPTO_ROM_LIB \
 		STM32MP_DDR_32BIT_INTERFACE \
 		STM32MP_DDR_DUAL_AXI_PORT \
diff --git a/plat/xilinx/common/include/plat_startup.h b/plat/xilinx/common/include/plat_startup.h
index ae9d52a..ed3946f 100644
--- a/plat/xilinx/common/include/plat_startup.h
+++ b/plat/xilinx/common/include/plat_startup.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
- * Copyright (C) 2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/xilinx/versal/aarch64/versal_common.c b/plat/xilinx/versal/aarch64/versal_common.c
index 0c8ee1e..88da279 100644
--- a/plat/xilinx/versal/aarch64/versal_common.c
+++ b/plat/xilinx/versal/aarch64/versal_common.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
- * Copyright (C) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/xilinx/versal_net/aarch64/versal_net_common.c b/plat/xilinx/versal_net/aarch64/versal_net_common.c
index 253c382..1a57330 100644
--- a/plat/xilinx/versal_net/aarch64/versal_net_common.c
+++ b/plat/xilinx/versal_net/aarch64/versal_net_common.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
- * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/xilinx/versal_net/aarch64/versal_net_helpers.S b/plat/xilinx/versal_net/aarch64/versal_net_helpers.S
index bbd937b..e1e2317 100644
--- a/plat/xilinx/versal_net/aarch64/versal_net_helpers.S
+++ b/plat/xilinx/versal_net/aarch64/versal_net_helpers.S
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
- * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/xilinx/versal_net/bl31_versal_net_setup.c b/plat/xilinx/versal_net/bl31_versal_net_setup.c
index 48be081..ae9dfe8 100644
--- a/plat/xilinx/versal_net/bl31_versal_net_setup.c
+++ b/plat/xilinx/versal_net/bl31_versal_net_setup.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
- * Copyright (C) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/xilinx/versal_net/include/plat_ipi.h b/plat/xilinx/versal_net/include/plat_ipi.h
index 5ac611c..30c51b5 100644
--- a/plat/xilinx/versal_net/include/plat_ipi.h
+++ b/plat/xilinx/versal_net/include/plat_ipi.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2022, Xilinx, Inc. All rights reserved.
- * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/xilinx/versal_net/include/plat_pm_common.h b/plat/xilinx/versal_net/include/plat_pm_common.h
index ad7b40f..6485df7 100644
--- a/plat/xilinx/versal_net/include/plat_pm_common.h
+++ b/plat/xilinx/versal_net/include/plat_pm_common.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2022, Xilinx, Inc. All rights reserved.
- * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/xilinx/versal_net/include/versal_net_def.h b/plat/xilinx/versal_net/include/versal_net_def.h
index ec36e55..8fb71f9 100644
--- a/plat/xilinx/versal_net/include/versal_net_def.h
+++ b/plat/xilinx/versal_net/include/versal_net_def.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
- * Copyright (C) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/xilinx/versal_net/plat_psci_pm.c b/plat/xilinx/versal_net/plat_psci_pm.c
index 9d401a5..d39fc2e 100644
--- a/plat/xilinx/versal_net/plat_psci_pm.c
+++ b/plat/xilinx/versal_net/plat_psci_pm.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2022, Xilinx, Inc. All rights reserved.
- * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/xilinx/versal_net/plat_topology.c b/plat/xilinx/versal_net/plat_topology.c
index c74faf2..ee756c4 100644
--- a/plat/xilinx/versal_net/plat_topology.c
+++ b/plat/xilinx/versal_net/plat_topology.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
- * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/xilinx/versal_net/sip_svc_setup.c b/plat/xilinx/versal_net/sip_svc_setup.c
index cc8306e..f6240f3 100644
--- a/plat/xilinx/versal_net/sip_svc_setup.c
+++ b/plat/xilinx/versal_net/sip_svc_setup.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
- * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/xilinx/versal_net/versal_net_gicv3.c b/plat/xilinx/versal_net/versal_net_gicv3.c
index e7d8e75..2fdef12 100644
--- a/plat/xilinx/versal_net/versal_net_gicv3.c
+++ b/plat/xilinx/versal_net/versal_net_gicv3.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
- * Copyright (C) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/xilinx/versal_net/versal_net_ipi.c b/plat/xilinx/versal_net/versal_net_ipi.c
index 26ded89..cf897e3 100644
--- a/plat/xilinx/versal_net/versal_net_ipi.c
+++ b/plat/xilinx/versal_net/versal_net_ipi.c
@@ -1,6 +1,6 @@
 /*
- * Copyright (C) 2022, Xilinx, Inc. All rights reserved.
- * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index 0e1899e..80b506b 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -249,6 +249,74 @@
 	SMC_RET0(&ctx->cpu_ctx);
 }
 
+/*******************************************************************************
+ * spmd_group0_interrupt_handler_nwd
+ * Group0 secure interrupt in the normal world are trapped to EL3. Delegate the
+ * handling of the interrupt to the platform handler, and return only upon
+ * successfully handling the Group0 interrupt.
+ ******************************************************************************/
+static uint64_t spmd_group0_interrupt_handler_nwd(uint32_t id,
+						  uint32_t flags,
+						  void *handle,
+						  void *cookie)
+{
+	uint32_t intid;
+
+	/* Sanity check the security state when the exception was generated. */
+	assert(get_interrupt_src_ss(flags) == NON_SECURE);
+
+	/* Sanity check the pointer to this cpu's context. */
+	assert(handle == cm_get_context(NON_SECURE));
+
+	assert(id == INTR_ID_UNAVAILABLE);
+
+	assert(plat_ic_get_pending_interrupt_type() == INTR_TYPE_EL3);
+
+	intid = plat_ic_get_pending_interrupt_id();
+
+	if (plat_spmd_handle_group0_interrupt(intid) < 0) {
+		ERROR("Group0 interrupt %u not handled\n", intid);
+		panic();
+	}
+
+	return 0U;
+}
+
+/*******************************************************************************
+ * spmd_handle_group0_intr_swd
+ * SPMC delegates handling of Group0 secure interrupt to EL3 firmware using
+ * FFA_EL3_INTR_HANDLE SMC call. Further, SPMD delegates the handling of the
+ * interrupt to the platform handler, and returns only upon successfully
+ * handling the Group0 interrupt.
+ ******************************************************************************/
+static uint64_t spmd_handle_group0_intr_swd(void *handle)
+{
+	uint32_t intid;
+
+	/* Sanity check the pointer to this cpu's context */
+	assert(handle == cm_get_context(SECURE));
+
+	assert(plat_ic_get_pending_interrupt_type() == INTR_TYPE_EL3);
+
+	intid = plat_ic_get_pending_interrupt_id();
+
+	/*
+	 * TODO: Currently due to a limitation in SPMD implementation, the
+	 * platform handler is expected to not delegate handling to NWd while
+	 * processing Group0 secure interrupt.
+	 */
+	if (plat_spmd_handle_group0_interrupt(intid) < 0) {
+		/* Group0 interrupt was not handled by the platform. */
+		ERROR("Group0 interrupt %u not handled\n", intid);
+		panic();
+	}
+
+	/* Return success. */
+	SMC_RET8(handle, FFA_SUCCESS_SMC32, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+		 FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+		 FFA_PARAM_MBZ);
+}
+
 #if ENABLE_RME && SPMD_SPM_AT_SEL2 && !RESET_TO_BL31
 static int spmd_dynamic_map_mem(uintptr_t base_addr, size_t size,
 				 unsigned int attr, uintptr_t *align_addr,
@@ -492,6 +560,16 @@
 		panic();
 	}
 
+	/*
+	 * Register an interrupt handler routing Group0 interrupts to SPMD
+	 * while the NWd is running.
+	 */
+	rc = register_interrupt_type_handler(INTR_TYPE_EL3,
+					     spmd_group0_interrupt_handler_nwd,
+					     flags);
+	if (rc != 0) {
+		panic();
+	}
 	return 0;
 }
 
@@ -1089,6 +1167,12 @@
 					handle, flags);
 		break; /* Not reached */
 #endif
+	case FFA_EL3_INTR_HANDLE:
+		if (secure_origin) {
+			return spmd_handle_group0_intr_swd(handle);
+		} else {
+			return spmd_ffa_error_return(handle, FFA_ERROR_DENIED);
+		}
 	default:
 		WARN("SPM: Unsupported call 0x%08x\n", smc_fid);
 		return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
diff --git a/services/std_svc/spmd/spmd_private.h b/services/std_svc/spmd/spmd_private.h
index d21a622..ff6942e 100644
--- a/services/std_svc/spmd/spmd_private.h
+++ b/services/std_svc/spmd/spmd_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -93,6 +93,13 @@
 int spmd_pm_secondary_ep_register(uintptr_t entry_point);
 bool spmd_check_address_in_binary_image(uint64_t address);
 
+/*
+ * Platform hook in EL3 firmware to handle for Group0 secure interrupt.
+ * Return values:
+ *  0 = success
+ *  otherwise it returns a negative value
+ */
+int plat_spmd_handle_group0_interrupt(uint32_t id);
 #endif /* __ASSEMBLER__ */
 
 #endif /* SPMD_PRIVATE_H */
diff --git a/tools/fiptool/Makefile b/tools/fiptool/Makefile
index ac262cd..2ebee33 100644
--- a/tools/fiptool/Makefile
+++ b/tools/fiptool/Makefile
@@ -54,10 +54,13 @@
 ifneq (${PLAT},)
 TF_PLATFORM_ROOT	:=	../../plat/
 include ${MAKE_HELPERS_DIRECTORY}plat_helpers.mk
-PLAT_FIPTOOL_HELPER_MK := ${PLAT_DIR}/plat_fiptool.mk
+COMBINED_PATH_FRAG := plat_fiptool/
+PLAT_FIPTOOL_HELPER_MK := $(foreach path_frag,$(subst /, ,$(patsubst ../../plat/%/,%,${PLAT_DIR})),\
+			  $(eval COMBINED_PATH_FRAG := ${COMBINED_PATH_FRAG}/${path_frag})\
+			  $(wildcard ${COMBINED_PATH_FRAG}/plat_fiptool.mk))
 endif
 
-ifneq (,$(wildcard ${PLAT_FIPTOOL_HELPER_MK}))
+ifneq (,$(wildcard $(lastword ${PLAT_FIPTOOL_HELPER_MK})))
 include ${PLAT_FIPTOOL_HELPER_MK}
 endif
 
diff --git a/plat/arm/board/tc/plat_def_uuid_config.c b/tools/fiptool/plat_fiptool/arm/board/tc/plat_def_uuid_config.c
similarity index 100%
rename from plat/arm/board/tc/plat_def_uuid_config.c
rename to tools/fiptool/plat_fiptool/arm/board/tc/plat_def_uuid_config.c
diff --git a/tools/fiptool/plat_fiptool/arm/board/tc/plat_fiptool.mk b/tools/fiptool/plat_fiptool/arm/board/tc/plat_fiptool.mk
new file mode 100644
index 0000000..70ccfc5
--- /dev/null
+++ b/tools/fiptool/plat_fiptool/arm/board/tc/plat_fiptool.mk
@@ -0,0 +1,12 @@
+#
+# Copyright (c) 2021, NXP. All rights reserved.
+# Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+INCLUDE_PATHS += -I./ \
+		 -I../../plat/arm/board/tc
+
+HOSTCCFLAGS += -DPLAT_DEF_FIP_UUID
+OBJECTS += plat_fiptool/arm/board/tc/plat_def_uuid_config.o
diff --git a/tools/nxp/plat_fiptool/plat_def_uuid_config.c b/tools/fiptool/plat_fiptool/nxp/plat_def_uuid_config.c
similarity index 100%
rename from tools/nxp/plat_fiptool/plat_def_uuid_config.c
rename to tools/fiptool/plat_fiptool/nxp/plat_def_uuid_config.c
diff --git a/tools/nxp/plat_fiptool/plat_fiptool.mk b/tools/fiptool/plat_fiptool/nxp/plat_fiptool.mk
similarity index 80%
rename from tools/nxp/plat_fiptool/plat_fiptool.mk
rename to tools/fiptool/plat_fiptool/nxp/plat_fiptool.mk
index ca2962a..6d7b07b 100644
--- a/tools/nxp/plat_fiptool/plat_fiptool.mk
+++ b/tools/fiptool/plat_fiptool/nxp/plat_fiptool.mk
@@ -1,5 +1,6 @@
 #
 # Copyright (c) 2021, NXP. All rights reserved.
+# Copyright (c) 2023, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -9,7 +10,7 @@
 # in the plat_def_toc_entries[].
 PLAT_DEF_UUID_CONFIG_FILE_NAME	:= plat_def_uuid_config
 
-PLAT_DEF_UUID_CONFIG_FILE_PATH := ../nxp/plat_fiptool
+PLAT_DEF_UUID_CONFIG_FILE_PATH := plat_fiptool/nxp/
 
 PLAT_DEF_OID := yes
 PLAT_DEF_UUID := yes
@@ -18,8 +19,6 @@
 
 INCLUDE_PATHS += -I${PLAT_DEF_UUID_OID_CONFIG_PATH} \
 		 -I./
-# Clean the stale object file.
-$(shell rm ${PLAT_DEF_UUID_CONFIG_FILE_PATH}/${PLAT_DEF_UUID_CONFIG_FILE_NAME}.o)
 
 ifeq (${PLAT_DEF_OID},yes)
 HOSTCCFLAGS += -DPLAT_DEF_OID
diff --git a/plat/st/stm32mp1/plat_def_uuid_config.c b/tools/fiptool/plat_fiptool/st/stm32mp1/plat_def_uuid_config.c
similarity index 100%
rename from plat/st/stm32mp1/plat_def_uuid_config.c
rename to tools/fiptool/plat_fiptool/st/stm32mp1/plat_def_uuid_config.c
diff --git a/plat/st/stm32mp1/plat_fiptool.mk b/tools/fiptool/plat_fiptool/st/stm32mp1/plat_fiptool.mk
similarity index 87%
rename from plat/st/stm32mp1/plat_fiptool.mk
rename to tools/fiptool/plat_fiptool/st/stm32mp1/plat_fiptool.mk
index 00570c2..1ba47c1 100644
--- a/plat/st/stm32mp1/plat_fiptool.mk
+++ b/tools/fiptool/plat_fiptool/st/stm32mp1/plat_fiptool.mk
@@ -16,7 +16,7 @@
 ifeq (${PLAT_DEF_UUID},yes)
 HOSTCCFLAGS += -DPLAT_DEF_FIP_UUID
 
-${PLAT_DEF_UUID_FILE_NAME}.o: ${PLAT_DIR}${PLAT_DEF_UUID_FILE_NAME}.c
+${PLAT_DEF_UUID_FILE_NAME}.o: plat_fiptool/st/stm32mp1/${PLAT_DEF_UUID_FILE_NAME}.c
 	${HOSTCC} -c ${CPPFLAGS} ${HOSTCCFLAGS} ${INCLUDE_PATHS} $< -o $@
 
 PLAT_OBJECTS += ${PLAT_DEF_UUID_FILE_NAME}.o