Merge "feat(mt8188): add EMI MPU support for SCP and DSP" into integration
diff --git a/Makefile b/Makefile
index 464544f..907ae21 100644
--- a/Makefile
+++ b/Makefile
@@ -599,6 +599,12 @@
 		ifneq ($(SP_LAYOUT_FILE),)
 		BL2_ENABLE_SP_LOAD := 1
 		endif
+
+		ifeq ($(SPMC_AT_EL3_SEL0_SP),1)
+			ifneq ($(SPMC_AT_EL3),1)
+			$(error SEL0 SP cannot be enabled without SPMC at EL3)
+			endif
+		endif
 	else
 		# All other SPDs in spd directory
 		SPD_DIR := spd
@@ -1191,6 +1197,7 @@
 	SPIN_ON_BL1_EXIT \
 	SPM_MM \
 	SPMC_AT_EL3 \
+	SPMC_AT_EL3_SEL0_SP \
 	SPMD_SPM_AT_SEL2 \
 	ENABLE_SPMD_LP \
 	TRANSFER_LIST \
@@ -1223,6 +1230,7 @@
 	CONDITIONAL_CMO \
 	RAS_FFH_SUPPORT \
 	PSA_CRYPTO	\
+	ENABLE_CONSOLE_GETC \
 )))
 
 # Numeric_Flags
@@ -1354,6 +1362,7 @@
 	SPIN_ON_BL1_EXIT \
 	SPM_MM \
 	SPMC_AT_EL3 \
+	SPMC_AT_EL3_SEL0_SP \
 	SPMD_SPM_AT_SEL2 \
 	TRANSFER_LIST \
 	TRUSTED_BOARD_BOOT \
@@ -1414,6 +1423,7 @@
 	SVE_VECTOR_LEN \
 	ENABLE_SPMD_LP \
 	PSA_CRYPTO	\
+	ENABLE_CONSOLE_GETC \
 )))
 
 ifeq (${SANITIZE_UB},trap)
diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S
index 7a8c41a..773b41d 100644
--- a/bl31/bl31.ld.S
+++ b/bl31/bl31.ld.S
@@ -101,7 +101,7 @@
     ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
         "cpu_ops not defined for this platform.")
 
-#if SPM_MM
+#if SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)
 #   ifndef SPM_SHIM_EXCEPTIONS_VMA
 #       define SPM_SHIM_EXCEPTIONS_VMA RAM
 #   endif /* SPM_SHIM_EXCEPTIONS_VMA */
@@ -128,7 +128,7 @@
     PROVIDE(__SPM_SHIM_EXCEPTIONS_LMA__ = LOADADDR(.spm_shim_exceptions));
 
     . = LOADADDR(.spm_shim_exceptions) + SIZEOF(.spm_shim_exceptions);
-#endif /* SPM_MM */
+#endif /* SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP) */
 
     __RW_START__ = .;
 
diff --git a/changelog.yaml b/changelog.yaml
index 2d6986b..33e5e8c 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -609,6 +609,9 @@
           - plat/xilinx
 
         subsections:
+          - title: DCC (Debug Communication Channel)
+            scope: dcc
+
           - title: Versal
             scope: versal
 
diff --git a/docs/components/secure-partition-manager.rst b/docs/components/secure-partition-manager.rst
index d4f0b00..5d3adec 100644
--- a/docs/components/secure-partition-manager.rst
+++ b/docs/components/secure-partition-manager.rst
@@ -152,6 +152,8 @@
   exception level is set to S-EL1.
   ``SPMD_SPM_AT_SEL2`` is enabled. The context save/restore routine
   and exhaustive list of registers is visible at `[4]`_.
+- **SPMC_AT_EL3_SEL0_SP**: this option enables the support to load SEL0 SP
+  when SPMC at EL3 support is enabled.
 - **SP_LAYOUT_FILE**: this option specifies a text description file
   providing paths to SP binary images and manifests in DTS format
   (see `Describing secure partitions`_). It
@@ -257,6 +259,22 @@
     PLAT=fvp \
     all fip
 
+Sample TF-A build command line when the SPMC is located at EL3 and SEL0 SP is
+enabled:
+
+.. code:: shell
+
+    make \
+    CROSS_COMPILE=aarch64-none-elf- \
+    SPD=spmd \
+    SPMD_SPM_AT_SEL2=0 \
+    SPMC_AT_EL3=1 \
+    SPMC_AT_EL3_SEL0_SP=1 \
+    BL32=<path-to-tee-binary> \
+    BL33=<path-to-bl33-binary> \
+    PLAT=fvp \
+    all fip
+
 FVP model invocation
 ====================
 
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 34d83f2..cd70a22 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -692,7 +692,7 @@
    +===========================+====================================+
    |           rsa             | 1024 , 2048 (default), 3072, 4096* |
    +---------------------------+------------------------------------+
-   |          ecdsa            |            unavailable             |
+   |          ecdsa            |         256 (default), 384         |
    +---------------------------+------------------------------------+
    |  ecdsa-brainpool-regular  |            unavailable             |
    +---------------------------+------------------------------------+
@@ -900,6 +900,10 @@
    disabled). This configuration supports pre-Armv8.4 platforms (aka not
    implementing the ``FEAT_SEL2`` extension). This is an experimental feature.
 
+-  ``SPMC_AT_EL3_SEL0_SP`` : Boolean option to enable SEL0 SP load support when
+   ``SPMC_AT_EL3`` is enabled. The default value if ``0`` (disabled). This
+   option cannot be enabled (``1``) when (``SPMC_AT_EL3``) is disabled.
+
 -  ``SPMC_OPTEE`` : This boolean option is used jointly with the SPM
    Dispatcher option (``SPD=spmd``) and with ``SPMD_SPM_AT_SEL2=0`` to
    indicate that the SPMC at S-EL1 is OP-TEE and an OP-TEE specific loading
@@ -1191,6 +1195,12 @@
   per the `PSA Crypto API specification`_. This feature is only supported if
   using MbedTLS 3.x version. By default it is disabled (``0``).
 
+- ``ENABLE_CONSOLE_GETC``: Boolean option to enable `getc()` feature in console
+  driver(s). By default it is disabled (``0``) because it constitutes an attack
+  vector into TF-A by potentially allowing an attacker to inject arbitrary data.
+  This option should only be enabled on a need basis if there is a use case for
+  reading characters from the console.
+
 GICv3 driver options
 --------------------
 
diff --git a/docs/process/security-hardening.rst b/docs/process/security-hardening.rst
index f9618db..eace467 100644
--- a/docs/process/security-hardening.rst
+++ b/docs/process/security-hardening.rst
@@ -135,6 +135,16 @@
   it is recommended to develop against ``W=2`` (which will eventually become the
   default).
 
+Additional guidelines are provided below for some security-related build
+options:
+
+- The ``ENABLE_CONSOLE_GETC`` build flag should be set to 0 to disable the
+  `getc()` feature, which allows the firmware to read characters from the
+  console. Keeping this feature enabled is considered dangerous from a security
+  point of view because it potentially allows an attacker to inject arbitrary
+  data into the firmware. It should only be enabled on a need basis if there is
+  a use case for it, for example in a testing or factory environment.
+
 .. rubric:: References
 
 -  `Arm ARM`_
diff --git a/drivers/amlogic/console/aarch64/meson_console.S b/drivers/amlogic/console/aarch64/meson_console.S
index 6d0a2d6..d955d83 100644
--- a/drivers/amlogic/console/aarch64/meson_console.S
+++ b/drivers/amlogic/console/aarch64/meson_console.S
@@ -69,7 +69,7 @@
 
 	mov	x0, x6
 	mov	x30, x7
-	finish_console_register meson putc=1, getc=1, flush=1
+	finish_console_register meson putc=1, getc=ENABLE_CONSOLE_GETC, flush=1
 
 register_fail:
 	ret	x7
diff --git a/drivers/arm/dcc/dcc_console.c b/drivers/arm/dcc/dcc_console.c
index 8d9f793..19c3450 100644
--- a/drivers/arm/dcc/dcc_console.c
+++ b/drivers/arm/dcc/dcc_console.c
@@ -53,6 +53,7 @@
 	return read_mdccsr_el0();
 }
 
