aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Deprez <olivier.deprez@arm.com>2021-03-12 16:28:28 +0100
committerTrustedFirmware Code Review <review@review.trustedfirmware.org>2021-03-12 16:28:28 +0100
commit80542392bdb5861ccba1d1563b10a0ad7d21b21e (patch)
tree528f9e5be4c325c5c467989780b0f28cc3ac460e
parenteb426de964d74d12d7fe85edb448430753819fda (diff)
parenteeb2547b9a774c90824e867ce7c331b319fc7c0d (diff)
downloadtf-a-tests-80542392bdb5861ccba1d1563b10a0ad7d21b21e.tar.gz
Merge changes from topic "cactus_message_loop"
* changes: Cactus: tidy message loop and commands definitions SPM: Helpers for error logging after FF-A calls FF-A: Tidying direct messaging API definitions SPM: Properly placing Cactus test files SPM: Tidying FF-A Memory Sharing tests TFTF: Use CACTUS_ECHO_CMD in direct message tests Cactus: Refactor handling of commands Cactus: Extend arguments in commands responses FF-A: Check FF-A return is a valid direct response FF-A: FFA_MSG_DIRECT_RESP call using 5 registers
-rw-r--r--include/runtime_services/cactus_message_loop.h44
-rw-r--r--include/runtime_services/cactus_test_cmds.h (renamed from spm/cactus/cactus_test_cmds.h)108
-rw-r--r--include/runtime_services/ffa_helpers.h37
-rw-r--r--include/runtime_services/spm_common.h35
-rw-r--r--spm/cactus/cactus.ld.S6
-rw-r--r--spm/cactus/cactus.mk8
-rw-r--r--spm/cactus/cactus_main.c233
-rw-r--r--spm/cactus/cactus_tests.h13
-rw-r--r--spm/cactus/cactus_tests/cactus_message_loop.c57
-rw-r--r--spm/cactus/cactus_tests/cactus_test_cpu_features.c29
-rw-r--r--spm/cactus/cactus_tests/cactus_test_direct_messaging.c116
-rw-r--r--spm/cactus/cactus_tests/cactus_test_ffa.c (renamed from spm/cactus/cactus_ffa_tests.c)177
-rw-r--r--spm/cactus/cactus_tests/cactus_test_memory_sharing.c179
-rw-r--r--tftf/tests/runtime_services/secure_service/ffa_helpers.c189
-rw-r--r--tftf/tests/runtime_services/secure_service/spm_common.c230
-rw-r--r--tftf/tests/runtime_services/secure_service/test_ffa_direct_messaging.c41
-rw-r--r--tftf/tests/runtime_services/secure_service/test_ffa_memory_sharing.c13
-rw-r--r--tftf/tests/runtime_services/secure_service/test_spm_cpu_features.c4
18 files changed, 867 insertions, 652 deletions
diff --git a/include/runtime_services/cactus_message_loop.h b/include/runtime_services/cactus_message_loop.h
new file mode 100644
index 00000000..d69e77ce
--- /dev/null
+++ b/include/runtime_services/cactus_message_loop.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <ffa_helpers.h>
+#include <spm_common.h>
+
+/**
+ * Pairs a command id with a function call, to handle the command ID.
+ */
+struct cactus_cmd_handler {
+ const uint64_t id;
+ smc_ret_values (*fn)(const smc_ret_values *args,
+ struct mailbox_buffers *mb);
+};
+
+/**
+ * Helper to create the name of a handler function.
+ */
+#define CACTUS_HANDLER_FN_NAME(name) cactus_##name##_handler
+
+/**
+ * Define handler's function signature.
+ */
+#define CACTUS_HANDLER_FN(name) \
+ static smc_ret_values CACTUS_HANDLER_FN_NAME(name)( \
+ const smc_ret_values *args, struct mailbox_buffers *mb)
+
+/**
+ * Helper to define Cactus command handler, and pair it with a command ID.
+ * It also creates a table with this information, to be traversed by
+ * 'cactus_handle_cmd' function.
+ */
+#define CACTUS_CMD_HANDLER(name, ID) \
+ CACTUS_HANDLER_FN(name); \
+ struct cactus_cmd_handler name __section(".cactus_handler") = { \
+ .id = ID, .fn = CACTUS_HANDLER_FN_NAME(name), \
+ }; \
+ CACTUS_HANDLER_FN(name)
+
+bool cactus_handle_cmd(smc_ret_values *cmd_args, smc_ret_values *ret,
+ struct mailbox_buffers *mb);
diff --git a/spm/cactus/cactus_test_cmds.h b/include/runtime_services/cactus_test_cmds.h
index c662d273..246f4f97 100644
--- a/spm/cactus/cactus_test_cmds.h
+++ b/include/runtime_services/cactus_test_cmds.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,14 +7,21 @@
#ifndef CACTUS_TEST_CMDS
#define CACTUS_TEST_CMDS
-#include <debug.h>
#include <ffa_helpers.h>
/**
* Success and error return to be sent over a msg response.
*/
-#define CACTUS_SUCCESS U(0)
-#define CACTUS_ERROR U(-1)
+#define CACTUS_SUCCESS U(0)
+#define CACTUS_ERROR U(-1)
+
+/**
+ * Error codes.
+ */
+#define CACTUS_ERROR_INVALID U(1)
+#define CACTUS_ERROR_TEST U(2)
+#define CACTUS_ERROR_FFA_CALL U(3)
+#define CACTUS_ERROR_UNHANDLED U(4)
/**
* Get command from struct smc_ret_values.
@@ -32,14 +39,66 @@ static inline smc_ret_values cactus_send_cmd(
ffa_vm_id_t source, ffa_vm_id_t dest, uint64_t cmd, uint64_t val0,
uint64_t val1, uint64_t val2, uint64_t val3)
{
- return ffa_msg_send_direct_req64_5args(source, dest, cmd, val0, val1,
- val2, val3);
+ return ffa_msg_send_direct_req64(source, dest, cmd, val0, val1, val2,
+ val3);
+}
+
+/**
+ * Template for responses to Cactus commands.
+ * 'cactus_send_response' is the template for custom responses, in case there is
+ * a need to propagate more than one value in the response of a command.
+ */
+static inline smc_ret_values cactus_send_response(
+ ffa_vm_id_t source, ffa_vm_id_t dest, uint32_t resp, uint32_t val0,
+ uint64_t val1, uint64_t val2, uint64_t val3)
+{
+ return ffa_msg_send_direct_resp64(source, dest, resp, val0, val1,
+ val2, val3);
+}
+
+/**
+ * For responses of one value only.
+ */
+static inline smc_ret_values cactus_response(
+ ffa_vm_id_t source, ffa_vm_id_t dest, uint32_t response)
+{
+ return ffa_msg_send_direct_resp64(source, dest, response, 0, 0, 0, 0);
+}
+
+static inline uint32_t cactus_get_response(smc_ret_values ret)
+{
+ return (uint32_t)ret.ret3;
+}
+
+/**
+ * In a successful test, in case the SP needs to propagate an extra value
+ * to conclude the test.
+ * If more arguments are needed, a custom response should be defined for the
+ * specific test.
+ */
+static inline smc_ret_values cactus_success_resp(
+ ffa_vm_id_t source, ffa_vm_id_t dest, uint64_t value)
+{
+ return cactus_send_response(source, dest, CACTUS_SUCCESS, value,
+ 0, 0, 0);
+}
+
+/**
+ * In case the test fails on the SP side, the 'error_code' should help specify
+ * the reason, which can be specific to the test, or general ones as defined
+ * in the error code list.
+ */
+static inline smc_ret_values cactus_error_resp(
+ ffa_vm_id_t source, ffa_vm_id_t dest, uint32_t error_code)
+{
+ return cactus_send_response(source, dest, CACTUS_ERROR, error_code,
+ 0, 0, 0);
}
-#define PRINT_CMD(smc_ret) \
- VERBOSE("cmd %lx; args: %lx, %lx, %lx, %lx\n", \
- smc_ret.ret3, smc_ret.ret4, smc_ret.ret5, \
- smc_ret.ret6, smc_ret.ret7)
+static inline uint32_t cactus_error_code(smc_ret_values ret)
+{
+ return (uint32_t) ret.ret4;
+}
/**
* With this test command the sender transmits a 64-bit value that it then
@@ -186,33 +245,8 @@ static inline ffa_vm_id_t cactus_req_mem_send_get_receiver(smc_ret_values ret)
static inline smc_ret_values cactus_req_simd_fill_send_cmd(
ffa_vm_id_t source, ffa_vm_id_t dest)
{
- return cactus_send_cmd(source, dest, CACTUS_REQ_SIMD_FILL_CMD, 0, 0, 0, 0);
-}
-
-/**
- * Template for responses to CACTUS commands.
- */
-static inline smc_ret_values cactus_response(
- ffa_vm_id_t source, ffa_vm_id_t dest, uint32_t response)
-{
- return ffa_msg_send_direct_resp(source, dest, response);
-}
-
-static inline smc_ret_values cactus_success_resp(
- ffa_vm_id_t source, ffa_vm_id_t dest)
-{
- return cactus_response(source, dest, CACTUS_SUCCESS);
-}
-
-static inline smc_ret_values cactus_error_resp(
- ffa_vm_id_t source, ffa_vm_id_t dest)
-{
- return cactus_response(source, dest, CACTUS_ERROR);
-}
-
-static inline uint32_t cactus_get_response(smc_ret_values ret)
-{
- return (uint32_t)ret.ret3;
+ return cactus_send_cmd(source, dest, CACTUS_REQ_SIMD_FILL_CMD, 0, 0, 0,
+ 0);
}
#endif
diff --git a/include/runtime_services/ffa_helpers.h b/include/runtime_services/ffa_helpers.h
index 02a956e8..4af051b8 100644
--- a/include/runtime_services/ffa_helpers.h
+++ b/include/runtime_services/ffa_helpers.h
@@ -364,16 +364,6 @@ uint32_t ffa_memory_region_init(
enum ffa_memory_shareability shareability, uint32_t *total_length,
uint32_t *fragment_length);
-ffa_memory_handle_t ffa_memory_send(
- struct ffa_memory_region *memory_region, uint32_t mem_func,
- uint32_t fragment_length, uint32_t total_length);
-
-ffa_memory_handle_t ffa_memory_init_and_send(
- struct ffa_memory_region *memory_region, size_t memory_region_max_size,
- ffa_vm_id_t sender, ffa_vm_id_t receiver,
- const struct ffa_memory_region_constituent* constituents,
- uint32_t constituents_count, uint32_t mem_func);
-
static inline ffa_vm_id_t ffa_dir_msg_dest(smc_ret_values val) {
return (ffa_vm_id_t)val.ret1 & U(0xFFFF);
}
@@ -382,24 +372,35 @@ static inline ffa_vm_id_t ffa_dir_msg_source(smc_ret_values val) {
return (ffa_vm_id_t)(val.ret1 >> 16U);
}
-smc_ret_values ffa_msg_send_direct_req(uint32_t source_id, uint32_t dest_id, uint32_t message);
-smc_ret_values ffa_msg_send_direct_req64_5args(uint32_t source_id, uint32_t dest_id,
- uint64_t arg0, uint64_t arg1,
- uint64_t arg2, uint64_t arg3,
- uint64_t arg4);
+smc_ret_values ffa_msg_send_direct_req64(ffa_vm_id_t source_id,
+ ffa_vm_id_t dest_id, uint64_t arg0,
+ uint64_t arg1, uint64_t arg2,
+ uint64_t arg3, uint64_t arg4);
+
+smc_ret_values ffa_msg_send_direct_req32(ffa_vm_id_t source_id,
+ ffa_vm_id_t dest_id, uint32_t arg0,
+ uint32_t arg1, uint32_t arg2,
+ uint32_t arg3, uint32_t arg4);
+
+smc_ret_values ffa_msg_send_direct_resp64(ffa_vm_id_t source_id,
+ ffa_vm_id_t dest_id, uint64_t arg0,
+ uint64_t arg1, uint64_t arg2,
+ uint64_t arg3, uint64_t arg4);
+
+smc_ret_values ffa_msg_send_direct_resp32(ffa_vm_id_t source_id,
+ ffa_vm_id_t dest_id, uint32_t arg0,
+ uint32_t arg1, uint32_t arg2,
+ uint32_t arg3, uint32_t arg4);
smc_ret_values ffa_run(uint32_t dest_id, uint32_t vcpu_id);
smc_ret_values ffa_version(uint32_t input_version);
smc_ret_values ffa_id_get(void);
smc_ret_values ffa_msg_wait(void);
-smc_ret_values ffa_msg_send_direct_resp(ffa_vm_id_t source_id,
- ffa_vm_id_t dest_id, uint32_t message);
smc_ret_values ffa_error(int32_t error_code);
smc_ret_values ffa_features(uint32_t feature);
smc_ret_values ffa_partition_info_get(const uint32_t uuid[4]);
smc_ret_values ffa_rx_release(void);
smc_ret_values ffa_rxtx_map(uintptr_t send, uintptr_t recv, uint32_t pages);
-
smc_ret_values ffa_mem_donate(uint32_t descriptor_length,
uint32_t fragment_length);
smc_ret_values ffa_mem_lend(uint32_t descriptor_length,
diff --git a/include/runtime_services/spm_common.h b/include/runtime_services/spm_common.h
index b0900023..dbb113ba 100644
--- a/include/runtime_services/spm_common.h
+++ b/include/runtime_services/spm_common.h
@@ -53,11 +53,18 @@ struct mailbox_buffers {
CONFIGURE_MAILBOX(mb_name, buffers_size); \
smc_ret = ffa_rxtx_map( \
(uintptr_t)mb_name.send, \
- (uintptr_t)mb_name.recv, \
+ (uintptr_t)mb_name.recv, \
buffers_size / PAGE_SIZE \
); \
} while (false)
+/**
+ * Helpers to evaluate returns of FF-A calls.
+ */
+bool is_ffa_call_error(smc_ret_values val);
+bool is_ffa_direct_response(smc_ret_values ret);
+bool is_expected_ffa_return(smc_ret_values ret, uint32_t func_id);
+
/*
* Vector length:
* SIMD: 128 bits = 16 bytes
@@ -82,4 +89,30 @@ bool check_spmc_execution_level(void);
unsigned int get_ffa_feature_test_target(const struct ffa_features_test **test_target);
+/**
+ * Helper to conduct a memory retrieve. This is to be called by the receiver
+ * of a memory share operation.
+ */
+bool memory_retrieve(struct mailbox_buffers *mb,
+ struct ffa_memory_region **retrieved, uint64_t handle,
+ ffa_vm_id_t sender, ffa_vm_id_t receiver,
+ uint32_t mem_func);
+
+/**
+ * Helper to conduct a memory relinquish. The caller is usually the receiver,
+ * after it being done with the memory shared, identified by the 'handle'.
+ */
+bool memory_relinquish(struct ffa_mem_relinquish *m, uint64_t handle,
+ ffa_vm_id_t id);
+
+ffa_memory_handle_t memory_send(
+ struct ffa_memory_region *memory_region, uint32_t mem_func,
+ uint32_t fragment_length, uint32_t total_length);
+
+ffa_memory_handle_t memory_init_and_send(
+ struct ffa_memory_region *memory_region, size_t memory_region_max_size,
+ ffa_vm_id_t sender, ffa_vm_id_t receiver,
+ const struct ffa_memory_region_constituent* constituents,
+ uint32_t constituents_count, uint32_t mem_func);
+
#endif /* SPM_COMMON_H */
diff --git a/spm/cactus/cactus.ld.S b/spm/cactus/cactus.ld.S
index 11b28ba9..50fc576e 100644
--- a/spm/cactus/cactus.ld.S
+++ b/spm/cactus/cactus.ld.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2017-2021, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -52,6 +52,10 @@ SECTIONS
. = ALIGN(PAGE_SIZE);
__DATA_START__ = .;
*(.data*)
+ . = ALIGN(PAGE_SIZE);
+ cactus_cmd_handler_begin = .;
+ KEEP(*(.cactus_handler))
+ cactus_cmd_handler_end = .;
. = NEXT(PAGE_SIZE);
__DATA_END__ = .;
}
diff --git a/spm/cactus/cactus.mk b/spm/cactus/cactus.mk
index 4a9cfcc2..08b824c1 100644
--- a/spm/cactus/cactus.mk
+++ b/spm/cactus/cactus.mk
@@ -33,13 +33,19 @@ CACTUS_SOURCES := \
$(addprefix spm/cactus/, \
aarch64/cactus_entrypoint.S \
cactus_debug.c \
- cactus_ffa_tests.c \
cactus_main.c \
) \
$(addprefix spm/common/, \
aarch64/sp_arch_helpers.S \
sp_helpers.c \
) \
+ $(addprefix spm/cactus/cactus_tests/, \
+ cactus_message_loop.c \
+ cactus_test_cpu_features.c \
+ cactus_test_direct_messaging.c \
+ cactus_test_ffa.c \
+ cactus_test_memory_sharing.c \
+ )
# TODO: Remove dependency on TFTF files.
CACTUS_SOURCES += \
diff --git a/spm/cactus/cactus_main.c b/spm/cactus/cactus_main.c
index 11d7b995..7e3f40bf 100644
--- a/spm/cactus/cactus_main.c
+++ b/spm/cactus/cactus_main.c
@@ -8,8 +8,8 @@
#include <errno.h>
#include <debug.h>
+#include <cactus_message_loop.h>
#include <cactus_platform_def.h>
-#include <cactus_test_cmds.h>
#include <drivers/arm/pl011.h>
#include <drivers/console.h>
#include <lib/aarch64/arch_helpers.h>
@@ -29,9 +29,6 @@
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
@@ -40,13 +37,11 @@ static __aligned(PAGE_SIZE) uint8_t share_page[PAGE_SIZE];
* but rather through Hafnium print hypercall.
*
*/
+
static void __dead2 message_loop(ffa_vm_id_t vm_id, struct mailbox_buffers *mb)
{
smc_ret_values ffa_ret;
- uint32_t sp_response;
- ffa_vm_id_t source;
ffa_vm_id_t destination;
- uint64_t cactus_cmd;
/*
* This initial wait call is necessary to inform SPMD that
@@ -73,235 +68,13 @@ static void __dead2 message_loop(ffa_vm_id_t vm_id, struct mailbox_buffers *mb)
destination = ffa_dir_msg_dest(ffa_ret);
- source = ffa_dir_msg_source(ffa_ret);
-
if (destination != vm_id) {
ERROR("%s(%u) invalid vm id 0x%x\n",
__func__, vm_id, destination);
break;
}
- PRINT_CMD(ffa_ret);
-
- cactus_cmd = cactus_get_cmd(ffa_ret);
-
- switch (cactus_cmd) {
- case CACTUS_MEM_SEND_CMD:
- ffa_memory_management_test(
- mb, vm_id, source,
- cactus_req_mem_send_get_mem_func(
- ffa_ret),
- cactus_mem_send_get_handle(ffa_ret));
-
- /*
- * If execution gets to this point means all operations
- * with memory retrieval went well, as such replying
- */
- 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_func_id(ffa_ret) !=
- FFA_MSG_SEND_DIRECT_RESP_SMC32) {
- ERROR("Failed to send message. error: %x\n",
- ffa_error_code(ffa_ret));
- ffa_ret = cactus_error_resp(vm_id, source);
- break;
- }
-
- /* If anything went bad on the receiver's end. */
- if (cactus_get_response(ffa_ret) == CACTUS_ERROR) {
- 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);
-
- VERBOSE("Received echo at %x, value %llx from %x.\n",
- destination, echo_val, source);
- ffa_ret = cactus_response(destination, source, echo_val);
- break;
- }
- case CACTUS_REQ_ECHO_CMD:
- {
- ffa_vm_id_t echo_dest =
- cactus_req_echo_get_echo_dest(ffa_ret);
- uint64_t echo_val = cactus_echo_get_val(ffa_ret);
- bool success = true;
-
- VERBOSE("%x requested to send echo to %x, value %llx\n",
- source, echo_dest, echo_val);
-
- ffa_ret = cactus_echo_send_cmd(vm_id, echo_dest,
- echo_val);
-
- if (ffa_func_id(ffa_ret) !=
- FFA_MSG_SEND_DIRECT_RESP_SMC32) {
- ERROR("Failed to send message. error: %x\n",
- ffa_error_code(ffa_ret));
- success = false;
- }
-
- if (cactus_get_response(ffa_ret) != echo_val) {
- ERROR("Echo Failed!\n");
- success = false;
- }
-
- ffa_ret = success ? cactus_success_resp(vm_id, source) :
- cactus_error_resp(vm_id, source);
- break;
- }
- case CACTUS_DEADLOCK_CMD:
- case CACTUS_REQ_DEADLOCK_CMD:
- {
- ffa_vm_id_t deadlock_dest =
- cactus_deadlock_get_next_dest(ffa_ret);
- ffa_vm_id_t deadlock_next_dest = source;
-
- if (cactus_cmd == CACTUS_DEADLOCK_CMD) {
- VERBOSE("%x is creating deadlock. next: %x\n",
- source, deadlock_dest);
- } else if (cactus_cmd == CACTUS_REQ_DEADLOCK_CMD) {
- VERBOSE(
- "%x requested deadlock with %x and %x\n",
- source, deadlock_dest, deadlock_next_dest);
-
- deadlock_next_dest =
- cactus_deadlock_get_next_dest2(ffa_ret);
- }
-
- ffa_ret = cactus_deadlock_send_cmd(vm_id, deadlock_dest,
- deadlock_next_dest);
-
- /*
- * Should be true for the last partition to attempt
- * an FF-A direct message, to the first partition.
- */
- bool is_deadlock_detected =
- (ffa_func_id(ffa_ret) == FFA_ERROR) &&
- (ffa_error_code(ffa_ret) == FFA_ERROR_BUSY);
-
- /*
- * Should be true after the deadlock has been detected
- * and after the first response has been sent down the
- * request chain.
- */
- bool is_returning_from_deadlock =
- (ffa_func_id(ffa_ret) ==
- FFA_MSG_SEND_DIRECT_RESP_SMC32)
- &&
- (cactus_get_response(ffa_ret) == CACTUS_SUCCESS);
-
- if (is_deadlock_detected) {
- NOTICE("Attempting dealock but got error %x\n",
- ffa_error_code(ffa_ret));
- }
-
- if (is_deadlock_detected ||
- is_returning_from_deadlock) {
- /*
- * This is not the partition, that would have
- * created the deadlock. As such, reply back
- * to the partitions.
- */
- ffa_ret = cactus_success_resp(vm_id, source);
- break;
- }
-
- /* Shouldn't get to this point */
- ERROR("Deadlock test went wrong!\n");
- ffa_ret = cactus_error_resp(vm_id, source);
- break;
- }
- case CACTUS_REQ_SIMD_FILL_CMD:
- fill_simd_vectors();
- ffa_ret = cactus_success_resp(vm_id, source);
- break;
- default:
- /*
- * Currently direct message test is handled here.
- * TODO: create a case within the switch case
- * For the sake of testing, add the vm id to the
- * received message.
- */
- sp_response = ffa_ret.ret3 | vm_id;
- VERBOSE("Replying with direct message response: %x\n", sp_response);
- ffa_ret = ffa_msg_send_direct_resp(vm_id,
- HYP_ID,
- sp_response);
-
+ if (!cactus_handle_cmd(&ffa_ret, &ffa_ret, mb)) {
break;
}
}
diff --git a/spm/cactus/cactus_tests.h b/spm/cactus/cactus_tests.h
index c0c235ec..1039ba5d 100644
--- a/spm/cactus/cactus_tests.h
+++ b/spm/cactus/cactus_tests.h
@@ -13,19 +13,6 @@
* Test functions
*/
-/*
- * Alter SIMD vectors to check saving of the context while switching between
- * the normal world and the secure world.
- */
-void fill_simd_vectors(void);
-
-/*
- * Test to FFA interfaces.
- */
-void ffa_memory_management_test(struct mailbox_buffers *mb, ffa_vm_id_t vm_id,
- ffa_vm_id_t sender, uint32_t mem_func,
- uint64_t handle);
-
void ffa_tests(struct mailbox_buffers *mb);
/*
diff --git a/spm/cactus/cactus_tests/cactus_message_loop.c b/spm/cactus/cactus_tests/cactus_message_loop.c
new file mode 100644
index 00000000..11207dca
--- /dev/null
+++ b/spm/cactus/cactus_tests/cactus_message_loop.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "cactus_message_loop.h"
+#include "cactus_test_cmds.h"
+#include <ffa_helpers.h>
+#include <debug.h>
+
+
+/**
+ * Begin and end of command handler table, respectively. Both symbols defined by
+ * the linker.
+ */
+extern struct cactus_cmd_handler cactus_cmd_handler_begin[];
+extern struct cactus_cmd_handler cactus_cmd_handler_end[];
+
+#define PRINT_CMD(smc_ret) \
+ VERBOSE("cmd %lx; args: %lx, %lx, %lx, %lx\n", \
+ smc_ret.ret3, smc_ret.ret4, smc_ret.ret5, \
+ smc_ret.ret6, smc_ret.ret7)
+
+/**
+ * Traverses command table from section ".cactus_handler", searches for a
+ * registered command and invokes the respective handler.
+ */
+bool cactus_handle_cmd(smc_ret_values *cmd_args, smc_ret_values *ret,
+ struct mailbox_buffers *mb)
+{
+ uint64_t in_cmd;
+
+ if (cmd_args == NULL || ret == NULL) {
+ ERROR("Invalid argumentos passed to %s!\n", __func__);
+ return false;
+ }
+
+ PRINT_CMD((*cmd_args));
+
+ in_cmd = cactus_get_cmd(*cmd_args);
+
+ for (struct cactus_cmd_handler *it_cmd = cactus_cmd_handler_begin;
+ it_cmd < cactus_cmd_handler_end;
+ it_cmd++) {
+ if (it_cmd->id == in_cmd) {
+ *ret = it_cmd->fn(cmd_args, mb);
+ return true;
+ }
+ }
+
+ ERROR("Unhandled test command!\n");
+ *ret = cactus_error_resp(ffa_dir_msg_dest(*cmd_args),
+ ffa_dir_msg_source(*cmd_args),
+ CACTUS_ERROR_UNHANDLED);
+ return true;
+}
diff --git a/spm/cactus/cactus_tests/cactus_test_cpu_features.c b/spm/cactus/cactus_tests/cactus_test_cpu_features.c
new file mode 100644
index 00000000..7bf6e830
--- /dev/null
+++ b/spm/cactus/cactus_tests/cactus_test_cpu_features.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "cactus_message_loop.h"
+#include "cactus_test_cmds.h"
+#include "spm_common.h"
+
+/*
+ * Fill SIMD vectors from secure world side with a unique value.
+ * 0x22 is just a dummy value to be distinguished from the value
+ * in the normal world.
+ */
+CACTUS_CMD_HANDLER(req_simd_fill, CACTUS_REQ_SIMD_FILL_CMD)
+{
+ simd_vector_t simd_vectors[SIMD_NUM_VECTORS];
+
+ for (unsigned int num = 0U; num < SIMD_NUM_VECTORS; num++) {
+ memset(simd_vectors[num], 0x22 * num, sizeof(simd_vector_t));
+ }
+
+ fill_simd_vector_regs(simd_vectors);
+
+ return cactus_response(ffa_dir_msg_dest(*args),
+ ffa_dir_msg_source(*args),
+ CACTUS_SUCCESS);
+}
diff --git a/spm/cactus/cactus_tests/cactus_test_direct_messaging.c b/spm/cactus/cactus_tests/cactus_test_direct_messaging.c
new file mode 100644
index 00000000..a59cfa24
--- /dev/null
+++ b/spm/cactus/cactus_tests/cactus_test_direct_messaging.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "cactus_message_loop.h"
+#include "cactus_test_cmds.h"
+#include <debug.h>
+#include <ffa_helpers.h>
+
+CACTUS_CMD_HANDLER(echo_cmd, CACTUS_ECHO_CMD)
+{
+ uint64_t echo_val = cactus_echo_get_val(*args);
+
+ VERBOSE("Received echo at %x, value %llx.\n", ffa_dir_msg_dest(*args),
+ echo_val);
+
+ return cactus_success_resp(ffa_dir_msg_dest(*args),
+ ffa_dir_msg_source(*args),
+ echo_val);
+}
+
+CACTUS_CMD_HANDLER(req_echo_cmd, CACTUS_REQ_ECHO_CMD)
+{
+ smc_ret_values ffa_ret;
+ ffa_vm_id_t vm_id = ffa_dir_msg_dest(*args);
+ ffa_vm_id_t echo_dest = cactus_req_echo_get_echo_dest(*args);
+ uint64_t echo_val = cactus_echo_get_val(*args);
+
+ VERBOSE("%x requested to send echo to %x, value %llx\n",
+ ffa_dir_msg_source(*args), echo_dest, echo_val);
+
+ ffa_ret = cactus_echo_send_cmd(vm_id, echo_dest, echo_val);
+
+ if (!is_ffa_direct_response(ffa_ret)) {
+ return cactus_error_resp(vm_id, ffa_dir_msg_source(*args),
+ CACTUS_ERROR_FFA_CALL);
+ }
+
+ if (cactus_get_response(ffa_ret) != CACTUS_SUCCESS ||
+ cactus_echo_get_val(ffa_ret) != echo_val) {
+ ERROR("Echo Failed!\n");
+ return cactus_error_resp(vm_id, ffa_dir_msg_source(*args),
+ CACTUS_ERROR_TEST);
+ }
+
+ return cactus_success_resp(vm_id, ffa_dir_msg_source(*args), 0);
+}
+
+static smc_ret_values base_deadlock_handler(ffa_vm_id_t vm_id,
+ ffa_vm_id_t source,
+ ffa_vm_id_t deadlock_dest,
+ ffa_vm_id_t deadlock_next_dest)
+{
+ smc_ret_values ffa_ret;
+
+ ffa_ret = cactus_deadlock_send_cmd(vm_id, deadlock_dest,
+ deadlock_next_dest);
+
+ /*
+ * Should be true for the last partition to attempt
+ * an FF-A direct message, to the first partition.
+ */
+ bool is_deadlock_detected = (ffa_func_id(ffa_ret) == FFA_ERROR) &&
+ (ffa_error_code(ffa_ret) == FFA_ERROR_BUSY);
+
+ /*
+ * Should be true after the deadlock has been detected and after the
+ * first response has been sent down the request chain.
+ */
+ bool is_returning_from_deadlock =
+ (is_ffa_direct_response(ffa_ret)) &&
+ (cactus_get_response(ffa_ret) == CACTUS_SUCCESS);
+
+ if (is_deadlock_detected) {
+ VERBOSE("Attempt to create deadlock failed\n");
+ }
+
+ if (is_deadlock_detected || is_returning_from_deadlock) {
+ /*
+ * This is not the partition, that would have created the
+ * deadlock. As such, reply back to the partitions.
+ */
+ return cactus_success_resp(vm_id, source, 0);
+ }
+
+ /* Shouldn't get to this point */
+ ERROR("Deadlock test went wrong!\n");
+ return cactus_error_resp(vm_id, source, CACTUS_ERROR_TEST);
+}
+
+CACTUS_CMD_HANDLER(deadlock_cmd, CACTUS_DEADLOCK_CMD)
+{
+ ffa_vm_id_t source = ffa_dir_msg_source(*args);
+ ffa_vm_id_t deadlock_dest = cactus_deadlock_get_next_dest(*args);
+ ffa_vm_id_t deadlock_next_dest = source;
+
+ VERBOSE("%x is creating deadlock. next: %x\n", source, deadlock_dest);
+
+ return base_deadlock_handler(ffa_dir_msg_dest(*args), source,
+ deadlock_dest, deadlock_next_dest);
+}
+
+CACTUS_CMD_HANDLER(req_deadlock_cmd, CACTUS_REQ_DEADLOCK_CMD)
+{
+ ffa_vm_id_t vm_id = ffa_dir_msg_dest(*args);
+ ffa_vm_id_t source = ffa_dir_msg_source(*args);
+ ffa_vm_id_t deadlock_dest = cactus_deadlock_get_next_dest(*args);
+ ffa_vm_id_t deadlock_next_dest = cactus_deadlock_get_next_dest2(*args);
+
+ VERBOSE("%x requested deadlock with %x and %x\n",
+ ffa_dir_msg_source(*args), deadlock_dest, deadlock_next_dest);
+
+ return base_deadlock_handler(vm_id, source, deadlock_dest, deadlock_next_dest);
+}
diff --git a/spm/cactus/cactus_ffa_tests.c b/spm/cactus/cactus_tests/cactus_test_ffa.c
index 032d2e2e..c1ba7835 100644
--- a/spm/cactus/cactus_ffa_tests.c
+++ b/spm/cactus/cactus_tests/cactus_test_ffa.c
@@ -14,7 +14,6 @@
#include <spm_common.h>
#include <lib/libc/string.h>
-#include <lib/xlat_tables/xlat_tables_v2.h>
/* FFA version test helpers */
#define FFA_MAJOR 1U
@@ -26,22 +25,6 @@ static const uint32_t tertiary_uuid[4] = TERTIARY_UUID;
static const uint32_t null_uuid[4] = {0};
/*
- * Fill SIMD vectors from secure world side with a unique value.
- * 0x22 is just a dummy value to be distinguished from the value
- * in the normal world.
- */
-void fill_simd_vectors(void)
-{
- simd_vector_t simd_vectors[SIMD_NUM_VECTORS];
-
- for (unsigned int num = 0U; num < SIMD_NUM_VECTORS; num++) {
- memset(simd_vectors[num], 0x22 * num, sizeof(simd_vector_t));
- }
-
- fill_simd_vector_regs(simd_vectors);
-}
-
-/*
* Test FFA_FEATURES interface.
*/
static void ffa_features_test(void)
@@ -179,166 +162,6 @@ void ffa_version_test(void)
announce_test_end(test_ffa_version);
}
-bool ffa_memory_retrieve_test(struct mailbox_buffers *mb,
- struct ffa_memory_region **retrieved,
- uint64_t handle, ffa_vm_id_t sender,
- ffa_vm_id_t receiver, uint32_t mem_func)
-{
- smc_ret_values ret;
- uint32_t fragment_size;
- uint32_t total_size;
- uint32_t descriptor_size;
-
- if (retrieved == NULL || mb == NULL) {
- ERROR("Invalid parameters!\n");
- return false;
- }
-
- /*
- * TODO: Revise shareability attribute in function call
- * below.
- * https://lists.trustedfirmware.org/pipermail/hafnium/2020-June/000023.html
- */
- descriptor_size = ffa_memory_retrieve_request_init(
- mb->send, handle, sender, receiver, 0, 0,
- FFA_DATA_ACCESS_RW,
- FFA_INSTRUCTION_ACCESS_NX,
- FFA_MEMORY_NORMAL_MEM,
- FFA_MEMORY_CACHE_WRITE_BACK,
- FFA_MEMORY_OUTER_SHAREABLE);
-
- ret = ffa_mem_retrieve_req(descriptor_size, descriptor_size);
-
- if (ffa_func_id(ret) != FFA_MEM_RETRIEVE_RESP) {
- ERROR("Couldn't retrieve the memory page. Error: %lx\n",
- ret.ret2);
- return false;
- }
-
- /*
- * Following total_size and fragment_size are useful to keep track
- * of the state of transaction. When the sum of all fragment_size of all
- * fragments is equal to total_size, the memory transaction has been
- * completed.
- * This is a simple test with only one segment. As such, upon
- * successful ffa_mem_retrieve_req, total_size must be equal to
- * fragment_size.
- */
- total_size = ret.ret1;
- fragment_size = ret.ret2;
-
- if (total_size != fragment_size) {
- ERROR("Only expect one memory segment to be sent!\n");
- return false;
- }
-
- if (fragment_size > PAGE_SIZE) {
- ERROR("Fragment should be smaller than RX buffer!\n");
- return false;
- }
-
- *retrieved = (struct ffa_memory_region *)mb->recv;
-
- if ((*retrieved)->receiver_count > MAX_MEM_SHARE_RECIPIENTS) {
- VERBOSE("SPMC memory sharing operations support max of %u "
- "receivers!\n", MAX_MEM_SHARE_RECIPIENTS);
- return false;
- }
-
- VERBOSE("Memory Retrieved!\n");
-
- return true;
-}
-
-bool ffa_memory_relinquish_test(struct ffa_mem_relinquish *m,
- uint64_t handle,
- ffa_vm_id_t id)
-{
- smc_ret_values ret;
-
- ffa_mem_relinquish_init(m, handle, 0, id);
- ret = ffa_mem_relinquish();
- if (ffa_func_id(ret) != FFA_SUCCESS_SMC32) {
- ERROR("%s failed to relinquish memory! error: %x\n",
- __func__, ffa_error_code(ret));
- return false;
- }
-
- VERBOSE("Memory Relinquished!\n");
- return true;
-}
-
-void ffa_memory_management_test(struct mailbox_buffers *mb, ffa_vm_id_t vm_id,
- ffa_vm_id_t sender, uint32_t mem_func,
- uint64_t handle)
-{
- const char *test_ffa = "Memory Management";
- struct ffa_memory_region *m;
- struct ffa_composite_memory_region *composite;
- int ret;
- unsigned int mem_attrs;
- uint32_t *ptr;
-
- announce_test_section_start(test_ffa);
-
- expect(ffa_memory_retrieve_test(
- mb, &m, handle, sender, vm_id, mem_func),
- true);
-
- composite = ffa_memory_region_get_composite(m, 0);
-
- VERBOSE("Address: %p; page_count: %x %x\n",
- composite->constituents[0].address,
- composite->constituents[0].page_count, PAGE_SIZE);
-
- /* This test is only concerned with RW permissions. */
- expect(ffa_get_data_access_attr(
- m->receivers[0].receiver_permissions.permissions),
- FFA_DATA_ACCESS_RW);
-
- 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,
- (uint64_t)composite->constituents[0].address,
- composite->constituents[0].page_count * PAGE_SIZE,
- mem_attrs);
- expect(ret, 0);
-
- VERBOSE("Memory has been mapped\n");
-
- ptr = (uint32_t *) composite->constituents[0].address;
-
- /* Write mem_func to retrieved memory region for validation purposes. */
- VERBOSE("Writing: %x\n", mem_func);
- for (unsigned int i = 0U; i < 5U; i++)
- ptr[i] = mem_func;
-
- /*
- * A FFA_MEM_DONATE changes the ownership of the page, as such no
- * relinquish is needed.
- */
- if (mem_func != FFA_MEM_DONATE_SMC32) {
- ret = mmap_remove_dynamic_region(
- (uint64_t)composite->constituents[0].address,
- composite->constituents[0].page_count * PAGE_SIZE);
- expect(ret, 0);
-
- expect(ffa_memory_relinquish_test(
- (struct ffa_mem_relinquish *)mb->send,
- m->handle, vm_id),
- true);
- }
-
- expect(ffa_func_id(ffa_rx_release()), FFA_SUCCESS_SMC32);
-
- announce_test_section_end(test_ffa);
-}
-
void ffa_tests(struct mailbox_buffers *mb)
{
const char *test_ffa = "FFA Interfaces";
diff --git a/spm/cactus/cactus_tests/cactus_test_memory_sharing.c b/spm/cactus/cactus_tests/cactus_test_memory_sharing.c
new file mode 100644
index 00000000..e7bce50f
--- /dev/null
+++ b/spm/cactus/cactus_tests/cactus_test_memory_sharing.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <cactus_def.h>
+#include "cactus_message_loop.h"
+#include "cactus_test_cmds.h"
+#include "cactus_tests.h"
+#include <debug.h>
+#include <ffa_helpers.h>
+#include <sp_helpers.h>
+#include <xlat_tables_defs.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+/* Memory section to be used for memory share operations */
+static __aligned(PAGE_SIZE) uint8_t share_page[PAGE_SIZE];
+
+CACTUS_CMD_HANDLER(mem_send_cmd, CACTUS_MEM_SEND_CMD)
+{
+ struct ffa_memory_region *m;
+ struct ffa_composite_memory_region *composite;
+ int ret;
+ unsigned int mem_attrs;
+ uint32_t *ptr;
+ ffa_vm_id_t source = ffa_dir_msg_source(*args);
+ ffa_vm_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);
+
+ expect(memory_retrieve(mb, &m, handle, source, vm_id, mem_func), true);
+
+ composite = ffa_memory_region_get_composite(m, 0);
+
+ VERBOSE("Address: %p; page_count: %x %x\n",
+ composite->constituents[0].address,
+ composite->constituents[0].page_count, PAGE_SIZE);
+
+ /* This test is only concerned with RW permissions. */
+ if (ffa_get_data_access_attr(
+ m->receivers[0].receiver_permissions.permissions) !=
+ FFA_DATA_ACCESS_RW) {
+ ERROR("Permissions not expected!\n");
+ return cactus_error_resp(vm_id, source, CACTUS_ERROR_TEST);
+ }
+
+ mem_attrs = MT_RW_DATA | MT_EXECUTE_NEVER;
+
+ if (!IS_SP_ID(source)) {
+ mem_attrs |= MT_NS;
+ }
+
+ ret = mmap_add_dynamic_region(
+ (uint64_t)composite->constituents[0].address,
+ (uint64_t)composite->constituents[0].address,
+ composite->constituents[0].page_count * PAGE_SIZE,
+ mem_attrs);
+
+ if (ret != 0) {
+ ERROR("Failed first mmap_add_dynamic_region!\n");
+ return cactus_error_resp(vm_id, source, CACTUS_ERROR_TEST);
+ }
+
+ VERBOSE("Memory has been mapped\n");
+
+ ptr = (uint32_t *) composite->constituents[0].address;
+
+ /* Write mem_func to retrieved memory region for validation purposes. */
+ VERBOSE("Writing: %x\n", mem_func);
+ for (unsigned int i = 0U; i < 5U; i++)
+ ptr[i] = mem_func;
+
+ /*
+ * A FFA_MEM_DONATE changes the ownership of the page, as such no
+ * relinquish is needed.
+ */
+ if (mem_func != FFA_MEM_DONATE_SMC32) {
+ ret = mmap_remove_dynamic_region(
+ (uint64_t)composite->constituents[0].address,
+ composite->constituents[0].page_count * PAGE_SIZE);
+
+ if (ret != 0) {
+ ERROR("Failed first mmap_add_dynamic_region!\n");
+ return cactus_error_resp(vm_id, source,
+ CACTUS_ERROR_TEST);
+ }
+
+ if (!memory_relinquish((struct ffa_mem_relinquish *)mb->send,
+ m->handle, vm_id)) {
+ return cactus_error_resp(vm_id, source,
+ CACTUS_ERROR_TEST);
+ }
+ }
+
+ if (ffa_func_id(ffa_rx_release()) != FFA_SUCCESS_SMC32) {
+ ERROR("Failed to release buffer!\n");
+ return cactus_error_resp(vm_id, source,
+ CACTUS_ERROR_FFA_CALL);
+ }
+
+ return cactus_success_resp(vm_id,
+ source, 0);
+}
+
+CACTUS_CMD_HANDLER(req_mem_send_cmd, CACTUS_REQ_MEM_SEND_CMD)
+{
+ smc_ret_values ffa_ret;
+ uint32_t mem_func = cactus_req_mem_send_get_mem_func(*args);
+ ffa_vm_id_t receiver = cactus_req_mem_send_get_receiver(*args);
+ ffa_memory_handle_t handle;
+ ffa_vm_id_t vm_id = ffa_dir_msg_dest(*args);
+ ffa_vm_id_t source = ffa_dir_msg_source(*args);
+
+ 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 = 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.
+ */
+ if (handle == FFA_MEMORY_HANDLE_INVALID) {
+ ERROR("Received an invalid FF-A memory Handle!\n");
+ return cactus_error_resp(vm_id, source,
+ CACTUS_ERROR_TEST);
+ }
+
+ ffa_ret = cactus_mem_send_cmd(vm_id, receiver, mem_func, handle);
+
+ if (!is_ffa_direct_response(ffa_ret)) {
+ return cactus_error_resp(vm_id, source, CACTUS_ERROR_FFA_CALL);
+ }
+
+ /* If anything went bad on the receiver's end. */
+ if (cactus_get_response(ffa_ret) == CACTUS_ERROR) {
+ ERROR("Received error from receiver!\n");
+ return cactus_error_resp(vm_id, source, CACTUS_ERROR_TEST);
+ }
+
+ 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.
+ */
+ ffa_ret = ffa_mem_reclaim(handle, 0);
+ if (is_ffa_call_error(ffa_ret)) {
+ return cactus_error_resp(vm_id, source,
+ CACTUS_ERROR_TEST);
+ }
+
+ /**
+ * 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
+ }
+
+ return cactus_success_resp(vm_id, source, 0);
+}
diff --git a/tftf/tests/runtime_services/secure_service/ffa_helpers.c b/tftf/tests/runtime_services/secure_service/ffa_helpers.c
index 923ee2c9..8e7b58c6 100644
--- a/tftf/tests/runtime_services/secure_service/ffa_helpers.c
+++ b/tftf/tests/runtime_services/secure_service/ffa_helpers.c
@@ -3,8 +3,6 @@
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-
-#include <debug.h>
#include <smccc.h>
#include <ffa_endpoints.h>
@@ -57,58 +55,83 @@ smc_ret_values ffa_run(uint32_t dest_id, uint32_t vcpu_id)
* -BUSY: Message target is busy
* -ABORTED: Message target ran into an unexpected error and has aborted
*/
-static smc_ret_values __ffa_msg_send_direct_req32_5(uint32_t source_id,
- uint32_t dest_id,
- uint32_t arg0,
- uint32_t arg1,
- uint32_t arg2,
- uint32_t arg3,
- uint32_t arg4)
+smc_ret_values ffa_msg_send_direct_req64(ffa_vm_id_t source_id,
+ ffa_vm_id_t dest_id, uint64_t arg0,
+ uint64_t arg1, uint64_t arg2,
+ uint64_t arg3, uint64_t arg4)
{
smc_args args = {
- FFA_MSG_SEND_DIRECT_REQ_SMC32,
- (source_id << 16) | dest_id,
- 0,
- arg0, arg1, arg2, arg3, arg4
+ .fid = FFA_MSG_SEND_DIRECT_REQ_SMC64,
+ .arg1 = ((uint32_t)(source_id << 16)) | (dest_id),
+ .arg2 = 0,
+ .arg3 = arg0,
+ .arg4 = arg1,
+ .arg5 = arg2,
+ .arg6 = arg3,
+ .arg7 = arg4,
};
return tftf_smc(&args);
}
-/* Direct message send helper accepting a single 32b message argument */
-smc_ret_values ffa_msg_send_direct_req(uint32_t source_id, uint32_t dest_id,
- uint32_t message)
+smc_ret_values ffa_msg_send_direct_req32(ffa_vm_id_t source_id,
+ ffa_vm_id_t dest_id, uint32_t arg0,
+ uint32_t arg1, uint32_t arg2,
+ uint32_t arg3, uint32_t arg4)
{
- return __ffa_msg_send_direct_req32_5(source_id, dest_id,
- message, 0, 0, 0, 0);
+ smc_args args = {
+ .fid = FFA_MSG_SEND_DIRECT_REQ_SMC32,
+ .arg1 = ((uint32_t)(source_id << 16)) | (dest_id),
+ .arg2 = 0,
+ .arg3 = arg0,
+ .arg4 = arg1,
+ .arg5 = arg2,
+ .arg6 = arg3,
+ .arg7 = arg4,
+ };
+
+ return tftf_smc(&args);
}
-smc_ret_values ffa_msg_send_direct_req64_5args(uint32_t source_id,
- uint32_t dest_id,
- uint64_t arg0,
- uint64_t arg1,
- uint64_t arg2,
- uint64_t arg3,
- uint64_t arg4)
+smc_ret_values ffa_msg_send_direct_resp64(ffa_vm_id_t source_id,
+ ffa_vm_id_t dest_id, uint64_t arg0,
+ uint64_t arg1, uint64_t arg2,
+ uint64_t arg3, uint64_t arg4)
{
smc_args args = {
- FFA_MSG_SEND_DIRECT_REQ_SMC64,
- (source_id << 16) | dest_id,
- 0,
- arg0, arg1, arg2, arg3, arg4
+ .fid = FFA_MSG_SEND_DIRECT_RESP_SMC64,
+ .arg1 = ((uint32_t)(source_id << 16)) | (dest_id),
+ .arg2 = 0,
+ .arg3 = arg0,
+ .arg4 = arg1,
+ .arg5 = arg2,
+ .arg6 = arg3,
+ .arg7 = arg4,
};
return tftf_smc(&args);
}
-/* Direct message send helper accepting a single 64b message argument */
-smc_ret_values ffa_msg_send_direct_req64(uint32_t source_id, uint32_t dest_id,
- uint64_t message)
+smc_ret_values ffa_msg_send_direct_resp32(ffa_vm_id_t source_id,
+ ffa_vm_id_t dest_id, uint32_t arg0,
+ uint32_t arg1, uint32_t arg2,
+ uint32_t arg3, uint32_t arg4)
{
- return ffa_msg_send_direct_req64_5args(source_id, dest_id,
- message, 0, 0, 0, 0);
+ smc_args args = {
+ .fid = FFA_MSG_SEND_DIRECT_RESP_SMC32,
+ .arg1 = ((uint32_t)(source_id << 16)) | (dest_id),
+ .arg2 = 0,
+ .arg3 = arg0,
+ .arg4 = arg1,
+ .arg5 = arg2,
+ .arg6 = arg3,
+ .arg7 = arg4,
+ };
+
+ return tftf_smc(&args);
}
+
/**
* Initialises the header of the given `ffa_memory_region`, not including the
* composite memory region offset.
@@ -268,91 +291,6 @@ uint32_t ffa_memory_retrieve_request_init(
memory_region->receiver_count * sizeof(struct ffa_memory_access);
}
-/**
- * Helper to call memory send function whose func id is passed as a parameter.
- * Returns a valid handle in case of successful operation or
- * FFA_MEMORY_HANDLE_INVALID if something goes wrong.
- *
- * TODO: Do memory send with 'ffa_memory_region' taking multiple segments
- */
-ffa_memory_handle_t ffa_memory_send(
- struct ffa_memory_region *memory_region, uint32_t mem_func,
- uint32_t fragment_length, uint32_t total_length)
-{
- smc_ret_values ret;
- ffa_vm_id_t receiver =
- memory_region->receivers[0].receiver_permissions.receiver;
-
- if (fragment_length != total_length) {
- ERROR("For now, fragment_length and total_length need to be"
- " equal");
- return FFA_MEMORY_HANDLE_INVALID;
- }
-
- switch (mem_func) {
- case FFA_MEM_SHARE_SMC32:
- ret = ffa_mem_share(total_length, fragment_length);
- break;
- case FFA_MEM_LEND_SMC32:
- ret = ffa_mem_lend(total_length, fragment_length);
- break;
- case FFA_MEM_DONATE_SMC32:
- ret = ffa_mem_donate(total_length, fragment_length);
- break;
- default:
- ERROR("TFTF - Invalid func id %x!\n", mem_func);
- return FFA_MEMORY_HANDLE_INVALID;
- }
-
- if (ffa_func_id(ret) != FFA_SUCCESS_SMC32) {
- ERROR("Failed to send memory to %x, error: %x.\n",
- receiver, ffa_error_code(ret));
- return FFA_MEMORY_HANDLE_INVALID;
- }
-
- return ffa_mem_success_handle(ret);
-;
-}
-
-/**
- * Helper that initializes and sends a memory region. The memory region's
- * configuration is statically defined and is implementation specific. However,
- * doing it in this file for simplicity and for testing purposes.
- */
-ffa_memory_handle_t ffa_memory_init_and_send(
- struct ffa_memory_region *memory_region, size_t memory_region_max_size,
- ffa_vm_id_t sender, ffa_vm_id_t receiver,
- const struct ffa_memory_region_constituent *constituents,
- uint32_t constituents_count, uint32_t mem_func)
-{
- uint32_t remaining_constituent_count;
- uint32_t total_length;
- uint32_t fragment_length;
-
- enum ffa_data_access data_access = (mem_func == FFA_MEM_DONATE_SMC32) ?
- FFA_DATA_ACCESS_NOT_SPECIFIED :
- FFA_DATA_ACCESS_RW;
-
- remaining_constituent_count = ffa_memory_region_init(
- memory_region, memory_region_max_size, sender, receiver, constituents,
- constituents_count, 0, 0, data_access,
- FFA_INSTRUCTION_ACCESS_NOT_SPECIFIED,
- FFA_MEMORY_NORMAL_MEM, FFA_MEMORY_CACHE_WRITE_BACK,
- FFA_MEMORY_INNER_SHAREABLE, &total_length, &fragment_length
- );
-
- /*
- * For simplicity of the test, and at least for the time being,
- * the following condition needs to be true.
- */
- if (remaining_constituent_count != 0U) {
- ERROR("Remaining constituent should be 0\n");
- return FFA_MEMORY_HANDLE_INVALID;
- }
-
- return ffa_memory_send(memory_region, mem_func, fragment_length,
- total_length);
-}
/*
* FFA Version ABI helper.
@@ -388,19 +326,6 @@ smc_ret_values ffa_msg_wait(void)
return tftf_smc(&args);
}
-smc_ret_values ffa_msg_send_direct_resp(ffa_vm_id_t source_id,
- ffa_vm_id_t dest_id,
- uint32_t message)
-{
- smc_args args = {
- .fid = FFA_MSG_SEND_DIRECT_RESP_SMC32,
- .arg1 = ((uint32_t)source_id << 16) | dest_id,
- .arg3 = message
- };
-
- return tftf_smc(&args);
-}
-
smc_ret_values ffa_error(int32_t error_code)
{
smc_args args = {
diff --git a/tftf/tests/runtime_services/secure_service/spm_common.c b/tftf/tests/runtime_services/secure_service/spm_common.c
index cc3ed5df..12b70a9a 100644
--- a/tftf/tests/runtime_services/secure_service/spm_common.c
+++ b/tftf/tests/runtime_services/secure_service/spm_common.c
@@ -4,13 +4,61 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <debug.h>
#include <ffa_endpoints.h>
#include <spm_common.h>
+#include <xlat_tables_v2.h>
#define __STR(x) #x
#define STR(x) __STR(x)
#define SIMD_TWO_VECTORS_BYTES_STR (2 * SIMD_VECTOR_LEN_BYTES)
+/**
+ * Helper to log errors after FF-A calls.
+ */
+bool is_ffa_call_error(smc_ret_values ret)
+{
+ if (ffa_func_id(ret) == FFA_ERROR) {
+ ERROR("FF-A call returned error (%x): %d\n",
+ ffa_func_id(ret), ffa_error_code(ret));
+ return true;
+ }
+ return false;
+}
+
+/**
+ * Helper to verify return of FF-A call is an FFA_MSG_SEND_DIRECT_RESP.
+ * Should be used after FFA_MSG_SEND_DIRECT_REQ, or after sending a test command
+ * to an SP.
+ */
+bool is_ffa_direct_response(smc_ret_values ret)
+{
+ if ((ffa_func_id(ret) == FFA_MSG_SEND_DIRECT_RESP_SMC32) ||
+ (ffa_func_id(ret) == FFA_MSG_SEND_DIRECT_RESP_SMC64)) {
+ return true;
+ }
+
+ ERROR("%x is not FF-A response.\n", ffa_func_id(ret));
+ /* To log error in case it is FFA_ERROR*/
+ is_ffa_call_error(ret);
+
+ return false;
+}
+
+/**
+ * Helper to check the return value of FF-A call is as expected.
+ */
+bool is_expected_ffa_return(smc_ret_values ret, uint32_t func_id)
+{
+ if (ffa_func_id(ret) == func_id) {
+ return true;
+ }
+
+ ERROR("Expecting %x, FF-A return was %x\n", func_id, ffa_func_id(ret));
+
+ return false;
+}
+
void fill_simd_vector_regs(const simd_vector_t v[SIMD_NUM_VECTORS])
{
#ifdef __aarch64__
@@ -83,8 +131,9 @@ bool check_spmc_execution_level(void)
* Send a first OP-TEE-defined protocol message through
* FFA direct message.
*/
- ret_values = ffa_msg_send_direct_req(HYP_ID, SP_ID(1),
- OPTEE_FFA_GET_API_VERSION);
+ ret_values = ffa_msg_send_direct_req32(HYP_ID, SP_ID(1),
+ OPTEE_FFA_GET_API_VERSION, 0,
+ 0, 0, 0);
if ((ret_values.ret3 == FFA_VERSION_MAJOR) &&
(ret_values.ret4 == FFA_VERSION_MINOR)) {
is_optee_spmc_criteria++;
@@ -94,8 +143,9 @@ bool check_spmc_execution_level(void)
* Send a second OP-TEE-defined protocol message through
* FFA direct message.
*/
- ret_values = ffa_msg_send_direct_req(HYP_ID, SP_ID(1),
- OPTEE_FFA_GET_OS_VERSION);
+ ret_values = ffa_msg_send_direct_req32(HYP_ID, SP_ID(1),
+ OPTEE_FFA_GET_OS_VERSION,
+ 0, 0, 0, 0);
if ((ret_values.ret3 == OPTEE_FFA_GET_OS_VERSION_MAJOR) &&
(ret_values.ret4 == OPTEE_FFA_GET_OS_VERSION_MINOR)) {
is_optee_spmc_criteria++;
@@ -146,3 +196,175 @@ unsigned int get_ffa_feature_test_target(
return sizeof(ffa_feature_test_target) /
sizeof(struct ffa_features_test);
}
+
+bool memory_retrieve(struct mailbox_buffers *mb,
+ struct ffa_memory_region **retrieved, uint64_t handle,
+ ffa_vm_id_t sender, ffa_vm_id_t receiver,
+ uint32_t mem_func)
+{
+ smc_ret_values ret;
+ uint32_t fragment_size;
+ uint32_t total_size;
+ uint32_t descriptor_size;
+
+ if (retrieved == NULL || mb == NULL) {
+ ERROR("Invalid parameters!\n");
+ return false;
+ }
+
+ /*
+ * TODO: Revise shareability attribute in function call
+ * below.
+ * https://lists.trustedfirmware.org/pipermail/hafnium/2020-June/000023.html
+ */
+ descriptor_size = ffa_memory_retrieve_request_init(
+ mb->send, handle, sender, receiver, 0, 0,
+ FFA_DATA_ACCESS_RW,
+ FFA_INSTRUCTION_ACCESS_NX,
+ FFA_MEMORY_NORMAL_MEM,
+ FFA_MEMORY_CACHE_WRITE_BACK,
+ FFA_MEMORY_OUTER_SHAREABLE);
+
+ ret = ffa_mem_retrieve_req(descriptor_size, descriptor_size);
+
+ if (ffa_func_id(ret) != FFA_MEM_RETRIEVE_RESP) {
+ ERROR("Couldn't retrieve the memory page. Error: %x\n",
+ ffa_error_code(ret));
+ return false;
+ }
+
+ /*
+ * Following total_size and fragment_size are useful to keep track
+ * of the state of transaction. When the sum of all fragment_size of all
+ * fragments is equal to total_size, the memory transaction has been
+ * completed.
+ * This is a simple test with only one segment. As such, upon
+ * successful ffa_mem_retrieve_req, total_size must be equal to
+ * fragment_size.
+ */
+ total_size = ret.ret1;
+ fragment_size = ret.ret2;
+
+ if (total_size != fragment_size) {
+ ERROR("Only expect one memory segment to be sent!\n");
+ return false;
+ }
+
+ if (fragment_size > PAGE_SIZE) {
+ ERROR("Fragment should be smaller than RX buffer!\n");
+ return false;
+ }
+
+ *retrieved = (struct ffa_memory_region *)mb->recv;
+
+ if ((*retrieved)->receiver_count > MAX_MEM_SHARE_RECIPIENTS) {
+ VERBOSE("SPMC memory sharing operations support max of %u "
+ "receivers!\n", MAX_MEM_SHARE_RECIPIENTS);
+ return false;
+ }
+
+ VERBOSE("Memory Retrieved!\n");
+
+ return true;
+}
+
+bool memory_relinquish(struct ffa_mem_relinquish *m, uint64_t handle,
+ ffa_vm_id_t id)
+{
+ smc_ret_values ret;
+
+ ffa_mem_relinquish_init(m, handle, 0, id);
+ ret = ffa_mem_relinquish();
+ if (ffa_func_id(ret) != FFA_SUCCESS_SMC32) {
+ ERROR("%s failed to relinquish memory! error: %x\n",
+ __func__, ffa_error_code(ret));
+ return false;
+ }
+
+ VERBOSE("Memory Relinquished!\n");
+ return true;
+}
+
+/**
+ * Helper to call memory send function whose func id is passed as a parameter.
+ * Returns a valid handle in case of successful operation or
+ * FFA_MEMORY_HANDLE_INVALID if something goes wrong.
+ *
+ * TODO: Do memory send with 'ffa_memory_region' taking multiple segments
+ */
+ffa_memory_handle_t memory_send(
+ struct ffa_memory_region *memory_region, uint32_t mem_func,
+ uint32_t fragment_length, uint32_t total_length)
+{
+ smc_ret_values ret;
+ ffa_vm_id_t receiver =
+ memory_region->receivers[0].receiver_permissions.receiver;
+
+ if (fragment_length != total_length) {
+ ERROR("For now, fragment_length and total_length need to be"
+ " equal");
+ return FFA_MEMORY_HANDLE_INVALID;
+ }
+
+ switch (mem_func) {
+ case FFA_MEM_SHARE_SMC32:
+ ret = ffa_mem_share(total_length, fragment_length);
+ break;
+ case FFA_MEM_LEND_SMC32:
+ ret = ffa_mem_lend(total_length, fragment_length);
+ break;
+ case FFA_MEM_DONATE_SMC32:
+ ret = ffa_mem_donate(total_length, fragment_length);
+ break;
+ default:
+ ERROR("TFTF - Invalid func id %x!\n", mem_func);
+ return FFA_MEMORY_HANDLE_INVALID;
+ }
+
+ if (is_ffa_call_error(ret)) {
+ ERROR("Failed to send message to: %x\n", receiver);
+ return FFA_MEMORY_HANDLE_INVALID;
+ }
+
+ return ffa_mem_success_handle(ret);
+}
+
+/**
+ * Helper that initializes and sends a memory region. The memory region's
+ * configuration is statically defined and is implementation specific. However,
+ * doing it in this file for simplicity and for testing purposes.
+ */
+ffa_memory_handle_t memory_init_and_send(
+ struct ffa_memory_region *memory_region, size_t memory_region_max_size,
+ ffa_vm_id_t sender, ffa_vm_id_t receiver,
+ const struct ffa_memory_region_constituent *constituents,
+ uint32_t constituents_count, uint32_t mem_func)
+{
+ uint32_t remaining_constituent_count;
+ uint32_t total_length;
+ uint32_t fragment_length;
+
+ enum ffa_data_access data_access = (mem_func == FFA_MEM_DONATE_SMC32) ?
+ FFA_DATA_ACCESS_NOT_SPECIFIED :
+ FFA_DATA_ACCESS_RW;
+
+ remaining_constituent_count = ffa_memory_region_init(
+ memory_region, memory_region_max_size, sender, receiver, constituents,
+ constituents_count, 0, 0, data_access,
+ FFA_INSTRUCTION_ACCESS_NOT_SPECIFIED,
+ FFA_MEMORY_NORMAL_MEM, FFA_MEMORY_CACHE_WRITE_BACK,
+ FFA_MEMORY_INNER_SHAREABLE, &total_length, &fragment_length
+ );
+
+ /*
+ * For simplicity of the test, and at least for the time being,
+ * the following condition needs to be true.
+ */
+ if (remaining_constituent_count != 0U) {
+ ERROR("Remaining constituent should be 0\n");
+ return FFA_MEMORY_HANDLE_INVALID;
+ }
+
+ return memory_send(memory_region, mem_func, fragment_length,
+ total_length);
+}
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_direct_messaging.c b/tftf/tests/runtime_services/secure_service/test_ffa_direct_messaging.c
index 12954426..83510b06 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_direct_messaging.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_direct_messaging.c
@@ -18,37 +18,28 @@
#define ECHO_VAL2 U(0xb0b0b0b0)
#define ECHO_VAL3 U(0xc0c0c0c0)
-#define DIRECT_MSG_TEST_PATTERN1 (0xaaaa0000)
-#define DIRECT_MSG_TEST_PATTERN2 (0xbbbb0000)
-#define DIRECT_MSG_TEST_PATTERN3 (0xcccc0000)
-
static const struct ffa_uuid expected_sp_uuids[] = {
{PRIMARY_UUID}, {SECONDARY_UUID}, {TERTIARY_UUID}
};
-static test_result_t send_receive_direct_msg(unsigned int sp_id,
- unsigned int test_pattern)
+static test_result_t send_cactus_echo_cmd(ffa_vm_id_t sender,
+ ffa_vm_id_t dest,
+ uint64_t value)
{
- smc_ret_values ret_values;
-
- /* Send a message to SP through direct messaging */
- ret_values = ffa_msg_send_direct_req(HYP_ID, sp_id, test_pattern);
+ smc_ret_values ret;
+ ret = cactus_echo_send_cmd(sender, dest, value);
/*
* Return responses may be FFA_MSG_SEND_DIRECT_RESP or FFA_INTERRUPT,
* but only expect the former. Expect SMC32 convention from SP.
*/
- if (ffa_func_id(ret_values) != FFA_MSG_SEND_DIRECT_RESP_SMC32) {
- tftf_testcase_printf("ffa_msg_send_direct_req returned %x\n",
- ffa_func_id(ret_values));
+ if (!is_ffa_direct_response(ret)) {
return TEST_RESULT_FAIL;
}
- /*
- * Message loop in SP returns initial message with the running VM id
- * into the lower 16 bits of initial message.
- */
- if (ret_values.ret3 != (test_pattern | sp_id)) {
+ if (cactus_get_response(ret) != CACTUS_SUCCESS ||
+ cactus_echo_get_val(ret) != value) {
+ ERROR("Echo Failed!\n");
return TEST_RESULT_FAIL;
}
@@ -67,7 +58,7 @@ test_result_t test_ffa_direct_messaging(void)
/**********************************************************************
* Send a message to SP1 through direct messaging
**********************************************************************/
- result = send_receive_direct_msg(SP_ID(1), DIRECT_MSG_TEST_PATTERN1);
+ result = send_cactus_echo_cmd(HYP_ID, SP_ID(1), ECHO_VAL1);
if (result != TEST_RESULT_SUCCESS) {
return result;
}
@@ -75,7 +66,7 @@ test_result_t test_ffa_direct_messaging(void)
/**********************************************************************
* Send a message to SP2 through direct messaging
**********************************************************************/
- result = send_receive_direct_msg(SP_ID(2), DIRECT_MSG_TEST_PATTERN2);
+ result = send_cactus_echo_cmd(HYP_ID, SP_ID(2), ECHO_VAL2);
if (result != TEST_RESULT_SUCCESS) {
return result;
}
@@ -83,7 +74,7 @@ test_result_t test_ffa_direct_messaging(void)
/**********************************************************************
* Send a message to SP1 through direct messaging
**********************************************************************/
- result = send_receive_direct_msg(SP_ID(1), DIRECT_MSG_TEST_PATTERN3);
+ result = send_cactus_echo_cmd(HYP_ID, SP_ID(1), ECHO_VAL3);
return result;
}
@@ -105,9 +96,7 @@ static test_result_t send_cactus_req_echo_cmd(ffa_vm_id_t sender,
ret = cactus_req_echo_send_cmd(sender, dest, echo_dest, value);
- if (ffa_func_id(ret) != FFA_MSG_SEND_DIRECT_RESP_SMC32) {
- ERROR("Failed to send message. error: %x\n",
- ffa_error_code(ret));
+ if (!is_ffa_direct_response(ret)) {
return TEST_RESULT_FAIL;
}
@@ -157,9 +146,7 @@ test_result_t test_ffa_sp_to_sp_deadlock(void)
ret = cactus_req_deadlock_send_cmd(HYP_ID, SP_ID(1), SP_ID(2), SP_ID(3));
- if (ffa_func_id(ret) != FFA_MSG_SEND_DIRECT_RESP_SMC32) {
- ERROR("Failed to send message. error: %x\n",
- ffa_error_code(ret));
+ if (!is_ffa_direct_response(ret)) {
return TEST_RESULT_FAIL;
}
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 05a8b591..f126c57d 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
@@ -10,6 +10,7 @@
#include <ffa_endpoints.h>
#include <test_helpers.h>
#include <tftf_lib.h>
+#include <spm_common.h>
#include <xlat_tables_defs.h>
#define MAILBOX_SIZE PAGE_SIZE
@@ -63,7 +64,7 @@ static test_result_t test_memory_send_sp(uint32_t mem_func)
const uint32_t constituents_count = sizeof(constituents) /
sizeof(struct ffa_memory_region_constituent);
- handle = ffa_memory_init_and_send((struct ffa_memory_region *)mb.send,
+ handle = memory_init_and_send((struct ffa_memory_region *)mb.send,
MAILBOX_SIZE, SENDER, RECEIVER,
constituents, constituents_count,
mem_func);
@@ -79,9 +80,7 @@ static test_result_t test_memory_send_sp(uint32_t mem_func)
ret = cactus_mem_send_cmd(SENDER, RECEIVER, mem_func, handle);
- if (ffa_func_id(ret) != FFA_MSG_SEND_DIRECT_RESP_SMC32) {
- ERROR("Failed to send message. error: %x\n",
- ffa_error_code(ret));
+ if (!is_ffa_direct_response(ret)) {
return TEST_RESULT_FAIL;
}
@@ -103,7 +102,7 @@ static test_result_t test_memory_send_sp(uint32_t mem_func)
(void)ptr;
if (mem_func != FFA_MEM_DONATE_SMC32 &&
- ffa_mem_reclaim(handle, 0).ret0 == FFA_ERROR) {
+ is_ffa_call_error(ffa_mem_reclaim(handle, 0))) {
tftf_testcase_printf("Couldn't reclaim memory\n");
return TEST_RESULT_FAIL;
}
@@ -144,9 +143,7 @@ static test_result_t test_req_mem_send_sp_to_sp(uint32_t mem_func,
ret = cactus_req_mem_send_send_cmd(HYP_ID, sender_sp, mem_func,
receiver_sp);
- if (ffa_func_id(ret) != FFA_MSG_SEND_DIRECT_RESP_SMC32) {
- ERROR("Failed to send message. error: %x\n",
- ffa_error_code(ret));
+ if (!is_ffa_direct_response(ret)) {
return TEST_RESULT_FAIL;
}
diff --git a/tftf/tests/runtime_services/secure_service/test_spm_cpu_features.c b/tftf/tests/runtime_services/secure_service/test_spm_cpu_features.c
index c6470c14..f57fa243 100644
--- a/tftf/tests/runtime_services/secure_service/test_spm_cpu_features.c
+++ b/tftf/tests/runtime_services/secure_service/test_spm_cpu_features.c
@@ -55,9 +55,7 @@ test_result_t test_simd_vectors_preserved(void)
smc_ret_values ret = cactus_req_simd_fill_send_cmd(SENDER, RECEIVER);
- if (ffa_func_id(ret) != FFA_MSG_SEND_DIRECT_RESP_SMC32) {
- ERROR("Failed to send message. error: %x\n",
- ffa_error_code(ret));
+ if (!is_ffa_direct_response(ret)) {
return TEST_RESULT_FAIL;
}