diff options
author | Imre Kis <imre.kis@arm.com> | 2021-02-09 19:05:27 +0100 |
---|---|---|
committer | György Szing <gyorgy.szing@arm.com> | 2021-07-02 13:58:01 +0200 |
commit | c674b5b698d149b5d042ea8f4aa46c303f55df83 (patch) | |
tree | 60d2e818a33a442b43162b4cfdfb5fd4e5a0d217 | |
parent | a30e77ce06bde1990bd3b7a8df469bfc499cee32 (diff) | |
download | trusted-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.cmake | 2 | ||||
-rw-r--r-- | components/messaging/ffa/libsp/include/sp_messaging.h | 64 | ||||
-rw-r--r-- | components/messaging/ffa/libsp/sp_messaging.c | 127 | ||||
-rw-r--r-- | components/messaging/ffa/libsp/test/test_sp_messaging.cpp | 241 | ||||
-rw-r--r-- | components/messaging/ffa/libsp/tests.cmake | 13 |
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 |