aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorImre Kis <imre.kis@arm.com>2021-02-09 19:05:27 +0100
committerGyörgy Szing <gyorgy.szing@arm.com>2021-07-02 13:58:01 +0200
commitc674b5b698d149b5d042ea8f4aa46c303f55df83 (patch)
tree60d2e818a33a442b43162b4cfdfb5fd4e5a0d217
parenta30e77ce06bde1990bd3b7a8df469bfc499cee32 (diff)
downloadtrusted-services-c674b5b698d149b5d042ea8f4aa46c303f55df83.tar.gz
libsp: Add SP messaging layer
Add SP messaging layer on top of FF-A's direct messaging functions. Change-Id: I70f053c17f20bdb25b6f86a26d185fb3143fcc0d Signed-off-by: Imre Kis <imre.kis@arm.com>
-rw-r--r--components/messaging/ffa/libsp/component.cmake2
-rw-r--r--components/messaging/ffa/libsp/include/sp_messaging.h64
-rw-r--r--components/messaging/ffa/libsp/sp_messaging.c127
-rw-r--r--components/messaging/ffa/libsp/test/test_sp_messaging.cpp241
-rw-r--r--components/messaging/ffa/libsp/tests.cmake13
5 files changed, 447 insertions, 0 deletions
diff --git a/components/messaging/ffa/libsp/component.cmake b/components/messaging/ffa/libsp/component.cmake
index a72e01c30..2fec443c9 100644
--- a/components/messaging/ffa/libsp/component.cmake
+++ b/components/messaging/ffa/libsp/component.cmake
@@ -15,6 +15,7 @@ target_sources(${TGT} PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/ffa_memory_descriptors.c"
"${CMAKE_CURRENT_LIST_DIR}/sp_discovery.c"
"${CMAKE_CURRENT_LIST_DIR}/sp_memory_management.c"
+ "${CMAKE_CURRENT_LIST_DIR}/sp_messaging.c"
"${CMAKE_CURRENT_LIST_DIR}/sp_rxtx.c"
)
@@ -29,6 +30,7 @@ set_property(TARGET ${TGT} PROPERTY PUBLIC_HEADER
${CMAKE_CURRENT_LIST_DIR}/include/sp_api_types.h
${CMAKE_CURRENT_LIST_DIR}/include/sp_discovery.h
${CMAKE_CURRENT_LIST_DIR}/include/sp_memory_management.h
+ ${CMAKE_CURRENT_LIST_DIR}/include/sp_messaging.h
${CMAKE_CURRENT_LIST_DIR}/include/sp_rxtx.h
)
diff --git a/components/messaging/ffa/libsp/include/sp_messaging.h b/components/messaging/ffa/libsp/include/sp_messaging.h
new file mode 100644
index 000000000..3ee5aae83
--- /dev/null
+++ b/components/messaging/ffa/libsp/include/sp_messaging.h
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ */
+
+#ifndef LIBSP_INCLUDE_SP_MESSAGING_H_
+#define LIBSP_INCLUDE_SP_MESSAGING_H_
+
+#include "sp_api_defines.h"
+#include "sp_api_types.h"
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SP_MSG_ARG_COUNT (4)
+
+/**
+ * @brief SP message type
+ */
+struct sp_msg {
+ uint16_t source_id;
+ uint16_t destination_id;
+ uint32_t args[SP_MSG_ARG_COUNT];
+};
+
+/**
+ * @brief Wait for a message and returns it.
+ * @param[out] msg The received message
+ *
+ * @return The SP API result
+ */
+sp_result sp_msg_wait(struct sp_msg *msg);
+
+/**
+ * @brief Sends a request message and waits for the response message
+ * which it returns then.
+ *
+ * @param[in] req The request message
+ * @param[out] resp The response message
+ *
+ * @return The SP API result
+ */
+sp_result sp_msg_send_direct_req(const struct sp_msg *req, struct sp_msg *resp);
+
+/**
+ * @brief Sends a response message and waits for a new request which it
+ * returns then.
+ *
+ * @param[in] resp The response message
+ * @param[out] req The request message
+ *
+ * @return The SP API result
+ */
+sp_result sp_msg_send_direct_resp(const struct sp_msg *resp,
+ struct sp_msg *req);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBSP_INCLUDE_SP_MESSAGING_H_ */
diff --git a/components/messaging/ffa/libsp/sp_messaging.c b/components/messaging/ffa/libsp/sp_messaging.c
new file mode 100644
index 000000000..9e2938454
--- /dev/null
+++ b/components/messaging/ffa/libsp/sp_messaging.c
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ */
+
+#include "ffa_api.h"
+#include "sp_api_defines.h"
+#include "sp_messaging.h"
+
+#include <string.h>
+
+#define SP_MSG_ARG_OFFSET (1)
+
+static void pack_ffa_direct_msg(const struct sp_msg *msg,
+ struct ffa_direct_msg *ffa_msg)
+{
+ uint32_t i = 0;
+
+ ffa_msg->source_id = msg->source_id;
+ ffa_msg->destination_id = msg->destination_id;
+
+ ffa_msg->args[0] = 0;
+ memcpy(&ffa_msg->args[SP_MSG_ARG_OFFSET], msg->args, sizeof(msg->args));
+}
+
+static void unpack_ffa_direct_msg(const struct ffa_direct_msg *ffa_msg,
+ struct sp_msg *msg)
+{
+ uint32_t i = 0;
+
+ if (ffa_msg->function_id != FFA_SUCCESS_32) {
+ /*
+ * Handling request or response (error is handled before call)
+ */
+ msg->source_id = ffa_msg->source_id;
+ msg->destination_id = ffa_msg->destination_id;
+
+ memcpy(msg->args, &ffa_msg->args[SP_MSG_ARG_OFFSET],
+ sizeof(msg->args));
+ } else {
+ /* Success has no message parameters */
+ *msg = (struct sp_msg){ 0 };
+ }
+}
+
+sp_result sp_msg_wait(struct sp_msg *msg)
+{
+ ffa_result ffa_res = FFA_OK;
+ struct ffa_direct_msg ffa_msg = { 0 };
+
+ if (!msg)
+ return SP_RESULT_INVALID_PARAMETERS;
+
+ ffa_res = ffa_msg_wait(&ffa_msg);
+ if (ffa_res != FFA_OK) {
+ *msg = (struct sp_msg){ 0 };
+ return SP_RESULT_FFA(ffa_res);
+ }
+
+ unpack_ffa_direct_msg(&ffa_msg, msg);
+
+ return SP_RESULT_OK;
+}
+
+sp_result sp_msg_send_direct_req(const struct sp_msg *req, struct sp_msg *resp)
+{
+ ffa_result ffa_res = FFA_OK;
+ struct ffa_direct_msg ffa_req = { 0 };
+ struct ffa_direct_msg ffa_resp = { 0 };
+
+ if (!resp)
+ return SP_RESULT_INVALID_PARAMETERS;
+
+ if (!req) {
+ *resp = (struct sp_msg){ 0 };
+ return SP_RESULT_INVALID_PARAMETERS;
+ }
+
+ pack_ffa_direct_msg(req, &ffa_req);
+
+ ffa_res = ffa_msg_send_direct_req(ffa_req.source_id,
+ ffa_req.destination_id,
+ ffa_req.args[0], ffa_req.args[1],
+ ffa_req.args[2], ffa_req.args[3],
+ ffa_req.args[4], &ffa_resp);
+
+ if (ffa_res != FFA_OK) {
+ *resp = (struct sp_msg){ 0 };
+ return SP_RESULT_FFA(ffa_res);
+ }
+
+ unpack_ffa_direct_msg(&ffa_resp, resp);
+
+ return SP_RESULT_OK;
+}
+
+sp_result sp_msg_send_direct_resp(const struct sp_msg *resp, struct sp_msg *req)
+{
+ ffa_result ffa_res = FFA_OK;
+ struct ffa_direct_msg ffa_resp = { 0 };
+ struct ffa_direct_msg ffa_req = { 0 };
+
+ if (!req)
+ return SP_RESULT_INVALID_PARAMETERS;
+
+ if (!resp) {
+ *req = (struct sp_msg){ 0 };
+ return SP_RESULT_INVALID_PARAMETERS;
+ }
+
+ pack_ffa_direct_msg(resp, &ffa_resp);
+
+ ffa_res = ffa_msg_send_direct_resp(ffa_resp.source_id,
+ ffa_resp.destination_id,
+ ffa_resp.args[0], ffa_resp.args[1],
+ ffa_resp.args[2], ffa_resp.args[3],
+ ffa_resp.args[4], &ffa_req);
+
+ if (ffa_res != FFA_OK) {
+ *req = (struct sp_msg){ 0 };
+ return SP_RESULT_FFA(ffa_res);
+ }
+
+ unpack_ffa_direct_msg(&ffa_req, req);
+
+ return SP_RESULT_OK;
+}
diff --git a/components/messaging/ffa/libsp/test/test_sp_messaging.cpp b/components/messaging/ffa/libsp/test/test_sp_messaging.cpp
new file mode 100644
index 000000000..2ddf1ab62
--- /dev/null
+++ b/components/messaging/ffa/libsp/test/test_sp_messaging.cpp
@@ -0,0 +1,241 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ */
+
+#include <CppUTest/TestHarness.h>
+#include <CppUTestExt/MockSupport.h>
+#include <stdint.h>
+#include <string.h>
+#include "mock_ffa_api.h"
+#include "../include/sp_messaging.h"
+
+#define SP_MSG_ARG_OFFSET (1)
+
+TEST_GROUP(sp_messaging)
+{
+ TEST_SETUP()
+ {
+ memset(&req, 0x00, sizeof(req));
+ memset(&resp, 0x00, sizeof(resp));
+ memset(&ffa_msg, 0x00, sizeof(ffa_msg));
+ }
+
+ TEST_TEARDOWN()
+ {
+ mock().checkExpectations();
+ mock().clear();
+ }
+
+ void copy_sp_to_ffa_args(const uint32_t sp_args[], uint32_t ffa_args[])
+ {
+ int i = 0;
+
+ for (i = 0; i < SP_MSG_ARG_COUNT; i++) {
+ ffa_args[i + SP_MSG_ARG_OFFSET] = sp_args[i];
+ }
+ }
+
+ void fill_ffa_msg(struct ffa_direct_msg * msg)
+ {
+ int i = 0;
+
+ msg->function_id = FFA_MSG_SEND_DIRECT_REQ_32;
+ msg->source_id = source_id;
+ msg->destination_id = dest_id;
+
+ msg->args[0] = 0;
+ for (i = 0; i < SP_MSG_ARG_COUNT; i++) {
+ msg->args[i + SP_MSG_ARG_OFFSET] = args[i];
+ }
+ }
+
+ void fill_sp_msg(struct sp_msg * msg)
+ {
+ int i = 0;
+
+ msg->source_id = source_id;
+ msg->destination_id = dest_id;
+ for (i = 0; i < SP_MSG_ARG_COUNT; i++) {
+ msg->args[i] = args[i + SP_MSG_ARG_OFFSET];
+ }
+ }
+
+ void ffa_and_sp_msg_equal(const struct ffa_direct_msg *ffa_msg,
+ const struct sp_msg *sp_msg)
+ {
+ int i = 0;
+
+ UNSIGNED_LONGS_EQUAL(ffa_msg->source_id, sp_msg->source_id);
+ UNSIGNED_LONGS_EQUAL(ffa_msg->destination_id,
+ sp_msg->destination_id);
+ for (i = 0; i < SP_MSG_ARG_COUNT; i++) {
+ UNSIGNED_LONGS_EQUAL(
+ ffa_msg->args[i + SP_MSG_ARG_OFFSET],
+ sp_msg->args[i]);
+ }
+ }
+
+ struct sp_msg req;
+ struct sp_msg resp;
+ struct ffa_direct_msg ffa_msg;
+
+ const uint16_t source_id = 0x1234;
+ const uint16_t dest_id = 0x5678;
+ const uint32_t args[SP_MSG_ARG_COUNT] = { 0x01234567, 0x12345678,
+ 0x23456789, 0x3456789a };
+ const sp_result result = -1;
+ const sp_msg empty_sp_msg = (const sp_msg){ 0 };
+};
+
+TEST(sp_messaging, sp_msg_wait_null_msg)
+{
+ LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, sp_msg_wait(NULL));
+}
+
+TEST(sp_messaging, sp_msg_wait_ffa_error)
+{
+ ffa_result result = FFA_ABORTED;
+
+ expect_ffa_msg_wait(&ffa_msg, result);
+
+ LONGS_EQUAL(SP_RESULT_FFA(result), sp_msg_wait(&req));
+ MEMCMP_EQUAL(&empty_sp_msg, &req, sizeof(empty_sp_msg));
+}
+
+TEST(sp_messaging, sp_msg_wait)
+{
+ fill_ffa_msg(&ffa_msg);
+ expect_ffa_msg_wait(&ffa_msg, FFA_OK);
+
+ LONGS_EQUAL(SP_RESULT_OK, sp_msg_wait(&req));
+ ffa_and_sp_msg_equal(&ffa_msg, &req);
+}
+
+TEST(sp_messaging, sp_msg_send_direct_req_resp_null)
+{
+ LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS,
+ sp_msg_send_direct_req(&req, NULL));
+}
+
+TEST(sp_messaging, sp_msg_send_direct_req_req_null)
+{
+ memset(&resp, 0x5a, sizeof(resp));
+ LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS,
+ sp_msg_send_direct_req(NULL, &resp));
+ MEMCMP_EQUAL(&empty_sp_msg, &resp, sizeof(empty_sp_msg));
+}
+
+TEST(sp_messaging, sp_msg_send_direct_req_ffa_error)
+{
+ ffa_result result = FFA_ABORTED;
+ uint32_t expected_ffa_args[5] = { 0 };
+
+ fill_sp_msg(&req);
+ memset(&resp, 0x5a, sizeof(resp));
+ copy_sp_to_ffa_args(req.args, expected_ffa_args);
+ expect_ffa_msg_send_direct_req(
+ req.source_id, req.destination_id, expected_ffa_args[0],
+ expected_ffa_args[1], expected_ffa_args[2],
+ expected_ffa_args[3], expected_ffa_args[4], &ffa_msg, result);
+
+ LONGS_EQUAL(SP_RESULT_FFA(result), sp_msg_send_direct_req(&req, &resp));
+ MEMCMP_EQUAL(&empty_sp_msg, &resp, sizeof(empty_sp_msg));
+}
+
+TEST(sp_messaging, sp_msg_send_direct_req_msg)
+{
+ uint32_t expected_ffa_args[5] = { 0 };
+
+ fill_sp_msg(&req);
+ fill_ffa_msg(&ffa_msg);
+ copy_sp_to_ffa_args(req.args, expected_ffa_args);
+ expect_ffa_msg_send_direct_req(
+ req.source_id, req.destination_id, expected_ffa_args[0],
+ expected_ffa_args[1], expected_ffa_args[2],
+ expected_ffa_args[3], expected_ffa_args[4], &ffa_msg, FFA_OK);
+
+ LONGS_EQUAL(SP_RESULT_OK, sp_msg_send_direct_req(&req, &resp));
+ ffa_and_sp_msg_equal(&ffa_msg, &resp);
+}
+
+TEST(sp_messaging, sp_msg_send_direct_req_success)
+{
+ uint32_t expected_ffa_args[5] = { 0 };
+
+ fill_sp_msg(&req);
+ ffa_msg.function_id = FFA_SUCCESS_32;
+ copy_sp_to_ffa_args(req.args, expected_ffa_args);
+ expect_ffa_msg_send_direct_req(
+ req.source_id, req.destination_id, expected_ffa_args[0],
+ expected_ffa_args[1], expected_ffa_args[2],
+ expected_ffa_args[3], expected_ffa_args[4], &ffa_msg, FFA_OK);
+
+ LONGS_EQUAL(SP_RESULT_OK, sp_msg_send_direct_req(&req, &resp));
+ MEMCMP_EQUAL(&empty_sp_msg, &resp, sizeof(empty_sp_msg));
+}
+
+TEST(sp_messaging, sp_msg_send_direct_resp_req_null)
+{
+ LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS,
+ sp_msg_send_direct_resp(&resp, NULL));
+}
+
+TEST(sp_messaging, sp_msg_send_direct_resp_resp_null)
+{
+ memset(&req, 0x5a, sizeof(req));
+ LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS,
+ sp_msg_send_direct_resp(NULL, &req));
+ MEMCMP_EQUAL(&empty_sp_msg, &req, sizeof(empty_sp_msg));
+}
+
+TEST(sp_messaging, sp_msg_send_direct_resp_ffa_error)
+{
+ ffa_result result = FFA_ABORTED;
+ uint32_t expected_ffa_args[5] = { 0 };
+
+ fill_sp_msg(&resp);
+ memset(&req, 0x5a, sizeof(req));
+ copy_sp_to_ffa_args(resp.args, expected_ffa_args);
+ expect_ffa_msg_send_direct_resp(
+ resp.source_id, resp.destination_id, expected_ffa_args[0],
+ expected_ffa_args[1], expected_ffa_args[2],
+ expected_ffa_args[3], expected_ffa_args[4], &ffa_msg, result);
+
+ LONGS_EQUAL(SP_RESULT_FFA(result),
+ sp_msg_send_direct_resp(&resp, &req));
+ MEMCMP_EQUAL(&empty_sp_msg, &req, sizeof(empty_sp_msg));
+}
+
+TEST(sp_messaging, sp_msg_send_direct_resp_msg)
+{
+ uint32_t expected_ffa_args[5] = { 0 };
+
+ fill_sp_msg(&resp);
+ fill_ffa_msg(&ffa_msg);
+ copy_sp_to_ffa_args(resp.args, expected_ffa_args);
+ expect_ffa_msg_send_direct_resp(
+ resp.source_id, resp.destination_id, expected_ffa_args[0],
+ expected_ffa_args[1], expected_ffa_args[2],
+ expected_ffa_args[3], expected_ffa_args[4], &ffa_msg, FFA_OK);
+
+ LONGS_EQUAL(SP_RESULT_OK, sp_msg_send_direct_resp(&resp, &req));
+ ffa_and_sp_msg_equal(&ffa_msg, &req);
+}
+
+TEST(sp_messaging, sp_msg_send_direct_resp_success)
+{
+ uint32_t expected_ffa_args[5] = { 0 };
+
+ fill_sp_msg(&req);
+ fill_sp_msg(&resp);
+ ffa_msg.function_id = FFA_SUCCESS_32;
+ copy_sp_to_ffa_args(resp.args, expected_ffa_args);
+ expect_ffa_msg_send_direct_resp(
+ resp.source_id, resp.destination_id, expected_ffa_args[0],
+ expected_ffa_args[1], expected_ffa_args[2],
+ expected_ffa_args[3], expected_ffa_args[4], &ffa_msg, FFA_OK);
+
+ LONGS_EQUAL(SP_RESULT_OK, sp_msg_send_direct_resp(&resp, &req));
+ MEMCMP_EQUAL(&empty_sp_msg, &req, sizeof(empty_sp_msg));
+}
diff --git a/components/messaging/ffa/libsp/tests.cmake b/components/messaging/ffa/libsp/tests.cmake
index 165803348..092aceff3 100644
--- a/components/messaging/ffa/libsp/tests.cmake
+++ b/components/messaging/ffa/libsp/tests.cmake
@@ -126,3 +126,16 @@ unit_test_add_suite(
COMPILE_DEFINITIONS
-DARM64
)
+
+unit_test_add_suite(
+ NAME libsp_sp_messaging
+ SOURCES
+ ${CMAKE_CURRENT_LIST_DIR}/test/test_sp_messaging.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/test/mock_ffa_api.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/sp_messaging.c
+ INCLUDE_DIRECTORIES
+ ${CMAKE_CURRENT_LIST_DIR}/include/
+ ${UNIT_TEST_PROJECT_PATH}/components/common/utils/include
+ COMPILE_DEFINITIONS
+ -DARM64
+) \ No newline at end of file