feat(cactus): memory sharing flags in test commands

Extend the test command CACTUS_MEM_SEND_CMD:
- To include the flags for the retriever to use in transaction
descriptor to the FFA_MEM_RETRIEVE_REQ.
- Number of words cactus should write to the shared page after
retrieving it.
- Check if memory has been cleared after mapping to cactus address space
if clear memory flag was propagated in the command arguments.

Signed-off-by: J-Alves <joao.alves@arm.com>
Change-Id: I825b0f766bd7132a3488cdd17d83fce85adf4a5a
diff --git a/include/runtime_services/cactus_test_cmds.h b/include/runtime_services/cactus_test_cmds.h
index 3bb27ed..130cfa5 100644
--- a/include/runtime_services/cactus_test_cmds.h
+++ b/include/runtime_services/cactus_test_cmds.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -196,10 +196,11 @@
 
 static inline smc_ret_values cactus_mem_send_cmd(
 	ffa_id_t source, ffa_id_t dest, uint32_t mem_func,
-	ffa_memory_handle_t handle)
+	ffa_memory_handle_t handle, ffa_memory_region_flags_t retrieve_flags,
+	uint32_t word_to_write)
 {
 	return cactus_send_cmd(source, dest, CACTUS_MEM_SEND_CMD, mem_func,
-			       handle, 0, 0);
+			       handle, retrieve_flags, word_to_write);
 }
 
 static inline ffa_memory_handle_t cactus_mem_send_get_handle(smc_ret_values ret)
@@ -207,6 +208,17 @@
 	return (ffa_memory_handle_t)ret.ret5;
 }
 
+static inline ffa_memory_region_flags_t cactus_mem_send_get_retrv_flags(
+	smc_ret_values ret)
+{
+	return (ffa_memory_region_flags_t)ret.ret6;
+}
+
+static inline uint32_t cactus_mem_send_words_to_write(smc_ret_values ret)
+{
+	return (uint32_t)ret.ret7;
+}
+
 /**
  * Command to request a memory management operation. The 'mem_func' argument
  * identifies the operation that is to be performend, and 'receiver' is the id
diff --git a/include/runtime_services/spm_common.h b/include/runtime_services/spm_common.h
index 4ec71fc..398d01a 100644
--- a/include/runtime_services/spm_common.h
+++ b/include/runtime_services/spm_common.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -129,7 +129,7 @@
 bool memory_retrieve(struct mailbox_buffers *mb,
 		     struct ffa_memory_region **retrieved, uint64_t handle,
 		     ffa_id_t sender, ffa_id_t receiver,
-		     uint32_t mem_func);
+		     uint32_t mem_func, ffa_memory_region_flags_t flags);
 
 /**
  * Helper to conduct a memory relinquish. The caller is usually the receiver,
diff --git a/spm/cactus/cactus_tests/cactus_test_memory_sharing.c b/spm/cactus/cactus_tests/cactus_test_memory_sharing.c
index ebca665..69d62dd 100644
--- a/spm/cactus/cactus_tests/cactus_test_memory_sharing.c
+++ b/spm/cactus/cactus_tests/cactus_test_memory_sharing.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -47,8 +47,12 @@
 	ffa_id_t vm_id = ffa_dir_msg_dest(*args);
 	uint32_t mem_func = cactus_req_mem_send_get_mem_func(*args);
 	uint64_t handle = cactus_mem_send_get_handle(*args);
+	ffa_memory_region_flags_t retrv_flags =
+					 cactus_mem_send_get_retrv_flags(*args);
+	uint32_t words_to_write = cactus_mem_send_words_to_write(*args);
 
-	expect(memory_retrieve(mb, &m, handle, source, vm_id, mem_func), true);
+	expect(memory_retrieve(mb, &m, handle, source, vm_id, mem_func,
+			       retrv_flags), true);
 
 	composite = ffa_memory_region_get_composite(m, 0);
 
@@ -85,10 +89,26 @@
 
 	ptr = (uint32_t *) composite->constituents[0].address;
 
+	/* Check that memory has been cleared by the SPMC before using it. */
+	if ((retrv_flags & FFA_MEMORY_REGION_FLAG_CLEAR) != 0U) {
+		VERBOSE("Check if memory has been cleared!\n");
+		for (uint32_t i = 0; i < words_to_write; i++) {
+			if (ptr[i] != 0) {
+				/*
+				 * If it hasn't been cleared, shouldn't be used.
+				 */
+				ERROR("Memory should have been cleared!\n");
+				return cactus_error_resp(
+					vm_id, source, CACTUS_ERROR_TEST);
+			}
+		}
+	}
+
 	/* Write mem_func to retrieved memory region for validation purposes. */
 	VERBOSE("Writing: %x\n", mem_func);
-	for (unsigned int i = 0U; i < 5U; i++)
+	for (unsigned int i = 0U; i < words_to_write; i++) {
 		ptr[i] = mem_func;
+	}
 
 	/*
 	 * A FFA_MEM_DONATE changes the ownership of the page, as such no
@@ -173,7 +193,7 @@
 					 ffa_error_code(ffa_ret));
 	}
 
-	ffa_ret = cactus_mem_send_cmd(vm_id, receiver, mem_func, handle);
+	ffa_ret = cactus_mem_send_cmd(vm_id, receiver, mem_func, handle, 0, 10);
 
 	if (!is_ffa_direct_response(ffa_ret)) {
 		return cactus_error_resp(vm_id, source, CACTUS_ERROR_FFA_CALL);
diff --git a/tftf/tests/runtime_services/secure_service/spm_common.c b/tftf/tests/runtime_services/secure_service/spm_common.c
index 16f3c12..aa1d2ed 100644
--- a/tftf/tests/runtime_services/secure_service/spm_common.c
+++ b/tftf/tests/runtime_services/secure_service/spm_common.c
@@ -351,7 +351,7 @@
 bool memory_retrieve(struct mailbox_buffers *mb,
 		     struct ffa_memory_region **retrieved, uint64_t handle,
 		     ffa_id_t sender, ffa_id_t receiver,
-		     uint32_t mem_func)
+		     uint32_t mem_func, ffa_memory_region_flags_t flags)
 {
 	smc_ret_values ret;
 	uint32_t fragment_size;
@@ -364,7 +364,7 @@
 	}
 
 	descriptor_size = ffa_memory_retrieve_request_init(
-	    mb->send, handle, sender, receiver, 0, 0,
+	    mb->send, handle, sender, receiver, 0, flags,
 	    FFA_DATA_ACCESS_RW,
 	    FFA_INSTRUCTION_ACCESS_NX,
 	    FFA_MEMORY_NORMAL_MEM,
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_memory_sharing.c b/tftf/tests/runtime_services/secure_service/test_ffa_memory_sharing.c
index e28c652..b96c438 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_memory_sharing.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_memory_sharing.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -50,6 +50,9 @@
 	uint32_t *ptr;
 	struct mailbox_buffers mb;
 
+	/* Arbitrarily write 5 words after using memory. */
+	const uint32_t nr_words_to_write = 5;
+
 	/***********************************************************************
 	 * Check if SPMC has ffa_version and expected FFA endpoints are deployed.
 	 **********************************************************************/
@@ -78,7 +81,8 @@
 
 	ptr = (uint32_t *)constituents[0].address;
 
-	ret = cactus_mem_send_cmd(SENDER, RECEIVER, mem_func, handle);
+	ret = cactus_mem_send_cmd(SENDER, RECEIVER, mem_func, handle, 0,
+				  nr_words_to_write);
 
 	if (!is_ffa_direct_response(ret)) {
 		return TEST_RESULT_FAIL;