Merge "fix(cpus): workaround for Cortex-X2 erratum 2282622" into integration
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..c9c3da9 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>
@@ -191,7 +192,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]
@@ -452,12 +456,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 +508,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
 
@@ -567,6 +577,32 @@
 #endif
 	blr	x15
 
+	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:
@@ -593,7 +629,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 253e876..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
@@ -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
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/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..44b25ba 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.len = (p + len) - pk.p;
+	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;
+	}
 	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,29 +316,45 @@
 
 	/*
 	 * 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 {
 		ret = mbedtls_asn1_get_tag(&p, end, &len,
 					   MBEDTLS_ASN1_CONSTRUCTED |
 					   MBEDTLS_ASN1_SEQUENCE);
@@ -340,7 +382,7 @@
 			return IMG_PARSER_ERR_FORMAT;
 		}
 		p += len;
-	}
+	} while (p < end);
 
 	if (p != end) {
 		return IMG_PARSER_ERR_FORMAT;
@@ -353,33 +395,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) {
-		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)) {
+	if ((sig_alg1.len >= (size_t)(end - p)) ||
+	    (0 != memcmp(sig_alg1.p, 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/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/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 fa293e3..c9b4447 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -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
@@ -578,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
@@ -626,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
@@ -1012,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))
@@ -1115,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))
@@ -1168,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))
@@ -1228,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))
@@ -1276,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))
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/tc/include/platform_def.h b/plat/arm/board/tc/include/platform_def.h
index 0fe4a0a..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
 
@@ -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/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/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/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/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/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/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/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));