aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJ-Alves <joao.alves@arm.com>2020-11-18 10:48:12 +0000
committerJ-Alves <joao.alves@arm.com>2021-01-20 14:44:50 +0000
commitd8edeed7e7b64fb92390df52ec96b655e0ed0a38 (patch)
tree91a30b0ae6f9dd73d6059bb3ebf5c3d4c50f6e4c
parent542d8d8cfd7ca5019d5b019afb03a67d15cd5cda (diff)
downloadtf-a-tests-d8edeed7e7b64fb92390df52ec96b655e0ed0a38.tar.gz
cactus: test SP-to-SP memory share operations
Handle 'CACTUS_REQ_MEM_SEND_CMD' by sending memory to the receiver SP. Signed-off-by: J-Alves <joao.alves@arm.com> Change-Id: I4ca1ff91c52640f3a7204cc63041a091c210d8b7
-rw-r--r--spm/cactus/cactus_ffa_tests.c6
-rw-r--r--spm/cactus/cactus_main.c88
2 files changed, 92 insertions, 2 deletions
diff --git a/spm/cactus/cactus_ffa_tests.c b/spm/cactus/cactus_ffa_tests.c
index 07aaacab8..5863456af 100644
--- a/spm/cactus/cactus_ffa_tests.c
+++ b/spm/cactus/cactus_ffa_tests.c
@@ -307,7 +307,11 @@ void ffa_memory_management_test(struct mailbox_buffers *mb, ffa_vm_id_t vm_id,
m->receivers[0].receiver_permissions.permissions),
FFA_DATA_ACCESS_RW);
- mem_attrs = MT_RW_DATA | MT_NS | MT_EXECUTE_NEVER;
+ mem_attrs = MT_RW_DATA | MT_EXECUTE_NEVER;
+
+ if (!IS_SP_ID(sender)) {
+ mem_attrs |= MT_NS;
+ }
ret = mmap_add_dynamic_region(
(uint64_t)composite->constituents[0].address,
diff --git a/spm/cactus/cactus_main.c b/spm/cactus/cactus_main.c
index da7e9139f..3883fac82 100644
--- a/spm/cactus/cactus_main.c
+++ b/spm/cactus/cactus_main.c
@@ -30,6 +30,9 @@
extern const char build_message[];
extern const char version_string[];
+/* Memory section to be used for memory share operations */
+static __aligned(PAGE_SIZE) uint8_t share_page[PAGE_SIZE];
+
/*
*
* Message loop function
@@ -46,7 +49,6 @@ static void __dead2 message_loop(ffa_vm_id_t vm_id, struct mailbox_buffers *mb)
ffa_vm_id_t destination;
uint64_t cactus_cmd;
-
/*
* This initial wait call is necessary to inform SPMD that
* SP initialization has completed. It blocks until receiving
@@ -99,7 +101,91 @@ static void __dead2 message_loop(ffa_vm_id_t vm_id, struct mailbox_buffers *mb)
*/
ffa_ret = CACTUS_SUCCESS_RESP(vm_id, source);
break;
+ case CACTUS_REQ_MEM_SEND_CMD:
+ {
+ uint32_t mem_func =
+ CACTUS_REQ_MEM_SEND_GET_MEM_FUNC(ffa_ret);
+ ffa_vm_id_t receiver =
+ CACTUS_REQ_MEM_SEND_GET_RECEIVER(ffa_ret);
+ ffa_memory_handle_t handle;
+
+ VERBOSE("%x requested to send memory to %x (func: %x)\n",
+ source, receiver, mem_func);
+
+ const struct ffa_memory_region_constituent
+ constituents[] = {
+ {(void *)share_page, 1, 0}
+ };
+
+ const uint32_t constituents_count = (
+ sizeof(constituents) /
+ sizeof(constituents[0])
+ );
+
+ handle = ffa_memory_init_and_send(
+ (struct ffa_memory_region *)mb->send, PAGE_SIZE,
+ vm_id, receiver, constituents,
+ constituents_count, mem_func);
+
+ /*
+ * If returned an invalid handle, we should break the
+ * test.
+ */
+ expect(handle != FFA_MEMORY_HANDLE_INVALID, true);
+ ffa_ret = CACTUS_MEM_SEND_CMD(vm_id, receiver, mem_func,
+ handle);
+
+ if (ffa_ret.ret0 != FFA_MSG_SEND_DIRECT_RESP_SMC32) {
+ ERROR("Failed to send message. error: %lx\n",
+ ffa_ret.ret2);
+ ffa_ret = CACTUS_ERROR_RESP(vm_id, source);
+ break;
+ }
+
+ /* If anything went bad on the receiver's end. */
+ if (CACTUS_IS_ERROR_RESP(ffa_ret)) {
+ ERROR("Received error from receiver!\n");
+ ffa_ret = CACTUS_ERROR_RESP(vm_id, source);
+ break;
+ }
+
+ if (mem_func != FFA_MEM_DONATE_SMC32) {
+ /*
+ * Do a memory reclaim only if the mem_func
+ * regards to memory share or lend operations,
+ * as with a donate the owner is permanently
+ * given up access to the memory region.
+ */
+ if (ffa_mem_reclaim(handle, 0)
+ .ret0 == FFA_ERROR) {
+ ERROR("Failed to reclaim memory!\n");
+ ffa_ret = CACTUS_ERROR_RESP(vm_id,
+ source);
+ break;
+ }
+
+ /**
+ * Read Content that has been written to memory
+ * to validate access to memory segment has been
+ * reestablished, and receiver made use of
+ * memory region.
+ */
+ #if (LOG_LEVEL >= LOG_LEVEL_VERBOSE)
+ uint32_t *ptr =
+ (uint32_t *)constituents
+ ->address;
+ VERBOSE("Memory contents after receiver"
+ " SP's use:\n");
+ for (unsigned int i = 0U; i < 5U; i++)
+ VERBOSE(" %u: %x\n", i,
+ ptr[i]);
+ #endif
+ }
+
+ ffa_ret = CACTUS_SUCCESS_RESP(vm_id, source);
+ }
+ break;
case CACTUS_ECHO_CMD:
{
uint64_t echo_val = CACTUS_ECHO_GET_VAL(ffa_ret);