Merge changes from topic "deprecate_io_drivers" into integration

* changes:
  refactor(st): remove unused io_mmc driver
  docs: deprecate io_dummy driver
diff --git a/Makefile b/Makefile
index c4350dc..f4d623e 100644
--- a/Makefile
+++ b/Makefile
@@ -350,27 +350,53 @@
 # General warnings
 WARNINGS		:=	-Wall -Wmissing-include-dirs -Wunused	\
 				-Wdisabled-optimization -Wvla -Wshadow	\
-				-Wno-unused-parameter -Wredundant-decls
+				-Wredundant-decls
+# stricter warnings
+WARNINGS		+=	-Wextra -Wno-trigraphs
+# too verbose for generic build
+WARNINGS		+=	-Wno-missing-field-initializers \
+				-Wno-type-limits -Wno-sign-compare \
+# on clang this flag gets reset if -Wextra is set after it. No difference on gcc
+WARNINGS		+=	-Wno-unused-parameter
 
 # Additional warnings
-# Level 1
-WARNING1 := -Wextra
-WARNING1 += -Wmissing-format-attribute
-WARNING1 += -Wmissing-prototypes
-WARNING1 += -Wold-style-definition
+# Level 1 - infrequent warnings we should have none of
+# full -Wextra
+WARNING1 += -Wsign-compare
+WARNING1 += -Wtype-limits
+WARNING1 += -Wmissing-field-initializers
 
-# Level 2
-WARNING2 := -Waggregate-return
-WARNING2 += -Wcast-align
-WARNING2 += -Wnested-externs
+# Level 2 - problematic warnings that we want
+# zlib, compiler-rt, coreboot, and mbdedtls blow up with these
+# TODO: disable just for them and move into default build
+WARNING2 += -Wold-style-definition
+WARNING2 += -Wmissing-prototypes
+WARNING2 += -Wmissing-format-attribute
+# TF-A aims to comply with this eventually. Effort too large at present
+WARNING2 += -Wundef
+# currently very involved and many platforms set this off
+WARNING2 += -Wunused-const-variable=2
 
+# Level 3 - very pedantic, frequently ignored
 WARNING3 := -Wbad-function-cast
+WARNING3 += -Waggregate-return
+WARNING3 += -Wnested-externs
+WARNING3 += -Wcast-align
 WARNING3 += -Wcast-qual
 WARNING3 += -Wconversion
 WARNING3 += -Wpacked
 WARNING3 += -Wpointer-arith
 WARNING3 += -Wswitch-default
 
+# Setting W is quite verbose and most warnings will be pre-existing issues
+# outside of the contributor's control. Don't fail the build on them so warnings
+# can be seen and hopefully addressed
+ifdef W
+ifneq (${W},0)
+E	 ?= 0
+endif
+endif
+
 ifeq (${W},1)
 WARNINGS += $(WARNING1)
 else ifeq (${W},2)
diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S
index 614ea71..0c60859 100644
--- a/bl31/aarch64/runtime_exceptions.S
+++ b/bl31/aarch64/runtime_exceptions.S
@@ -10,6 +10,7 @@
 #include <asm_macros.S>
 #include <bl31/ea_handle.h>
 #include <bl31/interrupt_mgmt.h>
+#include <bl31/sync_handle.h>
 #include <common/runtime_svc.h>
 #include <context.h>
 #include <el3_common_macros.S>