+#if ENABLE_CONSOLE_GETC
 static inline char __dcc_getchar(void)
 {
 	char c;
@@ -61,6 +62,7 @@
 
 	return c;
 }
+#endif
 
 static inline void __dcc_putchar(char c)
 {
@@ -102,6 +104,7 @@
 	return ch;
 }
 
+#if ENABLE_CONSOLE_GETC
 static int32_t dcc_console_getc(struct console *console)
 {
 	unsigned int status;
@@ -113,6 +116,7 @@
 
 	return __dcc_getchar();
 }
+#endif
 
 /**
  * dcc_console_flush() - Function to force a write of all buffered data
@@ -133,9 +137,12 @@
 static struct dcc_console dcc_console = {
 	.console = {
 		.flags = CONSOLE_FLAG_BOOT |
-			CONSOLE_FLAG_RUNTIME,
+			CONSOLE_FLAG_RUNTIME |
+			CONSOLE_FLAG_CRASH,
 		.putc = dcc_console_putc,
+#if ENABLE_CONSOLE_GETC
 		.getc = dcc_console_getc,
+#endif
 		.flush = dcc_console_flush,
 	},
 };
diff --git a/drivers/arm/pl011/aarch32/pl011_console.S b/drivers/arm/pl011/aarch32/pl011_console.S
index 9caeb0c..b7d1747 100644
--- a/drivers/arm/pl011/aarch32/pl011_console.S
+++ b/drivers/arm/pl011/aarch32/pl011_console.S
@@ -116,7 +116,7 @@
 
 	mov	r0, r4
 	pop	{r4, lr}
-	finish_console_register pl011 putc=1, getc=1, flush=1
+	finish_console_register pl011 putc=1, getc=ENABLE_CONSOLE_GETC, flush=1
 
 register_fail:
 	pop	{r4, pc}
diff --git a/drivers/arm/pl011/aarch64/pl011_console.S b/drivers/arm/pl011/aarch64/pl011_console.S
index 861d2ed..8cb0122 100644
--- a/drivers/arm/pl011/aarch64/pl011_console.S
+++ b/drivers/arm/pl011/aarch64/pl011_console.S
@@ -103,7 +103,7 @@
 
 	mov	x0, x6
 	mov	x30, x7
-	finish_console_register pl011 putc=1, getc=1, flush=1
+	finish_console_register pl011 putc=1, getc=ENABLE_CONSOLE_GETC, flush=1
 
 register_fail:
 	ret	x7
diff --git a/drivers/auth/mbedtls/mbedtls_common.mk b/drivers/auth/mbedtls/mbedtls_common.mk
index 376b6b7..e380c86 100644
--- a/drivers/auth/mbedtls/mbedtls_common.mk
+++ b/drivers/auth/mbedtls/mbedtls_common.mk
@@ -107,11 +107,21 @@
 
 ifeq (${TF_MBEDTLS_KEY_SIZE},)
     ifneq ($(findstring rsa,${TF_MBEDTLS_KEY_ALG}),)
-	ifeq (${KEY_SIZE},)
+        ifeq (${KEY_SIZE},)
             TF_MBEDTLS_KEY_SIZE		:=	2048
-	else
+        else ifneq ($(filter $(KEY_SIZE), 1024 2048 3072 4096),)
+            TF_MBEDTLS_KEY_SIZE		:=	${KEY_SIZE}
+        else
+            $(error "Invalid value for KEY_SIZE: ${KEY_SIZE}")
+        endif
+    else ifneq ($(findstring ecdsa,${TF_MBEDTLS_KEY_ALG}),)
+        ifeq (${KEY_SIZE},)
+            TF_MBEDTLS_KEY_SIZE		:=	256
+        else ifneq ($(filter $(KEY_SIZE), 256 384),)
             TF_MBEDTLS_KEY_SIZE		:=	${KEY_SIZE}
-	endif
+        else
+            $(error "Invalid value for KEY_SIZE: ${KEY_SIZE}")
+        endif
     endif
 endif
 
diff --git a/drivers/cadence/uart/aarch64/cdns_console.S b/drivers/cadence/uart/aarch64/cdns_console.S
index 1bdaa48..d2dd0a8 100644
--- a/drivers/cadence/uart/aarch64/cdns_console.S
+++ b/drivers/cadence/uart/aarch64/cdns_console.S
@@ -79,7 +79,7 @@
 
 	mov	x0, x6
 	mov	x30, x7
-	finish_console_register cdns putc=1, getc=1, flush=1
+	finish_console_register cdns putc=1, getc=ENABLE_CONSOLE_GETC, flush=1
 
 register_fail:
 	ret	x7
diff --git a/drivers/console/aarch32/skeleton_console.S b/drivers/console/aarch32/skeleton_console.S
index a9e13ec..05a5985 100644
--- a/drivers/console/aarch32/skeleton_console.S
+++ b/drivers/console/aarch32/skeleton_console.S
@@ -63,7 +63,7 @@
 	 * If any of the argument is unspecified, then the corresponding
 	 * entry in console_t is set to 0.
 	 */
-	finish_console_register xxx putc=1, getc=1, flush=1
+	finish_console_register xxx putc=1, getc=ENABLE_CONSOLE_GETC, flush=1
 
 	/* Jump here if hardware init fails or parameters are invalid. */
 register_fail:
diff --git a/drivers/console/aarch64/skeleton_console.S b/drivers/console/aarch64/skeleton_console.S
index 7ea2eec..3310d28 100644
--- a/drivers/console/aarch64/skeleton_console.S
+++ b/drivers/console/aarch64/skeleton_console.S
@@ -63,7 +63,7 @@
 	 * If any of the argument is unspecified, then the corresponding
 	 * entry in console_t is set to 0.
 	 */
-	finish_console_register xxx putc=1, getc=1, flush=1
+	finish_console_register xxx putc=1, getc=ENABLE_CONSOLE_GETC, flush=1
 
 	/* Jump here if hardware init fails or parameters are invalid. */
 register_fail:
diff --git a/drivers/console/multi_console.c b/drivers/console/multi_console.c
index 93c38d8..e962fff 100644
--- a/drivers/console/multi_console.c
+++ b/drivers/console/multi_console.c
@@ -108,6 +108,7 @@
 		return EOF;
 }
 
+#if ENABLE_CONSOLE_GETC
 int console_getc(void)
 {
 	int err = ERROR_NO_VALID_CONSOLE;
@@ -127,6 +128,7 @@
 
 	return err;
 }
