Merge "feat(juno): support StandaloneMm" into integration
diff --git a/plat/arm/board/juno/fdts/juno_fw_config.dts b/plat/arm/board/juno/fdts/juno_fw_config.dts
index 11e9574..3cd5ccf 100644
--- a/plat/arm/board/juno/fdts/juno_fw_config.dts
+++ b/plat/arm/board/juno/fdts/juno_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,10 +19,19 @@
 			id = <TB_FW_CONFIG_ID>;
 		};
 
+
 		hw-config {
 			load-address = <0x0 0x82000000>;
 			max-size = <PLAT_ARM_HW_CONFIG_SIZE>;
 			id = <HW_CONFIG_ID>;
 		};
+
+#if SPMC_AT_EL3
+		tos_fw-config {
+			load-address = <0x0 0x04001D00>;
+			max-size = <0x1000>;
+			id = <TOS_FW_CONFIG_ID>;
+		};
+#endif
 	};
 };
diff --git a/plat/arm/board/juno/fdts/juno_stmm_manifest.dts b/plat/arm/board/juno/fdts/juno_stmm_manifest.dts
new file mode 100644
index 0000000..96d44f9
--- /dev/null
+++ b/plat/arm/board/juno/fdts/juno_stmm_manifest.dts
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+#include <platform_def.h>
+
+/ {
+#define MODE_SEL0	(0x1)
+#define MODE_SEL1	(0x2)
+
+#define SECURE_RO 0x1
+#define SECURE_RW 0x3
+#define SECURE_EXECUTE_RO 0x5
+#define SECURE_EXECUTE_RW 0x7
+#define NON_SECURE_RO 0x9
+#define NON_SECURE_RW 0xB
+#define NON_SECURE_EXECUTE_RO 0xD
+#define NON_SECURE_EXECUTE_RW 0xF
+	/*
+	 * FF-A compatible Secure Partition Manager parses the
+	 * config file and fetch the following booting arguments to
+	 * pass on to the StandAloneMM(StMM) Secure Partition.
+	 */
+	compatible = "arm,ffa-manifest-1.0";
+
+	description = "Juno StandaloneMm";
+	ffa-version = <0x00010002>; /* 31:16 - Major, 15:0 - Minor */
+	uuid = <0xdcae8d37 0x46446bf0 0xab401483 0xa3873c93>;
+	id = <0x8001>;
+	execution-ctx-count = <PLATFORM_CORE_COUNT>;
+	exception-level = <MODE_SEL0>; /* SEL0*/
+	execution-state = <0>; /* AArch64*/
+	load-address = <0x0 0xff200000>;
+	image-size = <0x0 0x00300000>;
+	xlat-granule = <0>; /* 4KiB */
+	boot_info_reg = <0>; /* x0 */
+	boot-order = <0>;
+	messaging-method = <0x603>; /* Direct req/resp/req2/resp2 supported. */
+	power-management-messages = <0>;
+	gp-register-num = <0>;
+
+	device-regions {
+		compatible = "arm,ffa-manifest-device-regions";
+
+		/**
+		 * System registers, rtc, uart and etc regions for access from S-EL0.
+		 */
+		io_fpga {
+			base-address = <0x0 0x1C000000>;
+			pages-count = <0x3000>;
+			attributes = <SECURE_RW>;
+		};
+
+		system_reg_el0 {
+			base-address = <0x0 0x1C010000>;
+			pages-count = <0x10>;
+			attributes = <SECURE_RW>;
+		};
+
+		soc_peripherals {
+			base-address = <0x0 0x7FF50000>;
+			pages-count = <0x90>;
+			attributes = <SECURE_RW>;
+		};
+
+		nor_flash0 {
+			base-address = <0x0 0x08000000>;
+			pages-count = <0x4000>;
+			attributes = <SECURE_RW>;
+		};
+	};
+
+	memory-regions {
+		compatible = "arm,ffa-manifest-memory-regions";
+
+		/*
+		 * SPM Payload memory. Mapped as code region for S-EL0
+		 * Similar to ARM_SP_IMAGE_MMAP.
+		 */
+		stmm_region {
+			description = "image";
+			base-address = <0x0 0xff200000>;
+			pages-count = <0x300>;
+			/* StMM will remap the regions during runtime */
+			attributes = <SECURE_EXECUTE_RO>;
+		};
+
+		/*
+		 * Memory shared between EL3 and S-EL0.
+		 * Similar to ARM_SPM_BUF_EL0_MMAP.
+		 */
+		rx-tx-buffers {
+			description = "shared-buff";
+			base-address = <0x0 0xff500000>;
+			pages-count = <0x100>;
+			attributes = <SECURE_RW>;
+		};
+
+		/*
+		 * Memory shared between Normal world and S-EL0.
+		 * Similar to ARM_SP_IMAGE_NS_BUF_MMAP.
+		 */
+		ns_comm_buffer {
+			/*
+			 * Description is needed for StMM to identify
+			 * ns-communication buffer.
+			 */
+			description = "ns-comm";
+			base-address = <0x0 0xff600000>;
+			pages-count = <0x10>;
+			attributes = <NON_SECURE_RW>;
+		};
+
+		/*
+		 * Heap used by SP to allocate memory for DMA.
+		 */
+		heap {
+			/*
+			 * Description is needed for StMM to identify
+			 * heap buffer.
+			 */
+			description = "heap";
+			base-address = <0x0 0xFF610000>;
+			pages-count = <0x7F0>;
+			attributes = <SECURE_RW>;
+		};
+	};
+};
diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h
index c8439e9..73ee346 100644
--- a/plat/arm/board/juno/include/platform_def.h
+++ b/plat/arm/board/juno/include/platform_def.h
@@ -14,6 +14,7 @@
 #include <plat/arm/board/common/board_css_def.h>
 #include <plat/arm/board/common/v2m_def.h>
 #include <plat/arm/common/arm_def.h>