@@ -82,31 +83,6 @@
 1:
 #else
 	/*
-	 * For SoCs which do not implement RAS, use DSB as a barrier to
-	 * synchronize pending external aborts.
-	 */
-	dsb	sy
-
-	/* Unmask the SError interrupt */
-	msr	daifclr, #DAIF_ABT_BIT
-
-	/* Use ISB for the above unmask operation to take effect immediately */
-	isb
-
-	/*
-	 * Refer Note 1. No need to restore X30 as both handle_sync_exception
-	 * and handle_interrupt_exception macro which follow this macro modify
-	 * X30 anyway.
-	 */
-	str	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
-	mov 	x30, #1
-	str	x30, [sp, #CTX_EL3STATE_OFFSET + CTX_IS_IN_EL3]
-	dmb	sy
-#endif
-	.endm
-
-#if !RAS_EXTENSION
-	/*
 	 * Note 1: The explicit DSB at the entry of various exception vectors
 	 * for handling exceptions from lower ELs can inadvertently trigger an
 	 * SError exception in EL3 due to pending asynchronous aborts in lower
@@ -120,13 +96,9 @@
 	 * flag execute without causing further exceptions.
 	 */
 
-	/* ---------------------------------------------------------------------
-	 * This macro handles Asynchronous External Aborts.
-	 * ---------------------------------------------------------------------
-	 */
-	.macro	handle_async_ea
 	/*
-	 * Use a barrier to synchronize pending external aborts.
+	 * For SoCs which do not implement RAS, use DSB as a barrier to
+	 * synchronize pending external aborts.
 	 */
 	dsb	sy
 
@@ -136,33 +108,16 @@
 	/* Use ISB for the above unmask operation to take effect immediately */
 	isb
 
-	/* Refer Note 1 */
+	/*
+	 * Refer Note 1.
+	 * No need to restore X30 as macros following this modify x30 anyway.
+	 */
 	str	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
 	mov 	x30, #1
 	str	x30, [sp, #CTX_EL3STATE_OFFSET + CTX_IS_IN_EL3]
 	dmb	sy
-
-	b	handle_lower_el_async_ea
-	.endm
-
-	/*
-	 * This macro checks if the exception was taken due to SError in EL3 or
-	 * because of pending asynchronous external aborts from lower EL that got
-	 * triggered due to explicit synchronization in EL3. Refer Note 1.
-	 */
-	.macro check_if_serror_from_EL3
-	/* Assumes SP_EL3 on entry */
-	str	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
-	ldr	x30, [sp, #CTX_EL3STATE_OFFSET + CTX_IS_IN_EL3]
-	cbnz	x30, exp_from_EL3
-
-	/* Handle asynchronous external abort from lower EL */
-	b	handle_lower_el_async_ea
-
-exp_from_EL3:
-	/* Jump to plat_handle_el3_ea which does not return */
-	.endm
 #endif
+	.endm
 
 	/* ---------------------------------------------------------------------
 	 * This macro handles Synchronous exceptions.
@@ -191,7 +146,10 @@
 	b.eq	smc_handler32
 
 	cmp	x30, #EC_AARCH64_SMC
-	b.eq	smc_handler64
+	b.eq	sync_handler64
+
+	cmp	x30, #EC_AARCH64_SYS
+	b.eq	sync_handler64
 
 	/* Synchronous exceptions other than the above are assumed to be EA */
 	ldr	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
@@ -352,7 +310,19 @@
 
 vector_entry serror_sp_elx
 #if !RAS_EXTENSION
-	check_if_serror_from_EL3
+	/*
+	 * This will trigger if the exception was taken due to SError in EL3 or
+	 * because of pending asynchronous external aborts from lower EL that got
+	 * triggered due to explicit synchronization in EL3. Refer Note 1.
+	 */
+	/* Assumes SP_EL3 on entry */
+	str	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
+	ldr	x30, [sp, #CTX_EL3STATE_OFFSET + CTX_IS_IN_EL3]
+	cbnz	x30, 1f
+
+	/* Handle asynchronous external abort from lower EL */
+	b	handle_lower_el_async_ea
+1:
 #endif
 	no_ret	plat_handle_el3_ea
 end_vector_entry serror_sp_elx
@@ -391,7 +361,8 @@
 	msr	daifclr, #DAIF_ABT_BIT
 	b	enter_lower_el_async_ea
 #else
-	handle_async_ea
+	check_and_unmask_ea
+	b handle_lower_el_async_ea
 #endif
 end_vector_entry serror_aarch64
 
@@ -429,7 +400,8 @@
 	msr	daifclr, #DAIF_ABT_BIT
 	b	enter_lower_el_async_ea
 #else
-	handle_async_ea
+	check_and_unmask_ea
+	b handle_lower_el_async_ea
 #endif
 end_vector_entry serror_aarch32
 
@@ -452,12 +424,12 @@
 	 * Note that x30 has been explicitly saved and can be used here
 	 * ---------------------------------------------------------------------
 	 */
-func smc_handler
+func sync_exception_handler
 smc_handler32:
 	/* Check whether aarch32 issued an SMC64 */
 	tbnz	x0, #FUNCID_CC_SHIFT, smc_prohibited
 
-smc_handler64:
+sync_handler64:
 	/* NOTE: The code below must preserve x0-x4 */
 
 	/*
@@ -504,6 +476,12 @@
 	/* Load SCR_EL3 */
 	mrs	x18, scr_el3
 
+	/* check for system register traps */
+	mrs	x16, esr_el3
+	ubfx	x17, x16, #ESR_EC_SHIFT, #ESR_EC_LENGTH
+	cmp	x17, #EC_AARCH64_SYS
+	b.eq	sysreg_handler64
+
 	/* Clear flag register */
 	mov	x7, xzr
 
@@ -569,6 +547,32 @@
 
 	b	el3_exit
 
+sysreg_handler64:
+	mov	x0, x16		/* ESR_EL3, containing syndrome information */
+	mov	x1, x6		/* lower EL's context */
+	mov	x19, x6		/* save context pointer for after the call */
+	mov	sp, x12		/* EL3 runtime stack, as loaded above */
+
+	/* int handle_sysreg_trap(uint64_t esr_el3, cpu_context_t *ctx); */
+	bl	handle_sysreg_trap
+	/*
+	 * returns:
+	 *   -1: unhandled trap, panic
+	 *    0: handled trap, return to the trapping instruction (repeating it)
+	 *    1: handled trap, return to the next instruction
+	 */
+
+	tst	w0, w0
+	b.mi	do_panic	/* negative return value: panic */
+	b.eq	1f		/* zero: do not change ELR_EL3 */
+
+	/* advance the PC to continue after the instruction */
+	ldr	x1, [x19, #CTX_EL3STATE_OFFSET + CTX_ELR_EL3]
+	add	x1, x1, #4
+	str	x1, [x19, #CTX_EL3STATE_OFFSET + CTX_ELR_EL3]
+1:
+	b	el3_exit
+
 smc_unknown:
 	/*
 	 * Unknown SMC call. Populate return value with SMC_UNK and call
@@ -593,7 +597,7 @@
 	msr	spsel, #MODE_SP_ELX
 	no_ret	report_unhandled_exception
 #endif
-endfunc smc_handler
+endfunc sync_exception_handler
 
 	/* ---------------------------------------------------------------------
 	 * The following code handles exceptions caused by BRK instructions.
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index 4c93a55..ac15f9f 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -42,6 +42,7 @@
 				bl31/aarch64/ea_delegate.S			\
 				bl31/aarch64/runtime_exceptions.S		\
 				bl31/bl31_context_mgmt.c			\
+				bl31/bl31_traps.c				\
 				common/runtime_svc.c				\
 				lib/cpus/aarch64/dsu_helpers.S			\
 				plat/common/aarch64/platform_mp_stack.S		\
diff --git a/bl31/bl31_traps.c b/bl31/bl31_traps.c
new file mode 100644
index 0000000..b12185d
--- /dev/null
+++ b/bl31/bl31_traps.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2022, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Dispatch synchronous system register traps from lower ELs.
+ */
+
+#include <bl31/sync_handle.h>
+#include <context.h>
+
+int handle_sysreg_trap(uint64_t esr_el3, cpu_context_t *ctx)
+{
+	switch (esr_el3 & ISS_SYSREG_OPCODE_MASK) {
+#if ENABLE_FEAT_RNG_TRAP
+	case ISS_SYSREG_OPCODE_RNDR:
+	case ISS_SYSREG_OPCODE_RNDRRS:
+		return plat_handle_rng_trap(esr_el3, ctx);
+#endif
+	default:
+		return TRAP_RET_UNHANDLED;
+	}
+}
diff --git a/changelog.yaml b/changelog.yaml
index cfb2bb5..1e1f0a1 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+# Copyright (c) 2021-2023, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -744,6 +744,9 @@
           - title: mbedTLS
             scope: mbedtls
 
+      - title: Console
+        scope: console
+
       - title: Generic Clock
         scope: clk
 
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index 9a2ae73..914c959 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -506,8 +506,10 @@
 
 Arm Total Compute platform port
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:|M|: Anders Dellien <anders.dellien@arm.com>
-:|G|: `andersdellien-arm`_
+:|M|: Vishnu Banavath <vishnu.banavath@arm.com>
+:|G|: `vishnu-banavath`_
+:|M|: Rupinderjit Singh <rupinderjit.singh@arm.com>
+:|G|: `rupsin01`_
 :|F|: plat/arm/board/tc
 
 HiSilicon HiKey and HiKey960 platform ports
@@ -956,5 +958,6 @@
 .. _marcbonnici: https://github.com/marcbonnici
 .. _jayanthchidanand-arm: https://github.com/jayanthchidanand-arm
 .. _bytefire: https://github.com/bytefire
+.. _rupsin01: https://github.com/rupsin01
 
 .. _Project Maintenance Process: https://developer.trustedfirmware.org/w/collaboration/project-maintenance-process/
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index c07a0aa..8a8445d 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -317,6 +317,10 @@
    CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1, and r1p2, and
    it is still open.
 
+-  ``ERRATA_A78_2772019``: This applies errata 2772019 workaround to Cortex-A78
+   CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1, and r1p2, and
+   it is still open.
+
 For Cortex-A78 AE, the following errata build flags are defined :
 
 - ``ERRATA_A78_AE_1941500`` : This applies errata 1941500 workaround to
@@ -460,6 +464,10 @@
    CPU. This needs to be enabled for revisions r0p0, r1p0 and r1p1 of the CPU.
    It is still open.
 
+-  ``ERRATA_V1_2743093``: This applies errata 2743093 workaround to Neoverse-V1
+   CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1 and r1p2 of the
+   CPU. It is still open.
+
 For Cortex-A710, the following errata build flags are defined :
 
 -  ``ERRATA_A710_1987031``: This applies errata 1987031 workaround to
@@ -503,8 +511,8 @@
    of the CPU and is fixed in r2p1.
 
 -  ``ERRATA_A710_2282622``: This applies errata 2282622 workaround to
-   Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0
-   of the CPU and is fixed in r2p1.
+   Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0, r2p0 and
+   r2p1 of the CPU and is still open.
 
 - ``ERRATA_A710_2291219``: This applies errata 2291219 workaround to
    Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0
@@ -566,6 +574,10 @@
    CPU. This needs to be enabled for revision r0p0 of the CPU, it is fixed in
    r0p1.
 
+-  ``ERRATA_N2_2743089``: This applies errata 2743089 workaround to Neoverse-N2
+   CPU. This needs to be enabled for revisions r0p0, r0p1 and r0p2. It is fixed
+   in r0p3.
+
 For Cortex-X2, the following errata build flags are defined :
 
 -  ``ERRATA_X2_2002765``: This applies errata 2002765 workaround to Cortex-X2
@@ -579,29 +591,33 @@
 -  ``ERRATA_X2_2083908``: This applies errata 2083908 workaround to Cortex-X2
    CPU. This needs to be enabled for revision r2p0 of the CPU, it is still open.
 
--  ``ERRATA_X2_2017096``: This applies errata 2017096 workaround to
-   Cortex-X2 CPU. This needs to be enabled only for revisions r0p0, r1p0 and
-   r2p0 of the CPU, it is fixed in r2p1.
+-  ``ERRATA_X2_2017096``: This applies errata 2017096 workaround to Cortex-X2
+   CPU. This needs to be enabled only for revisions r0p0, r1p0 and r2p0 of the
+   CPU, it is fixed in r2p1.
 
--  ``ERRATA_X2_2081180``: This applies errata 2081180 workaround to
-   Cortex-X2 CPU. This needs to be enabled only for revisions r0p0, r1p0 and
-   r2p0 of the CPU, it is fixed in r2p1.
+-  ``ERRATA_X2_2081180``: This applies errata 2081180 workaround to Cortex-X2
+   CPU. This needs to be enabled only for revisions r0p0, r1p0 and r2p0 of the
+   CPU, it is fixed in r2p1.
 
--  ``ERRATA_X2_2216384``: This applies errata 2216384 workaround to
-   Cortex-X2 CPU. This needs to be enabled only for revisions r0p0, r1p0 and
-   r2p0 of the CPU, it is fixed in r2p1.
+-  ``ERRATA_X2_2216384``: This applies errata 2216384 workaround to Cortex-X2
+   CPU. This needs to be enabled only for revisions r0p0, r1p0 and r2p0 of the
+   CPU, it is fixed in r2p1.
 
--  ``ERRATA_X2_2147715``: This applies errata 2147715 workaround to
-   Cortex-X2 CPU. This needs to be enabled only for revision r2p0 of the CPU,
-   it is fixed in r2p1.
+-  ``ERRATA_X2_2147715``: This applies errata 2147715 workaround to Cortex-X2
+   CPU. This needs to be enabled only for revision r2p0 of the CPU, it is fixed
+   in r2p1.
 
--  ``ERRATA_X2_2371105``: This applies errata 2371105 workaround to
-   Cortex-X2 CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0
-   of the CPU and is fixed in r2p1.
+-  ``ERRATA_X2_2282622``: This applies errata 2282622 workaround to Cortex-X2
+   CPU. This needs to be enabled for revisions r0p0, r1p0, r2p0 and r2p1 of the
+   CPU and is still open.
 
--  ``ERRATA_X2_2768515``: This applies errata 2768515 workaround to
-   Cortex-X2 CPU. This needs to be enabled for revisions r0p0, r1p0, r2p0
-   and r2p1 of the CPU and is still open.
+-  ``ERRATA_X2_2371105``: This applies errata 2371105 workaround to Cortex-X2
+   CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0 of the CPU
+   and is fixed in r2p1.
+
+-  ``ERRATA_X2_2768515``: This applies errata 2768515 workaround to Cortex-X2
+   CPU. This needs to be enabled for revisions r0p0, r1p0, r2p0 and r2p1 of the
+   CPU and is still open.
 
 For Cortex-X3, the following errata build flags are defined :
 
@@ -742,7 +758,7 @@
 
 --------------
 
-*Copyright (c) 2014-2022, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.*
 
 .. _CVE-2017-5715: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715
 .. _CVE-2018-3639: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3639
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index e54ff41..d5ded5e 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -213,6 +213,12 @@
 
 -  ``E``: Boolean option to make warnings into errors. Default is 1.
 
+   When specifying higher warnings levels (``W=1`` and higher), this option
+   defaults to 0. This is done to encourage contributors to use them, as they
+   are expected to produce warnings that would otherwise fail the build. New
+   contributions are still expected to build with ``W=0`` and ``E=1`` (the
+   default).
+
 -  ``EL3_PAYLOAD_BASE``: This option enables booting an EL3 payload instead of
    the normal boot flow. It must specify the entry point address of the EL3
    payload. Please refer to the "Booting an EL3 payload" section for more
@@ -954,6 +960,43 @@
    regrouped and put in the root Makefile. This flag can take the values 0 to 3,
    each level enabling more warning options. Default is 0.
 
+   This option is closely related to the ``E`` option, which enables
+   ``-Werror``.
+
+   - ``W=0`` (default)
+
+     Enables a wide assortment of warnings, most notably ``-Wall`` and
+     ``-Wextra``, as well as various bad practices and things that are likely to
+     result in errors. Includes some compiler specific flags. No warnings are
+     expected at this level for any build.
+
+   - ``W=1``
+
+     Enables warnings we want the generic build to include but are too time
+     consuming to fix at the moment. It re-enables warnings taken out for
+     ``W=0`` builds (a few of the ``-Wextra`` additions). This level is expected
+     to eventually be merged into ``W=0``. Some warnings are expected on some
+     builds, but new contributions should not introduce new ones.
+
+   - ``W=2`` (recommended)
+
+    Enables warnings we want the generic build to include but cannot be enabled
+    due to external libraries. This level is expected to eventually be merged
+    into ``W=0``. Lots of warnings are expected, primarily from external
+    libraries like zlib and compiler-rt, but new controbutions should not
+    introduce new ones.
+
+   - ``W=3``
+
+     Enables warnings that are informative but not necessary and generally too
+     verbose and frequently ignored. A very large number of warnings are
+     expected.
+
+   The exact set of warning flags depends on the compiler and TF-A warning
+   level, however they are all succinctly set in the top-level Makefile. Please
+   refer to the `GCC`_ or `Clang`_ documentation for more information on the
+   individual flags.
+
 -  ``WARMBOOT_ENABLE_DCACHE_EARLY`` : Boolean option to enable D-cache early on
    the CPU after warm boot. This is applicable for platforms which do not
    require interconnect programming to enable cache coherency (eg: single
@@ -1161,3 +1204,5 @@
 .. _DEN0115: https://developer.arm.com/docs/den0115/latest
 .. _PSA FW update specification: https://developer.arm.com/documentation/den0118/a/
 .. _PSA DRTM specification: https://developer.arm.com/documentation/den0113/a
+.. _GCC: https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
+.. _Clang: https://clang.llvm.org/docs/DiagnosticsReference.html
diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst
index aa57e1d..80b72e5 100644
--- a/docs/getting_started/porting-guide.rst
+++ b/docs/getting_started/porting-guide.rst
@@ -2135,7 +2135,7 @@
 
 #. Providing runtime firmware services. Currently, BL31 only implements a
    subset of the Power State Coordination Interface (PSCI) API as a runtime
-   service. See Section 3.3 below for details of porting the PSCI
+   service. See :ref:`psci_in_bl31` below for details of porting the PSCI
    implementation.
 
 #. Optionally passing control to the BL32 image, pre-loaded at a platform-
@@ -2544,6 +2544,8 @@
 This function writes entropy into storage provided by the caller. If no entropy
 is available, it must return false and the storage must not be written.
 
+.. _psci_in_bl31:
+
 Power State Coordination Interface (in BL31)
 --------------------------------------------
 
@@ -3396,6 +3398,39 @@
 The default implementation of this function calls
 ``report_unhandled_exception``.
 
+Function : plat_handle_rng_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 RNDR or RNDRRS registers. It allows
+platforms implementing ``FEAT_RNG_TRAP`` and enabling ``ENABLE_FEAT_RNG_TRAP`` to
+emulate those system registers by returing back some entropy to the lower EL.
+
+The first parameter (``uint64_t esr_el3``) contains the content of the ESR_EL3
+syndrome register, which encodes the instruction that was trapped. The interesting
+information in there is the target register (``get_sysreg_iss_rt()``).
+
+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. Its content can be changed, to put the entropy into the target
+register.
+
+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 FEAT_RNG_TRAP.
+
 Build flags
 -----------
 
diff --git a/docs/process/security-hardening.rst b/docs/process/security-hardening.rst
index 507046f..f9618db 100644
--- a/docs/process/security-hardening.rst
+++ b/docs/process/security-hardening.rst
@@ -131,38 +131,9 @@
   overflows.
 
 - The ``W`` build flag can be used to enable a number of compiler warning
-  options to detect potentially incorrect code.
-
-  - W=0 (default value)
-
-    The ``Wunused`` with ``Wno-unused-parameter``, ``Wdisabled-optimization``
-    and ``Wvla`` flags are enabled.
-
-    The ``Wunused-but-set-variable``, ``Wmaybe-uninitialized`` and
-    ``Wpacked-bitfield-compat`` are GCC specific flags that are also enabled.
-
-  - W=1
-
-    Adds ``Wextra``, ``Wmissing-format-attribute``, ``Wmissing-prototypes``,
-    ``Wold-style-definition`` and ``Wunused-const-variable``.
-
-  - W=2
-
-    Adds ``Waggregate-return``, ``Wcast-align``, ``Wnested-externs``,
-    ``Wshadow``, ``Wlogical-op``.
-
-  - W=3
-
-    Adds ``Wbad-function-cast``, ``Wcast-qual``, ``Wconversion``, ``Wpacked``,
-    ``Wpointer-arith``, ``Wredundant-decls`` and
-    ``Wswitch-default``.
-
-  Refer to the GCC or Clang documentation for more information on the individual
-  options: https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html and
-  https://clang.llvm.org/docs/DiagnosticsReference.html.
-
-  NB: The ``Werror`` flag is enabled by default in TF-A and can be disabled by
-  setting the ``E`` build flag to 0.
+  options to detect potentially incorrect code. TF-A is tested with ``W=0`` but
+  it is recommended to develop against ``W=2`` (which will eventually become the
+  default).
 
 .. rubric:: References
 
diff --git a/docs/security_advisories/index.rst b/docs/security_advisories/index.rst
index b80ba34..c9b0f78 100644
--- a/docs/security_advisories/index.rst
+++ b/docs/security_advisories/index.rst
@@ -14,3 +14,4 @@
    security-advisory-tfv-7.rst
    security-advisory-tfv-8.rst
    security-advisory-tfv-9.rst
+   security-advisory-tfv-10.rst
diff --git a/docs/security_advisories/security-advisory-tfv-10.rst b/docs/security_advisories/security-advisory-tfv-10.rst
new file mode 100644
index 0000000..91dba07
--- /dev/null
+++ b/docs/security_advisories/security-advisory-tfv-10.rst
@@ -0,0 +1,159 @@
+Advisory TFV-10 (CVE-2022-47630)
+================================
+
++----------------+-------------------------------------------------------------+
+| Title          | Incorrect validation of X.509 certificate extensions can    |
+|                | result in an out-of-bounds read.                            |
++================+=============================================================+
+| CVE ID         | `CVE-2022-47630`_                                           |
++----------------+-------------------------------------------------------------+
+| Date           | Reported on 12 Dec 2022                                     |
++----------------+-------------------------------------------------------------+
+| Versions       | v1.2 to v2.8                                                |
+| Affected       |                                                             |
++----------------+-------------------------------------------------------------+
+| Configurations | BL1 and BL2 with Trusted Boot enabled with custom,          |
+| Affected       | downstream usages of ``get_ext()`` and/or ``auth_nvctr()``  |
+|                | interfaces. Not exploitable in upstream TF-A code.          |
++----------------+-------------------------------------------------------------+
+| Impact         | Out-of-bounds read.                                         |
++----------------+-------------------------------------------------------------+
+| Fix Version    | - `fd37982a19a4a291`_ "fix(auth): forbid junk after         |
+|                |   extensions"                                               |
+|                |                                                             |
+|                | - `72460f50e2437a85`_ "fix(auth): require at least one      |
+|                |   extension to be present"                                  |
+|                |                                                             |
+|                | - `f5c51855d36e399e`_ "fix(auth): properly validate X.509   |
+|                |   extensions"                                               |
+|                |                                                             |
+|                | - `abb8f936fd0ad085`_ "fix(auth): avoid out-of-bounds read  |
+|                |   in auth_nvctr()"                                          |
+|                |                                                             |
+|                | Note that `72460f50e2437a85`_ is not fixing any             |
+|                | vulnerability per se but it is required for                 |
+|                | `f5c51855d36e399e`_ to apply cleanly.                       |
++----------------+-------------------------------------------------------------+
+| Credit         | Demi Marie Obenour, Invisible Things Lab                    |
++----------------+-------------------------------------------------------------+
+
+This security advisory describes a vulnerability in the X.509 parser used to
+parse boot certificates in TF-A trusted boot: it is possible for a crafted
+certificate to cause an out-of-bounds memory read.
+
+Note that upstream platforms are **not** affected by this. Only downstream
+platforms may be, if (and only if) the interfaces described below are used in a
+different context than seen in upstream code. Details of such context is
+described in the rest of this document.
+
+To fully understand this security advisory, it is recommended to refer to the
+following standards documents:
+
+ - `RFC 5280`_, *Internet X.509 Public Key Infrastructure Certificate and
+   Certificate Revocation List (CRL) Profile*.
+
+ - `ITU-T X.690`_, *ASN.1 encoding rules: Specification of Basic Encoding Rules
+   (BER), Canonical Encoding Rules (CER) and Distinguished Encoding Rules
+   (DER).*
+
+Bug 1: Insufficient certificate validation
+------------------------------------------
+
+The vulnerability lies in the following source file:
+``drivers/auth/mbedtls/mbedtls_x509_parser.c``. By design, ``get_ext()`` does
+not check the return value of the various ``mbedtls_*()`` functions, as
+``cert_parse()`` is assumed to have guaranteed that they will always succeed.
+However, it passes the end of an extension as the end pointer to these
+functions, whereas ``cert_parse()`` passes the end of the ``TBSCertificate``.
+Furthermore, ``cert_parse()`` does not check that the contents of the extension
+have the same length as the extension itself. It also does not check that the
+extension block extends to the end of the ``TBSCertificate``.
+
+This is a problem, as ``mbedtls_asn1_get_tag()`` leaves ``*p`` and ``*len``
+undefined on failure.  In practice, this results in ``get_ext()`` continuing to
+parse at different offsets than were used (and validated) by ``cert_parse()``,
+which means that the in-bounds guarantee provided by ``cert_parse()`` no longer
+holds.  The result is that it is possible for ``get_ext()`` to read memory past
+the end of the certificate.  This could potentially access memory with dangerous
+read side effects, or leak microarchitectural state that could theoretically be
+retrieved through some side-channel attacks as part of a more complex attack.
+
+Bug 2: Missing bounds check in ``auth_nvctr()``
+-----------------------------------------------
+``auth_nvctr()`` does not check that the buffer provided is
+long enough to hold an ``ASN.1 INTEGER``.  Since ``auth_nvctr()`` will only ever
+read 6 bytes, it is possible to read up to 6 bytes past the end of the buffer.
+
+Exploitability Analysis
+-----------------------
+
+Upstream TF-A Code
+~~~~~~~~~~~~~~~~~~
+
+In upstream TF-A code, the only caller of ``auth_nvctr()`` takes its input from
+``get_ext()``, which means that the second bug is exploitable, so is the first.
+Therefore, only the first bug need be considered.
+
+All standard chains of trust provided in TF-A source tree (that is, under
+``drivers/auth/``) require that the certificate's signature has already been
+validated prior to calling ``get_ext()``, or any function that calls ``get_ext()``.
+Platforms taking their chain of trust from a dynamic configuration file (such as
+``fdts/cot_descriptors.dtsi``) are also safe, as signature verification will
+always be done prior to any calls to ``get_ext()`` or ``auth_nvctr()`` in this
+case, no matter the order of the properties in the file.  Therefore, it is not
+possible to exploit this vulnerability pre-authentication in upstream TF-A.
+
+Furthermore, the data read through ``get_ext()`` only
+ever gets used by the authentication framework (``drivers/auth/auth_mod.c``),
+which greatly reduces the range of inputs it will ever receive and thus the
+impact this has. Specifically, the authentication framework uses ``get_ext()``
+in three cases:
+
+ 1. Retrieving a hash from an X.509 certificate to check the integrity of a
+    child certificate (see ``auth_hash()``).
+
+ 2. Retrieving the signature details from an X.509 certificate to check its
+    authenticity and integrity (see ``auth_signature()``).
+
+ 3. Retrieving the security counter value from an X.509 certificate to protect
+    it from unauthorized rollback to a previous version (see ``auth_nvctr()``).
+
+None of these uses authentication framework write to the out-of-bounds memory,
+so no memory corruption is possible.
+
+In summary, there are 2 separate issues - one in ``get_ext()`` and another one
+in ``auth_nvctr()`` - but neither of these can be exploited in the context of
+TF-A upstream code.
+
+Only in the following 2 cases do we expect this vulnerability to be triggerable
+prior to authentication:
+
+ - The platform uses a custom chain of trust which uses the non-volatile counter
+   authentication method (``AUTH_METHOD_NV_CTR``) before the cryptographic
+   authentication method (``AUTH_METHOD_SIG``).
+
+ - The chain of trust uses a custom authentication method that calls
+   ``get_ext()`` before cryptographic authentication.
+
+Custom Image Parsers
+~~~~~~~~~~~~~~~~~~~~
+
+If the platform uses a custom image parser instead of the certificate parser,
+the bug in the certificate parser is obviously not relevant.  The bug in
+``auth_nvctr()`` *may* be relevant, but only if the returned data is:
+
+- Taken from an untrusted source (meaning that it is read prior to
+  authentication).
+
+- Not already checked to be a primitively-encoded ASN.1 tag.
+
+In particular, if the custom image parser implementation wraps a 32-bit integer
+in an ASN.1 ``INTEGER``, it is not affected.
+
+.. _CVE-2022-47630: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-47630
+.. _fd37982a19a4a291: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/commit/?id=fd37982a19a4a291
+.. _72460f50e2437a85: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/commit/?id=72460f50e2437a85
+.. _f5c51855d36e399e: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/commit/?id=f5c51855d36e399e
+.. _abb8f936fd0ad085: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/commit/?id=abb8f936fd0ad085
+.. _RFC 5280: https://www.ietf.org/rfc/rfc5280.txt
+.. _ITU-T X.690: https://www.itu.int/ITU-T/studygroups/com10/languages/X.690_1297.pdf
diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c
index bc93f93..f6c251d 100644
--- a/drivers/arm/gic/v3/gicv3_main.c
+++ b/drivers/arm/gic/v3/gicv3_main.c
@@ -12,6 +12,7 @@
 #include <common/interrupt_props.h>
 #include <drivers/arm/gicv3.h>
 #include <lib/spinlock.h>
+#include <plat/common/platform.h>
 
 #include "gicv3_private.h"
 
@@ -1287,12 +1288,14 @@
 
 	assert(gicv3_driver_data->gicr_base == 0U);
 
+	if (plat_can_cmo()) {
 	/* Ensure this function is called with Data Cache enabled */
 #ifndef __aarch64__
-	assert((read_sctlr() & SCTLR_C_BIT) != 0U);
+		assert((read_sctlr() & SCTLR_C_BIT) != 0U);
 #else
-	assert((read_sctlr_el3() & SCTLR_C_BIT) != 0U);
+		assert((read_sctlr_el3() & SCTLR_C_BIT) != 0U);
 #endif /* !__aarch64__ */
+	}
 
 	mpidr_self = read_mpidr_el1() & MPIDR_AFFINITY_MASK;
 	rdistif_base = gicr_frame;
diff --git a/drivers/auth/auth_mod.c b/drivers/auth/auth_mod.c
index fa9509a..1bf03d4 100644
--- a/drivers/auth/auth_mod.c
+++ b/drivers/auth/auth_mod.c
@@ -243,7 +243,7 @@
 		      unsigned int *cert_nv_ctr,
 		      bool *need_nv_ctr_upgrade)
 {
-	char *p;
+	unsigned char *p;
 	void *data_ptr = NULL;
 	unsigned int data_len, len, i;
 	unsigned int plat_nv_ctr;
@@ -258,16 +258,24 @@
 
 	/* Parse the DER encoded integer */
 	assert(data_ptr);
-	p = (char *)data_ptr;
-	if (*p != ASN1_INTEGER) {
+	p = (unsigned char *)data_ptr;
+
+	/*
+	 * Integers must be at least 3 bytes: 1 for tag, 1 for length, and 1
+	 * for value.  The first byte (tag) must be ASN1_INTEGER.
+	 */
+	if ((data_len < 3) || (*p != ASN1_INTEGER)) {
 		/* Invalid ASN.1 integer */
 		return 1;
 	}
 	p++;
 
-	/* NV-counters are unsigned integers up to 32-bit */
-	len = (unsigned int)(*p & 0x7f);
-	if ((*p & 0x80) || (len > 4)) {
+	/*
+	 * NV-counters are unsigned integers up to 31 bits.  Trailing
+	 * padding is not allowed.
+	 */
+	len = (unsigned int)*p;
+	if ((len > 4) || (data_len - 2 != len)) {
 		return 1;
 	}
 	p++;
diff --git a/drivers/auth/mbedtls/mbedtls_crypto.c b/drivers/auth/mbedtls/mbedtls_crypto.c
index d231179..42a0925 100644
--- a/drivers/auth/mbedtls/mbedtls_crypto.c
+++ b/drivers/auth/mbedtls/mbedtls_crypto.c
@@ -115,7 +115,7 @@
 	end = (unsigned char *)(p + sig_len);
 	signature.tag = *p;
 	rc = mbedtls_asn1_get_bitstring_null(&p, end, &signature.len);
-	if (rc != 0) {
+	if ((rc != 0) || ((size_t)(end - p) != signature.len)) {
 		rc = CRYPTO_ERR_SIGNATURE;
 		goto end1;
 	}
@@ -170,12 +170,15 @@
 	size_t len;
 	int rc;
 
-	/* Digest info should be an MBEDTLS_ASN1_SEQUENCE */
+	/*
+	 * Digest info should be an MBEDTLS_ASN1_SEQUENCE
+	 * and consume all bytes.
+	 */
 	p = (unsigned char *)digest_info_ptr;
 	end = p + digest_info_len;
 	rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
 				  MBEDTLS_ASN1_SEQUENCE);
-	if (rc != 0) {
+	if (rc != 0 || ((size_t)(end - p) != len)) {
 		return CRYPTO_ERR_HASH;
 	}
 
@@ -195,9 +198,9 @@
 		return CRYPTO_ERR_HASH;
 	}
 
-	/* Hash should be octet string type */
+	/* Hash should be octet string type and consume all bytes */
 	rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING);
-	if (rc != 0) {
+	if ((rc != 0) || ((size_t)(end - p) != len)) {
 		return CRYPTO_ERR_HASH;
 	}
 
diff --git a/drivers/auth/mbedtls/mbedtls_x509_parser.c b/drivers/auth/mbedtls/mbedtls_x509_parser.c
index 993ef12..bef2f3d 100644
--- a/drivers/auth/mbedtls/mbedtls_x509_parser.c
+++ b/drivers/auth/mbedtls/mbedtls_x509_parser.c
@@ -85,9 +85,6 @@
 	p = v3_ext.p;
 	end = v3_ext.p + v3_ext.len;
 
-	mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
-			     MBEDTLS_ASN1_SEQUENCE);
-
 	while (p < end) {
 		zeromem(&extn_oid, sizeof(extn_oid));
 		is_critical = 0; /* DEFAULT FALSE */
@@ -144,8 +141,23 @@
 {
 	int ret, is_critical;
 	size_t len;
-	unsigned char *p, *end, *crt_end;
-	mbedtls_asn1_buf sig_alg1, sig_alg2;
+	unsigned char *p, *end, *crt_end, *pk_end;
+	mbedtls_asn1_buf sig_alg1;
+	/*
+	 * The unique ASN.1 DER encoding of [0] EXPLICIT INTEGER { v3(2} }.
+	 */
+	static const char v3[] = {
+		/* The outer CONTEXT SPECIFIC 0 tag */
+		MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC | 0,
+		/* The number bytes used to encode the inner INTEGER */
+		3,
+		/* The tag of the inner INTEGER */
+		MBEDTLS_ASN1_INTEGER,
+		/* The number of bytes needed to represent 2 */
+		1,
+		/* The actual value 2 */
+		2,
+	};
 
 	p = (unsigned char *)img;
 	len = img_len;
@@ -163,7 +175,7 @@
 		return IMG_PARSER_ERR_FORMAT;
 	}
 
-	if (len > (size_t)(end - p)) {
+	if (len != (size_t)(end - p)) {
 		return IMG_PARSER_ERR_FORMAT;
 	}
 	crt_end = p + len;
@@ -181,15 +193,14 @@
 	tbs.len = end - tbs.p;
 
 	/*
-	 * Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
+	 * Version  ::=  [0] EXPLICIT INTEGER {  v1(0), v2(1), v3(2)  }
+	 * -- only v3 accepted
 	 */
-	ret = mbedtls_asn1_get_tag(&p, end, &len,
-				   MBEDTLS_ASN1_CONTEXT_SPECIFIC |
-				   MBEDTLS_ASN1_CONSTRUCTED | 0);
-	if (ret != 0) {
+	if (((end - p) <= (ptrdiff_t)sizeof(v3)) ||
+	    (memcmp(p, v3, sizeof(v3)) != 0)) {
 		return IMG_PARSER_ERR_FORMAT;
 	}
-	p += len;
+	p += sizeof(v3);
 
 	/*
 	 * CertificateSerialNumber  ::=  INTEGER
@@ -257,9 +268,24 @@
 	if (ret != 0) {
 		return IMG_PARSER_ERR_FORMAT;
 	}
+	pk_end = p + len;
+	pk.len = pk_end - pk.p;
+
+	/* algorithm */
+	ret = mbedtls_asn1_get_tag(&p, pk_end, &len, MBEDTLS_ASN1_CONSTRUCTED |
+				   MBEDTLS_ASN1_SEQUENCE);
+	if (ret != 0) {
+		return IMG_PARSER_ERR_FORMAT;
+	}
-	pk.len = (p + len) - pk.p;
 	p += len;
 
+	/* Key is a BIT STRING and must use all bytes in SubjectPublicKeyInfo */
+	ret = mbedtls_asn1_get_bitstring_null(&p, pk_end, &len);
+	if ((ret != 0) || (p + len != pk_end)) {
+		return IMG_PARSER_ERR_FORMAT;
+	}
+	p = pk_end;
+
 	/*
 	 * issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
 	 */
@@ -290,57 +316,79 @@
 
 	/*
 	 * extensions      [3]  EXPLICIT Extensions OPTIONAL
+	 * }
+	 *
+	 * X.509 and RFC5280 allow omitting the extensions entirely.
+	 * However, in TF-A, a certificate with no extensions would
+	 * always fail later on, as the extensions contain the
+	 * information needed to authenticate the next stage in the
+	 * boot chain.  Furthermore, get_ext() assumes that the
+	 * extensions have been parsed into v3_ext, and allowing
+	 * there to be no extensions would pointlessly complicate
+	 * the code.  Therefore, just reject certificates without
+	 * extensions.  This is also why version 1 and 2 certificates
+	 * are rejected above.
 	 */
 	ret = mbedtls_asn1_get_tag(&p, end, &len,
 				   MBEDTLS_ASN1_CONTEXT_SPECIFIC |
 				   MBEDTLS_ASN1_CONSTRUCTED | 3);
-	if (ret != 0) {
+	if ((ret != 0) || (len != (size_t)(end - p))) {
 		return IMG_PARSER_ERR_FORMAT;
 	}
 
 	/*
 	 * Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
+	 * -- must use all remaining bytes in TBSCertificate
 	 */
-	v3_ext.p = p;
 	ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
 				   MBEDTLS_ASN1_SEQUENCE);
-	if (ret != 0) {
+	if ((ret != 0) || (len != (size_t)(end - p))) {
 		return IMG_PARSER_ERR_FORMAT;
 	}
-	v3_ext.len = (p + len) - v3_ext.p;
+	v3_ext.p = p;
+	v3_ext.len = len;
 
 	/*
-	 * Check extensions integrity
+	 * Check extensions integrity.  At least one extension is
+	 * required: the ASN.1 specifies a minimum size of 1, and at
+	 * least one extension is needed to authenticate the next stage
+	 * in the boot chain.
 	 */
-	while (p < end) {
+	do {
+		unsigned char *end_ext_data;
+
 		ret = mbedtls_asn1_get_tag(&p, end, &len,
 					   MBEDTLS_ASN1_CONSTRUCTED |
 					   MBEDTLS_ASN1_SEQUENCE);
 		if (ret != 0) {
 			return IMG_PARSER_ERR_FORMAT;
 		}
+		end_ext_data = p + len;
 
 		/* Get extension ID */
-		ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OID);
+		ret = mbedtls_asn1_get_tag(&p, end_ext_data, &len, MBEDTLS_ASN1_OID);
 		if (ret != 0) {
 			return IMG_PARSER_ERR_FORMAT;
 		}
 		p += len;
 
 		/* Get optional critical */
-		ret = mbedtls_asn1_get_bool(&p, end, &is_critical);
+		ret = mbedtls_asn1_get_bool(&p, end_ext_data, &is_critical);
 		if ((ret != 0) && (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)) {
 			return IMG_PARSER_ERR_FORMAT;
 		}
 
-		/* Data should be octet string type */
-		ret = mbedtls_asn1_get_tag(&p, end, &len,
+		/*
+		 * Data should be octet string type and must use all bytes in
+		 * the Extension.
+		 */
+		ret = mbedtls_asn1_get_tag(&p, end_ext_data, &len,
 					   MBEDTLS_ASN1_OCTET_STRING);
-		if (ret != 0) {
+		if ((ret != 0) || ((p + len) != end_ext_data)) {
 			return IMG_PARSER_ERR_FORMAT;
 		}
-		p += len;
-	}
+		p = end_ext_data;
+	} while (p < end);
 
 	if (p != end) {
 		return IMG_PARSER_ERR_FORMAT;
@@ -353,33 +401,22 @@
 	 *  -- end of TBSCertificate
 	 *
 	 *  signatureAlgorithm   AlgorithmIdentifier
+	 *  -- Does not need to be parsed.  Ensuring it is bitwise
+	 *  -- identical (including the tag!) with the first signature
+	 *  -- algorithm is sufficient.
 	 */
-	sig_alg2.p = p;
-	ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
-				   MBEDTLS_ASN1_SEQUENCE);
-	if (ret != 0) {
+	if ((sig_alg1.len >= (size_t)(end - p)) ||
+	    (0 != memcmp(sig_alg1.p, p, sig_alg1.len))) {
 		return IMG_PARSER_ERR_FORMAT;
 	}
-	if ((end - p) < 1) {
-		return IMG_PARSER_ERR_FORMAT;
-	}
-	sig_alg2.len = (p + len) - sig_alg2.p;
-	p += len;
-
-	/* Compare both signature algorithms */
-	if (sig_alg1.len != sig_alg2.len) {
-		return IMG_PARSER_ERR_FORMAT;
-	}
-	if (0 != memcmp(sig_alg1.p, sig_alg2.p, sig_alg1.len)) {
-		return IMG_PARSER_ERR_FORMAT;
-	}
+	p += sig_alg1.len;
 	memcpy(&sig_alg, &sig_alg1, sizeof(sig_alg));
 
 	/*
 	 * signatureValue       BIT STRING
 	 */
 	signature.p = p;
-	ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_BIT_STRING);
+	ret = mbedtls_asn1_get_bitstring_null(&p, end, &len);
 	if (ret != 0) {
 		return IMG_PARSER_ERR_FORMAT;
 	}
diff --git a/drivers/brcm/emmc/emmc_csl_sdcard.c b/drivers/brcm/emmc/emmc_csl_sdcard.c
index 9e2c618..40bc4a0 100644
--- a/drivers/brcm/emmc/emmc_csl_sdcard.c
+++ b/drivers/brcm/emmc/emmc_csl_sdcard.c
@@ -479,10 +479,11 @@
 			handle->device->cfg.blockSize = 512;
 		}
 
-		if (handle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY)
+		if (handle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) {
 			EMMC_TRACE("Sector addressing\n");
-		else
+		} else {
 			EMMC_TRACE("Byte addressing\n");
+		}
 
 		EMMC_TRACE("Ext_CSD_storage[162]: 0x%02X  Ext_CSD_storage[179]: 0x%02X\n",
 			   emmc_global_buf_ptr->u.Ext_CSD_storage[162],
diff --git a/drivers/brcm/emmc/emmc_pboot_hal_memory_drv.c b/drivers/brcm/emmc/emmc_pboot_hal_memory_drv.c
index 68f93e7..fcd499f 100644
--- a/drivers/brcm/emmc/emmc_pboot_hal_memory_drv.c
+++ b/drivers/brcm/emmc/emmc_pboot_hal_memory_drv.c
@@ -278,8 +278,9 @@
 
 	SDIO_base = EMMC_CTRL_REGS_BASE_ADDR;
 
-	if (SDIO_base == SDIO0_EMMCSDXC_SYSADDR)
+	if (SDIO_base == SDIO0_EMMCSDXC_SYSADDR) {
 		EMMC_TRACE(" ---> for SDIO 0 Controller\n\n");
+	}
 
 	memset(p_sdhandle, 0, sizeof(struct sd_handle));
 
@@ -290,8 +291,9 @@
 	memset(p_sdhandle->card, 0, sizeof(struct sd_card_info));
 
 	if (chal_sd_start((CHAL_HANDLE *) p_sdhandle->device,
-			  SD_PIO_MODE, SDIO_base, SDIO_base) != SD_OK)
+			  SD_PIO_MODE, SDIO_base, SDIO_base) != SD_OK) {
 		return NULL;
+	}
 
 	set_config(p_sdhandle, SD_NORMAL_SPEED, MAX_CMD_RETRY, SD_DMA_OFF,
 		   SD_DMA_BOUNDARY_4K, EMMC_BLOCK_SIZE, EMMC_WFE_RETRY);
@@ -330,14 +332,16 @@
 	VERBOSE("EMMC READ: dst=0x%lx, src=0x%lx, size=0x%lx\n",
 			storage_addr, mem_addr, bytes_to_read);
 
-	if (storage_size < bytes_to_read)
+	if (storage_size < bytes_to_read) {
 		/* Don't have sufficient storage to complete the operation */
 		return 0;
+	}
 
 	/* Range check non high capacity memory */
 	if ((p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) == 0) {
-		if (mem_addr > 0x80000000)
+		if (mem_addr > 0x80000000) {
 			return 0;
+		}
 	}
 
 	/* High capacity card use block address mode */
@@ -384,10 +388,11 @@
 			/* Update Physical address */
 			outputBuf += manual_copy_size;
 
-			if (p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY)
+			if (p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) {
 				blockAddr++;
-			else
+			} else {
 				blockAddr += blockSize;
+			}
 		} else {
 			return 0;
 		}
@@ -395,10 +400,11 @@
 
 	while (remSize >= blockSize) {
 
-		if (remSize >= SD_MAX_BLK_TRANSFER_LENGTH)
+		if (remSize >= SD_MAX_BLK_TRANSFER_LENGTH) {
 			readLen = SD_MAX_BLK_TRANSFER_LENGTH;
-		else
+		} else {
 			readLen = (remSize / blockSize) * blockSize;
+		}
 
 		/* Check for overflow */
 		if ((rdCount + readLen) > storage_size ||
@@ -409,10 +415,11 @@
 		}
 
 		if (!read_block(p_sdhandle, outputBuf, blockAddr, readLen)) {
-			if (p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY)
+			if (p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) {
 				blockAddr += (readLen / blockSize);
-			else
+			} else {
 				blockAddr += readLen;
+			}
 
 			remSize -= readLen;
 			rdCount += readLen;
@@ -463,8 +470,9 @@
 
 	/* range check non high capacity memory */
 	if ((p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) == 0) {
-		if (mem_addr > 0x80000000)
+		if (mem_addr > 0x80000000) {
 			return 0;
+		}
 	}
 
 	/* the high capacity card use block address mode */
@@ -491,11 +499,12 @@
 				blockAddr, p_sdhandle->device->cfg.blockSize)) {
 
 			if (remSize <
-			    (p_sdhandle->device->cfg.blockSize - offset))
+			    (p_sdhandle->device->cfg.blockSize - offset)) {
 				manual_copy_size = remSize;
-			else
+			} else {
 				manual_copy_size =
 				    p_sdhandle->device->cfg.blockSize - offset;
+			}
 
 			memcpy((void *)((uintptr_t)
 				(emmc_global_buf_ptr->u.tempbuf + offset)),
@@ -530,11 +539,12 @@
 				inputBuf += manual_copy_size;
 
 				if (p_sdhandle->device->ctrl.ocr &
-				    SD_CARD_HIGH_CAPACITY)
+				    SD_CARD_HIGH_CAPACITY) {
 					blockAddr++;
-				else
+				} else {
 					blockAddr +=
 					    p_sdhandle->device->cfg.blockSize;
+				}
 			} else
 				return 0;
 		} else {
diff --git a/drivers/imx/usdhc/imx_usdhc.c b/drivers/imx/usdhc/imx_usdhc.c
index 07f55b7..49dfc07 100644
--- a/drivers/imx/usdhc/imx_usdhc.c
+++ b/drivers/imx/usdhc/imx_usdhc.c
@@ -136,7 +136,8 @@
 		break;
 	case MMC_CMD(18):
 		multiple = 1;
-		/* fall thru for read op */
+		/* for read op */
+		/* fallthrough */
 	case MMC_CMD(17):
 	case MMC_CMD(8):
 		mixctl |= MIXCTRL_DTDSEL;
@@ -144,7 +145,8 @@
 		break;
 	case MMC_CMD(25):
 		multiple = 1;
-		/* fall thru for data op flag */
+		/* for data op flag */
+		/* fallthrough */
 	case MMC_CMD(24):
 		data = 1;
 		break;
diff --git a/drivers/nxp/ddr/nxp-ddr/ddr.c b/drivers/nxp/ddr/nxp-ddr/ddr.c
index c051b3b..faf20e9 100644
--- a/drivers/nxp/ddr/nxp-ddr/ddr.c
+++ b/drivers/nxp/ddr/nxp-ddr/ddr.c
@@ -269,7 +269,7 @@
 	unsigned int i;
 	const struct dynamic_odt *pdodt = NULL;
 
-	const static struct dynamic_odt *table[2][5] = {
+	static const struct dynamic_odt *table[2][5] = {
 		{single_S, single_D, NULL, NULL},
 		{dual_SS, dual_DD, NULL, NULL},
 	};
diff --git a/drivers/nxp/ddr/phy-gen2/messages.h b/drivers/nxp/ddr/phy-gen2/messages.h
index 7dec7df..a2310f2 100644
--- a/drivers/nxp/ddr/phy-gen2/messages.h
+++ b/drivers/nxp/ddr/phy-gen2/messages.h
@@ -13,7 +13,7 @@
 	const char *msg;
 };
 
-const static struct phy_msg messages_1d[] = {
+static const struct phy_msg messages_1d[] = {
 	{0x00000001,
 	 "PMU1:prbsGenCtl:%x\n"
 	},
@@ -1239,7 +1239,7 @@
 	},
 };
 
-const static struct phy_msg messages_2d[] = {
+static const struct phy_msg messages_2d[] = {
 	{0x00000001,
 	 "PMU0: Converting %d into an MR\n"
 	},
diff --git a/drivers/renesas/common/emmc/emmc_cmd.c b/drivers/renesas/common/emmc/emmc_cmd.c
index d255bff..02fc26b 100644
--- a/drivers/renesas/common/emmc/emmc_cmd.c
+++ b/drivers/renesas/common/emmc/emmc_cmd.c
@@ -254,8 +254,7 @@
 				(SD_INFO2_ALL_ERR | SD_INFO2_CLEAR));
 
 			state = ESTATE_ISSUE_CMD;
-			/* through */
-
+			/* fallthrough */
 		case ESTATE_ISSUE_CMD:
 			/* ARG */
 			SETR_32(SD_ARG, mmc_drv_obj.cmd_info.arg);
@@ -454,8 +453,8 @@
 				SETR_32(SD_STOP, 0x00000000U);
 				mmc_drv_obj.during_dma_transfer = FALSE;
 			}
-			/* through */
 
+			/* fallthrough */
 		case ESTATE_ERROR:
 			if (err_not_care_flag == TRUE) {
 				mmc_drv_obj.during_cmd_processing = FALSE;
diff --git a/drivers/renesas/common/rom/rom_api.c b/drivers/renesas/common/rom/rom_api.c
index fda2815..4eede17 100644
--- a/drivers/renesas/common/rom/rom_api.c
+++ b/drivers/renesas/common/rom/rom_api.c
@@ -11,7 +11,7 @@
 #include "rcar_def.h"
 #include "rom_api.h"
 
-typedef uint32_t(*rom_secure_boot_api_f) (uint32_t *key, uint32_t *cert,
+typedef uint32_t(*rom_secure_boot_api_f) (uint32_t key, uint32_t cert,
 					  rom_read_flash_f pFuncReadFlash);
 
 typedef uint32_t(*rom_get_lcs_api_f) (uint32_t *lcs);
@@ -68,7 +68,7 @@
 	return index;
 }
 
-uint32_t rcar_rom_secure_boot_api(uint32_t *key, uint32_t *cert,
+uint32_t rcar_rom_secure_boot_api(uint32_t key, uint32_t cert,
 			     rom_read_flash_f read_flash)
 {
 	static const uintptr_t rom_api_table[API_TABLE_MAX] = {
diff --git a/drivers/renesas/common/rom/rom_api.h b/drivers/renesas/common/rom/rom_api.h
index 1d5b03d..4b10080 100644
--- a/drivers/renesas/common/rom/rom_api.h
+++ b/drivers/renesas/common/rom/rom_api.h
@@ -24,7 +24,7 @@
 #define LCS_FA					(0x7U)
 
 typedef uint32_t(*rom_read_flash_f) (uint64_t src, uint8_t *dst, uint32_t len);
-uint32_t rcar_rom_secure_boot_api(uint32_t *key, uint32_t *cert,
+uint32_t rcar_rom_secure_boot_api(uint32_t key, uint32_t cert,
 				  rom_read_flash_f f);
 uint32_t rcar_rom_get_lcs(uint32_t *lcs);
 
diff --git a/drivers/st/crypto/stm32_pka.c b/drivers/st/crypto/stm32_pka.c
index e03cf0f..2bbb31d 100644
--- a/drivers/st/crypto/stm32_pka.c
+++ b/drivers/st/crypto/stm32_pka.c
@@ -254,13 +254,6 @@
 
 static struct stm32_pka_platdata pka_pdata;
 
-#pragma weak stm32_pka_get_platdata
-
-int stm32_pka_get_platdata(struct stm32_pka_platdata *pdata)
-{
-	return -ENODEV;
-}
-
 static int stm32_pka_parse_fdt(void)
 {
 	int node;
@@ -583,10 +576,7 @@
 
 	err = stm32_pka_parse_fdt();
 	if (err != 0) {
-		err = stm32_pka_get_platdata(&pka_pdata);
-		if (err != 0) {
-			return err;
-		}
+		return err;
 	}
 
 	clk_enable(pka_pdata.clock_id);
diff --git a/drivers/st/crypto/stm32_saes.c b/drivers/st/crypto/stm32_saes.c
index 02baf21..f4da571 100644
--- a/drivers/st/crypto/stm32_saes.c
+++ b/drivers/st/crypto/stm32_saes.c
@@ -139,15 +139,8 @@
 #define SET_CHAINING_MODE(mod, cr) \
 	mmio_clrsetbits_32((cr), _SAES_CR_CHMOD_MASK, _SAES_CR_CHMOD_##mod << _SAES_CR_CHMOD_SHIFT)
 
-#define pragma weak stm32_saes_get_platdata
-
 static struct stm32_saes_platdata saes_pdata;
 
-int stm32_saes_get_platdata(struct stm32_saes_platdata *pdata)
-{
-	return -ENODEV;
-}
-
 static int stm32_saes_parse_fdt(struct stm32_saes_platdata *pdata)
 {
 	int node;
@@ -389,10 +382,7 @@
 
 	err = stm32_saes_parse_fdt(&saes_pdata);
 	if (err != 0) {
-		err = stm32_saes_get_platdata(&saes_pdata);
-		if (err != 0) {
-			return err;
-		}
+		return err;
 	}
 
 	clk_enable(saes_pdata.clock_id);
diff --git a/drivers/st/usb/stm32mp1_usb.c b/drivers/st/usb/stm32mp1_usb.c
index 9a49690..78890f5 100644
--- a/drivers/st/usb/stm32mp1_usb.c
+++ b/drivers/st/usb/stm32mp1_usb.c
@@ -4,6 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <assert.h>
 #include <stdint.h>
 
 #include <arch_helpers.h>
@@ -794,7 +795,7 @@
 	uint32_t epint;
 	uint32_t epnum;
 	uint32_t temp;
-	enum usb_status ret;
+	enum usb_status __unused ret;
 
 	if (usb_dwc2_get_mode(handle) != USB_OTG_MODE_DEVICE) {
 		return USB_NOTHING;
@@ -947,9 +948,7 @@
 
 		/* Setup EP0 to receive SETUP packets */
 		ret = usb_dwc2_ep0_out_start(handle);
-		if (ret != USBD_OK) {
-			return ret;
-		}
+		assert(ret == USBD_OK);
 
 		mmio_write_32(usb_base_addr + OTG_GINTSTS, OTG_GINTSTS_USBRST);
 
@@ -959,9 +958,7 @@
 	/* Handle enumeration done interrupt */
 	if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_ENUMDNE) != 0U) {
 		ret = usb_dwc2_activate_setup(handle);
-		if (ret != USBD_OK) {
-			return ret;
-		}
+		assert(ret == USBD_OK);
 
 		mmio_clrbits_32(usb_base_addr + OTG_GUSBCFG, OTG_GUSBCFG_TRDT);
 
diff --git a/fdts/tc.dts b/fdts/tc.dts
index 5a8792e..192f407 100644
--- a/fdts/tc.dts
+++ b/fdts/tc.dts
@@ -213,9 +213,9 @@
 			linux,cma-default;
 		};
 
-		optee@0xfce00000 {
-			reg = <0x00000000 0xfce00000 0 0x00200000>;
-			no-map;
+		optee@0xf8e00000 {
+			compatible = "restricted-dma-pool";
+			reg = <0x00000000 0xf8e00000 0 0x00200000>;
 		};
 	};
 
@@ -463,17 +463,18 @@
 		interrupt-names = "JOB", "MMU", "GPU";
 		clocks = <&soc_refclk100mhz>;
 		clock-names = "clk_mali";
+		iommus = <&smmu_700 0x200>;
 		operating-points = <
 			/* KHz uV */
 			50000 820000
 		>;
 	};
 
-	smmu: smmu@2ce00000 {
+	smmu_700: smmu_700@3f000000 {
 		#iommu-cells = <1>;
 		compatible = "arm,smmu-v3";
-		reg = <0x0 0x2ce00000 0x0 0x20000>;
-		status = "okay";
+		reg = <0x0 0x3f000000 0x0 0x5000000>;
+		dma-coherent;
 	};
 
 	dp0: display@2cc00000 {
@@ -485,9 +486,7 @@
 		interrupt-names = "DPU";
 		clocks = <&scmi_clk 0>;
 		clock-names = "aclk";
-		iommus = <&smmu 0>, <&smmu 1>, <&smmu 2>, <&smmu 3>,
-			<&smmu 4>, <&smmu 5>, <&smmu 6>, <&smmu 7>,
-			<&smmu 8>, <&smmu 9>;
+		iommus = <&smmu_700 0x100>;
 		pl0: pipeline@0 {
 			reg = <0>;
 			clocks = <&scmi_clk 1>;
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index f63e923..9e13c3d 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -1282,6 +1282,12 @@
 #define GCR_EL1			S3_0_C1_C0_6
 
 /*******************************************************************************
+ * Armv8.5 - Random Number Generator Registers
+ ******************************************************************************/
+#define RNDR			S3_3_C2_C4_0
+#define RNDRRS			S3_3_C2_C4_1
+
+/*******************************************************************************
  * FEAT_HCX - Extended Hypervisor Configuration Register
  ******************************************************************************/
 #define HCRX_EL2		S3_4_C1_C2_2
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index 50a5ad4..fe9b5a5 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -546,8 +546,8 @@
 DEFINE_RENAME_SYSREG_RW_FUNCS(gcr_el1, GCR_EL1)
 
 /* Armv8.5 FEAT_RNG Registers */
-DEFINE_SYSREG_READ_FUNC(rndr)
-DEFINE_SYSREG_READ_FUNC(rndrrs)
+DEFINE_RENAME_SYSREG_READ_FUNC(rndr, RNDR)
+DEFINE_RENAME_SYSREG_READ_FUNC(rndrrs, RNDRRS)
 
 /* FEAT_HCX Register */
 DEFINE_RENAME_SYSREG_RW_FUNCS(hcrx_el2, HCRX_EL2)
diff --git a/include/bl31/sync_handle.h b/include/bl31/sync_handle.h
new file mode 100644
index 0000000..e211575
--- /dev/null
+++ b/include/bl31/sync_handle.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2022, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TRAP_HANDLE_H
+#define TRAP_HANDLE_H
+
+#include <stdbool.h>
+#include <context.h>
+
+#define ISS_SYSREG_OPCODE_MASK		0x3ffc1eUL
+#define ISS_SYSREG_REG_MASK		0x0003e0UL
+#define ISS_SYSREG_REG_SHIFT		5U
+#define ISS_SYSREG_DIRECTION_MASK	0x000001UL
+
+#define ISS_SYSREG_OPCODE_RNDR		0x30c808U
+#define ISS_SYSREG_OPCODE_RNDRRS	0x32c808U
+
+#define TRAP_RET_UNHANDLED		-1
+#define TRAP_RET_REPEAT			0
+#define TRAP_RET_CONTINUE		1
+
+#ifndef __ASSEMBLER__
+static inline unsigned int get_sysreg_iss_rt(uint64_t esr)
+{
+	return (esr & ISS_SYSREG_REG_MASK) >> ISS_SYSREG_REG_SHIFT;
+}
+
+static inline bool is_sysreg_iss_write(uint64_t esr)
+{
+	return !(esr & ISS_SYSREG_DIRECTION_MASK);
+}
+
+/**
+ * handle_sysreg_trap() - Handle AArch64 system register traps from lower ELs
+ * @esr_el3: The content of ESR_EL3, containing the trap syndrome information
+ * @ctx: Pointer to the lower EL context, containing saved registers
+ *
+ * Called by the exception handler when a synchronous trap identifies as a
+ * system register trap (EC=0x18). ESR contains the encoding of the op[x] and
+ * CRm/CRn fields, to identify the system register, and the target/source
+ * GPR plus the direction (MRS/MSR). The lower EL's context can be altered
+ * by the function, to inject back the result of the emulation.
+ *
+ * Return: indication how to proceed with the trap:
+ *   TRAP_RET_UNHANDLED(-1): trap is unhandled, trigger panic
+ *   TRAP_RET_REPEAT(0): trap was handled, return to the trapping instruction
+ *			 (repeating it)
+ *   TRAP_RET_CONTINUE(1): trap was handled, return to the next instruction
+ *		           (continuing after it)
+ */
+int handle_sysreg_trap(uint64_t esr_el3, cpu_context_t *ctx);
+
+/* Prototypes for system register emulation handlers provided by platforms. */
+int plat_handle_rng_trap(uint64_t esr_el3, cpu_context_t *ctx);
+
+#endif /* __ASSEMBLER__ */
+
+#endif
diff --git a/include/lib/fconf/fconf.h b/include/lib/fconf/fconf.h
index 131c542..3762021 100644
--- a/include/lib/fconf/fconf.h
+++ b/include/lib/fconf/fconf.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2022, ARM Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,7 +21,7 @@
  */
 #define FCONF_REGISTER_POPULATOR(config, name, callback)			\
 	__attribute__((used, section(".fconf_populator")))			\
-	const struct fconf_populator (name##__populator) = {			\
+	static const struct fconf_populator (name##__populator) = {		\
 		.config_type = (#config),					\
 		.info = (#name),						\
 		.populate = (callback)						\
diff --git a/include/lib/libc/aarch32/limits_.h b/include/lib/libc/aarch32/limits_.h
index 26cec17..a67ec53 100644
--- a/include/lib/libc/aarch32/limits_.h
+++ b/include/lib/libc/aarch32/limits_.h
@@ -1,11 +1,11 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #define SCHAR_MAX  0x7F
-#define SCHAR_MIN  (-SCHAR_MIN - 1)
+#define SCHAR_MIN  (-SCHAR_MAX - 1)
 #define CHAR_MAX   0x7F
 #define CHAR_MIN   (-CHAR_MAX - 1)
 #define UCHAR_MAX  0xFFU
diff --git a/include/lib/libc/aarch64/limits_.h b/include/lib/libc/aarch64/limits_.h
index e36cfe7..1bb0681 100644
--- a/include/lib/libc/aarch64/limits_.h
+++ b/include/lib/libc/aarch64/limits_.h
@@ -1,11 +1,11 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #define SCHAR_MAX  0x7F
-#define SCHAR_MIN  (-SCHAR_MIN - 1)
+#define SCHAR_MIN  (-SCHAR_MAX - 1)
 #define CHAR_MAX   0x7F
 #define CHAR_MIN   (-CHAR_MAX - 1)
 #define UCHAR_MAX  0xFFU
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index 8407bbd..3351036 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -421,4 +421,17 @@
 void plat_fwu_set_images_source(const struct fwu_metadata *metadata);
 uint32_t plat_fwu_get_boot_idx(void);
 
+/*
+ * Optional function to indicate if cache management operations can be
+ * performed.
+ */
+#if CONDITIONAL_CMO
+uint64_t plat_can_cmo(void);
+#else
+static inline uint64_t plat_can_cmo(void)
+{
+	return 1;
+}
+#endif /* CONDITIONAL_CMO */
+
 #endif /* PLATFORM_H */
diff --git a/lib/cpus/aarch64/cortex_a710.S b/lib/cpus/aarch64/cortex_a710.S
index 3ea55df..cebd6f0 100644
--- a/lib/cpus/aarch64/cortex_a710.S
+++ b/lib/cpus/aarch64/cortex_a710.S
@@ -355,22 +355,22 @@
 
 /* ---------------------------------------------------------------
  * Errata Workaround for Cortex-A710 Erratum 2282622.
- * This applies to revision r0p0, r1p0 and r2p0.
- * It is fixed in r2p1.
+ * This applies to revision r0p0, r1p0, r2p0 and r2p1.
+ * It is still open.
  * Inputs:
  * x0: variant[4:7] and revision[0:3] of current cpu.
  * Shall clobber: x0, x1, x17
  * ---------------------------------------------------------------
  */
 func errata_a710_2282622_wa
-	/* Compare x0 against revision r2p0 */
+	/* Compare x0 against revision r2p1 */
 	mov     x17, x30
 	bl      check_errata_2282622
 	cbz     x0, 1f
 
 	/* Apply the workaround */
 	mrs     x1, CORTEX_A710_CPUACTLR2_EL1
-	orr     x1, x1, BIT(0)
+	orr     x1, x1, #BIT(0)
 	msr     CORTEX_A710_CPUACTLR2_EL1, x1
 
 1:
@@ -378,8 +378,8 @@
 endfunc errata_a710_2282622_wa
 
 func check_errata_2282622
-	/* Applies to r0p0, r1p0 and r2p0 */
-	mov     x1, #0x20
+	/* Applies to r0p0, r1p0, r2p0 and r2p1 */
+	mov     x1, #0x21
 	b       cpu_rev_var_ls
 endfunc check_errata_2282622
 
diff --git a/lib/cpus/aarch64/cortex_a78.S b/lib/cpus/aarch64/cortex_a78.S
index dd3487a..38f58bb 100644
--- a/lib/cpus/aarch64/cortex_a78.S
+++ b/lib/cpus/aarch64/cortex_a78.S
@@ -326,6 +326,31 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_2395406
 
+/* ----------------------------------------------------
+ * Errata Workaround for Cortex-A78 Errata 2772019
+ * This applies to revisions <= r1p2 and is still open.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * ----------------------------------------------------
+ */
+func errata_a78_2772019_wa
+	mov	x17, x30
+	bl	check_errata_2772019
+	cbz	x0, 1f
+
+
+	/* dsb before isb of power down sequence */
+	dsb	sy
+1:
+	ret	x17
+endfunc errata_a78_2772019_wa
+
+func check_errata_2772019
+	/* Applies to all revisions <= r1p2 */
+	mov	x1, #0x12
+	b	cpu_rev_var_ls
+endfunc check_errata_2772019
+
 func check_errata_cve_2022_23960
 #if WORKAROUND_CVE_2022_23960
 	mov	x0, #ERRATA_APPLIES
@@ -434,6 +459,12 @@
 	mrs	x0, CORTEX_A78_CPUPWRCTLR_EL1
 	orr	x0, x0, #CORTEX_A78_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
 	msr	CORTEX_A78_CPUPWRCTLR_EL1, x0
+#if ERRATA_A78_2772019
+	mov	x15, x30
+	bl	cpu_get_rev_var
+	bl	errata_a78_2772019_wa
+	mov	x30, x15
+#endif /* ERRATA_A78_2772019 */
 	isb
 	ret
 endfunc cortex_a78_core_pwr_dwn
@@ -461,6 +492,7 @@
 	report_errata ERRATA_A78_2242635, cortex_a78, 2242635
 	report_errata ERRATA_A78_2376745, cortex_a78, 2376745
 	report_errata ERRATA_A78_2395406, cortex_a78, 2395406
+	report_errata ERRATA_A78_2772019, cortex_a78, 2772019
 	report_errata WORKAROUND_CVE_2022_23960, cortex_a78, cve_2022_23960
 
 	ldp	x8, x30, [sp], #16
diff --git a/lib/cpus/aarch64/cortex_x2.S b/lib/cpus/aarch64/cortex_x2.S
index f56d50a..497bd52 100644
--- a/lib/cpus/aarch64/cortex_x2.S
+++ b/lib/cpus/aarch64/cortex_x2.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -267,13 +267,43 @@
 	b	cpu_rev_var_range
 endfunc check_errata_2147715
 
-/* -------------------------------------------------------
- * Errata Workaround for Cortex-X2 Erratum 2371105.
- * This applies to revisions <= r2p0 and is fixed in r2p1.
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * -------------------------------------------------------
- */
+	/* ---------------------------------------------------------------
+	 * Errata Workaround for Cortex-X2 Erratum 2282622.
+	 * This applies to revision r0p0, r1p0, r2p0 and r2p1.
+	 * It is still open.
+	 * Inputs:
+	 * x0: variant[4:7] and revision[0:3] of current cpu.
+	 * Shall clobber: x0, x1, x17
+	 * ---------------------------------------------------------------
+	 */
+func errata_x2_2282622_wa
+	/* Compare x0 against revision r2p1 */
+	mov     x17, x30
+	bl      check_errata_2282622
+	cbz     x0, 1f
+
+	/* Apply the workaround */
+	mrs     x1, CORTEX_X2_CPUACTLR2_EL1
+	orr     x1, x1, #BIT(0)
+	msr     CORTEX_X2_CPUACTLR2_EL1, x1
+
+1:
+	ret     x17
+endfunc errata_x2_2282622_wa
+
+func check_errata_2282622
+	/* Applies to r0p0, r1p0, r2p0 and r2p1 */
+	mov     x1, #0x21
+	b       cpu_rev_var_ls
+endfunc check_errata_2282622
+
+	/* -------------------------------------------------------
+	 * Errata Workaround for Cortex-X2 Erratum 2371105.
+	 * This applies to revisions <= r2p0 and is fixed in r2p1.
+	 * x0: variant[4:7] and revision[0:3] of current cpu.
+	 * Shall clobber: x0-x17
+	 * -------------------------------------------------------
+	 */
 func errata_x2_2371105_wa
 	/* Check workaround compatibility. */
 	mov	x17, x30
@@ -295,13 +325,13 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_2371105
 
-/* ----------------------------------------------------
- * Errata Workaround for Cortex-X2 Errata #2768515
- * This applies to revisions <= r2p1 and is still open.
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * ----------------------------------------------------
- */
+	/* ----------------------------------------------------
+	 * Errata Workaround for Cortex-X2 Errata #2768515
+	 * This applies to revisions <= r2p1 and is still open.
+	 * x0: variant[4:7] and revision[0:3] of current cpu.
+	 * Shall clobber: x0-x17
+	 * ----------------------------------------------------
+	 */
 func errata_x2_2768515_wa
 	mov	x17, x30
 	bl	check_errata_2768515
@@ -362,6 +392,7 @@
 	report_errata ERRATA_X2_2083908, cortex_x2, 2083908
 	report_errata ERRATA_X2_2147715, cortex_x2, 2147715
 	report_errata ERRATA_X2_2216384, cortex_x2, 2216384
+	report_errata ERRATA_X2_2282622, cortex_x2, 2282622
 	report_errata ERRATA_X2_2371105, cortex_x2, 2371105
 	report_errata ERRATA_X2_2768515, cortex_x2, 2768515
 	report_errata WORKAROUND_CVE_2022_23960, cortex_x2, cve_2022_23960
@@ -421,6 +452,11 @@
 	bl	errata_x2_2147715_wa
 #endif
 
+#if ERRATA_X2_2282622
+	mov	x0, x18
+	bl	errata_x2_2282622_wa
+#endif
+
 #if ERRATA_X2_2371105
 	mov	x0, x18
 	bl	errata_x2_2371105_wa
diff --git a/lib/cpus/aarch64/neoverse_n2.S b/lib/cpus/aarch64/neoverse_n2.S
index 5861dec..dbf5941 100644
--- a/lib/cpus/aarch64/neoverse_n2.S
+++ b/lib/cpus/aarch64/neoverse_n2.S
@@ -428,6 +428,30 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_2388450
 
+/* -------------------------------------------------------
+ * Errata Workaround for Neoverse N2 Erratum 2743089.
+ * This applies to revisions <= r0p2 and is fixed in r0p3.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * -------------------------------------------------------
+ */
+func errata_n2_2743089_wa
+	mov	x17, x30
+	bl	check_errata_2743089
+	cbz	x0, 1f
+
+	/* dsb before isb of power down sequence */
+	dsb	sy
+1:
+	ret	x17
+endfunc errata_n2_2743089_wa
+
+func check_errata_2743089
+	/* Applies to all revisions <= r0p2 */
+	mov	x1, #0x02
+	b	cpu_rev_var_ls
+endfunc check_errata_2743089
+
 func check_errata_cve_2022_23960
 #if WORKAROUND_CVE_2022_23960
 	mov	x0, #ERRATA_APPLIES
@@ -576,6 +600,12 @@
 	mrs	x0, NEOVERSE_N2_CPUPWRCTLR_EL1
 	orr	x0, x0, #NEOVERSE_N2_CORE_PWRDN_EN_BIT
 	msr	NEOVERSE_N2_CPUPWRCTLR_EL1, x0
+#if ERRATA_N2_2743089
+	mov	x15, x30
+	bl	cpu_get_rev_var
+	bl	errata_n2_2743089_wa
+	mov	x30, x15
+#endif /* ERRATA_N2_2743089 */
 	isb
 	ret
 endfunc neoverse_n2_core_pwr_dwn
@@ -607,6 +637,7 @@
 	report_errata ERRATA_N2_2326639, neoverse_n2, 2326639
 	report_errata ERRATA_N2_2376738, neoverse_n2, 2376738
 	report_errata ERRATA_N2_2388450, neoverse_n2, 2388450
+	report_errata ERRATA_N2_2743089, neoverse_n2, 2743089
 	report_errata WORKAROUND_CVE_2022_23960, neoverse_n2, cve_2022_23960
 	report_errata ERRATA_DSU_2313941, neoverse_n2, dsu_2313941
 
diff --git a/lib/cpus/aarch64/neoverse_v1.S b/lib/cpus/aarch64/neoverse_v1.S
index 3282fbc..c3a70ca 100644
--- a/lib/cpus/aarch64/neoverse_v1.S
+++ b/lib/cpus/aarch64/neoverse_v1.S
@@ -462,6 +462,30 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_2372203
 
+	/* ----------------------------------------------------
+	 * Errata Workaround for Neoverse V1 Errata #2743093.
+	 * This applies to revisions <= r1p2 and is still open.
+	 * x0: variant[4:7] and revision[0:3] of current cpu.
+	 * Shall clobber: x0-x17
+	 * ----------------------------------------------------
+	 */
+func errata_neoverse_v1_2743093_wa
+	mov	x17, x30
+	bl	check_errata_2743093
+	cbz	x0, 1f
+
+	/* dsb before isb of power down sequence */
+	dsb	sy
+1:
+	ret	x17
+endfunc errata_neoverse_v1_2743093_wa
+
+func check_errata_2743093
+	/* Applies to all revisions <= r1p2 */
+	mov	x1, #0x12
+	b	cpu_rev_var_ls
+endfunc check_errata_2743093
+
 func check_errata_cve_2022_23960
 #if WORKAROUND_CVE_2022_23960
 	mov	x0, #ERRATA_APPLIES
@@ -483,6 +507,12 @@
 	mrs	x0, NEOVERSE_V1_CPUPWRCTLR_EL1
 	orr	x0, x0, #NEOVERSE_V1_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
 	msr	NEOVERSE_V1_CPUPWRCTLR_EL1, x0
+#if ERRATA_V1_2743093
+	mov	x15, x30
+	bl	cpu_get_rev_var
+	bl	errata_neoverse_v1_2743093_wa
+	mov	x30, x15
+#endif /* ERRATA_V1_2743093 */
 	isb
 	ret
 endfunc neoverse_v1_core_pwr_dwn
@@ -513,6 +543,7 @@
 	report_errata ERRATA_V1_2216392, neoverse_v1, 2216392
 	report_errata ERRATA_V1_2294912, neoverse_v1, 2294912
 	report_errata ERRATA_V1_2372203, neoverse_v1, 2372203
+	report_errata ERRATA_V1_2743093, neoverse_v1, 2743093
 	report_errata WORKAROUND_CVE_2022_23960, neoverse_v1, cve_2022_23960
 
 	ldp	x8, x30, [sp], #16
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 527a82f..c9b4447 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2014-2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.
 # Copyright (c) 2020-2022, NVIDIA Corporation. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
@@ -357,6 +357,11 @@
 # to revisions r0p0, r1p0, r1p1, and r1p2 of the A78 cpu. It is still open.
 ERRATA_A78_2395406	?=0
 
+# Flag to apply erratum 2772019 workaround during powerdown. This erratum
+# applies to revisions r0p0, r1p0, r1p1 and r1p2 of the A78 cpu. It is still
+# open.
+ERRATA_A78_2772019	?=0
+
 # Flag to apply erratum 1941500 workaround during reset. This erratum applies
 # to revisions r0p0 and r0p1 of the A78 AE cpu. It is still open.
 ERRATA_A78_AE_1941500	?=0
@@ -462,10 +467,6 @@
 # applies to all revisions <= r4p1 of the Neoverse N1 cpu and is still open.
 ERRATA_N1_2743102	?=0
 
-# Flag to apply erratum 2002655 workaround during reset. This erratum applies
-# to revisions r0p0 of the Neoverse-N2 cpu, it is still open.
-ERRATA_N2_2002655	?=0
-
 # Flag to apply erratum 1618635 workaround during reset. This erratum applies
 # to revision r0p0 of the Neoverse V1 cpu and was fixed in the revision r1p0.
 ERRATA_V1_1618635	?=0
@@ -516,6 +517,11 @@
 # to revisions r0p0, r1p0 and r1p1 of the Neoverse V1 cpu and is still open.
 ERRATA_V1_2372203	?=0
 
+# Flag to apply erratum 2743093 workaround during powerdown. This erratum
+# applies to revisions r0p0, r1p0, r1p1 and r1p2  of the Neoverse V1 cpu and is
+# still open.
+ERRATA_V1_2743093	?=0
+
 # Flag to apply erratum 1987031 workaround during reset. This erratum applies
 # to revisions r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is still open.
 ERRATA_A710_1987031	?=0
@@ -557,7 +563,8 @@
 ERRATA_A710_2216384	?=0
 
 # Flag to apply erratum 2282622 workaround during reset. This erratum applies
-# to revision r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is fixed in r2p1.
+# to revision r0p0, r1p0, r2p0 and r2p1 of the Cortex-A710 cpu and is still
+# open.
 ERRATA_A710_2282622	?=0
 
 # Flag to apply erratum 2291219 workaround during reset. This erratum applies
@@ -577,6 +584,10 @@
 # still open.
 ERRATA_A710_2768515	?=0
 
+# Flag to apply erratum 2002655 workaround during reset. This erratum applies
+# to revisions r0p0 of the Neoverse-N2 cpu, it is still open.
+ERRATA_N2_2002655	?=0
+
 # Flag to apply erratum 2067956 workaround during reset. This erratum applies
 # to revision r0p0 of the Neoverse N2 cpu and is still open.
 ERRATA_N2_2067956	?=0
@@ -625,6 +636,10 @@
 # to revision r0p0 of the Neoverse N2 cpu, it is fixed in r0p1.
 ERRATA_N2_2388450	?=0
 
+# Flag to apply erratum 2743089 workaround during during powerdown. This erratum
+# applies to all revisions <= r0p2 of the Neoverse N2 cpu, it is fixed in r0p3.
+ERRATA_N2_2743089	?=0
+
 # Flag to apply erratum 2002765 workaround during reset. This erratum applies
 # to revisions r0p0, r1p0, and r2p0 of the Cortex-X2 cpu and is still open.
 ERRATA_X2_2002765	?=0
@@ -656,6 +671,11 @@
 # only to revision r2p0 of the Cortex-X2 cpu, it is fixed in r2p1.
 ERRATA_X2_2147715	?=0
 
+# Flag to apply erratum 2282622 workaround during reset. This erratum applies
+# to revision r0p0, r1p0, r2p0 and r2p1 of the Cortex-X2 cpu and is still
+# open.
+ERRATA_X2_2282622	?=0
+
 # Flag to apply erratum 2371105 workaround during reset. This erratum applies
 # to revision r0p0, r1p0 and r2p0 of the Cortex-X2 cpu and is fixed in r2p1.
 ERRATA_X2_2371105	?=0
@@ -1006,6 +1026,10 @@
 $(eval $(call assert_boolean,ERRATA_A78_2395406))
 $(eval $(call add_define,ERRATA_A78_2395406))
 
+# Process ERRATA_A78_2772019 flag
+$(eval $(call assert_boolean,ERRATA_A78_2772019))
+$(eval $(call add_define,ERRATA_A78_2772019))
+
 # Process ERRATA_A78_AE_1941500 flag
 $(eval $(call assert_boolean,ERRATA_A78_AE_1941500))
 $(eval $(call add_define,ERRATA_A78_AE_1941500))
@@ -1109,10 +1133,6 @@
 # Process ERRATA_N1_2743102 flag
 $(eval $(call assert_boolean,ERRATA_N1_2743102))
 $(eval $(call add_define,ERRATA_N1_2743102))
-#
-# Process ERRATA_N2_2002655 flag
-$(eval $(call assert_boolean,ERRATA_N2_2002655))
-$(eval $(call add_define,ERRATA_N2_2002655))
 
 # Process ERRATA_V1_1618635 flag
 $(eval $(call assert_boolean,ERRATA_V1_1618635))
@@ -1162,6 +1182,10 @@
 $(eval $(call assert_boolean,ERRATA_V1_2372203))
 $(eval $(call add_define,ERRATA_V1_2372203))
 
+# Process ERRATA_V1_2743093 flag
+$(eval $(call assert_boolean,ERRATA_V1_2743093))
+$(eval $(call add_define,ERRATA_V1_2743093))
+
 # Process ERRATA_A710_1987031 flag
 $(eval $(call assert_boolean,ERRATA_A710_1987031))
 $(eval $(call add_define,ERRATA_A710_1987031))
@@ -1222,6 +1246,10 @@
 $(eval $(call assert_boolean,ERRATA_A710_2768515))
 $(eval $(call add_define,ERRATA_A710_2768515))
 
+# Process ERRATA_N2_2002655 flag
+$(eval $(call assert_boolean,ERRATA_N2_2002655))
+$(eval $(call add_define,ERRATA_N2_2002655))
+
 # Process ERRATA_N2_2067956 flag
 $(eval $(call assert_boolean,ERRATA_N2_2067956))
 $(eval $(call add_define,ERRATA_N2_2067956))
@@ -1270,6 +1298,10 @@
 $(eval $(call assert_boolean,ERRATA_N2_2388450))
 $(eval $(call add_define,ERRATA_N2_2388450))
 
+# Process ERRATA_N2_2743089 flag
+$(eval $(call assert_boolean,ERRATA_N2_2743089))
+$(eval $(call add_define,ERRATA_N2_2743089))
+
 # Process ERRATA_X2_2002765 flag
 $(eval $(call assert_boolean,ERRATA_X2_2002765))
 $(eval $(call add_define,ERRATA_X2_2002765))
@@ -1298,6 +1330,10 @@
 $(eval $(call assert_boolean,ERRATA_X2_2147715))
 $(eval $(call add_define,ERRATA_X2_2147715))
 
+# Process ERRATA_X2_2282622 flag
+$(eval $(call assert_boolean,ERRATA_X2_2282622))
+$(eval $(call add_define,ERRATA_X2_2282622))
+
 # Process ERRATA_X2_2371105 flag
 $(eval $(call assert_boolean,ERRATA_X2_2371105))
 $(eval $(call add_define,ERRATA_X2_2371105))
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index 60501f6..aa0327b 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -285,7 +285,7 @@
 	mrs	x12, MPAMVPMV_EL2
 	stp	x11, x12, [x0, #CTX_MPAMVPM7_EL2]
 	ret
-endfunc func el2_sysregs_context_save_mpam
+endfunc el2_sysregs_context_save_mpam
 
 func el2_sysregs_context_restore_mpam
 	ldr	x10, [x0, #CTX_MPAM2_EL2]
diff --git a/lib/libc/snprintf.c b/lib/libc/snprintf.c
index 6a2f0ba..0e3256c 100644
--- a/lib/libc/snprintf.c
+++ b/lib/libc/snprintf.c
@@ -209,6 +209,7 @@
 				break;
 			case 'X':
 				capitalise = true;
+				/* fallthrough */
 			case 'x':
 				unum = get_unum_va_args(args, l_count);
 				unsigned_num_print(&s, n, &chars_printed,
diff --git a/plat/arm/board/fvp/fvp_sync_traps.c b/plat/arm/board/fvp/fvp_sync_traps.c
new file mode 100644
index 0000000..91240f7
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_sync_traps.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2022, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file just contains demonstration code, to "handle" RNG traps.
+ */
+
+#include <stdbool.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <bl31/sync_handle.h>
+#include <context.h>
+
+/*
+ * SCR_EL3.SCR_TRNDR_BIT also affects execution in EL3, so allow to disable
+ * the trap temporarily.
+ */
+static void enable_rng_trap(bool enable)
+{
+	uint64_t scr_el3 = read_scr_el3();
+
+	if (enable) {
+		scr_el3 |= SCR_TRNDR_BIT;
+	} else {
+		scr_el3 &= ~SCR_TRNDR_BIT;
+	}
+
+	write_scr_el3(scr_el3);
+	isb();
+}
+
+/*
+ * This emulation code here is not very meaningful: enabling the RNG
+ * trap typically happens for a reason, so just calling the actual
+ * hardware instructions might not be useful or even possible.
+ */
+int plat_handle_rng_trap(uint64_t esr_el3, cpu_context_t *ctx)
+{
+	/* extract the target register number from the exception syndrome */
+	unsigned int rt = get_sysreg_iss_rt(esr_el3);
+
+	/* ignore XZR accesses and writes to the register */
+	if (rt == 31 || is_sysreg_iss_write(esr_el3)) {
+		return TRAP_RET_CONTINUE;
+	}
+
+	enable_rng_trap(false);
+	if ((esr_el3 & ISS_SYSREG_OPCODE_MASK) == ISS_SYSREG_OPCODE_RNDR) {
+		ctx->gpregs_ctx.ctx_regs[rt] = read_rndr();
+	} else {
+		ctx->gpregs_ctx.ctx_regs[rt] = read_rndrrs();
+	}
+	enable_rng_trap(true);
+
+	/*
+	 * We successfully handled the trap, continue with the next
+	 * instruction.
+	 */
+	return TRAP_RET_CONTINUE;
+}
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 51ba035..f28a6ff 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -198,6 +198,10 @@
 				plat/arm/board/fvp/fvp_realm_attest_key.c
 endif
 
+ifeq (${ENABLE_FEAT_RNG_TRAP},1)
+BL31_SOURCES		+=	plat/arm/board/fvp/fvp_sync_traps.c
+endif
+
 ifeq (${BL2_AT_EL3},1)
 BL2_SOURCES		+=	plat/arm/board/fvp/${ARCH}/fvp_helpers.S	\
 				plat/arm/board/fvp/fvp_bl2_el3_setup.c		\
diff --git a/plat/arm/board/rdn2/include/platform_def.h b/plat/arm/board/rdn2/include/platform_def.h
index 3474016..8e63de5 100644
--- a/plat/arm/board/rdn2/include/platform_def.h
+++ b/plat/arm/board/rdn2/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -92,6 +92,8 @@
 
 #if (CSS_SGI_PLATFORM_VARIANT == 1)
 #define PLAT_ARM_GICR_BASE		UL(0x30100000)
+#elif (CSS_SGI_PLATFORM_VARIANT == 3)
+#define PLAT_ARM_GICR_BASE		UL(0x30300000)
 #else
 #define PLAT_ARM_GICR_BASE		UL(0x301C0000)
 #endif
diff --git a/plat/arm/board/rdn2/platform.mk b/plat/arm/board/rdn2/platform.mk
index 7492fe5..b30e3fc 100644
--- a/plat/arm/board/rdn2/platform.mk
+++ b/plat/arm/board/rdn2/platform.mk
@@ -1,13 +1,13 @@
-# Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-RD_N2_VARIANTS	:= 0 1 2
+RD_N2_VARIANTS	:= 0 1 2 3
 ifneq ($(CSS_SGI_PLATFORM_VARIANT),\
 	$(filter $(CSS_SGI_PLATFORM_VARIANT),$(RD_N2_VARIANTS)))
- $(error "CSS_SGI_PLATFORM_VARIANT for RD-N2 should be 0, 1 or 2, currently set \
-     to ${CSS_SGI_PLATFORM_VARIANT}.")
+ $(error "CSS_SGI_PLATFORM_VARIANT for RD-N2 should be 0, 1, 2 or 3, currently \
+	set to ${CSS_SGI_PLATFORM_VARIANT}.")
 endif
 
 $(eval $(call CREATE_SEQ,SEQ,4))
diff --git a/plat/arm/board/rdn2/rdn2_topology.c b/plat/arm/board/rdn2/rdn2_topology.c
index 89300f8..24acc4d 100644
--- a/plat/arm/board/rdn2/rdn2_topology.c
+++ b/plat/arm/board/rdn2/rdn2_topology.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,19 +16,22 @@
 	CSS_SGI_MAX_CPUS_PER_CLUSTER,
 	CSS_SGI_MAX_CPUS_PER_CLUSTER,
 	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-#if (CSS_SGI_PLATFORM_VARIANT != 2 || (CSS_SGI_PLATFORM_VARIANT == 2 && CSS_SGI_CHIP_COUNT > 1))
+#if (PLAT_ARM_CLUSTER_COUNT > 4 || \
+	(CSS_SGI_PLATFORM_VARIANT == 2 && CSS_SGI_CHIP_COUNT > 1))
 	CSS_SGI_MAX_CPUS_PER_CLUSTER,
 	CSS_SGI_MAX_CPUS_PER_CLUSTER,
 	CSS_SGI_MAX_CPUS_PER_CLUSTER,
 	CSS_SGI_MAX_CPUS_PER_CLUSTER,
 #endif
-#if (CSS_SGI_PLATFORM_VARIANT == 0 || (CSS_SGI_PLATFORM_VARIANT == 2 && CSS_SGI_CHIP_COUNT > 2))
+#if (PLAT_ARM_CLUSTER_COUNT > 8 || \
+	(CSS_SGI_PLATFORM_VARIANT == 2 && CSS_SGI_CHIP_COUNT > 2))
 	CSS_SGI_MAX_CPUS_PER_CLUSTER,
 	CSS_SGI_MAX_CPUS_PER_CLUSTER,
 	CSS_SGI_MAX_CPUS_PER_CLUSTER,
 	CSS_SGI_MAX_CPUS_PER_CLUSTER,
 #endif
-#if (CSS_SGI_PLATFORM_VARIANT == 0 || (CSS_SGI_PLATFORM_VARIANT == 2 && CSS_SGI_CHIP_COUNT > 3))
+#if (PLAT_ARM_CLUSTER_COUNT > 8 || \
+	(CSS_SGI_PLATFORM_VARIANT == 2 && CSS_SGI_CHIP_COUNT > 3))
 	CSS_SGI_MAX_CPUS_PER_CLUSTER,
 	CSS_SGI_MAX_CPUS_PER_CLUSTER,
 	CSS_SGI_MAX_CPUS_PER_CLUSTER,
@@ -83,7 +86,7 @@
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x5)),
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x6)),
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x7)),
-#if (CSS_SGI_PLATFORM_VARIANT == 0)
+#if (PLAT_ARM_CLUSTER_COUNT > 8)
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x8)),
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x9)),
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xA)),
diff --git a/plat/arm/board/tc/include/platform_def.h b/plat/arm/board/tc/include/platform_def.h
index bc4f254..a3b7839 100644
--- a/plat/arm/board/tc/include/platform_def.h
+++ b/plat/arm/board/tc/include/platform_def.h
@@ -25,13 +25,28 @@
  * The top 16MB of ARM_DRAM1 is configured as secure access only using the TZC,
  * its base is ARM_AP_TZC_DRAM1_BASE.
  *
- * Reserve 32MB below ARM_AP_TZC_DRAM1_BASE for:
+ * Reserve 96 MB below ARM_AP_TZC_DRAM1_BASE for:
  *   - BL32_BASE when SPD_spmd is enabled
- *   - Region to load Trusted OS
+ *   - Region to load secure partitions
+ *
+ *
+ *  0xF900_0000  ------------------   TC_TZC_DRAM1_BASE
+ *               |                |
+ *               |      SPMC      |
+ *               |       SP       |
+ *               |     (96MB)     |
+ *  0xFF00_0000  ------------------   ARM_AP_TZC_DRAM1_BASE
+ *               |       AP       |
+ *               |   EL3 Monitor  |
+ *               |       SCP      |
+ *               |     (16MB)     |
+ *  0xFFFF_FFFF  ------------------
+ *
+ *
  */
 #define TC_TZC_DRAM1_BASE		(ARM_AP_TZC_DRAM1_BASE -	\
 					 TC_TZC_DRAM1_SIZE)
-#define TC_TZC_DRAM1_SIZE		UL(0x02000000)	/* 32 MB */
+#define TC_TZC_DRAM1_SIZE		96 * SZ_1M	/* 96 MB */
 #define TC_TZC_DRAM1_END		(TC_TZC_DRAM1_BASE +		\
 					 TC_TZC_DRAM1_SIZE - 1)
 
@@ -68,7 +83,9 @@
  * max size of BL32 image.
  */
 #if defined(SPD_spmd)
-#define PLAT_ARM_SPMC_BASE		TC_TZC_DRAM1_BASE
+#define TC_EL2SPMC_LOAD_ADDR		(TC_TZC_DRAM1_BASE + 0x04000000)
+
+#define PLAT_ARM_SPMC_BASE		TC_EL2SPMC_LOAD_ADDR
 #define PLAT_ARM_SPMC_SIZE		UL(0x200000)  /* 2 MB */
 #endif
 
@@ -101,7 +118,7 @@
  * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size
  * plus a little space for growth.
  */
-#define PLAT_ARM_MAX_BL1_RW_SIZE	0xD000
+#define PLAT_ARM_MAX_BL1_RW_SIZE	0x12000
 
 /*
  * PLAT_ARM_MAX_ROMLIB_RW_SIZE is define to use a full page
@@ -129,7 +146,7 @@
  * BL2 and BL1-RW. Current size is considering that TRUSTED_BOARD_BOOT and
  * MEASURED_BOOT is enabled.
  */
-#define PLAT_ARM_MAX_BL31_SIZE		0x47000
+#define PLAT_ARM_MAX_BL31_SIZE		0x60000
 
 /*
  * Size of cacheable stacks
@@ -152,7 +169,7 @@
 # if SPM_MM
 #  define PLATFORM_STACK_SIZE		0x500
 # else
-#  define PLATFORM_STACK_SIZE		0x400
+#  define PLATFORM_STACK_SIZE		0xa00
 # endif
 #elif defined(IMAGE_BL32)
 # define PLATFORM_STACK_SIZE		0x440
@@ -276,8 +293,8 @@
 		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_DEFAULT))
 
 /*
- * The first region below, TC_TZC_DRAM1_BASE (0xfd000000) to
- * ARM_SCP_TZC_DRAM1_END (0xffffffff) will mark the last 48 MB of DRAM as
+ * The first region below, TC_TZC_DRAM1_BASE (0xf9000000) to
+ * ARM_SCP_TZC_DRAM1_END (0xffffffff) will mark the last 112 MB of DRAM as
  * secure. The second and third regions gives non secure access to rest of DRAM.
  */
 #define TC_TZC_REGIONS_DEF	\
diff --git a/plat/arm/board/tc/include/tc_plat.h b/plat/arm/board/tc/include/tc_plat.h
index 28c0308..f7ce2fe 100644
--- a/plat/arm/board/tc/include/tc_plat.h
+++ b/plat/arm/board/tc/include/tc_plat.h
@@ -9,4 +9,8 @@
 
 void tc_bl31_common_platform_setup(void);
 
+#ifdef PLATFORM_TEST
+void run_platform_tests(void);
+#endif
+
 #endif /* TC_PLAT_H */
diff --git a/plat/arm/board/tc/plat_tc_mbedtls_config.h b/plat/arm/board/tc/plat_tc_mbedtls_config.h
new file mode 100644
index 0000000..d776b63
--- /dev/null
+++ b/plat/arm/board/tc/plat_tc_mbedtls_config.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2022, Arm Ltd. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_TC_MBEDTLS_CONFIG_H
+#define PLAT_TC_MBEDTLS_CONFIG_H
+
+#include <mbedtls_config.h>
+#include <export/lib/utils_def_exp.h>
+
+#ifndef TF_MBEDTLS_HEAP_SIZE
+#error TF_MBEDTLS_HEAP_SIZE is not defined
+#else
+#define PLATFORM_TEST_MIN_MBEDTLS_HEAP_SIZE	(8 * 1024)
+/* Only change heap size if it is less then the minimum required. */
+#if TF_MBEDTLS_HEAP_SIZE < PLATFORM_TEST_MIN_MBEDTLS_HEAP_SIZE
+#undef TF_MBEDTLS_HEAP_SIZE
+#define TF_MBEDTLS_HEAP_SIZE	PLATFORM_TEST_MIN_MBEDTLS_HEAP_SIZE
+#endif
+#endif
+
+#define MBEDTLS_PSA_CRYPTO_C
+#define MBEDTLS_HMAC_DRBG_C
+#define MBEDTLS_ENTROPY_C
+#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
+#define MBEDTLS_NO_PLATFORM_ENTROPY
+#define MBEDTLS_TEST_NULL_ENTROPY
+#define MBEDTLS_ECP_C
+#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
+
+#endif /* PLAT_TC_MBEDTLS_CONFIG_H */
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index 37ba229..74c0f17 100644
--- a/plat/arm/board/tc/platform.mk
+++ b/plat/arm/board/tc/platform.mk
@@ -193,6 +193,11 @@
 
 endif
 
+# Add this include as first, before arm_common.mk. This is necessary because
+# arm_common.mk builds Mbed TLS, and platform_test.mk can change the list of
+# Mbed TLS files that are to be compiled (LIBMBEDTLS_SRCS).
+include plat/arm/board/tc/platform_test.mk
+
 include plat/arm/common/arm_common.mk
 include plat/arm/css/common/css_common.mk
 include plat/arm/soc/common/soc_css.mk
diff --git a/plat/arm/board/tc/platform_test.mk b/plat/arm/board/tc/platform_test.mk
new file mode 100644
index 0000000..c2ee69e
--- /dev/null
+++ b/plat/arm/board/tc/platform_test.mk
@@ -0,0 +1,80 @@
+# Copyright (c) 2022, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ifeq (${PLATFORM_TEST},1)
+
+    # The variables need to be set to compile the platform test:
+    ifeq (${TF_M_TESTS_PATH},)
+        # Example: ../rss/tf-m-tests
+        $(error Error: TF_M_TESTS_PATH not set)
+    endif
+    ifeq (${TF_M_EXTRAS_PATH},)
+        # Example: ../rss/tf-m-extras
+        $(error Error: TF_M_EXTRAS_PATH not set)
+    endif
+    ifeq (${MEASUREMENT_VALUE_SIZE},)
+        MEASUREMENT_VALUE_SIZE	:=	32
+    endif
+    ifeq (${MEASURED_BOOT_HASH_ALG},)
+        MEASURED_BOOT_HASH_ALG	:=	"PSA_ALG_SHA_256"
+    endif
+
+    DELEGATED_ATTEST_TESTS_PATH	=	$(TF_M_EXTRAS_PATH)/partitions/delegated_attestation/test
+    MEASURED_BOOT_TESTS_PATH	=	$(TF_M_EXTRAS_PATH)/partitions/measured_boot/test
+
+    MBEDTLS_CONFIG_FILE		=	"<plat_tc_mbedtls_config.h>"
+
+    LIBMBEDTLS_SRCS		+= 	$(addprefix ${MBEDTLS_DIR}/library/,	\
+					entropy.c				\
+					entropy_poll.c				\
+					hmac_drbg.c				\
+					psa_crypto.c				\
+					psa_crypto_client.c			\
+					psa_crypto_driver_wrappers.c		\
+					psa_crypto_hash.c			\
+					psa_crypto_rsa.c			\
+					psa_crypto_ecp.c			\
+					psa_crypto_slot_management.c		\
+					)
+
+    BL31_SOURCES	+=	${RSS_COMMS_SOURCES} 				\
+				plat/arm/common/arm_dyn_cfg.c 			\
+				${TC_BASE}/rss_ap_tests.c 			\
+				${TC_BASE}/rss_ap_testsuites.c 			\
+				${TC_BASE}/rss_ap_test_stubs.c			\
+				$(TF_M_TESTS_PATH)/test/framework/test_framework.c \
+				$(MEASURED_BOOT_TESTS_PATH)/measured_boot_common.c \
+				$(MEASURED_BOOT_TESTS_PATH)/measured_boot_tests_common.c \
+				$(DELEGATED_ATTEST_TESTS_PATH)/delegated_attest_test.c \
+				drivers/auth/mbedtls/mbedtls_common.c 		\
+				lib/psa/measured_boot.c 			\
+				lib/psa/delegated_attestation.c
+
+    PLAT_INCLUDES	+=	-I$(TF_M_EXTRAS_PATH)/partitions/measured_boot/interface/include \
+				-I$(TF_M_EXTRAS_PATH)/partitions/delegated_attestation/interface/include \
+				-I$(TF_M_TESTS_PATH)/test/framework 		\
+				-I$(TF_M_TESTS_PATH)/log 			\
+				-I$(TF_M_TESTS_PATH)/test/secure_fw/suites/extra \
+				-I$(MEASURED_BOOT_TESTS_PATH)/non_secure 	\
+				-I$(DELEGATED_ATTEST_TESTS_PATH) 		\
+				-I$(DELEGATED_ATTEST_TESTS_PATH)/non_secure \
+				-Iplat/arm/board/tc 				\
+				-Iinclude/drivers/auth/mbedtls 			\
+				-Iinclude/drivers/arm
+
+    # Some of the PSA functions are declared in multiple header files, that
+    # triggers this warning.
+    TF_CFLAGS		+=	-Wno-error=redundant-decls
+
+    # TODO: Created patch for warning in tf-m-tests
+    TF_CFLAGS		+=	-Wno-error=return-type
+
+    # Define macros that are used by the code coming from the tf-m-extras repo.
+    $(eval $(call add_define,MEASUREMENT_VALUE_SIZE))
+    $(eval $(call add_define,MEASURED_BOOT_HASH_ALG))
+    $(eval $(call add_define,DELEG_ATTEST_DUMP_TOKEN_AND_KEY))
+
+    $(eval $(call add_define,PLATFORM_TEST))
+endif
diff --git a/plat/arm/board/tc/region_defs.h b/plat/arm/board/tc/region_defs.h
new file mode 100644
index 0000000..d3dfd13
--- /dev/null
+++ b/plat/arm/board/tc/region_defs.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2022, Arm Ltd. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef REGION_DEFS_H
+#define REGION_DEFS_H
+
+#define PSA_INITIAL_ATTEST_TOKEN_MAX_SIZE   0x800
+
+#endif /* REGION_DEFS_H */
diff --git a/plat/arm/board/tc/rss_ap_test_stubs.c b/plat/arm/board/tc/rss_ap_test_stubs.c
new file mode 100644
index 0000000..aa97476
--- /dev/null
+++ b/plat/arm/board/tc/rss_ap_test_stubs.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2022, Arm Ltd. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+#include <delegated_attestation.h>
+#include <measured_boot.h>
+#include <psa/error.h>
+
+
+psa_status_t
+tfm_measured_boot_extend_measurement(uint8_t index,
+				     const uint8_t *signer_id,
+				     size_t signer_id_size,
+				     const uint8_t *version,
+				     size_t version_size,
+				     uint32_t measurement_algo,
+				     const uint8_t *sw_type,
+				     size_t sw_type_size,
+				     const uint8_t *measurement_value,
+				     size_t measurement_value_size,
+				     bool lock_measurement)
+{
+	return rss_measured_boot_extend_measurement(index,
+						    signer_id,
+						    signer_id_size,
+						    version,
+						    version_size,
+						    measurement_algo,
+						    sw_type,
+						    sw_type_size,
+						    measurement_value,
+						    measurement_value_size,
+						    lock_measurement);
+}
+
+psa_status_t
+tfm_measured_boot_read_measurement(uint8_t index,
+				   uint8_t *signer_id,
+				   size_t signer_id_size,
+				   size_t *signer_id_len,
+				   uint8_t *version,
+				   size_t version_size,
+				   size_t *version_len,
+				   uint32_t *measurement_algo,
+				   uint8_t *sw_type,
+				   size_t sw_type_size,
+				   size_t *sw_type_len,
+				   uint8_t *measurement_value,
+				   size_t measurement_value_size,
+				   size_t *measurement_value_len,
+				   bool *is_locked)
+{
+	return rss_measured_boot_read_measurement(index,
+						  signer_id,
+						  signer_id_size,
+						  signer_id_len,
+						  version,
+						  version_size,
+						  version_len,
+						  measurement_algo,
+						  sw_type,
+						  sw_type_size,
+						  sw_type_len,
+						  measurement_value,
+						  measurement_value_size,
+						  measurement_value_len,
+						  is_locked);
+}
+
+psa_status_t
+tfm_delegated_attest_get_token(const uint8_t *dak_pub_hash,
+			       size_t         dak_pub_hash_size,
+			       uint8_t       *token_buf,
+			       size_t         token_buf_size,
+			       size_t        *token_size)
+{
+	return rss_delegated_attest_get_token(dak_pub_hash,
+					      dak_pub_hash_size,
+					      token_buf,
+					      token_buf_size,
+					      token_size);
+}
+
+psa_status_t
+tfm_delegated_attest_get_delegated_key(uint8_t   ecc_curve,
+				       uint32_t  key_bits,
+				       uint8_t  *key_buf,
+				       size_t    key_buf_size,
+				       size_t   *key_size,
+				       uint32_t  hash_algo)
+{
+	return rss_delegated_attest_get_delegated_key(ecc_curve,
+						      key_bits,
+						      key_buf,
+						      key_buf_size,
+						      key_size,
+						      hash_algo);
+}
+
+int tfm_log_printf(const char *fmt, ...)
+{
+	int count;
+	va_list ap;
+
+	va_start(ap, fmt);
+	count = vprintf(fmt, ap);
+	va_end(ap);
+
+	return count;
+}
+
+void printf_set_color(int color_id)
+{
+	(void)color_id;
+}
diff --git a/plat/arm/board/tc/rss_ap_tests.c b/plat/arm/board/tc/rss_ap_tests.c
new file mode 100644
index 0000000..b62043e
--- /dev/null
+++ b/plat/arm/board/tc/rss_ap_tests.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2022, Arm Ltd. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdio.h>
+
+#include <mbedtls_common.h>
+#include <plat/common/platform.h>
+#include <psa/crypto.h>
+#include <rss_comms.h>
+
+#include "rss_ap_testsuites.h"
+
+static struct test_suite_t test_suites[] = {
+	{.freg = register_testsuite_delegated_attest},
+	{.freg = register_testsuite_measured_boot},
+};
+
+static void run_tests(void)
+{
+	enum test_suite_err_t ret;
+	psa_status_t status;
+	size_t i;
+
+	rss_comms_init(PLAT_RSS_AP_SND_MHU_BASE, PLAT_RSS_AP_RCV_MHU_BASE);
+	mbedtls_init();
+	status = psa_crypto_init();
+	if (status != PSA_SUCCESS) {
+		printf("\n\npsa_crypto_init failed (status = %d)\n", status);
+		assert(false);
+		plat_error_handler(-1);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(test_suites); ++i) {
+		struct test_suite_t *suite = &(test_suites[i]);
+
+		suite->freg(suite);
+		ret = run_testsuite(suite);
+		if (ret != TEST_SUITE_ERR_NO_ERROR) {
+			printf("\n\nError during executing testsuite '%s'.\n", suite->name);
+			assert(false);
+			plat_error_handler(-1);
+		}
+	}
+	printf("\nAll tests are run.\n");
+}
+
+void run_platform_tests(void)
+{
+	size_t i;
+
+	run_tests();
+
+	printf("\n\n");
+
+	/* Print a summary of all the tests that had been run. */
+	printf("SUMMARY:\n");
+	for (i = 0; i < ARRAY_SIZE(test_suites); ++i) {
+
+		struct test_suite_t *suite = &(test_suites[i]);
+
+		switch (suite->val) {
+		case TEST_PASSED:
+			printf("    %s PASSED.\n", suite->name);
+			break;
+		case TEST_FAILED:
+			printf("    %s FAILED.\n", suite->name);
+			break;
+		case TEST_SKIPPED:
+			printf("    %s SKIPPED.\n", suite->name);
+			break;
+		default:
+			assert(false);
+			break;
+		}
+	}
+
+	printf("\n\n");
+}
diff --git a/plat/arm/board/tc/rss_ap_testsuites.c b/plat/arm/board/tc/rss_ap_testsuites.c
new file mode 100644
index 0000000..aa47d4c
--- /dev/null
+++ b/plat/arm/board/tc/rss_ap_testsuites.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2022, Arm Ltd. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * `delegated_attest_ns_interface_testsuite.c` and
+ * `measured_boot_ns_interface_testsuite.c` are not added to the build directly.
+ * but are included in this file, and this file is added to the build. This is
+ * necessary because both files define the function `extra_tests_init`, so a
+ * linker error occurs when both are linked to BL31. This file defines a macro
+ * that renames the colliding function names to something unique.
+ * `plat/arm/board/tc/rss_ap_tests.c` can call the test init functions with
+ * their new name.
+ */
+
+#define register_testsuite_extra_ns_interface \
+	register_testsuite_delegated_attest
+#include <delegated_attest_ns_interface_testsuite.c>
+
+#undef register_testsuite_extra_ns_interface
+#define register_testsuite_extra_ns_interface \
+	register_testsuite_measured_boot
+#include <measured_boot_ns_interface_testsuite.c>
\ No newline at end of file
diff --git a/plat/arm/board/tc/rss_ap_testsuites.h b/plat/arm/board/tc/rss_ap_testsuites.h
new file mode 100644
index 0000000..58502ab
--- /dev/null
+++ b/plat/arm/board/tc/rss_ap_testsuites.h
@@ -0,0 +1,16 @@
+
+/*
+ * Copyright (c) 2022, Arm Ltd. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RSS_AP_TESTSUITES_H
+#define RSS_AP_TESTSUITES_H
+
+#include <test_framework.h>
+
+void register_testsuite_measured_boot(struct test_suite_t *p_test_suite);
+void register_testsuite_delegated_attest(struct test_suite_t *p_test_suite);
+
+#endif /* RSS_AP_TESTSUITES_H */
diff --git a/plat/arm/board/tc/tc_bl31_setup.c b/plat/arm/board/tc/tc_bl31_setup.c
index 2cdf045..c79558d 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-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -52,6 +52,12 @@
 void tc_bl31_common_platform_setup(void)
 {
 	arm_bl31_platform_setup();
+#ifdef PLATFORM_TEST
+	run_platform_tests();
+
+	/* Suspend booting */
+	plat_error_handler(-1);
+#endif
 }
 
 const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
diff --git a/plat/arm/css/sgi/include/sgi_variant.h b/plat/arm/css/sgi/include/sgi_variant.h
index 223ac3e..8f9529a 100644
--- a/plat/arm/css/sgi/include/sgi_variant.h
+++ b/plat/arm/css/sgi/include/sgi_variant.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,6 +22,7 @@
 
 /* SID Version values for RD-N2 variants */
 #define RD_N2_CFG1_SID_VER_PART_NUM		0x07B6
+#define RD_N2_CFG3_SID_VER_PART_NUM		0x07F1
 
 /* SID Version values for RD-V2 */
 #define RD_V2_SID_VER_PART_NUM			0x07F2
diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c
index 9adcb7c..df2ce38 100644
--- a/plat/arm/css/sgi/sgi_bl31_setup.c
+++ b/plat/arm/css/sgi/sgi_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -80,7 +80,8 @@
 		sgi_plat_info.platform_id == RD_V1_SID_VER_PART_NUM ||
 		sgi_plat_info.platform_id == RD_N2_SID_VER_PART_NUM ||
 		sgi_plat_info.platform_id == RD_V2_SID_VER_PART_NUM ||
-		sgi_plat_info.platform_id == RD_N2_CFG1_SID_VER_PART_NUM) {
+		sgi_plat_info.platform_id == RD_N2_CFG1_SID_VER_PART_NUM ||
+		sgi_plat_info.platform_id == RD_N2_CFG3_SID_VER_PART_NUM) {
 		if (channel_id >= ARRAY_SIZE(plat_rd_scmi_info))
 			panic();
 		return &plat_rd_scmi_info[channel_id];
diff --git a/plat/imx/common/imx_sip_handler.c b/plat/imx/common/imx_sip_handler.c
index d4b3425..ec8631a 100644
--- a/plat/imx/common/imx_sip_handler.c
+++ b/plat/imx/common/imx_sip_handler.c
@@ -20,7 +20,7 @@
 #if defined(PLAT_imx8qm) || defined(PLAT_imx8qx)
 
 #ifdef PLAT_imx8qm
-const static int ap_cluster_index[PLATFORM_CLUSTER_COUNT] = {
+static const int ap_cluster_index[PLATFORM_CLUSTER_COUNT] = {
 	SC_R_A53, SC_R_A72,
 };
 #endif
diff --git a/plat/imx/imx8qm/imx8qm_bl31_setup.c b/plat/imx/imx8qm/imx8qm_bl31_setup.c
index 68eb534..bd7896a 100644
--- a/plat/imx/imx8qm/imx8qm_bl31_setup.c
+++ b/plat/imx/imx8qm/imx8qm_bl31_setup.c
@@ -62,7 +62,7 @@
 #error "Provide proper UART number in IMX_DEBUG_UART"
 #endif
 
-const static int imx8qm_cci_map[] = {
+static const int imx8qm_cci_map[] = {
 	CLUSTER0_CCI_SLVAE_IFACE,
 	CLUSTER1_CCI_SLVAE_IFACE
 };
diff --git a/plat/imx/imx8qm/imx8qm_psci.c b/plat/imx/imx8qm/imx8qm_psci.c
index bdba37c..dcc502f 100644
--- a/plat/imx/imx8qm/imx8qm_psci.c
+++ b/plat/imx/imx8qm/imx8qm_psci.c
@@ -26,7 +26,7 @@
 #define SYSTEM_PWR_STATE(state) \
 	((state)->pwr_domain_state[PLAT_MAX_PWR_LVL])
 
-const static int ap_core_index[PLATFORM_CORE_COUNT] = {
+static const int ap_core_index[PLATFORM_CORE_COUNT] = {
 	SC_R_A53_0, SC_R_A53_1, SC_R_A53_2,
 	SC_R_A53_3, SC_R_A72_0, SC_R_A72_1,
 };
diff --git a/plat/imx/imx8qx/imx8qx_psci.c b/plat/imx/imx8qx/imx8qx_psci.c
index aab3a2d..5f05566 100644
--- a/plat/imx/imx8qx/imx8qx_psci.c
+++ b/plat/imx/imx8qx/imx8qx_psci.c
@@ -18,7 +18,7 @@
 
 #include "../../common/sci/imx8_mu.h"
 
-const static int ap_core_index[PLATFORM_CORE_COUNT] = {
+static const int ap_core_index[PLATFORM_CORE_COUNT] = {
 	SC_R_A35_0, SC_R_A35_1, SC_R_A35_2, SC_R_A35_3
 };
 
diff --git a/plat/mediatek/common/mtk_smc_handlers.c b/plat/mediatek/common/mtk_smc_handlers.c
index 51a960f..92b3873 100644
--- a/plat/mediatek/common/mtk_smc_handlers.c
+++ b/plat/mediatek/common/mtk_smc_handlers.c
@@ -51,6 +51,7 @@
 		x3 = x3 & MASK_32_BIT; \
 		x4 = x4 & MASK_32_BIT; \
 	} \
+	/* fallthrough */ \
 	case _smc_id##_AARCH64: \
 	{ \
 		if (_smc_id##_descriptor_index < 0) { \
diff --git a/plat/mediatek/drivers/iommu/mtk_iommu_smc.c b/plat/mediatek/drivers/iommu/mtk_iommu_smc.c
index 9762d0b..e998725 100644
--- a/plat/mediatek/drivers/iommu/mtk_iommu_smc.c
+++ b/plat/mediatek/drivers/iommu/mtk_iommu_smc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2022-2023, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -75,25 +75,32 @@
 	return MTK_SIP_E_SUCCESS;
 }
 
-static int mtk_infra_master_config_sec(uint32_t dev_id, uint32_t enable)
+static int mtk_infra_master_config_sec(uint32_t dev_id_msk, uint32_t enable)
 {
 	const struct mtk_ifr_mst_config *ifr_cfg;
-	uint32_t reg_addr;
+	uint32_t dev_id, reg_addr, reg_mask;
 
 	mtk_infra_iommu_enable_protect();
 
-	if (dev_id >= MMU_DEV_NUM) {
-		return MTK_SIP_E_NOT_SUPPORTED;
+	if (dev_id_msk >= BIT(MMU_DEV_NUM)) {
+		return MTK_SIP_E_INVALID_PARAM;
 	}
 
-	ifr_cfg = &g_ifr_mst_cfg[dev_id];
-	reg_addr = g_ifr_mst_cfg_base[(ifr_cfg->cfg_addr_idx)] +
-		   g_ifr_mst_cfg_offs[(ifr_cfg->cfg_addr_idx)];
+	for (dev_id = 0U; dev_id < MMU_DEV_NUM; dev_id++) {
+		if ((dev_id_msk & BIT(dev_id)) == 0U) {
+			continue;
+		}
 
-	if (enable > 0U) {
-		mmio_setbits_32(reg_addr, IFR_CFG_MMU_EN_MSK(ifr_cfg->r_mmu_en_bit));
-	} else {
-		mmio_clrbits_32(reg_addr, IFR_CFG_MMU_EN_MSK(ifr_cfg->r_mmu_en_bit));
+		ifr_cfg = &g_ifr_mst_cfg[dev_id];
+		reg_addr = g_ifr_mst_cfg_base[(ifr_cfg->cfg_addr_idx)] +
+			   g_ifr_mst_cfg_offs[(ifr_cfg->cfg_addr_idx)];
+		reg_mask = IFR_CFG_MMU_EN_MSK(ifr_cfg->r_mmu_en_bit);
+
+		if (enable > 0U) {
+			mmio_setbits_32(reg_addr, reg_mask);
+		} else {
+			mmio_clrbits_32(reg_addr, reg_mask);
+		}
 	}
 
 	return MTK_SIP_E_SUCCESS;
diff --git a/plat/nvidia/tegra/soc/t186/plat_memctrl.c b/plat/nvidia/tegra/soc/t186/plat_memctrl.c
index 81de674..2533013 100644
--- a/plat/nvidia/tegra/soc/t186/plat_memctrl.c
+++ b/plat/nvidia/tegra/soc/t186/plat_memctrl.c
@@ -20,7 +20,7 @@
 /*******************************************************************************
  * Array to hold stream_id override config register offsets
  ******************************************************************************/
-const static uint32_t tegra186_streamid_override_regs[] = {
+static const uint32_t tegra186_streamid_override_regs[] = {
 	MC_STREAMID_OVERRIDE_CFG_SDMMCRA,
 	MC_STREAMID_OVERRIDE_CFG_SDMMCRAA,
 	MC_STREAMID_OVERRIDE_CFG_SDMMCR,
@@ -34,7 +34,7 @@
 /*******************************************************************************
  * Array to hold the security configs for stream IDs
  ******************************************************************************/
-const static mc_streamid_security_cfg_t tegra186_streamid_sec_cfgs[] = {
+static const mc_streamid_security_cfg_t tegra186_streamid_sec_cfgs[] = {
 	mc_make_sec_cfg(SCEW, NON_SECURE, NO_OVERRIDE, DISABLE),
 	mc_make_sec_cfg(AFIR, NON_SECURE, OVERRIDE, DISABLE),
 	mc_make_sec_cfg(AFIW, NON_SECURE, OVERRIDE, DISABLE),
@@ -112,7 +112,7 @@
 /*******************************************************************************
  * Array to hold the transaction override configs
  ******************************************************************************/
-const static mc_txn_override_cfg_t tegra186_txn_override_cfgs[] = {
+static const mc_txn_override_cfg_t tegra186_txn_override_cfgs[] = {
 	mc_make_txn_override_cfg(BPMPW, CGID_TAG_ADR),
 	mc_make_txn_override_cfg(EQOSW, CGID_TAG_ADR),
 	mc_make_txn_override_cfg(NVJPGSWR, CGID_TAG_ADR),
diff --git a/plat/nxp/common/psci/plat_psci.c b/plat/nxp/common/psci/plat_psci.c
index 9281e97..f6dd7b3 100644
--- a/plat/nxp/common/psci/plat_psci.c
+++ b/plat/nxp/common/psci/plat_psci.c
@@ -350,7 +350,7 @@
 		else if (SOC_SYSTEM_STANDBY)
 			state->pwr_domain_state[PLAT_MAX_LVL] =
 				PLAT_MAX_RET_STATE;
-		 /* intentional fall-thru condition */
+		 /* fallthrough */
 	case PWR_STATE_LVL_SYS:
 		if (pwrdn && SOC_SYSTEM_PWR_DWN)
 			state->pwr_domain_state[PLAT_SYS_LVL] =
@@ -358,7 +358,7 @@
 		else if (SOC_SYSTEM_STANDBY)
 			state->pwr_domain_state[PLAT_SYS_LVL] =
 				PLAT_MAX_RET_STATE;
-		 /* intentional fall-thru condition */
+		 /* fallthrough */
 	case PWR_STATE_LVL_CLSTR:
 		if (pwrdn && SOC_CLUSTER_PWR_DWN)
 			state->pwr_domain_state[PLAT_CLSTR_LVL] =
@@ -366,7 +366,7 @@
 		else if (SOC_CLUSTER_STANDBY)
 			state->pwr_domain_state[PLAT_CLSTR_LVL] =
 				PLAT_MAX_RET_STATE;
-		 /* intentional fall-thru condition */
+		 /* fallthrough */
 	case PWR_STATE_LVL_CORE:
 		stat = PSCI_E_SUCCESS;
 
diff --git a/plat/qemu/qemu_sbsa/platform.mk b/plat/qemu/qemu_sbsa/platform.mk
index 5a6b1e1..2393b39 100644
--- a/plat/qemu/qemu_sbsa/platform.mk
+++ b/plat/qemu/qemu_sbsa/platform.mk
@@ -123,5 +123,6 @@
 ARM_PRELOADED_DTB_BASE := PLAT_QEMU_DT_BASE
 $(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
 
-# Do not enable SVE
-ENABLE_SVE_FOR_NS	:= 0
+# Later QEMU versions support SME and SVE.
+ENABLE_SVE_FOR_NS	:= 1
+ENABLE_SME_FOR_NS	:= 1
diff --git a/plat/st/common/include/stm32mp_common.h b/plat/st/common/include/stm32mp_common.h
index a5316b6..bb3401f 100644
--- a/plat/st/common/include/stm32mp_common.h
+++ b/plat/st/common/include/stm32mp_common.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2018-2023, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -35,6 +35,9 @@
 /* Return the base address of the RCC peripheral */
 uintptr_t stm32mp_rcc_base(void);
 
+void stm32mp_gic_pcpu_init(void);
+void stm32mp_gic_init(void);
+
 /* Check MMU status to allow spinlock use */
 bool stm32mp_lock_available(void);
 
@@ -113,12 +116,15 @@
 int stm32mp_map_ddr_non_cacheable(void);
 int stm32mp_unmap_ddr(void);
 
-/* Functions to save and get boot peripheral info */
-void stm32_save_boot_interface(uint32_t interface, uint32_t instance);
+/* Function to save boot info */
+void stm32_save_boot_info(boot_api_context_t *boot_context);
+/* Function to get boot peripheral info */
 void stm32_get_boot_interface(uint32_t *interface, uint32_t *instance);
+/* Function to get BOOT_MODE backup register address */
+uintptr_t stm32_get_bkpr_boot_mode_addr(void);
 
-/* Functions to save and get boot authentication status and partition used */
-void stm32_save_boot_auth(uint32_t auth_status, uint32_t boot_partition);
+/* Display board information from the value found in OTP fuse */
+void stm32_display_board_info(uint32_t board_id);
 
 #if PSA_FWU_SUPPORT
 void stm32mp1_fwu_set_boot_idx(void);
diff --git a/plat/st/common/stm32mp_common.c b/plat/st/common/stm32mp_common.c
index bb56bac..f842e16 100644
--- a/plat/st/common/stm32mp_common.c
+++ b/plat/st/common/stm32mp_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,7 @@
 #include <drivers/st/stm32_console.h>
 #include <drivers/st/stm32mp_clkfunc.h>
 #include <drivers/st/stm32mp_reset.h>
+#include <lib/mmio.h>
 #include <lib/smccc.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
@@ -24,6 +25,36 @@
 #define HEADER_VERSION_MAJOR_MASK	GENMASK(23, 16)
 #define RESET_TIMEOUT_US_1MS		1000U
 
+/* Internal layout of the 32bit OTP word board_id */
+#define BOARD_ID_BOARD_NB_MASK		GENMASK_32(31, 16)
+#define BOARD_ID_BOARD_NB_SHIFT		16
+#define BOARD_ID_VARCPN_MASK		GENMASK_32(15, 12)
+#define BOARD_ID_VARCPN_SHIFT		12
+#define BOARD_ID_REVISION_MASK		GENMASK_32(11, 8)
+#define BOARD_ID_REVISION_SHIFT		8
+#define BOARD_ID_VARFG_MASK		GENMASK_32(7, 4)
+#define BOARD_ID_VARFG_SHIFT		4
+#define BOARD_ID_BOM_MASK		GENMASK_32(3, 0)
+
+#define BOARD_ID2NB(_id)		(((_id) & BOARD_ID_BOARD_NB_MASK) >> \
+					 BOARD_ID_BOARD_NB_SHIFT)
+#define BOARD_ID2VARCPN(_id)		(((_id) & BOARD_ID_VARCPN_MASK) >> \
+					 BOARD_ID_VARCPN_SHIFT)
+#define BOARD_ID2REV(_id)		(((_id) & BOARD_ID_REVISION_MASK) >> \
+					 BOARD_ID_REVISION_SHIFT)
+#define BOARD_ID2VARFG(_id)		(((_id) & BOARD_ID_VARFG_MASK) >> \
+					 BOARD_ID_VARFG_SHIFT)
+#define BOARD_ID2BOM(_id)		((_id) & BOARD_ID_BOM_MASK)
+
+#define BOOT_AUTH_MASK			GENMASK_32(23, 20)
+#define BOOT_AUTH_SHIFT			20
+#define BOOT_PART_MASK			GENMASK_32(19, 16)
+#define BOOT_PART_SHIFT			16
+#define BOOT_ITF_MASK			GENMASK_32(15, 12)
+#define BOOT_ITF_SHIFT			12
+#define BOOT_INST_MASK			GENMASK_32(11, 8)
+#define BOOT_INST_SHIFT			8
+
 static console_t console;
 
 uintptr_t plat_get_ns_image_entrypoint(void)
@@ -277,3 +308,69 @@
 {
 	return (int32_t)(stm32mp_get_chip_version() & SOC_ID_REV_MASK);
 }
+
+void stm32_display_board_info(uint32_t board_id)
+{
+	char rev[2];
+
+	rev[0] = BOARD_ID2REV(board_id) - 1 + 'A';
+	rev[1] = '\0';
+	NOTICE("Board: MB%04x Var%u.%u Rev.%s-%02u\n",
+	       BOARD_ID2NB(board_id),
+	       BOARD_ID2VARCPN(board_id),
+	       BOARD_ID2VARFG(board_id),
+	       rev,
+	       BOARD_ID2BOM(board_id));
+}
+
+void stm32_save_boot_info(boot_api_context_t *boot_context)
+{
+	uint32_t auth_status;
+
+	assert(boot_context->boot_interface_instance <= (BOOT_INST_MASK >> BOOT_INST_SHIFT));
+	assert(boot_context->boot_interface_selected <= (BOOT_ITF_MASK >> BOOT_ITF_SHIFT));
+	assert(boot_context->boot_partition_used_toboot <= (BOOT_PART_MASK >> BOOT_PART_SHIFT));
+
+	switch (boot_context->auth_status) {
+	case BOOT_API_CTX_AUTH_NO:
+		auth_status = 0x0U;
+		break;
+
+	case BOOT_API_CTX_AUTH_SUCCESS:
+		auth_status = 0x2U;
+		break;
+
+	case BOOT_API_CTX_AUTH_FAILED:
+	default:
+		auth_status = 0x1U;
+		break;
+	}
+
+	clk_enable(TAMP_BKP_REG_CLK);
+
+	mmio_clrsetbits_32(stm32_get_bkpr_boot_mode_addr(),
+			   BOOT_ITF_MASK | BOOT_INST_MASK | BOOT_PART_MASK | BOOT_AUTH_MASK,
+			   (boot_context->boot_interface_instance << BOOT_INST_SHIFT) |
+			   (boot_context->boot_interface_selected << BOOT_ITF_SHIFT) |
+			   (boot_context->boot_partition_used_toboot << BOOT_PART_SHIFT) |
+			   (auth_status << BOOT_AUTH_SHIFT));
+
+	clk_disable(TAMP_BKP_REG_CLK);
+}
+
+void stm32_get_boot_interface(uint32_t *interface, uint32_t *instance)
+{
+	static uint32_t itf;
+
+	if (itf == 0U) {
+		clk_enable(TAMP_BKP_REG_CLK);
+
+		itf = mmio_read_32(stm32_get_bkpr_boot_mode_addr()) &
+		      (BOOT_ITF_MASK | BOOT_INST_MASK);
+
+		clk_disable(TAMP_BKP_REG_CLK);
+	}
+
+	*interface = (itf & BOOT_ITF_MASK) >> BOOT_ITF_SHIFT;
+	*instance = (itf & BOOT_INST_MASK) >> BOOT_INST_SHIFT;
+}
diff --git a/plat/st/common/stm32mp_crypto_lib.c b/plat/st/common/stm32mp_crypto_lib.c
index acfe701..0da0019 100644
--- a/plat/st/common/stm32mp_crypto_lib.c
+++ b/plat/st/common/stm32mp_crypto_lib.c
@@ -79,7 +79,7 @@
 	}
 }
 
-int get_plain_pk_from_asn1(void *pk_ptr, unsigned int pk_len, void **plain_pk,
+static int get_plain_pk_from_asn1(void *pk_ptr, unsigned int pk_len, void **plain_pk,
 			   unsigned int *len, int *pk_alg)
 {
 	int ret;
diff --git a/plat/st/common/stm32mp_fconf_io.c b/plat/st/common/stm32mp_fconf_io.c
index 0b6cc78..1a59f0b 100644
--- a/plat/st/common/stm32mp_fconf_io.c
+++ b/plat/st/common/stm32mp_fconf_io.c
@@ -28,7 +28,7 @@
 #endif
 
 #if (STM32MP_SDMMC || STM32MP_EMMC) && PSA_FWU_SUPPORT
-io_block_spec_t metadata_block_spec = {
+static io_block_spec_t metadata_block_spec = {
 	.offset = 0,    /* To be filled at runtime */
 	.length = 0,    /* To be filled at runtime */
 };
diff --git a/plat/st/stm32mp1/stm32mp1_gic.c b/plat/st/common/stm32mp_gic.c
similarity index 75%
rename from plat/st/stm32mp1/stm32mp1_gic.c
rename to plat/st/common/stm32mp_gic.c
index 851a9cf..d02b635 100644
--- a/plat/st/stm32mp1/stm32mp1_gic.c
+++ b/plat/st/common/stm32mp_gic.c
@@ -1,21 +1,20 @@
 /*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <libfdt.h>
-
-#include <platform_def.h>
-
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <drivers/arm/gicv2.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <lib/utils.h>
+#include <libfdt.h>
 #include <plat/common/platform.h>
 
+#include <platform_def.h>
+
-struct stm32_gic_instance {
+struct stm32mp_gic_instance {
 	uint32_t cells;
 	uint32_t phandle_node;
 };
@@ -24,7 +23,7 @@
  * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0
  * interrupts.
  *****************************************************************************/
-static const interrupt_prop_t stm32mp1_interrupt_props[] = {
+static const interrupt_prop_t stm32mp_interrupt_props[] = {
 	PLATFORM_G1S_PROPS(GICV2_INTR_GROUP0),
 	PLATFORM_G0_PROPS(GICV2_INTR_GROUP0)
 };
@@ -33,15 +32,15 @@
 static unsigned int target_mask_array[PLATFORM_CORE_COUNT] = {1, 2};
 
 static gicv2_driver_data_t platform_gic_data = {
-	.interrupt_props = stm32mp1_interrupt_props,
-	.interrupt_props_num = ARRAY_SIZE(stm32mp1_interrupt_props),
+	.interrupt_props = stm32mp_interrupt_props,
+	.interrupt_props_num = ARRAY_SIZE(stm32mp_interrupt_props),
 	.target_masks = target_mask_array,
 	.target_masks_num = ARRAY_SIZE(target_mask_array),
 };
 
-static struct stm32_gic_instance stm32_gic;
+static struct stm32mp_gic_instance stm32mp_gic;
 
-void stm32mp1_gic_init(void)
+void stm32mp_gic_init(void)
 {
 	int node;
 	void *fdt;
@@ -71,20 +70,20 @@
 		panic();
 	}
 
-	stm32_gic.cells = fdt32_to_cpu(*cuint);
+	stm32mp_gic.cells = fdt32_to_cpu(*cuint);
 
-	stm32_gic.phandle_node = fdt_get_phandle(fdt, node);
-	if (stm32_gic.phandle_node == 0U) {
+	stm32mp_gic.phandle_node = fdt_get_phandle(fdt, node);
+	if (stm32mp_gic.phandle_node == 0U) {
 		panic();
 	}
 
 	gicv2_driver_init(&platform_gic_data);
 	gicv2_distif_init();
 
-	stm32mp1_gic_pcpu_init();
+	stm32mp_gic_pcpu_init();
 }
 
-void stm32mp1_gic_pcpu_init(void)
+void stm32mp_gic_pcpu_init(void)
 {
 	gicv2_pcpu_distif_init();
 	gicv2_set_pe_target_mask(plat_my_core_pos());
diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c
index 87d2d39..eeabd09 100644
--- a/plat/st/stm32mp1/bl2_plat_setup.c
+++ b/plat/st/stm32mp1/bl2_plat_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
  */
@@ -290,10 +290,7 @@
 		panic();
 	}
 
-	stm32_save_boot_interface(boot_context->boot_interface_selected,
-				  boot_context->boot_interface_instance);
-	stm32_save_boot_auth(boot_context->auth_status,
-			     boot_context->boot_partition_used_toboot);
+	stm32_save_boot_info(boot_context);
 
 #if STM32MP_USB_PROGRAMMER && STM32MP15
 	/* Deconfigure all UART RX pins configured by ROM code */
diff --git a/plat/st/stm32mp1/include/stm32mp1_private.h b/plat/st/stm32mp1/include/stm32mp1_private.h
index 21ef60d..4a52255 100644
--- a/plat/st/stm32mp1/include/stm32mp1_private.h
+++ b/plat/st/stm32mp1/include/stm32mp1_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,9 +14,6 @@
 void stm32mp1_arch_security_setup(void);
 void stm32mp1_security_setup(void);
 
-void stm32mp1_gic_pcpu_init(void);
-void stm32mp1_gic_init(void);
-
 void stm32mp1_syscfg_init(void);
 void stm32mp1_syscfg_enable_io_compensation_start(void);
 void stm32mp1_syscfg_enable_io_compensation_finish(void);
diff --git a/plat/st/stm32mp1/plat_image_load.c b/plat/st/stm32mp1/plat_image_load.c
index c4048fc..c455544 100644
--- a/plat/st/stm32mp1/plat_image_load.c
+++ b/plat/st/stm32mp1/plat_image_load.c
@@ -5,6 +5,7 @@
  */
 
 #include <common/desc_image_load.h>
+#include <plat/common/platform.h>
 
 /*******************************************************************************
  * This function flushes the data structures so that they are visible
diff --git a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
index 1d754d9..f5184e7 100644
--- a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
+++ b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -32,7 +32,7 @@
 
 BL32_SOURCES		+=	${GICV2_SOURCES}			\
 				plat/common/plat_gicv2.c		\
-				plat/st/stm32mp1/stm32mp1_gic.c
+				plat/st/common/stm32mp_gic.c
 
 # Generic PSCI
 BL32_SOURCES		+=	plat/common/plat_psci_common.c
diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c
index 50b0794..b46f4af 100644
--- a/plat/st/stm32mp1/sp_min/sp_min_setup.c
+++ b/plat/st/stm32mp1/sp_min/sp_min_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
  */
@@ -7,9 +7,8 @@
 #include <assert.h>
 #include <string.h>
 
-#include <platform_def.h>
-
 #include <arch_helpers.h>
+#include <bl32/sp_min/platform_sp_min.h>
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <context.h>
@@ -27,7 +26,7 @@
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
 
-#include <platform_sp_min.h>
+#include <platform_def.h>
 
 /******************************************************************************
  * Placeholder variables for copying the arguments that have been passed to
@@ -181,7 +180,7 @@
 {
 	generic_delay_timer_init();
 
-	stm32mp1_gic_init();
+	stm32mp_gic_init();
 
 	if (stm32_iwdg_init() < 0) {
 		panic();
diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h
index f0d8526..8cac4b5 100644
--- a/plat/st/stm32mp1/stm32mp1_def.h
+++ b/plat/st/stm32mp1/stm32mp1_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -548,6 +548,7 @@
  ******************************************************************************/
 #define TAMP_BASE			U(0x5C00A000)
 #define TAMP_BKP_REGISTER_BASE		(TAMP_BASE + U(0x100))
+#define TAMP_BKP_REG_CLK		RTCAPB
 #define TAMP_COUNTR			U(0x40)
 
 #if !(defined(__LINKER__) || defined(__ASSEMBLER__))
diff --git a/plat/st/stm32mp1/stm32mp1_pm.c b/plat/st/stm32mp1/stm32mp1_pm.c
index 6e438c4..7439381 100644
--- a/plat/st/stm32mp1/stm32mp1_pm.c
+++ b/plat/st/stm32mp1/stm32mp1_pm.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
  */
@@ -118,7 +118,7 @@
  ******************************************************************************/
 static void stm32_pwr_domain_on_finish(const psci_power_state_t *target_state)
 {
-	stm32mp1_gic_pcpu_init();
+	stm32mp_gic_pcpu_init();
 
 	write_cntfrq_el0(cntfrq_core0);
 }
diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c
index e6cb071..ea35055 100644
--- a/plat/st/stm32mp1/stm32mp1_private.c
+++ b/plat/st/stm32mp1/stm32mp1_private.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
  */
@@ -16,37 +16,12 @@
 #include <plat/common/platform.h>
 #include <platform_def.h>
 
-/* Internal layout of the 32bit OTP word board_id */
-#define BOARD_ID_BOARD_NB_MASK		GENMASK(31, 16)
-#define BOARD_ID_BOARD_NB_SHIFT		16
-#define BOARD_ID_VARCPN_MASK		GENMASK(15, 12)
-#define BOARD_ID_VARCPN_SHIFT		12
-#define BOARD_ID_REVISION_MASK		GENMASK(11, 8)
-#define BOARD_ID_REVISION_SHIFT		8
-#define BOARD_ID_VARFG_MASK		GENMASK(7, 4)
-#define BOARD_ID_VARFG_SHIFT		4
-#define BOARD_ID_BOM_MASK		GENMASK(3, 0)
-
-#define BOARD_ID2NB(_id)		(((_id) & BOARD_ID_BOARD_NB_MASK) >> \
-					 BOARD_ID_BOARD_NB_SHIFT)
-#define BOARD_ID2VARCPN(_id)		(((_id) & BOARD_ID_VARCPN_MASK) >> \
-					 BOARD_ID_VARCPN_SHIFT)
-#define BOARD_ID2REV(_id)		(((_id) & BOARD_ID_REVISION_MASK) >> \
-					 BOARD_ID_REVISION_SHIFT)
-#define BOARD_ID2VARFG(_id)		(((_id) & BOARD_ID_VARFG_MASK) >> \
-					 BOARD_ID_VARFG_SHIFT)
-#define BOARD_ID2BOM(_id)		((_id) & BOARD_ID_BOM_MASK)
-
 #if STM32MP13
 #define TAMP_BOOT_MODE_BACKUP_REG_ID	U(30)
 #endif
 #if STM32MP15
 #define TAMP_BOOT_MODE_BACKUP_REG_ID	U(20)
 #endif
-#define TAMP_BOOT_MODE_ITF_MASK		GENMASK(15, 8)
-#define TAMP_BOOT_MODE_ITF_SHIFT	8
-#define TAMP_BOOT_MODE_AUTH_MASK	GENMASK(23, 16)
-#define TAMP_BOOT_MODE_AUTH_SHIFT	16
 
 /*
  * Backup register to store fwu update information.
@@ -520,23 +495,14 @@
 
 void stm32mp_print_boardinfo(void)
 {
-	uint32_t board_id = 0;
+	uint32_t board_id = 0U;
 
 	if (stm32_get_otp_value(BOARD_ID_OTP, &board_id) != 0) {
 		return;
 	}
 
 	if (board_id != 0U) {
-		char rev[2];
-
-		rev[0] = BOARD_ID2REV(board_id) - 1 + 'A';
-		rev[1] = '\0';
-		NOTICE("Board: MB%04x Var%u.%u Rev.%s-%02u\n",
-		       BOARD_ID2NB(board_id),
-		       BOARD_ID2VARCPN(board_id),
-		       BOARD_ID2VARFG(board_id),
-		       rev,
-		       BOARD_ID2BOM(board_id));
+		stm32_display_board_info(board_id);
 	}
 }
 
@@ -697,51 +663,9 @@
 }
 #endif
 
-void stm32_save_boot_interface(uint32_t interface, uint32_t instance)
+uintptr_t stm32_get_bkpr_boot_mode_addr(void)
 {
-	uintptr_t bkpr_itf_idx = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
-
-	clk_enable(RTCAPB);
-
-	mmio_clrsetbits_32(bkpr_itf_idx,
-			   TAMP_BOOT_MODE_ITF_MASK,
-			   ((interface << 4) | (instance & 0xFU)) <<
-			   TAMP_BOOT_MODE_ITF_SHIFT);
-
-	clk_disable(RTCAPB);
-}
-
-void stm32_get_boot_interface(uint32_t *interface, uint32_t *instance)
-{
-	static uint32_t itf;
-
-	if (itf == 0U) {
-		uintptr_t bkpr = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
-
-		clk_enable(RTCAPB);
-
-		itf = (mmio_read_32(bkpr) & TAMP_BOOT_MODE_ITF_MASK) >>
-			TAMP_BOOT_MODE_ITF_SHIFT;
-
-		clk_disable(RTCAPB);
-	}
-
-	*interface = itf >> 4;
-	*instance = itf & 0xFU;
-}
-
-void stm32_save_boot_auth(uint32_t auth_status, uint32_t boot_partition)
-{
-	uint32_t boot_status = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
-
-	clk_enable(RTCAPB);
-
-	mmio_clrsetbits_32(boot_status,
-			   TAMP_BOOT_MODE_AUTH_MASK,
-			   ((auth_status << 4) | (boot_partition & 0xFU)) <<
-			   TAMP_BOOT_MODE_AUTH_SHIFT);
-
-	clk_disable(RTCAPB);
+	return tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
 }
 
 #if PSA_FWU_SUPPORT
diff --git a/plat/xilinx/common/ipi.c b/plat/xilinx/common/ipi.c
index 6438896..8fa7bc5 100644
--- a/plat/xilinx/common/ipi.c
+++ b/plat/xilinx/common/ipi.c
@@ -39,7 +39,7 @@
 #define IPI_BIT_MASK(I) (ipi_table[(I)].ipi_bit_mask)
 
 /* IPI configuration table */
-const static struct ipi_config *ipi_table;
+static const struct ipi_config *ipi_table;
 
 /* Total number of IPI */
 static uint32_t ipi_total;
diff --git a/plat/xilinx/versal/bl31_versal_setup.c b/plat/xilinx/versal/bl31_versal_setup.c
index 9b36208..995c852 100644
--- a/plat/xilinx/versal/bl31_versal_setup.c
+++ b/plat/xilinx/versal/bl31_versal_setup.c
@@ -135,7 +135,7 @@
 	} else if (ret != FSBL_HANDOFF_SUCCESS) {
 		panic();
 	} else {
-		INFO("BL31: fsbl-atf handover success %u\n", ret);
+		INFO("BL31: PLM to TF-A handover success %u\n", ret);
 	}
 
 	NOTICE("BL31: Secure code at 0x%lx\n", bl32_image_ep_info.pc);
diff --git a/plat/xilinx/versal/versal_ipi.c b/plat/xilinx/versal/versal_ipi.c
index f99af82..d821929 100644
--- a/plat/xilinx/versal/versal_ipi.c
+++ b/plat/xilinx/versal/versal_ipi.c
@@ -19,7 +19,7 @@
 #include <lib/mmio.h>
 
 /* versal ipi configuration table */
-const static struct ipi_config versal_ipi_table[] = {
+static const struct ipi_config versal_ipi_table[] = {
 	/* A72 IPI */
 	[IPI_ID_APU] = {
 		.ipi_bit_mask = IPI0_TRIG_BIT,
diff --git a/plat/xilinx/versal_net/include/versal_net_def.h b/plat/xilinx/versal_net/include/versal_net_def.h
index 8cb5bf3..14e63d5 100644
--- a/plat/xilinx/versal_net/include/versal_net_def.h
+++ b/plat/xilinx/versal_net/include/versal_net_def.h
@@ -53,9 +53,9 @@
 
 #define PSX_CRF_RST_TIMESTAMP_OFFSET	U(0x33C)
 
-#define APU_PCLI			U(0xECB10000)
-#define APU_PCLI_CPU_STEP		U(0x30)
-#define APU_PCLI_CLUSTER_CPU_STEP	(4U * APU_PCLI_CPU_STEP)
+#define APU_PCLI			(0xECB10000ULL)
+#define APU_PCLI_CPU_STEP		(0x30ULL)
+#define APU_PCLI_CLUSTER_CPU_STEP	(4ULL * APU_PCLI_CPU_STEP)
 #define APU_PCLI_CLUSTER_OFFSET		U(0x8000)
 #define APU_PCLI_CLUSTER_STEP		U(0x1000)
 #define PCLI_PREQ_OFFSET		U(0x4)
@@ -67,13 +67,29 @@
 /* Firmware Image Package */
 #define VERSAL_NET_PRIMARY_CPU		U(0)
 
-#define CORE_0_IEN_POWER_OFFSET			(0x00000018U)
+#define CORE_0_ISR_WAKE_OFFSET			(0x00000020ULL)
+#define APU_PCIL_CORE_X_ISR_WAKE_REG(cpu_id)	(APU_PCLI + (CORE_0_ISR_WAKE_OFFSET + \
+						 (APU_PCLI_CPU_STEP * (cpu_id))))
+#define APU_PCIL_CORE_X_ISR_WAKE_MASK		(0x00000001U)
+#define CORE_0_IEN_WAKE_OFFSET			(0x00000028ULL)
+#define APU_PCIL_CORE_X_IEN_WAKE_REG(cpu_id)	(APU_PCLI + (CORE_0_IEN_WAKE_OFFSET + \
+						 (APU_PCLI_CPU_STEP * (cpu_id))))
+#define APU_PCIL_CORE_X_IEN_WAKE_MASK		(0x00000001U)
+#define CORE_0_IDS_WAKE_OFFSET			(0x0000002CULL)
+#define APU_PCIL_CORE_X_IDS_WAKE_REG(cpu_id)	(APU_PCLI + (CORE_0_IDS_WAKE_OFFSET + \
+						 (APU_PCLI_CPU_STEP * (cpu_id))))
+#define APU_PCIL_CORE_X_IDS_WAKE_MASK		(0x00000001U)
+#define CORE_0_ISR_POWER_OFFSET			(0x00000010ULL)
+#define APU_PCIL_CORE_X_ISR_POWER_REG(cpu_id)	(APU_PCLI + (CORE_0_ISR_POWER_OFFSET + \
+						 (APU_PCLI_CPU_STEP * (cpu_id))))
+#define APU_PCIL_CORE_X_ISR_POWER_MASK		U(0x00000001)
+#define CORE_0_IEN_POWER_OFFSET			(0x00000018ULL)
 #define APU_PCIL_CORE_X_IEN_POWER_REG(cpu_id)	(APU_PCLI + (CORE_0_IEN_POWER_OFFSET + \
-						 (0x30 * cpu_id)))
+						 (APU_PCLI_CPU_STEP * (cpu_id))))
 #define APU_PCIL_CORE_X_IEN_POWER_MASK		(0x00000001U)
-#define CORE_0_IDS_POWER_OFFSET			(0x0000001CU)
+#define CORE_0_IDS_POWER_OFFSET			(0x0000001CULL)
 #define APU_PCIL_CORE_X_IDS_POWER_REG(cpu_id)	(APU_PCLI + (CORE_0_IDS_POWER_OFFSET + \
-						 (0x30 * cpu_id)))
+						 (APU_PCLI_CPU_STEP * (cpu_id))))
 #define APU_PCIL_CORE_X_IDS_POWER_MASK		(0x00000001U)
 #define CORE_PWRDN_EN_BIT_MASK			(0x1U)
 
@@ -122,9 +138,17 @@
  * UART related constants
  ******************************************************************************/
 #define VERSAL_NET_UART0_BASE		U(0xF1920000)
+#define VERSAL_NET_UART1_BASE		U(0xF1930000)
+
 #define VERSAL_NET_UART_BAUDRATE	115200
 
+#if VERSAL_NET_CONSOLE_IS(pl011) || VERSAL_NET_CONSOLE_IS(pl011_0)
 #define VERSAL_NET_UART_BASE		VERSAL_NET_UART0_BASE
+#elif VERSAL_NET_CONSOLE_IS(pl011_1)
+#define VERSAL_NET_UART_BASE		VERSAL_NET_UART1_BASE
+#else
+# error "invalid VERSAL_NET_CONSOLE"
+#endif
 
 #define PLAT_VERSAL_NET_CRASH_UART_BASE		VERSAL_NET_UART_BASE
 #define PLAT_VERSAL_NET_CRASH_UART_CLK_IN_HZ	VERSAL_NET_UART_CLOCK
diff --git a/plat/xilinx/versal_net/plat_psci_pm.c b/plat/xilinx/versal_net/plat_psci_pm.c
index 8beaa9a..c713061 100644
--- a/plat/xilinx/versal_net/plat_psci_pm.c
+++ b/plat/xilinx/versal_net/plat_psci_pm.c
@@ -196,6 +196,7 @@
 	VERBOSE("%s: power_state: 0x%x\n", __func__, power_state);
 
 	int32_t pstate = psci_get_pstate_type(power_state);
+	uint64_t i;
 
 	assert(req_state);
 
@@ -203,7 +204,8 @@
 	if (pstate == PSTATE_TYPE_STANDBY) {
 		req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_RET_STATE;
 	} else {
-		req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_OFF_STATE;
+		for (i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++)
+			req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
 	}
 
 	/* We expect the 'state id' to be zero */
@@ -221,8 +223,10 @@
  */
 static void versal_net_get_sys_suspend_power_state(psci_power_state_t *req_state)
 {
-	req_state->pwr_domain_state[PSCI_CPU_PWR_LVL] = PLAT_MAX_OFF_STATE;
-	req_state->pwr_domain_state[1] = PLAT_MAX_OFF_STATE;
+	uint64_t i;
+
+	for (i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++)
+		req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
 }
 
 static const struct plat_psci_ops versal_net_nopmc_psci_ops = {
diff --git a/plat/xilinx/versal_net/platform.mk b/plat/xilinx/versal_net/platform.mk
index b3d56bc..622ae98 100644
--- a/plat/xilinx/versal_net/platform.mk
+++ b/plat/xilinx/versal_net/platform.mk
@@ -53,6 +53,11 @@
 HW_ASSISTED_COHERENCY := 1
 
 VERSAL_NET_CONSOLE	?=	pl011
+ifeq (${VERSAL_NET_CONSOLE}, $(filter ${VERSAL_NET_CONSOLE},pl011 pl011_0 pl011_1))
+else
+  $(error Please define VERSAL_NET_CONSOLE)
+endif
+
 $(eval $(call add_define_val,VERSAL_NET_CONSOLE,VERSAL_NET_CONSOLE_ID_${VERSAL_NET_CONSOLE}))
 
 PLAT_INCLUDES		:=	-Iinclude/plat/arm/common/			\
diff --git a/plat/xilinx/versal_net/pm_service/pm_client.c b/plat/xilinx/versal_net/pm_service/pm_client.c
index 6487324..f543193 100644
--- a/plat/xilinx/versal_net/pm_service/pm_client.c
+++ b/plat/xilinx/versal_net/pm_service/pm_client.c
@@ -164,8 +164,18 @@
 
 	isb();
 
+	/* Clear power down interrupt status before enabling */
+	mmio_write_32(APU_PCIL_CORE_X_ISR_POWER_REG(cpu_id),
+		      APU_PCIL_CORE_X_ISR_POWER_MASK);
+	/* Enable power down interrupt */
 	mmio_write_32(APU_PCIL_CORE_X_IEN_POWER_REG(cpu_id),
 		      APU_PCIL_CORE_X_IEN_POWER_MASK);
+	/* Clear wakeup interrupt status before enabling */
+	mmio_write_32(APU_PCIL_CORE_X_ISR_WAKE_REG(cpu_id),
+		      APU_PCIL_CORE_X_ISR_WAKE_MASK);
+	/* Enable wake interrupt */
+	mmio_write_32(APU_PCIL_CORE_X_IEN_WAKE_REG(cpu_id),
+		      APU_PCIL_CORE_X_IEN_WAKE_MASK);
 
 	bakery_lock_release(&pm_client_secure_lock);
 }
@@ -197,6 +207,7 @@
 void pm_client_wakeup(const struct pm_proc *proc)
 {
 	uint32_t cpuid = pm_get_cpuid(proc->node_id);
+	uintptr_t val;
 
 	if (cpuid == UNDEFINED_CPUID) {
 		return;
@@ -204,7 +215,22 @@
 
 	bakery_lock_get(&pm_client_secure_lock);
 
-	/* TODO: clear powerdown bit for affected cpu */
+	/* Clear powerdown request */
+	val = read_cpu_pwrctrl_val();
+	val &= ~CORE_PWRDN_EN_BIT_MASK;
+	write_cpu_pwrctrl_val(val);
+
+	isb();
+
+	/* Disabled power down interrupt */
+	mmio_write_32(APU_PCIL_CORE_X_IDS_POWER_REG(cpuid),
+			APU_PCIL_CORE_X_IDS_POWER_MASK);
+	/* Clear wakeup interrupt status before disabling */
+	mmio_write_32(APU_PCIL_CORE_X_ISR_WAKE_REG(cpuid),
+		      APU_PCIL_CORE_X_ISR_WAKE_MASK);
+	/* Disable wake interrupt */
+	mmio_write_32(APU_PCIL_CORE_X_IDS_WAKE_REG(cpuid),
+		      APU_PCIL_CORE_X_IDS_WAKE_MASK);
 
 	bakery_lock_release(&pm_client_secure_lock);
 }
diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
index 4adbef3..a3f0278 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
@@ -334,22 +334,18 @@
 		SMC_RET1(handle, (uint64_t)ret);
 
 	case PM_GET_API_VERSION:
-		/* Check is PM API version already verified */
-		if (pm_ctx.api_version >= PM_VERSION) {
-			if (ipi_irq_flag == 0U) {
-				/*
-				 * Enable IPI IRQ
-				 * assume the rich OS is OK to handle callback IRQs now.
-				 * Even if we were wrong, it would not enable the IRQ in
-				 * the GIC.
-				 */
-				pm_ipi_irq_enable(primary_proc);
-				ipi_irq_flag = 1U;
-			}
-			SMC_RET1(handle, (uint64_t)PM_RET_SUCCESS |
-				 ((uint64_t)pm_ctx.api_version << 32));
+		if (ipi_irq_flag == 0U) {
+			/*
+			 * Enable IPI IRQ
+			 * assume the rich OS is OK to handle callback IRQs now.
+			 * Even if we were wrong, it would not enable the IRQ in
+			 * the GIC.
+			 */
+			pm_ipi_irq_enable(primary_proc);
+			ipi_irq_flag = 1U;
 		}
-
+		SMC_RET1(handle, (uint64_t)PM_RET_SUCCESS |
+			 ((uint64_t)pm_ctx.api_version << 32));
 	case PM_FPGA_LOAD:
 		ret = pm_fpga_load(pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3]);
 		SMC_RET1(handle, (uint64_t)ret);
diff --git a/plat/xilinx/zynqmp/zynqmp_ipi.c b/plat/xilinx/zynqmp/zynqmp_ipi.c
index 4ea3c6a..acd31df 100644
--- a/plat/xilinx/zynqmp/zynqmp_ipi.c
+++ b/plat/xilinx/zynqmp/zynqmp_ipi.c
@@ -21,7 +21,7 @@
 #include <plat_private.h>
 
 /* Zynqmp ipi configuration table */
-const static struct ipi_config zynqmp_ipi_table[] = {
+static const struct ipi_config zynqmp_ipi_table[] = {
 	/* APU IPI */
 	{
 		.ipi_bit_mask = 0x1,
diff --git a/services/std_svc/spm/el3_spmc/spmc.h b/services/std_svc/spm/el3_spmc/spmc.h
index 5233650..61afee3 100644
--- a/services/std_svc/spm/el3_spmc/spmc.h
+++ b/services/std_svc/spm/el3_spmc/spmc.h
@@ -228,6 +228,12 @@
 	uint32_t uuid[4];
 };
 
+/* FF-A Partition Info Get related macros. */
+#define FFA_PARTITION_INFO_GET_PROPERTIES_V1_0_MASK	U(0x7)
+#define FFA_PARTITION_INFO_GET_EXEC_STATE_SHIFT 	U(8)
+#define FFA_PARTITION_INFO_GET_AARCH32_STATE 		U(0)
+#define FFA_PARTITION_INFO_GET_AARCH64_STATE 		U(1)
+
 /* Reference to power management hooks */
 extern const spd_pm_ops_t spmc_pm;
 
diff --git a/services/std_svc/spm/el3_spmc/spmc_main.c b/services/std_svc/spm/el3_spmc/spmc_main.c
index 9b8621a..08e7218 100644
--- a/services/std_svc/spm/el3_spmc/spmc_main.c
+++ b/services/std_svc/spm/el3_spmc/spmc_main.c
@@ -746,6 +746,27 @@
 }
 
 /*
+ * Helper function to populate the properties field of a Partition Info Get
+ * descriptor.
+ */
+static uint32_t
+partition_info_get_populate_properties(uint32_t sp_properties,
+				       enum sp_execution_state sp_ec_state)
+{
+	uint32_t properties = sp_properties;
+	uint32_t ec_state;
+
+	/* Determine the execution state of the SP. */
+	ec_state = sp_ec_state == SP_STATE_AARCH64 ?
+		   FFA_PARTITION_INFO_GET_AARCH64_STATE :
+		   FFA_PARTITION_INFO_GET_AARCH32_STATE;
+
+	properties |= ec_state << FFA_PARTITION_INFO_GET_EXEC_STATE_SHIFT;
+
+	return properties;
+}
+
+/*
  * Collate the partition information in a v1.1 partition information
  * descriptor format, this will be converter later if required.
  */
@@ -771,7 +792,12 @@
 			desc = &partitions[*partition_count];
 			desc->ep_id = el3_lp_descs[index].sp_id;
 			desc->execution_ctx_count = PLATFORM_CORE_COUNT;
-			desc->properties = el3_lp_descs[index].properties;
+			/* LSPs must be AArch64. */
+			desc->properties =
+				partition_info_get_populate_properties(
+					el3_lp_descs[index].properties,
+					SP_STATE_AARCH64);
+
 			if (null_uuid) {
 				copy_uuid(desc->uuid, el3_lp_descs[index].uuid);
 			}
@@ -794,7 +820,11 @@
 			 * S-EL1 SPs.
 			 */
 			desc->execution_ctx_count = PLATFORM_CORE_COUNT;
-			desc->properties = sp_desc[index].properties;
+			desc->properties =
+				partition_info_get_populate_properties(
+					sp_desc[index].properties,
+					sp_desc[index].execution_state);
+
 			if (null_uuid) {
 				copy_uuid(desc->uuid, sp_desc[index].uuid);
 			}
@@ -835,7 +865,7 @@
 
 /*
  * If the caller of the PARTITION_INFO_GET ABI was a v1.0 caller, populate
- * the coresponding descriptor format from the v1.1 descriptor array.
+ * the corresponding descriptor format from the v1.1 descriptor array.
  */
 static uint64_t partition_info_populate_v1_0(struct ffa_partition_info_v1_1
 					     *partitions,
@@ -860,8 +890,10 @@
 		v1_0_partitions[index].ep_id = partitions[index].ep_id;
 		v1_0_partitions[index].execution_ctx_count =
 			partitions[index].execution_ctx_count;
+		/* Only report v1.0 properties. */
 		v1_0_partitions[index].properties =
-			partitions[index].properties;
+			(partitions[index].properties &
+			FFA_PARTITION_INFO_GET_PROPERTIES_V1_0_MASK);
 	}
 	return 0;
 }
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index 7e6c89d..afd0f2e 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -868,7 +868,8 @@
 						     FFA_ERROR_NOT_SUPPORTED);
 		}
 
-		/* Fall through to forward the call to the other world */
+		/* Forward the call to the other world */
+		/* fallthrough */
 	case FFA_MSG_SEND:
 	case FFA_MSG_SEND_DIRECT_RESP_SMC64:
 	case FFA_MEM_DONATE_SMC32:
@@ -908,7 +909,8 @@
 			spmd_spm_core_sync_exit(0ULL);
 		}
 