+#endif
 
 void console_flush(void)
 {
diff --git a/drivers/marvell/uart/a3700_console.S b/drivers/marvell/uart/a3700_console.S
index c7eb165..a1eacbc 100644
--- a/drivers/marvell/uart/a3700_console.S
+++ b/drivers/marvell/uart/a3700_console.S
@@ -140,7 +140,7 @@
 
 	mov	x0, x6
 	mov	x30, x7
-	finish_console_register a3700, putc=1, getc=1, flush=1
+	finish_console_register a3700, putc=1, getc=ENABLE_CONSOLE_GETC, flush=1
 
 register_fail:
 	ret	x7
diff --git a/drivers/nxp/console/16550_console.S b/drivers/nxp/console/16550_console.S
index 044d3d0..b5617a3 100644
--- a/drivers/nxp/console/16550_console.S
+++ b/drivers/nxp/console/16550_console.S
@@ -167,7 +167,7 @@
 register_16550:
 	mov	x0, x6
 	mov	x30, x7
-	finish_console_register 16550 putc=1, getc=1, flush=1
+	finish_console_register 16550 putc=1, getc=ENABLE_CONSOLE_GETC, flush=1
 
 register_fail:
 	ret	x7
diff --git a/drivers/ti/uart/aarch32/16550_console.S b/drivers/ti/uart/aarch32/16550_console.S
index 0429f87..898a68d 100644
--- a/drivers/ti/uart/aarch32/16550_console.S
+++ b/drivers/ti/uart/aarch32/16550_console.S
@@ -124,7 +124,7 @@
 register_16550:
 	mov	r0, r4
 	pop	{r4, lr}
-	finish_console_register 16550 putc=1, getc=1, flush=1
+	finish_console_register 16550 putc=1, getc=ENABLE_CONSOLE_GETC, flush=1
 
 register_fail:
 	pop	{r4, pc}
diff --git a/drivers/ti/uart/aarch64/16550_console.S b/drivers/ti/uart/aarch64/16550_console.S
index cb21512..2b1b5a9 100644
--- a/drivers/ti/uart/aarch64/16550_console.S
+++ b/drivers/ti/uart/aarch64/16550_console.S
@@ -118,7 +118,7 @@
 register_16550:
 	mov	x0, x6
 	mov	x30, x7
-	finish_console_register 16550 putc=1, getc=1, flush=1
+	finish_console_register 16550 putc=1, getc=ENABLE_CONSOLE_GETC, flush=1
 
 register_fail:
 	ret	x7
diff --git a/include/arch/aarch32/console_macros.S b/include/arch/aarch32/console_macros.S
index 996cb32..726b281 100644
--- a/include/arch/aarch32/console_macros.S
+++ b/include/arch/aarch32/console_macros.S
@@ -29,12 +29,20 @@
 	.endif
 	str	r1, [r0, #CONSOLE_T_PUTC]
 
+	/*
+	 * If ENABLE_CONSOLE_GETC support is disabled, but a getc callback is
+	 * specified nonetheless, the assembler will abort on encountering the
+	 * CONSOLE_T_GETC macro, which is undefined.
+	 */
 	.ifne \getc
 	  ldr	r1, =console_\_driver\()_getc
+	  str	r1, [r0, #CONSOLE_T_GETC]
 	.else
+#if ENABLE_CONSOLE_GETC
 	  mov	r1, #0
+	  str	r1, [r0, #CONSOLE_T_GETC]
+#endif
 	.endif
-	str	r1, [r0, #CONSOLE_T_GETC]
 
 	.ifne \flush
 	  ldr	r1, =console_\_driver\()_flush
diff --git a/include/arch/aarch64/console_macros.S b/include/arch/aarch64/console_macros.S
index 3285d85..8adb9cd 100644
--- a/include/arch/aarch64/console_macros.S
+++ b/include/arch/aarch64/console_macros.S
@@ -30,12 +30,19 @@
 	  str	xzr, [x0, #CONSOLE_T_PUTC]
 	.endif
 
+	/*
+	 * If ENABLE_CONSOLE_GETC support is disabled, but a getc callback is
+	 * specified nonetheless, the assembler will abort on encountering the
+	 * CONSOLE_T_GETC macro, which is undefined.
+	 */
 	.ifne \getc
 	  adrp	x1, console_\_driver\()_getc
 	  add	x1, x1, :lo12:console_\_driver\()_getc
 	  str	x1, [x0, #CONSOLE_T_GETC]
 	.else
+#if ENABLE_CONSOLE_GETC
 	  str	xzr, [x0, #CONSOLE_T_GETC]
+#endif
 	.endif
 
 	.ifne \flush
diff --git a/include/common/tbbr/cot_def.h b/include/common/tbbr/cot_def.h
index 822c474..1d28772 100644
--- a/include/common/tbbr/cot_def.h
+++ b/include/common/tbbr/cot_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -46,7 +46,13 @@
 #error "Invalid value for TF_MBEDTLS_KEY_SIZE"
 #endif
 #else /* Only using ECDSA keys. */
+#if TF_MBEDTLS_KEY_SIZE == 384
+#define PK_DER_LEN                      120
+#elif TF_MBEDTLS_KEY_SIZE == 256
 #define PK_DER_LEN                      92
+#else
+#error "Invalid value for TF_MBEDTLS_KEY_SIZE"
+#endif
 #endif
 
 #if TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA256
diff --git a/include/drivers/auth/mbedtls/mbedtls_config-3.h b/include/drivers/auth/mbedtls/mbedtls_config-3.h
index ba936a3..923fc54 100644
--- a/include/drivers/auth/mbedtls/mbedtls_config-3.h
+++ b/include/drivers/auth/mbedtls/mbedtls_config-3.h
@@ -62,8 +62,12 @@
 #if TF_MBEDTLS_USE_ECDSA
 #define MBEDTLS_ECDSA_C
 #define MBEDTLS_ECP_C
+#if TF_MBEDTLS_KEY_SIZE == 384
+#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
+#else
 #define MBEDTLS_ECP_DP_SECP256R1_ENABLED
 #endif
+#endif
 #if TF_MBEDTLS_USE_RSA
 #define MBEDTLS_RSA_C
 #define MBEDTLS_X509_RSASSA_PSS_SUPPORT
diff --git a/include/drivers/console.h b/include/drivers/console.h
index f499571..fa4eb94 100644
--- a/include/drivers/console.h
+++ b/include/drivers/console.h
@@ -12,10 +12,16 @@
 #define CONSOLE_T_NEXT			(U(0) * REGSZ)
 #define CONSOLE_T_FLAGS			(U(1) * REGSZ)
 #define CONSOLE_T_PUTC			(U(2) * REGSZ)
+#if ENABLE_CONSOLE_GETC
 #define CONSOLE_T_GETC			(U(3) * REGSZ)
 #define CONSOLE_T_FLUSH			(U(4) * REGSZ)
 #define CONSOLE_T_BASE			(U(5) * REGSZ)
 #define CONSOLE_T_DRVDATA		(U(6) * REGSZ)
+#else
+#define CONSOLE_T_FLUSH			(U(3) * REGSZ)
+#define CONSOLE_T_BASE			(U(4) * REGSZ)
+#define CONSOLE_T_DRVDATA		(U(5) * REGSZ)
+#endif
 
 #define CONSOLE_FLAG_BOOT		(U(1) << 0)
 #define CONSOLE_FLAG_RUNTIME		(U(1) << 1)
@@ -42,7 +48,9 @@
 	 */
 	u_register_t flags;
 	int (*const putc)(int character, struct console *console);
+#if ENABLE_CONSOLE_GETC
 	int (*const getc)(struct console *console);
+#endif
 	void (*const flush)(struct console *console);
 	uintptr_t base;
 	/* Additional private driver data may follow here. */
@@ -75,8 +83,10 @@
 void console_switch_state(unsigned int new_state);
 /* Output a character on all consoles registered for the current state. */
 int console_putc(int c);
+#if ENABLE_CONSOLE_GETC
 /* Read a character (blocking) from any console registered for current state. */
 int console_getc(void);
+#endif
 /* Flush all consoles registered for the current state. */
 void console_flush(void);
 
diff --git a/include/drivers/console_assertions.h b/include/drivers/console_assertions.h
index 00caa31..9f06573 100644
--- a/include/drivers/console_assertions.h
+++ b/include/drivers/console_assertions.h
@@ -19,8 +19,10 @@
 	assert_console_t_flags_offset_mismatch);
 CASSERT(CONSOLE_T_PUTC == __builtin_offsetof(console_t, putc),
 	assert_console_t_putc_offset_mismatch);
+#if ENABLE_CONSOLE_GETC
 CASSERT(CONSOLE_T_GETC == __builtin_offsetof(console_t, getc),
 	assert_console_t_getc_offset_mismatch);
+#endif
 CASSERT(CONSOLE_T_FLUSH == __builtin_offsetof(console_t, flush),
 	assert_console_t_flush_offset_mismatch);
 CASSERT(CONSOLE_T_DRVDATA == sizeof(console_t),
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index 0ab0e82..314eb93 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -24,8 +24,6 @@
  */
 #define ARM_ROTPK_HEADER_LEN		19
 #define ARM_ROTPK_HASH_LEN		32
-/* ARM_ROTPK_KEY_LEN includes DER header + raw key material */
-#define ARM_ROTPK_KEY_LEN		294
 
 /* Special value used to verify platform parameters from BL2 to BL31 */
 #define ARM_BL31_PLAT_PARAM_VAL		ULL(0x0f1e2d3c4b5a6978)
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 2fdbfb7..0fb06a6 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -53,7 +53,7 @@
 		PLAT_ARM_TZC_NS_DEV_ACCESS}
 #endif
 
-#if SPM_MM
+#if SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)
 #define ARM_TZC_REGIONS_DEF						\
 	{ARM_AP_TZC_DRAM1_BASE, ARM_EL3_TZC_DRAM1_END + ARM_L1_GPT_SIZE,\
 		TZC_REGION_S_RDWR, 0},					\
@@ -176,10 +176,17 @@
 #define STATE_SW_E_DENIED		(-3)
 
 /* plat_get_rotpk_info() flags */
-#define ARM_ROTPK_REGS_ID		1
-#define ARM_ROTPK_DEVEL_RSA_ID		2
-#define ARM_ROTPK_DEVEL_ECDSA_ID	3
+#define ARM_ROTPK_REGS_ID			1
+#define ARM_ROTPK_DEVEL_RSA_ID			2
+#define ARM_ROTPK_DEVEL_ECDSA_ID		3
 #define ARM_ROTPK_DEVEL_FULL_DEV_RSA_KEY_ID	4
+#define ARM_ROTPK_DEVEL_FULL_DEV_ECDSA_KEY_ID	5
+
+#define ARM_USE_DEVEL_ROTPK							\
+	(ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) ||			\
+	(ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) ||			\
+	(ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_FULL_DEV_RSA_KEY_ID) ||	\
+	(ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_FULL_DEV_ECDSA_KEY_ID)
 
 /* IO storage utility functions */
 int arm_io_setup(void);
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 321ae9f..ea22655 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -240,6 +240,9 @@
 # Use the FF-A SPMC implementation in EL3.
 SPMC_AT_EL3			:= 0
 
+# Enable SEL0 SP when SPMC is enabled at EL3
+SPMC_AT_EL3_SEL0_SP		:=0
+
 # Use SPM at S-EL2 as a default config for SPMD
 SPMD_SPM_AT_SEL2		:= 1
 
@@ -362,3 +365,8 @@
 
 # By default, disable PSA crypto (use MbedTLS legacy crypto API).
 PSA_CRYPTO			:= 0
+
+# getc() support from the console(s).
+# Disabled by default because it constitutes an attack vector into TF-A. It
+# should only be enabled if there is a use case for it.
+ENABLE_CONSOLE_GETC		:= 0
diff --git a/plat/arm/board/common/board_arm_trusted_boot.c b/plat/arm/board/common/board_arm_trusted_boot.c
index 24d88ee..c4f15dd 100644
--- a/plat/arm/board/common/board_arm_trusted_boot.c
+++ b/plat/arm/board/common/board_arm_trusted_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -94,20 +94,25 @@
 #endif
 
 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
-    (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) || \
-    (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_FULL_DEV_RSA_KEY_ID)
+    (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
 int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len,
 			unsigned int *flags)
 {
-	if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_FULL_DEV_RSA_KEY_ID) {
-		*key_ptr = arm_rotpk_key;
-		*key_len = arm_rotpk_key_end - arm_rotpk_key;
-		*flags = 0;
-	} else {
-		*key_ptr = arm_rotpk_header;
-		*key_len = arm_rotpk_hash_end - arm_rotpk_header;
-		*flags = ROTPK_IS_HASH;
-	}
+	*key_ptr = arm_rotpk_header;
+	*key_len = arm_rotpk_hash_end - arm_rotpk_header;
+	*flags = ROTPK_IS_HASH;
+	return 0;
+}
+#endif
+
+#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_FULL_DEV_RSA_KEY_ID) || \
+    (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_FULL_DEV_ECDSA_KEY_ID)
+int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len,
+			unsigned int *flags)
+{
+	*key_ptr = arm_rotpk_key;
+	*key_len = arm_rotpk_key_end - arm_rotpk_key;
+	*flags = 0;
 	return 0;
 }
 #endif
@@ -144,9 +149,7 @@
 	return arm_get_rotpk_info_cc(key_ptr, key_len, flags);
 #else
 
-#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
-    (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) || \
-    (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_FULL_DEV_RSA_KEY_ID)
+#if ARM_USE_DEVEL_ROTPK
 	return arm_get_rotpk_info_dev(key_ptr, key_len, flags);
 #elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
 	return arm_get_rotpk_info_regs(key_ptr, key_len, flags);
diff --git a/plat/arm/board/common/board_common.mk b/plat/arm/board/common/board_common.mk
index 4665827..cbdbf70 100644
--- a/plat/arm/board/common/board_common.mk
+++ b/plat/arm/board/common/board_common.mk
@@ -39,6 +39,16 @@
 	ARM_ROTPK_S = plat/arm/board/common/rotpk/arm_full_dev_rsa_rotpk.S
 $(warning Development keys support for FVP is deprecated. Use `regs` \
 option instead)
+else ifeq (${ARM_ROTPK_LOCATION}, devel_full_dev_ecdsa_key)
+	CRYPTO_ALG=ec
+	ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_FULL_DEV_ECDSA_KEY_ID
+ifeq (${KEY_SIZE},384)
+	ARM_ROTPK_S = plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p384_rotpk.S
+else
+	ARM_ROTPK_S = plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p256_rotpk.S
+endif
+$(warning Development keys support for FVP is deprecated. Use `regs` \
+option instead)
 else
 $(error "Unsupported ARM_ROTPK_LOCATION value")
 endif
diff --git a/plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p256_rotpk.S b/plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p256_rotpk.S
new file mode 100644
index 0000000..690bdbc
--- /dev/null
+++ b/plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p256_rotpk.S
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+	.global arm_rotpk_key
+	.global arm_rotpk_key_end
+
+	.section .rodata.arm_rotpk_key, "a"
+
+/* Derived from arm_rotprivk_ecdsa.pem private key file. */
+arm_rotpk_key:
+	.byte 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D
+	.byte 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01
+	.byte 0x07, 0x03, 0x42, 0x00, 0x04, 0x9B, 0xE6, 0x48, 0xBD, 0x34, 0x38
+	.byte 0xE1, 0xA2, 0xA4, 0xF3, 0x70, 0xE1, 0x54, 0xBB, 0x2F, 0xB0, 0x5A
+	.byte 0x4A, 0x0C, 0xFF, 0xC2, 0x87, 0xDB, 0xC0, 0xFB, 0x81, 0xE9, 0xF9
+	.byte 0xF9, 0x95, 0x7D, 0x7E, 0xA0, 0x0C, 0x7F, 0x0A, 0xD4, 0xE0, 0x62
+	.byte 0x4A, 0x94, 0x5F, 0xEC, 0x52, 0x7D, 0x44, 0x63, 0xC8, 0x9F, 0x61
+	.byte 0xFA, 0xC6, 0xCB, 0x7E, 0x6B, 0x53, 0xAD, 0x2C, 0xC5, 0x94, 0x0D
+	.byte 0x1A, 0x86, 0x91
+arm_rotpk_key_end:
diff --git a/plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p384_rotpk.S b/plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p384_rotpk.S
new file mode 100644
index 0000000..eaf2de4
--- /dev/null
+++ b/plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p384_rotpk.S
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+	.global arm_rotpk_key
+	.global arm_rotpk_key_end
+
+	.section .rodata.arm_rotpk_key, "a"
+
+/* Derived from arm_rotprivk_ecdsa_secp384r1.pem private key file. */
+arm_rotpk_key:
+	.byte 0x30, 0x76, 0x30, 0x10, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D
+	.byte 0x02, 0x01, 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22, 0x03, 0x62
+	.byte 0x00, 0x04, 0xB8, 0xB0, 0xC7, 0xC4, 0x57, 0x19, 0xB7, 0x5A, 0x06
+	.byte 0x36, 0xC5, 0xD8, 0x3C, 0x4E, 0xC3, 0xB5, 0xE1, 0x15, 0x60, 0x0E
+	.byte 0x63, 0xD8, 0xAF, 0x22, 0x2C, 0x6D, 0x79, 0x29, 0xDF, 0x46, 0xA9
+	.byte 0x30, 0x12, 0x16, 0x2D, 0x4F, 0x0F, 0x96, 0x6B, 0x1F, 0x87, 0x06
+	.byte 0xDB, 0x8F, 0xD7, 0x08, 0x46, 0xE4, 0x4C, 0x22, 0xF3, 0xDE, 0xCE
+	.byte 0x0F, 0x72, 0x27, 0x00, 0xAA, 0xD8, 0xC3, 0x79, 0x80, 0x5E, 0xF1
+	.byte 0x35, 0x1B, 0x33, 0xB6, 0x31, 0xC4, 0x59, 0xD4, 0xE9, 0x65, 0x91
+	.byte 0x22, 0x58, 0x2F, 0x87, 0xF1, 0x6C, 0x27, 0xBE, 0x99, 0x6F, 0x5F
+	.byte 0x6C, 0x14, 0xC5, 0x37, 0x0C, 0x73, 0xB4, 0xE4, 0x8A, 0x63
+arm_rotpk_key_end:
diff --git a/plat/arm/board/common/rotpk/arm_full_dev_rsa_rotpk.S b/plat/arm/board/common/rotpk/arm_full_dev_rsa_rotpk.S
index 4bb04dc..4532e53 100644
--- a/plat/arm/board/common/rotpk/arm_full_dev_rsa_rotpk.S
+++ b/plat/arm/board/common/rotpk/arm_full_dev_rsa_rotpk.S
@@ -1,32 +1,40 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-/* corstone1000 platform provides custom values for the macros defined in
- * arm_def.h , so only platform_def.h needs to be included
- */
-#if !defined(TARGET_PLATFORM_FVP) && !defined(TARGET_PLATFORM_FPGA)
-#include "plat/arm/common/arm_def.h"
-#else
-#include <platform_def.h>
-#endif
-
 	.global arm_rotpk_key
 	.global arm_rotpk_key_end
 
 	.section .rodata.arm_rotpk_key, "a"
 
 arm_rotpk_key:
-	.byte 0x30, 0x82, 0x01, 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01
-	.byte 0x05, 0x00, 0x03, 0x82, 0x01, 0x0F, 0x00, 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01
-	.byte 0x00, 0xCB, 0x2C, 0x60, 0xD5, 0x8D, 0x63, 0xD4, 0x07, 0x79, 0x7E, 0xC7, 0x16, 0x96, 0xBD, 0x4D, 0x24, 0x4E, 0xAC, 0x86, 0xE6, 0xB7, 0x71, 0xE3, 0xC5, 0x54, 0x0B, 0xE7, 0x14, 0x1C, 0xBD, 0x29, 0x1A, 0xC1, 0x3F, 0x7A, 0xB6, 0x02, 0xAA, 0xAB, 0x36, 0xC4, 0xD9, 0x36, 0x69, 0x6C, 0xE2, 0x65, 0xC3, 0x9B, 0xB1, 0xBF, 0x3D, 0xA8, 0x56, 0x26, 0xCB, 0xFD, 0x04, 0x01, 0xBA, 0xAC, 0x3E, 0x54, 0x32, 0xCA, 0x79, 0x5E, 0xBB, 0xB2, 0x05, 0xEA, 0x06, 0x58, 0xF2, 0x74, 0xBA, 0xE1, 0xF4, 0x87, 0xC0, 0x19, 0x0A, 0x1F, 0x66, 0x07, 0x77, 0x84, 0x83, 0xA1, 0x1C, 0xEF, 0xFF, 0x28, 0x59, 0xE7, 0xC3, 0x68, 0x7D, 0x26, 0x20, 0x43, 0xEB, 0x56, 0x63, 0xF3, 0x39, 0x31, 0xD8, 0x2B, 0x51, 0xA9, 0xBC, 0x4F, 0xD0, 0xF6, 0xDE, 0x95, 0xDC, 0x5F, 0x5B, 0xC1, 0xED, 0x90, 0x6F, 0xEC, 0x28, 0x91, 0x7E, 0x17, 0xED, 0x78, 0x90, 0xF4, 0x60, 0xA7, 0xC4, 0xC7, 0x4F, 0x50, 0xED, 0x5D, 0x13, 0x3A, 0x21, 0x2B, 0x70, 0xC5, 0x61, 0x7B, 0x08, 0x21, 0x65, 0x3A, 0xCD, 0x82, 0x56, 0x8C, 0x7A, 0x47, 0xAC, 0x89, 0xE8, 0xA5, 0x48, 0x48
-	.byte 0x31, 0xD9, 0x1D, 0x46, 0xE5, 0x85, 0x86, 0x98, 0xA0, 0xE5, 0xC0, 0xA6, 0x6A, 0xBD, 0x07, 0xE4, 0x92, 0x57, 0x61, 0x07, 0x8F, 0x7D, 0x5A, 0x4D, 0xCA, 0xAE, 0x36, 0xB9, 0x56, 0x04, 0x10, 0xF2, 0x6C, 0xBE, 0xF6, 0x3B, 0x6C, 0x80, 0x3E, 0xBE , 0x0E, 0xA3, 0x4D , 0xC7 , 0xD4, 0x7E , 0xA7  , 0x49, 0xD4, 0xF2, 0xD2, 0xBC, 0xCF, 0x30, 0xA8, 0xE7, 0x74, 0x8F, 0x64, 0xDF, 0xBC, 0x5C, 0x47, 0x68, 0xCC, 0x40, 0x4C, 0xF8, 0x83, 0xCC, 0xCB, 0x40, 0x35, 0x04, 0x60, 0xCA, 0xB3, 0xA4, 0x17, 0x9F, 0x03, 0xCA, 0x1D, 0x5A, 0xFA, 0xD1, 0xAF, 0x21, 0x57, 0x10, 0xD3, 0x02, 0x03, 0x01, 0x00, 0x01
-
+	.byte 0x30, 0x82, 0x01, 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48
+	.byte 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01
+	.byte 0x0F, 0x00, 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, 0x00
+	.byte 0xCB, 0x2C, 0x60, 0xD5, 0x8D, 0x63, 0xD4, 0x07, 0x79, 0x7E, 0xC7
+	.byte 0x16, 0x96, 0xBD, 0x4D, 0x24, 0x4E, 0xAC, 0x86, 0xE6, 0xB7, 0x71
+	.byte 0xE3, 0xC5, 0x54, 0x0B, 0xE7, 0x14, 0x1C, 0xBD, 0x29, 0x1A, 0xC1
+	.byte 0x3F, 0x7A, 0xB6, 0x02, 0xAA, 0xAB, 0x36, 0xC4, 0xD9, 0x36, 0x69
+	.byte 0x6C, 0xE2, 0x65, 0xC3, 0x9B, 0xB1, 0xBF, 0x3D, 0xA8, 0x56, 0x26
+	.byte 0xCB, 0xFD, 0x04, 0x01, 0xBA, 0xAC, 0x3E, 0x54, 0x32, 0xCA, 0x79
+	.byte 0x5E, 0xBB, 0xB2, 0x05, 0xEA, 0x06, 0x58, 0xF2, 0x74, 0xBA, 0xE1
+	.byte 0xF4, 0x87, 0xC0, 0x19, 0x0A, 0x1F, 0x66, 0x07, 0x77, 0x84, 0x83
+	.byte 0xA1, 0x1C, 0xEF, 0xFF, 0x28, 0x59, 0xE7, 0xC3, 0x68, 0x7D, 0x26
+	.byte 0x20, 0x43, 0xEB, 0x56, 0x63, 0xF3, 0x39, 0x31, 0xD8, 0x2B, 0x51
+	.byte 0xA9, 0xBC, 0x4F, 0xD0, 0xF6, 0xDE, 0x95, 0xDC, 0x5F, 0x5B, 0xC1
+	.byte 0xED, 0x90, 0x6F, 0xEC, 0x28, 0x91, 0x7E, 0x17, 0xED, 0x78, 0x90
+	.byte 0xF4, 0x60, 0xA7, 0xC4, 0xC7, 0x4F, 0x50, 0xED, 0x5D, 0x13, 0x3A
+	.byte 0x21, 0x2B, 0x70, 0xC5, 0x61, 0x7B, 0x08, 0x21, 0x65, 0x3A, 0xCD
+	.byte 0x82, 0x56, 0x8C, 0x7A, 0x47, 0xAC, 0x89, 0xE8, 0xA5, 0x48, 0x48
+	.byte 0x31, 0xD9, 0x1D, 0x46, 0xE5, 0x85, 0x86, 0x98, 0xA0, 0xE5, 0xC0
+	.byte 0xA6, 0x6A, 0xBD, 0x07, 0xE4, 0x92, 0x57, 0x61, 0x07, 0x8F, 0x7D
+	.byte 0x5A, 0x4D, 0xCA, 0xAE, 0x36, 0xB9, 0x56, 0x04, 0x10, 0xF2, 0x6C
+	.byte 0xBE, 0xF6, 0x3B, 0x6C, 0x80, 0x3E, 0xBE, 0x0E, 0xA3, 0x4D, 0xC7
+	.byte 0xD4, 0x7E, 0xA7, 0x49, 0xD4, 0xF2, 0xD2, 0xBC, 0xCF, 0x30, 0xA8
+	.byte 0xE7, 0x74, 0x8F, 0x64, 0xDF, 0xBC, 0x5C, 0x47, 0x68, 0xCC, 0x40
+	.byte 0x4C, 0xF8, 0x83, 0xCC, 0xCB, 0x40, 0x35, 0x04, 0x60, 0xCA, 0xB3
+	.byte 0xA4, 0x17, 0x9F, 0x03, 0xCA, 0x1D, 0x5A, 0xFA, 0xD1, 0xAF, 0x21
+	.byte 0x57, 0x10, 0xD3, 0x02, 0x03, 0x01, 0x00, 0x01
 arm_rotpk_key_end:
-
-.if ARM_ROTPK_KEY_LEN != arm_rotpk_key_end - arm_rotpk_key
-.error "Invalid ROTPK length."
-.endif
-
diff --git a/plat/arm/board/common/rotpk/arm_rotprivk_ecdsa_secp384r1.pem b/plat/arm/board/common/rotpk/arm_rotprivk_ecdsa_secp384r1.pem
new file mode 100644
index 0000000..d40fc05
--- /dev/null
+++ b/plat/arm/board/common/rotpk/arm_rotprivk_ecdsa_secp384r1.pem
@@ -0,0 +1,6 @@
+-----BEGIN PRIVATE KEY-----
+MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDAWrGXulAoVCrH3oRMC
+/AGvn2LA6+VI0xtd9eCWCzIcOSt+AC+/kULZnypuC8bdGJOhZANiAAS4sMfEVxm3
+WgY2xdg8TsO14RVgDmPYryIsbXkp30apMBIWLU8Plmsfhwbbj9cIRuRMIvPezg9y
+JwCq2MN5gF7xNRsztjHEWdTpZZEiWC+H8WwnvplvX2wUxTcMc7TkimM=
+-----END PRIVATE KEY-----
diff --git a/plat/arm/board/rdn2/include/platform_def.h b/plat/arm/board/rdn2/include/platform_def.h
index ff1a437..2391b72 100644
--- a/plat/arm/board/rdn2/include/platform_def.h
+++ b/plat/arm/board/rdn2/include/platform_def.h
@@ -102,4 +102,25 @@
 #define PLAT_REBOOT_PRI		GIC_HIGHEST_SEC_PRIORITY
 #define PLAT_EHF_DESC		EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_REBOOT_PRI)
 
+/*
+ * Number of Secure Partitions supported.
+ * SPMC at EL3, uses this count to configure the maximum number of supported
+ * secure partitions.
+ */
+#define SECURE_PARTITION_COUNT          1
+
+/*
+ * Number of NWd Partitions supported.
+ * SPMC at EL3, uses this count to configure the maximum number of supported
+ * nwld partitions.
+ */
+#define NS_PARTITION_COUNT              1
+
+/*
+ * Number of Logical Partitions supported.
+ * SPMC at EL3, uses this count to configure the maximum number of supported
+ * logical partitions.
+ */
+#define MAX_EL3_LP_DESCS_COUNT		1
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/rdn2/rdn2_plat.c b/plat/arm/board/rdn2/rdn2_plat.c
index e8a967e..f117456 100644
--- a/plat/arm/board/rdn2/rdn2_plat.c
+++ b/plat/arm/board/rdn2/rdn2_plat.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,6 +8,7 @@
 #include <drivers/arm/gic600_multichip.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
+#include <services/el3_spmc_ffa_memory.h>
 #include <rdn2_ras.h>
 #include <sgi_soc_platform_def_v2.h>
 #include <sgi_plat.h>
@@ -141,3 +142,41 @@
 #endif
 }
 #endif /* IMAGE_BL31 */
+
+#if SPMC_AT_EL3
+
+#define DATASTORE_SIZE 1024
+
+__section("arm_el3_tzc_dram") uint8_t plat_spmc_shmem_datastore[DATASTORE_SIZE];
+
+int plat_spmc_shmem_datastore_get(uint8_t **datastore, size_t *size)
+{
+	*datastore = plat_spmc_shmem_datastore;
+	*size = DATASTORE_SIZE;
+	return 0;
+}
+
+/*
+ * Add dummy implementations of memory management related platform hooks.
+ * Memory share/lend operation are not required on RdN2 platform.
+ */
+int plat_spmc_shmem_begin(struct ffa_mtd *desc)
+{
+	return 0;
+}
+
+int plat_spmc_shmem_reclaim(struct ffa_mtd *desc)
+{
+	return 0;
+}
+
+int plat_spmd_handle_group0_interrupt(uint32_t intid)
+{
+	/*
+	 * As of now, there are no sources of Group0 secure interrupt enabled
+	 * for RDN2.
+	 */
+	(void)intid;
+	return -1;
+}
+#endif
diff --git a/plat/arm/css/sgi/include/sgi_base_platform_def.h b/plat/arm/css/sgi/include/sgi_base_platform_def.h
index b9c785f..8a13bf3 100644
--- a/plat/arm/css/sgi/include/sgi_base_platform_def.h
+++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -33,7 +33,7 @@
  * chips are accessed - secure ram, css device and soc device regions.
  */
 #if defined(IMAGE_BL31)
-# if SPM_MM
+# if SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)
 #  define PLAT_ARM_MMAP_ENTRIES		(9  + ((CSS_SGI_CHIP_COUNT - 1) * 3))
 #  define MAX_XLAT_TABLES		(7  + ((CSS_SGI_CHIP_COUNT - 1) * 3))
 #  define PLAT_SP_IMAGE_MMAP_REGIONS	10
@@ -210,7 +210,7 @@
 #define PLAT_SP_PRI				0x10
 #endif
 
-#if SPM_MM && RAS_FFH_SUPPORT
+#if (SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)) && RAS_FFH_SUPPORT
 /*
  * CPER buffer memory of 128KB is reserved and it is placed adjacent to the
  * memory shared between EL3 and S-EL0.
@@ -232,7 +232,7 @@
 #define PLAT_ARM_SP_IMAGE_STACK_BASE		(PLAT_SP_IMAGE_NS_BUF_BASE +   \
 						 PLAT_SP_IMAGE_NS_BUF_SIZE +   \
 						 CSS_SGI_SP_CPER_BUF_SIZE)
-#elif SPM_MM
+#elif (SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP))
 /*
  * Secure partition stack follows right after the memory region that is shared
  * between EL3 and S-EL0.
diff --git a/plat/arm/css/sgi/sgi_plat_v2.c b/plat/arm/css/sgi/sgi_plat_v2.c
index 8de0efe..85f99d4 100644
--- a/plat/arm/css/sgi/sgi_plat_v2.c
+++ b/plat/arm/css/sgi/sgi_plat_v2.c
@@ -54,7 +54,7 @@
 #if ARM_BL31_IN_DRAM
 	ARM_MAP_BL31_SEC_DRAM,
 #endif
-#if SPM_MM
+#if SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)
 	ARM_SP_IMAGE_MMAP,
 #endif
 #if TRUSTED_BOARD_BOOT && !RESET_TO_BL2
@@ -73,7 +73,7 @@
 	CSS_SGI_MAP_DEVICE,
 	SOC_PLATFORM_PERIPH_MAP_DEVICE,
 	SOC_SYSTEM_PERIPH_MAP_DEVICE,
-#if SPM_MM
+#if SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)
 	ARM_SPM_BUF_EL3_MMAP,
 #endif
 	{0}
diff --git a/plat/common/aarch64/plat_ehf.c b/plat/common/aarch64/plat_ehf.c
index be0fac1..41b175d 100644
--- a/plat/common/aarch64/plat_ehf.c
+++ b/plat/common/aarch64/plat_ehf.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2020, Broadcom
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -25,7 +25,7 @@
 	EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SDEI_NORMAL_PRI),
 #endif
 
-#if SPM_MM
+#if SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)
 #if RAS_FFH_SUPPORT
 #if (PLAT_SP_PRI != PLAT_RAS_PRI)
 	EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SP_PRI),
diff --git a/plat/imx/common/aarch32/imx_uart_console.S b/plat/imx/common/aarch32/imx_uart_console.S
index 1a1229a..2a35b5e 100644
--- a/plat/imx/common/aarch32/imx_uart_console.S
+++ b/plat/imx/common/aarch32/imx_uart_console.S
@@ -28,7 +28,7 @@
 
 	mov	r0, r4
 	pop	{r4, lr}
-	finish_console_register imx_uart putc=1, getc=1, flush=1
+	finish_console_register imx_uart putc=1, getc=ENABLE_CONSOLE_GETC, flush=1
 
 register_fail:
 	pop	{r4, pc}
diff --git a/plat/imx/common/imx_uart_console.S b/plat/imx/common/imx_uart_console.S
index 4d17288..560db15 100644
--- a/plat/imx/common/imx_uart_console.S
+++ b/plat/imx/common/imx_uart_console.S
@@ -33,7 +33,7 @@
 
 	mov	x0, x6
 	mov	x30, x7
-	finish_console_register imx_uart putc=1, getc=1, flush=1
+	finish_console_register imx_uart putc=1, getc=ENABLE_CONSOLE_GETC, flush=1
 
 register_fail:
 	ret	x7
diff --git a/plat/imx/common/lpuart_console.S b/plat/imx/common/lpuart_console.S
index ff01e35..7acf773 100644
--- a/plat/imx/common/lpuart_console.S
+++ b/plat/imx/common/lpuart_console.S
@@ -27,7 +27,7 @@
 
 	mov	x0, x6
 	mov	x30, x7
-	finish_console_register lpuart putc=1, getc=1, flush=1
+	finish_console_register lpuart putc=1, getc=ENABLE_CONSOLE_GETC, flush=1
 
 register_fail:
 	ret	x7
diff --git a/plat/nvidia/tegra/drivers/spe/shared_console.S b/plat/nvidia/tegra/drivers/spe/shared_console.S
index d1b18dd..5ad4eb8 100644
--- a/plat/nvidia/tegra/drivers/spe/shared_console.S
+++ b/plat/nvidia/tegra/drivers/spe/shared_console.S
@@ -71,7 +71,7 @@
 	cbz	x3, register_fail
 	str	x0, [x3, #CONSOLE_T_BASE]
 	mov	x0, x3
-	finish_console_register spe putc=1, getc=1, flush=1
+	finish_console_register spe putc=1, getc=ENABLE_CONSOLE_GETC, flush=1
 
 register_fail:
 	mov	w0, wzr
diff --git a/plat/socionext/uniphier/uniphier_console_setup.c b/plat/socionext/uniphier/uniphier_console_setup.c
index 9fda26e..9268f5d 100644
--- a/plat/socionext/uniphier/uniphier_console_setup.c
+++ b/plat/socionext/uniphier/uniphier_console_setup.c
@@ -30,7 +30,9 @@
 		 CONSOLE_FLAG_CRASH |
 		 CONSOLE_FLAG_TRANSLATE_CRLF,
 	.putc = uniphier_console_putc,
+#if ENABLE_CONSOLE_GETC
 	.getc = uniphier_console_getc,
+#endif
 	.flush = uniphier_console_flush,
 };
 
diff --git a/plat/st/common/common.mk b/plat/st/common/common.mk
index d10f185..7f93961 100644
--- a/plat/st/common/common.mk
+++ b/plat/st/common/common.mk
@@ -165,7 +165,6 @@
 ifeq (${GENERATE_COT},1)
 TFW_NVCTR_VAL			:=	0
 NTFW_NVCTR_VAL			:=	0
-KEY_SIZE			:=
 KEY_ALG				:=	ecdsa
 HASH_ALG			:=	sha256
 
@@ -178,6 +177,7 @@
 
 endif
 TF_MBEDTLS_KEY_ALG		:=	ecdsa
+KEY_SIZE			:=	256
 
 ifneq (${MBEDTLS_DIR},)
 MBEDTLS_MAJOR=$(shell grep -hP "define MBEDTLS_VERSION_MAJOR" \
diff --git a/services/std_svc/spm/spm_mm/aarch64/spm_mm_shim_exceptions.S b/services/std_svc/spm/common/aarch64/spm_shim_exceptions.S
similarity index 100%
rename from services/std_svc/spm/spm_mm/aarch64/spm_mm_shim_exceptions.S
rename to services/std_svc/spm/common/aarch64/spm_shim_exceptions.S
diff --git a/services/std_svc/spm/common/include/spm_common.h b/services/std_svc/spm/common/include/spm_common.h
index 68805fc..c736919 100644
--- a/services/std_svc/spm/common/include/spm_common.h
+++ b/services/std_svc/spm/common/include/spm_common.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -32,11 +32,15 @@
 #ifndef __ASSEMBLER__
 
 #include <stdint.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
 
 /* Assembly helpers */
 uint64_t spm_secure_partition_enter(uint64_t *c_rt_ctx);
 void __dead2 spm_secure_partition_exit(uint64_t c_rt_ctx, uint64_t ret);
 
+/* Helper to obtain a reference to the SP's translation table context */
+xlat_ctx_t *spm_get_sp_xlat_context(void);
+
 #endif /* __ASSEMBLER__ */
 
 #endif /* SPM_COMMON_H */
diff --git a/services/std_svc/spm/spm_mm/spm_mm_shim_private.h b/services/std_svc/spm/common/include/spm_shim_private.h
similarity index 75%
rename from services/std_svc/spm/spm_mm/spm_mm_shim_private.h
rename to services/std_svc/spm/common/include/spm_shim_private.h
index f69c748..bcb1147 100644
--- a/services/std_svc/spm/spm_mm/spm_mm_shim_private.h
+++ b/services/std_svc/spm/common/include/spm_shim_private.h
@@ -1,11 +1,11 @@
 /*
- * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef SPM_MM_SHIM_PRIVATE_H
-#define SPM_MM_SHIM_PRIVATE_H
+#ifndef SPM_SHIM_PRIVATE_H
+#define SPM_SHIM_PRIVATE_H
 
 #include <stdint.h>
 
@@ -23,4 +23,4 @@
 #define SPM_SHIM_EXCEPTIONS_SIZE	\
 	(SPM_SHIM_EXCEPTIONS_END - SPM_SHIM_EXCEPTIONS_START)
 
-#endif /* SPM_MM_SHIM_PRIVATE_H */
+#endif /* SPM_SHIM_PRIVATE_H */
diff --git a/services/std_svc/spm/common/spm.mk b/services/std_svc/spm/common/spm.mk
index 9aa96be..65fd72a 100644
--- a/services/std_svc/spm/common/spm.mk
+++ b/services/std_svc/spm/common/spm.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2022-2023, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -10,8 +10,14 @@
 
 INCLUDES	+=	-Iservices/std_svc/spm/common/include
 
-SPM_SOURCES	:=	$(addprefix services/std_svc/spm/common/,\
-			${ARCH}/spm_helpers.S)
+SPM_SOURCES	:=	$(addprefix services/std_svc/spm/common/,	\
+			${ARCH}/spm_helpers.S				\
+			${ARCH}/spm_shim_exceptions.S)
+
+ifeq (1, $(filter 1, ${SPM_MM} ${SPMC_AT_EL3_SEL0_SP}))
+SPM_SOURCES	+=	$(addprefix services/std_svc/spm/common/,       \
+			spm_xlat_common.c)
+endif
 
 # Let the top-level Makefile know that we intend to include a BL32 image
 NEED_BL32		:=	yes
diff --git a/services/std_svc/spm/common/spm_xlat_common.c b/services/std_svc/spm/common/spm_xlat_common.c
new file mode 100644
index 0000000..a463c8b
--- /dev/null
+++ b/services/std_svc/spm/common/spm_xlat_common.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <platform_def.h>
+
+/* Place translation tables by default along with the ones used by BL31. */
+#ifndef PLAT_SP_IMAGE_XLAT_SECTION_NAME
+#define PLAT_SP_IMAGE_XLAT_SECTION_NAME	".xlat_table"
+#endif
+#ifndef PLAT_SP_IMAGE_BASE_XLAT_SECTION_NAME
+#define PLAT_SP_IMAGE_BASE_XLAT_SECTION_NAME	".bss"
+#endif
+
+/* Allocate and initialise the translation context for the secure partitions. */
+REGISTER_XLAT_CONTEXT2(sp,
+		       PLAT_SP_IMAGE_MMAP_REGIONS,
+		       PLAT_SP_IMAGE_MAX_XLAT_TABLES,
+		       PLAT_VIRT_ADDR_SPACE_SIZE, PLAT_PHY_ADDR_SPACE_SIZE,
+		       EL1_EL0_REGIME, PLAT_SP_IMAGE_XLAT_SECTION_NAME,
+		       PLAT_SP_IMAGE_BASE_XLAT_SECTION_NAME);
+
+/* Get handle of Secure Partition translation context */
+xlat_ctx_t *spm_get_sp_xlat_context(void)
+{
+	return &sp_xlat_ctx;
+};
diff --git a/services/std_svc/spm/spm_mm/spm_mm.mk b/services/std_svc/spm/spm_mm/spm_mm.mk
index 513e8ef..cbc7940 100644
--- a/services/std_svc/spm/spm_mm/spm_mm.mk
+++ b/services/std_svc/spm/spm_mm/spm_mm.mk
@@ -21,7 +21,6 @@
 endif
 
 SPM_MM_SOURCES	:=	$(addprefix services/std_svc/spm/spm_mm/,	\
-			${ARCH}/spm_mm_shim_exceptions.S		\
 			spm_mm_main.c					\
 			spm_mm_setup.c					\
 			spm_mm_xlat.c)
diff --git a/services/std_svc/spm/spm_mm/spm_mm_private.h b/services/std_svc/spm/spm_mm/spm_mm_private.h
index 0eff1c0..3a52a3e 100644
--- a/services/std_svc/spm/spm_mm/spm_mm_private.h
+++ b/services/std_svc/spm/spm_mm/spm_mm_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -55,8 +55,6 @@
 
 void spm_sp_setup(sp_context_t *sp_ctx);
 
-xlat_ctx_t *spm_get_sp_xlat_context(void);
-
 int32_t spm_memory_attributes_get_smc_handler(sp_context_t *sp_ctx,
 					      uintptr_t base_va);
 int spm_memory_attributes_set_smc_handler(sp_context_t *sp_ctx,
diff --git a/services/std_svc/spm/spm_mm/spm_mm_setup.c b/services/std_svc/spm/spm_mm/spm_mm_setup.c
index 04dc212..4e65c9c 100644
--- a/services/std_svc/spm/spm_mm/spm_mm_setup.c
+++ b/services/std_svc/spm/spm_mm/spm_mm_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -21,7 +21,7 @@
 
 #include "spm_common.h"
 #include "spm_mm_private.h"
-#include "spm_mm_shim_private.h"
+#include "spm_shim_private.h"
 
 /* Setup context of the Secure Partition */
 void spm_sp_setup(sp_context_t *sp_ctx)
diff --git a/services/std_svc/spm/spm_mm/spm_mm_xlat.c b/services/std_svc/spm/spm_mm/spm_mm_xlat.c
index b1ca55a..01d95c7 100644
--- a/services/std_svc/spm/spm_mm/spm_mm_xlat.c
+++ b/services/std_svc/spm/spm_mm/spm_mm_xlat.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,33 +15,11 @@
 #include <services/spm_mm_svc.h>
 
 #include "spm_mm_private.h"
-#include "spm_mm_shim_private.h"
-
-/* Place translation tables by default along with the ones used by BL31. */
-#ifndef PLAT_SP_IMAGE_XLAT_SECTION_NAME
-#define PLAT_SP_IMAGE_XLAT_SECTION_NAME	".xlat_table"
-#endif
-#ifndef PLAT_SP_IMAGE_BASE_XLAT_SECTION_NAME
-#define PLAT_SP_IMAGE_BASE_XLAT_SECTION_NAME	".bss"
-#endif
-
-/* Allocate and initialise the translation context for the secure partitions. */
-REGISTER_XLAT_CONTEXT2(sp,
-		       PLAT_SP_IMAGE_MMAP_REGIONS,
-		       PLAT_SP_IMAGE_MAX_XLAT_TABLES,
-		       PLAT_VIRT_ADDR_SPACE_SIZE, PLAT_PHY_ADDR_SPACE_SIZE,
-		       EL1_EL0_REGIME, PLAT_SP_IMAGE_XLAT_SECTION_NAME,
-		       PLAT_SP_IMAGE_BASE_XLAT_SECTION_NAME);
+#include "spm_shim_private.h"
 
 /* Lock used for SP_MEMORY_ATTRIBUTES_GET and SP_MEMORY_ATTRIBUTES_SET */
 static spinlock_t mem_attr_smc_lock;
 
-/* Get handle of Secure Partition translation context */
-xlat_ctx_t *spm_get_sp_xlat_context(void)
-{
-	return &sp_xlat_ctx;
-};
-
 /*
  * Attributes are encoded using a different format in the SMC interface than in
  * the Trusted Firmware, where the mmap_attr_t enum type is used. This function
diff --git a/tools/cert_create/include/key.h b/tools/cert_create/include/key.h
index 312575b..56f1c21 100644
--- a/tools/cert_create/include/key.h
+++ b/tools/cert_create/include/key.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -44,7 +44,7 @@
 static const unsigned int KEY_SIZES[KEY_ALG_MAX_NUM][KEY_SIZE_MAX_NUM] = {
 	{ 2048, 1024, 3072, 4096 },	/* KEY_ALG_RSA */
 #ifndef OPENSSL_NO_EC
-	{},				/* KEY_ALG_ECDSA_NIST */
+	{ 256, 384 },			/* KEY_ALG_ECDSA_NIST */
 	{},				/* KEY_ALG_ECDSA_BRAINPOOL_R */
 	{}				/* KEY_ALG_ECDSA_BRAINPOOL_T */
 #endif /* OPENSSL_NO_EC */
diff --git a/tools/cert_create/src/key.c b/tools/cert_create/src/key.c
index 32229d1..14c8e18 100644
--- a/tools/cert_create/src/key.c
+++ b/tools/cert_create/src/key.c
@@ -1,9 +1,10 @@
 /*
- * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <assert.h>
 #include <getopt.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -112,7 +113,12 @@
 
 static int key_create_ecdsa_nist(key_t *key, int key_bits)
 {
-	return key_create_ecdsa(key, key_bits, "prime256v1");
+	if (key_bits == 384) {
+		return key_create_ecdsa(key, key_bits, "secp384r1");
+	} else {
+		assert(key_bits == 256);
+		return key_create_ecdsa(key, key_bits, "prime256v1");
+	}
 }
 
 static int key_create_ecdsa_brainpool_r(key_t *key, int key_bits)
@@ -154,7 +160,12 @@
 
 static int key_create_ecdsa_nist(key_t *key, int key_bits)
 {
-	return key_create_ecdsa(key, key_bits, NID_X9_62_prime256v1);
+	if (key_bits == 384) {
+		return key_create_ecdsa(key, key_bits, NID_secp384r1);
+	} else {
+		assert(key_bits == 256);
+		return key_create_ecdsa(key, key_bits, NID_X9_62_prime256v1);
+	}
 }
 
 static int key_create_ecdsa_brainpool_r(key_t *key, int key_bits)