Merge changes from topic "ja/spm_rme" into integration

* changes:
  docs: change FVP argument in RME configuration
  feat(fvp): added calls to unprotect/protect memory
diff --git a/docs/components/realm-management-extension.rst b/docs/components/realm-management-extension.rst
index f228e6b..39186b4 100644
--- a/docs/components/realm-management-extension.rst
+++ b/docs/components/realm-management-extension.rst
@@ -237,7 +237,7 @@
  -C bp.ve_sysregs.exit_on_shutdown=1                            \
  -C cache_state_modelled=1                                      \
  -C bp.dram_size=4                                              \
- -C bp.secure_memory=1                                          \
+ -C bp.secure_memory=0                                          \
  -C pci.pci_smmuv3.mmu.SMMU_ROOT_IDR0=3                         \
  -C pci.pci_smmuv3.mmu.SMMU_ROOT_IIDR=0x43B                     \
  -C pci.pci_smmuv3.mmu.root_register_page_offset=0x20000        \
diff --git a/include/lib/smccc.h b/include/lib/smccc.h
index 8fd6093..c493105 100644
--- a/include/lib/smccc.h
+++ b/include/lib/smccc.h
@@ -111,6 +111,8 @@
 #define SMC_OK				ULL(0)
 #define SMC_UNK				-1
 #define SMC_PREEMPTED			-2	/* Not defined by the SMCCC */
+#define SMC_DENIED			-3	/* Not defined by the SMCCC */
+#define SMC_INVALID_PARAM		-4	/* Not defined by the SMCCC */
 
 /* Return codes for Arm Architecture Service SMC calls */
 #define SMC_ARCH_CALL_SUCCESS		0
diff --git a/include/plat/arm/common/arm_sip_svc.h b/include/plat/arm/common/arm_sip_svc.h
index 266092e..a6fd42b 100644
--- a/include/plat/arm/common/arm_sip_svc.h
+++ b/include/plat/arm/common/arm_sip_svc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019,2021-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019,2021-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -42,6 +42,16 @@
 #define ARM_SIP_SET_INTERRUPT_PENDING	U(0x82000100)
 #endif
 