-		/* Fall through to forward the call to the other world */
+		/* Forward the call to the other world */
+		/* fallthrough */
 	case FFA_INTERRUPT:
 	case FFA_MSG_YIELD:
 		/* This interface must be invoked only by the Secure world */
diff --git a/services/std_svc/trng/trng_entropy_pool.c b/services/std_svc/trng/trng_entropy_pool.c
index 30105b3..dd08c5e 100644
--- a/services/std_svc/trng/trng_entropy_pool.c
+++ b/services/std_svc/trng/trng_entropy_pool.c
@@ -66,7 +66,7 @@
 bool trng_pack_entropy(uint32_t nbits, uint64_t *out)
 {
 	bool ret = true;
-
+	uint32_t bits_to_discard = nbits;
 	spin_lock(&trng_pool_lock);
 
 	if (!trng_fill_entropy(nbits)) {
@@ -111,9 +111,66 @@
 		 *                   5 4 3 2 1 0 7 6
 		 *                  [e,e,e,e,e,e,e,e]
 		 */
-		out[word_i] = 0;
 		out[word_i] |= entropy[ENTROPY_WORD_INDEX(word_i)] >> rshift;
 
+		/**
+		 * Discarding the used/packed entropy bits from the respective
+		 * words, (word_i) and (word_i+1) as applicable.
+		 * In each iteration of the loop, we pack 64bits of entropy to
+		 * the output buffer. The bits are picked linearly starting from
+		 * 1st word (entropy[0]) till 4th word (entropy[3]) and then
+		 * rolls back (entropy[0]). Discarding of bits is managed
+		 * similarly.
+		 *
+		 * The following diagram illustrates the logic:
+		 *
+		 *          |---------entropy pool----------|
+		 * C var    |--(word_i + 1)-|----word_i-----|
+		 * bit idx  |7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0|
+		 *          [e,e,e,e,e,e,e,e|e,e,0,0,0,0,0,0]
+		 *          |   [e,e,e,e,e,e,e,e]           |
+		 *          |   |--out[word_i]--|           |
+		 *    lshift|---|               |--rshift---|
+		 *          |e,e|0,0,0,0,0,0,0,0|0,0,0,0,0,0|
+		 *              |<==   ||    ==>|
+		 *               bits_to_discard (from these bytes)
+		 *
+		 * variable(bits_to_discard): Tracks the amount of bits to be
+		 * discarded and is updated accordingly in each iteration.
+		 *
+		 * It monitors these packed bits from respective word_i and
+		 * word_i+1 and overwrites them with zeros accordingly.
+		 * It discards linearly from the lowest index and moves upwards
+		 * until bits_to_discard variable becomes zero.
+		 *
+		 * In the above diagram,for example, we pack 2bytes(7th and 6th
+		 * from word_i) and 6bytes(0th till 5th from word_i+1), combine
+		 * and pack them as 64bit to output buffer out[i].
+		 * Depending on the number of bits requested, we discard the
+		 * bits from these packed bytes by overwriting them with zeros.
+		 */
+
+		/*
+		 * If the bits to be discarded is lesser than the amount of bits
+		 * copied to the output buffer from word_i, we discard that much
+		 * amount of bits only.
+		 */
+		if (bits_to_discard < (BITS_PER_WORD - rshift)) {
+			entropy[ENTROPY_WORD_INDEX(word_i)] &=
+			(~0ULL << ((bits_to_discard+rshift) % BITS_PER_WORD));
+			bits_to_discard = 0;
+		} else {
+		/*
+		 * If the bits to be discarded is more than the amount of valid
+		 * upper bits from word_i, which has been copied to the output
+		 * buffer, we just set the entire word_i to 0, as the lower bits
+		 * will be already zeros from previous operations, and the
+		 * bits_to_discard is updated precisely.
+		 */
+			entropy[ENTROPY_WORD_INDEX(word_i)] = 0;
+			bits_to_discard -= (BITS_PER_WORD - rshift);
+		}
+
 		/*
 		 * Note that a shift of 64 bits is treated as a shift of 0 bits.
 		 * When the shift amount is the same as the BITS_PER_WORD, we
@@ -123,6 +180,35 @@
 		if (lshift != BITS_PER_WORD) {
 			out[word_i] |= entropy[ENTROPY_WORD_INDEX(word_i + 1)]
 				<< lshift;
+			/**
+			 * Discarding the remaining packed bits from upperword
+			 * (word[i+1]) which was copied to output buffer by
+			 * overwriting with zeros.
+			 *
+			 * If the remaining bits to be discarded is lesser than
+			 * the amount of bits from [word_i+1], which has been
+			 * copied to the output buffer, we overwrite that much
+			 * amount of bits only.
+			 */
+			if (bits_to_discard < (BITS_PER_WORD - lshift)) {
+				entropy[ENTROPY_WORD_INDEX(word_i+1)]  &=
+				(~0ULL << ((bits_to_discard) % BITS_PER_WORD));
+				bits_to_discard = 0;
+			} else {
+			/*
+			 * If bits to discard is more than the bits from word_i+1
+			 * which got packed into the output, then we discard all
+			 * those copied bits.
+			 *
+			 * Note: we cannot set the entire word_i+1 to 0, as
+			 * there are still some unused valid entropy bits at the
+			 * upper end for future use.
+			 */
+				entropy[ENTROPY_WORD_INDEX(word_i+1)]  &=
+				(~0ULL << ((BITS_PER_WORD - lshift) % BITS_PER_WORD));
+				bits_to_discard -= (BITS_PER_WORD - lshift);
+		}
+
 		}
 	}
 	const uint64_t mask = ~0ULL >> (BITS_PER_WORD - (nbits % BITS_PER_WORD));