+#include <plat/arm/common/arm_spm_def.h>
 #include <plat/arm/css/common/css_def.h>
 #include <plat/arm/soc/common/soc_css_def.h>
 #include <plat/common/common_def.h>
@@ -131,8 +132,15 @@
 #endif
 
 #ifdef IMAGE_BL31
-# define PLAT_ARM_MMAP_ENTRIES		8
-# define MAX_XLAT_TABLES		6
+# if SPMC_AT_EL3
+#   define PLAT_ARM_MMAP_ENTRIES		10
+#   define MAX_XLAT_TABLES		8
+#   define PLAT_SP_IMAGE_MMAP_REGIONS 30
+#   define PLAT_SP_IMAGE_MAX_XLAT_TABLES 12
+# else
+#   define PLAT_ARM_MMAP_ENTRIES		8
+#   define MAX_XLAT_TABLES		6
+# endif
 #endif
 
 #ifdef IMAGE_BL32
@@ -140,6 +148,30 @@
 # define MAX_XLAT_TABLES		4
 #endif
 
+#if SPMC_AT_EL3
+/*
+ * 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 Normal World Partitions supported.
+ * SPMC at EL3, uses this count to configure the maximum number of supported
+ * NWd 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 /* SPMC_AT_EL3 */
+
 /*
  * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size
  * plus a little space for growth.
@@ -211,6 +243,9 @@
 # define PLATFORM_STACK_SIZE		UL(0x440)
 #endif
 
+#define PLAT_ARM_SP_IMAGE_STACK_BASE	(PLAT_SP_IMAGE_NS_BUF_BASE +	\
+					 PLAT_SP_IMAGE_NS_BUF_SIZE)
+
 /* CCI related constants */
 #define PLAT_ARM_CCI_BASE		UL(0x2c090000)
 #define PLAT_ARM_CCI_CLUSTER0_SL_IFACE_IX	4
diff --git a/plat/arm/board/juno/juno_bl31_setup.c b/plat/arm/board/juno/juno_bl31_setup.c
index 2eec105..ae69b43 100644
--- a/plat/arm/board/juno/juno_bl31_setup.c
+++ b/plat/arm/board/juno/juno_bl31_setup.c
@@ -11,6 +11,7 @@
 #include <lib/fconf/fconf_dyn_cfg_getter.h>
 
 #include <plat/arm/common/plat_arm.h>
+#include <platform_def.h>
 
 void __init bl31_early_platform_setup2(u_register_t arg0,
 		u_register_t arg1, u_register_t arg2, u_register_t arg3)
diff --git a/plat/arm/board/juno/juno_common.c b/plat/arm/board/juno/juno_common.c
index 2cd01e4..e3a6b42 100644
--- a/plat/arm/board/juno/juno_common.c
+++ b/plat/arm/board/juno/juno_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -58,6 +58,9 @@
 #ifdef JUNO_ETHOSN_TZMP1
 	JUNO_ETHOSN_PROT_FW_RW,
 #endif
+#if SPMC_AT_EL3
+	ARM_SP_IMAGE_MMAP,
+#endif
 	{0}
 };
 #endif
