summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--spm/cactus/cactus_main.c2
-rw-r--r--spm/common/sp_tests/sp_test_ffa.c230
-rw-r--r--spm/common/sp_tests/sp_tests.h2
-rw-r--r--spm/ivy/app/ivy_main.c2
4 files changed, 232 insertions, 4 deletions
diff --git a/spm/cactus/cactus_main.c b/spm/cactus/cactus_main.c
index 9d40caf..1e46025 100644
--- a/spm/cactus/cactus_main.c
+++ b/spm/cactus/cactus_main.c
@@ -323,7 +323,7 @@ void __dead2 cactus_main(bool primary_cold_boot,
register_maintenance_interrupt_handlers();
/* Invoking Tests */
- ffa_tests(&mb);
+ ffa_tests(&mb, ffa_id);
msg_loop:
/* End up to message loop */
diff --git a/spm/common/sp_tests/sp_test_ffa.c b/spm/common/sp_tests/sp_test_ffa.c
index 73db187..c26db44 100644
--- a/spm/common/sp_tests/sp_test_ffa.c
+++ b/spm/common/sp_tests/sp_test_ffa.c
@@ -14,6 +14,8 @@
#include <spm_helpers.h>
#include <spm_common.h>
#include <lib/libc/string.h>
+#include <xlat_tables_defs.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
/* FFA version test helpers */
#define FFA_MAJOR 1U
@@ -252,7 +254,232 @@ void ffa_spm_id_get_test(void)
}
}
-void ffa_tests(struct mailbox_buffers *mb)
+static const struct ffa_uuid scmi_uuid = {TERTIARY_UUID};
+static const struct ffa_partition_info ffa_expected_scmi_info =
+ {
+ .id = SP_ID(3),
+ .exec_context = TERTIARY_EXEC_CTX_COUNT,
+ .properties = (FFA_PARTITION_AARCH64_EXEC |
+ FFA_PARTITION_DIRECT_REQ_RECV |
+ FFA_PARTITION_DIRECT_REQ_SEND |
+ FFA_PARTITION_NOTIFICATION),
+ .uuid = {TERTIARY_UUID}
+ };
+
+enum scmi_ffa_pta_cmd {
+ /*
+ * FFA_SCMI_CMD_CAPABILITIES - Get channel capabilities
+ *
+ * [out] data0: Cmd FFA_SCMI_CMD_CAPABILITIES
+ * [in] data1: Capability bit mask
+ */
+ FFA_SCMI_CMD_CAPABILITIES = 0,
+
+ /*
+ * FFA_SCMI_CMD_GET_CHANNEL - Get channel handle
+ *
+ * [out] data0: Cmd FFA_SCMI_CMD_GET_CHANNEL
+ * [out] data1: Channel identifier
+ * [in] data1: Returned channel handle
+ * [out] data2: Shared memory handle (optional)
+ */
+ FFA_SCMI_CMD_GET_CHANNEL = 1,
+
+ /*
+ * FFA_SCMI_CMD_MSG_SEND_DIRECT_REQ - Process direct SCMI message
+ * with shared memory
+ *
+ * [out] data0: Cmd FFA_SCMI_CMD_MSG_SEND_DIRECT_REQ
+ * [out] data1: Channel handle
+ * [in/out] data2: Response size
+ *
+ */
+ FFA_SCMI_CMD_MSG_SEND_DIRECT_REQ = 2,
+
+ /*
+ * FFA_SCMI_CMD_SEND_MSG2 - Process SCMI message in RXTX buffer
+ *
+ * Use FFA RX/TX message to exchange request with the SCMI server.
+ */
+ FFA_SCMI_CMD_MSG_SEND2 = 3,
+};
+
+#ifdef PLAT_XLAT_TABLES_DYNAMIC
+/**
+ * Each Cactus SP has a memory region dedicated to memory sharing tests
+ * described in their partition manifest.
+ * This function returns the expected base address depending on the
+ * SP ID (should be the same as the manifest).
+ */
+static void *share_page(ffa_id_t cactus_sp_id)
+{
+ switch (cactus_sp_id) {
+ case SP_ID(1):
+ return (void *)CACTUS_SP1_MEM_SHARE_BASE;
+ case SP_ID(2):
+ return (void *)CACTUS_SP2_MEM_SHARE_BASE;
+ case SP_ID(3):
+ return (void *)CACTUS_SP3_MEM_SHARE_BASE;
+ default:
+ ERROR("Helper function expecting a valid Cactus SP ID!\n");
+ panic();
+ }
+}
+
+static void *share_page_non_secure(ffa_id_t cactus_sp_id)
+{
+ if (cactus_sp_id != SP_ID(3)) {
+ ERROR("Helper function expecting a valid Cactus SP ID!\n");
+ panic();
+ }
+
+ return (void *)CACTUS_SP3_NS_MEM_SHARE_BASE;
+}
+
+ffa_memory_handle_t ffa_scmi_share_memory(struct mailbox_buffers *mb, ffa_id_t source, ffa_id_t dest)
+{
+ struct ffa_value ffa_ret;
+ uint32_t mem_func = FFA_MEM_SHARE_SMC32;
+ ffa_memory_handle_t handle;
+ bool non_secure = false;
+ void *share_page_addr =
+ non_secure ? share_page_non_secure(source) : share_page(source);
+ unsigned int mem_attrs;
+ int ret;
+
+ VERBOSE("%x requested to send memory to %x (func: %x), page: %llx\n",
+ source, dest, mem_func, (uint64_t)share_page_addr);
+
+ const struct ffa_memory_region_constituent constituents[] = {
+ {share_page_addr, 1, 0}
+ };
+
+ const uint32_t constituents_count = (sizeof(constituents) /
+ sizeof(constituents[0]));
+
+ VERBOSE("Sharing at 0x%llx\n", (uint64_t)constituents[0].address);
+ mem_attrs = MT_RW_DATA;
+
+ if (non_secure) {
+ mem_attrs |= MT_NS;
+ }
+
+ ret = mmap_add_dynamic_region(
+ (uint64_t)constituents[0].address,
+ (uint64_t)constituents[0].address,
+ constituents[0].page_count * PAGE_SIZE,
+ mem_attrs);
+
+ if (ret != 0) {
+ ERROR("Failed map share memory before sending (%d)!\n",
+ ret);
+ return 0;
+ }
+
+ handle = memory_init_and_send(
+ (struct ffa_memory_region *)mb->send, PAGE_SIZE,
+ source, dest, constituents,
+ constituents_count, mem_func, &ffa_ret);
+
+ return handle;
+}
+#else
+ffa_memory_handle_t ffa_scmi_share_memory(struct mailbox_buffers *mb, ffa_id_t source, ffa_id_t dest)
+{
+ return 0;
+}
+
+static void *share_page(ffa_id_t cactus_sp_id)
+{
+ return NULL;
+}
+#endif
+
+struct scmi_msg_payld {
+ uint32_t msg_header;
+ uint32_t msg_payload[];
+};
+
+void ffa_scmi_server_test(struct mailbox_buffers *mb, ffa_id_t source_id)
+{
+ ffa_id_t dest_id;
+ uint64_t cmd, val0, val1, val2, val3;
+ struct ffa_value ret;
+ ffa_memory_handle_t mem_id;
+ uint32_t channel_id;
+ struct scmi_msg_payld *share_page_addr;
+
+ INFO("Test SCMI server partition\n");
+ if (ffa_partition_info_helper(mb, scmi_uuid, &ffa_expected_scmi_info, 1))
+ INFO("SCMI server partition is present\n");
+ else
+ return;
+
+ dest_id = ffa_expected_scmi_info.id;
+
+ cmd = FFA_SCMI_CMD_CAPABILITIES;
+ val0 = val1 = val2 = val3 = 0;
+
+ ret = ffa_msg_send_direct_req64(source_id, dest_id, cmd, val0, val1, val2, val3);
+ if (!is_ffa_direct_response(ret)) {
+ INFO("SCMI server fails\n");
+ return;
+ }
+
+ INFO("SCMI server capabilities 0x%lx\n", ret.arg4);
+
+#ifndef PLAT_XLAT_TABLES_DYNAMIC
+ /* stop here because we can't dynamiccally map memory */
+ return;
+#endif
+
+ mem_id = ffa_scmi_share_memory(mb, source_id, dest_id);
+
+ cmd = FFA_SCMI_CMD_GET_CHANNEL;
+ val0 = 0;
+ val1 = mem_id;
+ val2 = val3 = 0;
+
+ ret = ffa_msg_send_direct_req64(source_id, dest_id, cmd, val0, val1, val2, val3);
+ if (!is_ffa_direct_response(ret)) {
+ INFO("SCMI server fails\n");
+ return;
+ }
+
+ channel_id = ret.arg4;
+ INFO("SCMI server channel id 0x%x\n", channel_id);
+
+ if (channel_id == 0xffffffff)
+ return;
+
+ cmd = FFA_SCMI_CMD_MSG_SEND_DIRECT_REQ;
+ val0 = channel_id;
+ val1 = 16;
+ val2 = val3 = 0;
+
+ /* 1-1 PA-VA mapping */
+ /* scmi header :
+ * token : [27:18]
+ * protocol_id : [17:10]
+ * message_type: [9:8]
+ * message_id : [7:0]
+ */
+ share_page_addr = share_page(source_id);
+ share_page_addr->msg_header = 0x10 << 10 | 0x3;
+
+ return;
+
+ ret = ffa_msg_send_direct_req64(source_id, dest_id, cmd, val0, val1, val2, val3);
+ if (!is_ffa_direct_response(ret)) {
+ INFO("SCMI server fails\n");
+ return;
+ }
+
+ INFO("SCMI server returned size 0x%lx\n", ret.arg5);
+
+}
+
+void ffa_tests(struct mailbox_buffers *mb, ffa_id_t my_ffa_id)
{
const char *test_ffa = "FF-A setup and discovery";
@@ -263,6 +490,7 @@ void ffa_tests(struct mailbox_buffers *mb)
ffa_spm_id_get_test();
ffa_partition_info_get_test(mb);
ffa_partition_info_get_regs_test();
+ ffa_scmi_server_test(mb, my_ffa_id);
announce_test_section_end(test_ffa);
}
diff --git a/spm/common/sp_tests/sp_tests.h b/spm/common/sp_tests/sp_tests.h
index 10d3b9b..7f1007b 100644
--- a/spm/common/sp_tests/sp_tests.h
+++ b/spm/common/sp_tests/sp_tests.h
@@ -13,6 +13,6 @@
* Test functions
*/
-void ffa_tests(struct mailbox_buffers *mb);
+void ffa_tests(struct mailbox_buffers *mb, ffa_id_t my_ffa_id);
#endif /* CACTUS_TESTS_H */
diff --git a/spm/ivy/app/ivy_main.c b/spm/ivy/app/ivy_main.c
index 1e2cd6a..5e06a32 100644
--- a/spm/ivy/app/ivy_main.c
+++ b/spm/ivy/app/ivy_main.c
@@ -47,7 +47,7 @@ init:
panic();
}
- ffa_tests(&mb);
+ ffa_tests(&mb, my_id);
ret = ffa_msg_wait();