+/**
+ * Arm SiP Service Call for the SPM to leverage RME to protect a give memory range.
+ * Protected memory range is one whose PAS was made secure.
+ * Unprotect relates to reverting a protect operation.
+ */
+#if SPMD_SPM_AT_SEL2 && ENABLE_RME
+#define PLAT_PROTECT_MEM_SMC64 0xC2000101
+#define PLAT_UNPROTECT_MEM_SMC64 0xC2000102
+#endif
+
 /* SiP handler specific to each Arm platform. */
 uintptr_t plat_arm_sip_handler(uint32_t smc_fid,
 				u_register_t x1,
diff --git a/plat/arm/common/plat_arm_sip_svc.c b/plat/arm/common/plat_arm_sip_svc.c
index b1dab16..d496d2e 100644
--- a/plat/arm/common/plat_arm_sip_svc.c
+++ b/plat/arm/common/plat_arm_sip_svc.c
@@ -1,10 +1,11 @@
 /*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <stdint.h>
+#include <errno.h>
 
 #include <common/debug.h>
 #include <common/runtime_svc.h>
@@ -12,10 +13,73 @@
 #include <plat/arm/common/arm_sip_svc.h>
 #include <plat/common/platform.h>
 
+#if ENABLE_RME && SPMD_SPM_AT_SEL2
+#include <lib/gpt_rme/gpt_rme.h>
+#endif
+
 #if ENABLE_SPMD_LP
 #include <services/el3_spmd_logical_sp.h>
 #endif
 
+#if (ENABLE_RME == 1) && (defined(SPD_spmd) && SPMD_SPM_AT_SEL2 == 1)
+static uint64_t plat_protect_memory(bool protect,
+				    bool secure_origin,
+				    const uint64_t base,
+				    const size_t size,
+				    void *handle)
+{
+	uint64_t ret = SMC_INVALID_PARAM;
+	uint64_t last_updated = 0;
+
+	if (!secure_origin) {
+		SMC_RET1(handle, SMC_UNK);
+		/* Shall not be reached. */
+	}
+
+	if ((base % PAGE_SIZE_4KB) != 0U &&
+	    (size % PAGE_SIZE_4KB) != 0U) {
+		VERBOSE("Base address must be aligned to 4k.\n");
+		SMC_RET1(handle, SMC_INVALID_PARAM);
+		/* Shall not be reached. */
+	}
+
+	if ((ULONG_MAX - base) < size) {
+		VERBOSE("Base + Size results in overflow.\n");
+		SMC_RET1(handle, SMC_INVALID_PARAM);
+		/* Shall not be reached. */
+	}
+
+	for (uint64_t it = base; it < (base + size); it += PAGE_SIZE_4KB) {
+		/*
+		 * If protect is true, add memory to secure PAS.
+		 * Else unprotect it, making part of non-secure PAS.
+		 */
+		ret = protect
+			? gpt_delegate_pas(it, PAGE_SIZE_4KB,
+					   SMC_FROM_SECURE)
+			: gpt_undelegate_pas(it, PAGE_SIZE_4KB,
+					     SMC_FROM_SECURE);
+
+		switch (ret) {
+		case 0:
+			last_updated = it;
+			break;
+		case -EINVAL:
+			SMC_RET2(handle, SMC_INVALID_PARAM, last_updated);
+			break; /* Shall not be reached. */
+		case -EPERM:
+			SMC_RET2(handle, SMC_DENIED, last_updated);
+			break; /* Shall not be reached. */
+		default:
+			ERROR("Unexpected return\n");
+			panic();
+		}
+	}
+
+	SMC_RET1(handle, SMC_OK);
+}
+#endif /* ENABLE_RME  && SPMD_SPM_AT_SEL2 */
+
 uintptr_t plat_arm_sip_handler(uint32_t smc_fid,
 				u_register_t x1,
 				u_register_t x2,
@@ -25,13 +89,14 @@
 				void *handle,
 				u_register_t flags)
 {
-#if PLAT_TEST_SPM
 	bool secure_origin;
 
 	/* Determine which security state this SMC originated from */
 	secure_origin = is_caller_secure(flags);
+	(void) secure_origin;
 
 	switch (smc_fid) {
+#if PLAT_TEST_SPM
 	case ARM_SIP_SET_INTERRUPT_PENDING:
 		if (!secure_origin) {
 			SMC_RET1(handle, SMC_UNK);
@@ -42,10 +107,19 @@
 
 		SMC_RET1(handle, SMC_OK);
 		break; /* Not reached */
-	default:
+#endif
+
+#if (ENABLE_RME == 1) && (defined(SPD_spmd) && SPMD_SPM_AT_SEL2 == 1)
+	case PLAT_PROTECT_MEM_SMC64:
+		INFO("Sip Call - Protect memory\n");
+		return plat_protect_memory(true, secure_origin, x1, x2, handle);
 		break;
-	}
+	case PLAT_UNPROTECT_MEM_SMC64:
+		INFO("Sip Call - Unprotect memory\n");
+		return plat_protect_memory(false, secure_origin, x1, x2, handle);
+		break;
 #endif
+	}
 
 #if ENABLE_SPMD_LP
 	return plat_spmd_logical_sp_smc_handler(smc_fid, x1, x2, x3, x4,
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index 5d19868..e200b80 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -844,7 +844,7 @@
 	unsigned int linear_id = plat_my_core_pos();
 	spmd_spm_core_context_t *ctx = spmd_get_context();
 	bool secure_origin;
-	int32_t ret;
+	int ret;
 	uint32_t input_version;
 
 	/* Determine which security state this SMC originated from */