diff options
author | J-Alves <joao.alves@arm.com> | 2020-11-18 10:48:12 +0000 |
---|---|---|
committer | J-Alves <joao.alves@arm.com> | 2021-01-20 14:44:50 +0000 |
commit | d8edeed7e7b64fb92390df52ec96b655e0ed0a38 (patch) | |
tree | 91a30b0ae6f9dd73d6059bb3ebf5c3d4c50f6e4c | |
parent | 542d8d8cfd7ca5019d5b019afb03a67d15cd5cda (diff) | |
download | tf-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.c | 6 | ||||
-rw-r--r-- | spm/cactus/cactus_main.c | 88 |
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); |