diff --git a/plat/arm/board/juno/juno_el3_spmc.c b/plat/arm/board/juno/juno_el3_spmc.c
new file mode 100644
index 0000000..7d1e44f
--- /dev/null
+++ b/plat/arm/board/juno/juno_el3_spmc.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2022-2025, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/xlat_tables/xlat_tables_defs.h>
+#include <services/el3_spmc_ffa_memory.h>
+
+#include <platform_def.h>
+
+__section(".arm_el3_tzc_dram") __unused static uint8_t plat_spmc_shmem_datastore[PAGE_SIZE];
+
+int plat_spmc_shmem_datastore_get(uint8_t **datastore, size_t *size)
+{
+	*datastore = (uint8_t *)plat_spmc_shmem_datastore;
+	*size = PAGE_SIZE;
+	return 0;
+}
+
+/*
+ * Add dummy implementations of memory management related platform hooks.
+ * These can be used to implement platform specific functionality to support
+ * a memory sharing/lending operation.
+ *
+ * Note: The hooks must be located as part of the initial share request and
+ * final reclaim to prevent order dependencies with operations that may take
+ * place in the normal world without visibility of the SPMC.
+ */
+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 Juno.
+	 */
+	(void)intid;
+	return -1;
+}
+
diff --git a/plat/arm/board/juno/juno_security.c b/plat/arm/board/juno/juno_security.c
index 72e7e78..23000da 100644
--- a/plat/arm/board/juno/juno_security.c
+++ b/plat/arm/board/juno/juno_security.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2025, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -88,6 +88,20 @@
 
 #endif /* JUNO_ETHOSN_TZMP1 */
 
+#if SPMC_AT_EL3
+
+// Use last 2MB as secure storage only.
+#define V2M_FLASH0_SECURE_START	(V2M_FLASH0_BASE + V2M_FLASH0_SIZE - 0x200000)
+#define V2M_FLASH0_SECURE_END	(V2M_FLASH0_BASE + V2M_FLASH0_SIZE - 1)
+
+static const arm_tzc_regions_info_t juno_stmm_tzc_regions[] = {
+	ARM_TZC_REGIONS_DEF,
+	{ V2M_FLASH0_SECURE_START, V2M_FLASH0_SECURE_END, TZC_REGION_S_RDWR, 0 },
+	{},
+};
+
+#endif /* SPMC_AT_EL3 */
+
 /*******************************************************************************
  * Set up the MMU-401 SSD tables. The power-on configuration has all stream IDs
  * assigned to Non-Secure except some for the DMA-330. Assign those back to the
@@ -161,6 +175,11 @@
 	INFO("TZC protected FW memory range for NPU TZMP usecase: %p - %p\n",
 	     (void *)JUNO_ETHOSN_FW_TZC_PROT_DRAM2_BASE,
 	     (void *)JUNO_ETHOSN_FW_TZC_PROT_DRAM2_END);
+#elif SPMC_AT_EL3
+	INFO("TZC protected some of Nor flash memory range for StandaloneMm: %p - %p\n",
+	     (void *)V2M_FLASH0_SECURE_START,
+	     (void *)V2M_FLASH0_SECURE_END);
+	arm_tzc400_setup(PLAT_ARM_TZC_BASE, juno_stmm_tzc_regions);
 #else
 	arm_tzc400_setup(PLAT_ARM_TZC_BASE, NULL);
 #endif
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index 38ba0ed..a5de78f 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -29,6 +29,14 @@
 PLAT_BL_COMMON_SOURCES	:=	plat/arm/board/juno/${ARCH}/juno_helpers.S \
 				plat/arm/board/juno/juno_common.c
 
+ifeq (${SPMC_AT_EL3}, 1)
+PLAT_BL_COMMON_SOURCES	+=	plat/arm/board/juno/juno_el3_spmc.c
+endif
+
+ifeq (${HOB_LIST}, 1)
+include lib/hob/hob.mk
+endif
+
 # Flag to enable support for AArch32 state on JUNO
 JUNO_AARCH32_EL3_RUNTIME	:=	0
 $(eval $(call assert_boolean,JUNO_AARCH32_EL3_RUNTIME))
@@ -205,6 +213,13 @@
 # Add the HW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${HW_CONFIG},--hw-config,${HW_CONFIG}))
 
+
+ifeq (${SPD},spmd)
+ifneq ($(ARM_SPMC_MANIFEST_DTS),)
+FDT_SOURCES +=	${ARM_SPMC_MANIFEST_DTS}
+endif
+endif
+
 include drivers/arm/ethosn/ethosn_npu.mk
 include plat/arm/board/common/board_common.mk
 include plat/arm/common/arm_common.mk