aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorImre Kis <imre.kis@arm.com>2020-11-30 20:58:57 +0100
committerGy├Ârgy Szing <gyorgy.szing@arm.com>2021-02-02 10:00:13 +0000
commitbee52707b2771c89fb83fdb7fd25fd2571bdc526 (patch)
treebe1bbcbae7f3990d7309a33c05b55154a31eca2c
parent18dfa71212ab673dc7cd975a400c254228baa156 (diff)
downloadtrusted-services-bee52707b2771c89fb83fdb7fd25fd2571bdc526.tar.gz
libsp: Unit testing the functions of ffa_api.h
Testing the FF-A layer by mocking the FF-A SVC layer and validating calls and returned values. Signed-off-by: Imre Kis <imre.kis@arm.com> Change-Id: I544a5fa0b5eb1c72e3443ff7862dacee1b3e8097
-rw-r--r--components/messaging/ffa/libsp/test/test_ffa_api.cpp1166
-rw-r--r--components/messaging/ffa/libsp/tests.cmake13
2 files changed, 1179 insertions, 0 deletions
diff --git a/components/messaging/ffa/libsp/test/test_ffa_api.cpp b/components/messaging/ffa/libsp/test/test_ffa_api.cpp
new file mode 100644
index 0000000..5ab7c8a
--- /dev/null
+++ b/components/messaging/ffa/libsp/test/test_ffa_api.cpp
@@ -0,0 +1,1166 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ */
+
+#include <CppUTest/TestHarness.h>
+#include <CppUTestExt/MockSupport.h>
+#include <stdint.h>
+#include <string.h>
+#include "ffa_api.h"
+#include "mock_assert.h"
+#include "mock_ffa_internal_api.h"
+
+void expect_ffa_interrupt_handler(uint32_t id)
+{
+ mock().expectOneCall("ffa_interrupt_handler")
+ .withUnsignedIntParameter("id", id);
+}
+
+void ffa_interrupt_handler(uint32_t id)
+{
+ mock().actualCall("ffa_interrupt_handler")
+ .withUnsignedIntParameter("id", id);
+}
+
+TEST_GROUP(ffa_api)
+{
+ TEST_SETUP()
+ {
+ memset(&svc_result, 0x00, sizeof(svc_result));
+ memset(&msg, 0x00, sizeof(msg));
+ }
+
+ TEST_TEARDOWN()
+ {
+ mock().checkExpectations();
+ mock().clear();
+ }
+
+ void setup_error_response(int32_t error_code)
+ {
+ svc_result.a0 = 0x84000060;
+ svc_result.a2 = (uint32_t)error_code;
+ }
+
+ void msg_equal(uint32_t func_id, uint16_t source_id, uint16_t dest_id,
+ uint32_t arg0, uint32_t arg1, uint32_t arg2,
+ uint32_t arg3, uint32_t arg4)
+ {
+ UNSIGNED_LONGS_EQUAL(func_id, msg.function_id);
+ UNSIGNED_LONGS_EQUAL(source_id, msg.source_id);
+ UNSIGNED_LONGS_EQUAL(dest_id, msg.destination_id);
+ UNSIGNED_LONGS_EQUAL(arg0, msg.args[0]);
+ UNSIGNED_LONGS_EQUAL(arg1, msg.args[1]);
+ UNSIGNED_LONGS_EQUAL(arg2, msg.args[2]);
+ UNSIGNED_LONGS_EQUAL(arg3, msg.args[3]);
+ UNSIGNED_LONGS_EQUAL(arg4, msg.args[4]);
+ }
+
+ struct ffa_params svc_result;
+ struct ffa_direct_msg msg;
+};
+
+TEST(ffa_api, ffa_version)
+{
+ uint32_t version = 0;
+ const uint32_t test_version = 0x78901234;
+
+ svc_result.a0 = test_version;
+ expect_ffa_svc(0x84000063, 0x10000U, 0, 0, 0, 0, 0, 0, &svc_result);
+
+ ffa_result result = ffa_version(&version);
+ LONGS_EQUAL(FFA_OK, result);
+ UNSIGNED_LONGS_EQUAL(test_version, version);
+}
+
+TEST(ffa_api, ffa_version_error)
+{
+ uint32_t version = 0;
+
+ svc_result.a0 = 0xffffffff;
+ expect_ffa_svc(0x84000063, 0x10000U, 0, 0, 0, 0, 0, 0, &svc_result);
+
+ ffa_result result = ffa_version(&version);
+ LONGS_EQUAL(-1, result);
+ UNSIGNED_LONGS_EQUAL(0, version);
+}
+
+TEST(ffa_api, ffa_features)
+{
+ const uint32_t func_id = 0x11223344;
+ const uint32_t features0 = 0x01234567;
+ const uint32_t features1 = 0x89abcdef;
+ struct ffa_interface_properties properties = { 0xffffffff, 0xffffffff };
+
+ svc_result.a0 = 0x84000061;
+ svc_result.a2 = features0;
+ svc_result.a3 = features1;
+ expect_ffa_svc(0x84000064, func_id, 0, 0, 0, 0, 0, 0, &svc_result);
+
+ ffa_result result = ffa_features(func_id, &properties);
+ LONGS_EQUAL(0, result);
+ UNSIGNED_LONGS_EQUAL(features0, properties.interface_properties[0]);
+ UNSIGNED_LONGS_EQUAL(features1, properties.interface_properties[1]);
+}
+
+TEST(ffa_api, ffa_features_error)
+{
+ const uint32_t func_id = 0x11223344;
+ struct ffa_interface_properties properties = { 0xffffffff, 0xffffffff };
+
+ setup_error_response(-1);
+ expect_ffa_svc(0x84000064, func_id, 0, 0, 0, 0, 0, 0, &svc_result);
+
+ ffa_result result = ffa_features(func_id, &properties);
+ LONGS_EQUAL(-1, result);
+ UNSIGNED_LONGS_EQUAL(0, properties.interface_properties[0]);
+ UNSIGNED_LONGS_EQUAL(0, properties.interface_properties[1]);
+}
+
+TEST(ffa_api, ffa_features_unknown_response)
+{
+ const uint32_t func_id = 0x11223344;
+ struct ffa_interface_properties properties = { 0, 0 };
+ assert_environment_t assert_env;
+
+ svc_result.a0 = 0x12345678;
+ expect_ffa_svc(0x84000064, func_id, 0, 0, 0, 0, 0, 0, &svc_result);
+
+ if (SETUP_ASSERT_ENVIRONMENT(assert_env)) {
+ ffa_features(func_id, &properties);
+ }
+}
+
+TEST(ffa_api, ffa_rx_release)
+{
+ svc_result.a0 = 0x84000061;
+ expect_ffa_svc(0x84000065, 0, 0, 0, 0, 0, 0, 0, &svc_result);
+
+ ffa_result result = ffa_rx_release();
+ LONGS_EQUAL(FFA_OK, result);
+}
+
+TEST(ffa_api, ffa_rx_release_error)
+{
+ setup_error_response(-1);
+ expect_ffa_svc(0x84000065, 0, 0, 0, 0, 0, 0, 0, &svc_result);
+
+ ffa_result result = ffa_rx_release();
+ LONGS_EQUAL(-1, result);
+}
+
+TEST(ffa_api, ffa_rx_release_unknown_response)
+{
+ assert_environment_t assert_env;
+
+ svc_result.a0 = 0x12345678;
+ expect_ffa_svc(0x84000065, 0, 0, 0, 0, 0, 0, 0, &svc_result);
+
+ if (SETUP_ASSERT_ENVIRONMENT(assert_env)) {
+ ffa_rx_release();
+ }
+}
+
+TEST(ffa_api, ffa_rxtx_map)
+{
+ const uint64_t tx_buffer = 0xfedcba9876543210ULL;
+ const uint64_t rx_buffer = 0x0123456789abcdefULL;
+ const uint64_t page_count = (1 << 6) - 1;
+
+ svc_result.a0 = 0x84000061;
+ expect_ffa_svc(0x84000066, tx_buffer, rx_buffer, page_count, 0, 0, 0, 0,
+ &svc_result);
+
+ ffa_result result = ffa_rxtx_map((const void *)tx_buffer,
+ (const void *)rx_buffer, page_count);
+ LONGS_EQUAL(0, result);
+}
+
+TEST(ffa_api, ffa_rxtx_map_error)
+{
+ const uint64_t tx_buffer = 0xfedcba9876543210ULL;
+ const uint64_t rx_buffer = 0x0123456789abcdefULL;
+ const uint64_t page_count = (1 << 6) - 1;
+
+ setup_error_response(-1);
+ expect_ffa_svc(0x84000066, tx_buffer, rx_buffer, page_count, 0, 0, 0, 0,
+ &svc_result);
+
+ ffa_result result = ffa_rxtx_map((const void *)tx_buffer,
+ (const void *)rx_buffer, page_count);
+ LONGS_EQUAL(-1, result);
+}
+
+TEST(ffa_api, ffa_rxtx_map_unknown_response)
+{
+ const uint64_t tx_buffer = 0xfedcba9876543210ULL;
+ const uint64_t rx_buffer = 0x0123456789abcdefULL;
+ const uint64_t page_count = (1 << 6) - 1;
+ assert_environment_t assert_env;
+
+ svc_result.a0 = 0x12345678;
+ expect_ffa_svc(0x84000066, tx_buffer, rx_buffer, page_count, 0, 0, 0, 0,
+ &svc_result);
+
+ if (SETUP_ASSERT_ENVIRONMENT(assert_env)) {
+ ffa_rxtx_map((const void *)tx_buffer, (const void *)rx_buffer,
+ page_count);
+ }
+}
+
+TEST(ffa_api, ffa_rxtx_map_too_many_pages)
+{
+ const uint64_t tx_buffer = 0xfedcba9876543210ULL;
+ const uint64_t rx_buffer = 0x0123456789abcdefULL;
+ const uint64_t page_count = (1 << 6);
+ assert_environment_t assert_env;
+
+ svc_result.a0 = 0x12345678;
+
+ if (SETUP_ASSERT_ENVIRONMENT(assert_env)) {
+ ffa_rxtx_map((const void *)tx_buffer, (const void *)rx_buffer,
+ page_count);
+ }
+}
+
+TEST(ffa_api, ffa_rxtx_unmap)
+{
+ const uint16_t id = 0xffff;
+
+ svc_result.a0 = 0x84000061;
+ expect_ffa_svc(0x84000067, ((uint32_t)id) << 16, 0, 0, 0, 0, 0, 0,
+ &svc_result);
+
+ ffa_result result = ffa_rxtx_unmap(id);
+ LONGS_EQUAL(FFA_OK, result);
+}
+
+TEST(ffa_api, ffa_rxtx_unmap_error)
+{
+ const uint16_t id = 0xffff;
+
+ setup_error_response(-1);
+ expect_ffa_svc(0x84000067, ((uint32_t)id) << 16, 0, 0, 0, 0, 0, 0,
+ &svc_result);
+
+ ffa_result result = ffa_rxtx_unmap(id);
+ LONGS_EQUAL(-1, result);
+}
+
+TEST(ffa_api, ffa_rxtx_unmap_unknown_response)
+{
+ const uint16_t id = 0xffff;
+ assert_environment_t assert_env;
+
+ svc_result.a0 = 0x12345678;
+ expect_ffa_svc(0x84000067, ((uint32_t)id) << 16, 0, 0, 0, 0, 0, 0,
+ &svc_result);
+
+ if (SETUP_ASSERT_ENVIRONMENT(assert_env)) {
+ ffa_rxtx_unmap(id);
+ }
+}
+
+TEST(ffa_api, ffa_partition_info_get)
+{
+ const struct ffa_uuid uuid = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab,
+ 0xcd, 0xef, 0x12, 0x34, 0x56, 0x78,
+ 0x9a, 0xbc, 0xde, 0xf0 };
+ uint32_t count = 0;
+ const uint32_t count_result = 0xaabbccdd;
+
+ svc_result.a0 = 0x84000061;
+ svc_result.a2 = count_result;
+ expect_ffa_svc(0x84000068, 0x67452301, 0xefcdab89, 0x78563412,
+ 0xf0debc9a, 0, 0, 0, &svc_result);
+
+ ffa_result result = ffa_partition_info_get(&uuid, &count);
+ LONGS_EQUAL(FFA_OK, result);
+ UNSIGNED_LONGS_EQUAL(count_result, count);
+}
+
+TEST(ffa_api, ffa_partition_info_get_error)
+{
+ const struct ffa_uuid uuid = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab,
+ 0xcd, 0xef, 0x12, 0x34, 0x56, 0x78,
+ 0x9a, 0xbc, 0xde, 0xf0 };
+ uint32_t count = 0x1234;
+
+ setup_error_response(-1);
+ expect_ffa_svc(0x84000068, 0x67452301, 0xefcdab89, 0x78563412,
+ 0xf0debc9a, 0, 0, 0, &svc_result);
+
+ ffa_result result = ffa_partition_info_get(&uuid, &count);
+ LONGS_EQUAL(-1, result);
+ UNSIGNED_LONGS_EQUAL(0, count);
+}
+
+TEST(ffa_api, ffa_partition_info_get_unknown_response)
+{
+ const struct ffa_uuid uuid = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab,
+ 0xcd, 0xef, 0x12, 0x34, 0x56, 0x78,
+ 0x9a, 0xbc, 0xde, 0xf0 };
+ uint32_t count = 0;
+ const uint32_t count_result = 0xaabbccdd;
+ assert_environment_t assert_env;
+
+ svc_result.a0 = 0x12345678;
+ svc_result.a2 = count_result;
+ expect_ffa_svc(0x84000068, 0x67452301, 0xefcdab89, 0x78563412,
+ 0xf0debc9a, 0, 0, 0, &svc_result);
+
+ if (SETUP_ASSERT_ENVIRONMENT(assert_env)) {
+ ffa_partition_info_get(&uuid, &count);
+ }
+}
+
+TEST(ffa_api, ffa_id_get)
+{
+ uint16_t id = 0;
+ const uint16_t id_result = 0xfedc;
+
+ svc_result.a0 = 0x84000061;
+ svc_result.a2 = id_result;
+ expect_ffa_svc(0x84000069, 0, 0, 0, 0, 0, 0, 0, &svc_result);
+
+ ffa_result result = ffa_id_get(&id);
+ LONGS_EQUAL(FFA_OK, result);
+ UNSIGNED_LONGS_EQUAL(id_result, id);
+}
+
+TEST(ffa_api, ffa_id_get_error)
+{
+ uint16_t id = 0;
+
+ setup_error_response(-1);
+ expect_ffa_svc(0x84000069, 0, 0, 0, 0, 0, 0, 0, &svc_result);
+
+ ffa_result result = ffa_id_get(&id);
+ LONGS_EQUAL(-1, result);
+ UNSIGNED_LONGS_EQUAL(0xffff, id);
+}
+
+TEST(ffa_api, ffa_id_get_unknown_response)
+{
+ uint16_t id = 0xffff;
+ assert_environment_t assert_env;
+
+ svc_result.a0 = 0x12345678;
+ expect_ffa_svc(0x84000069, 0, 0, 0, 0, 0, 0, 0, &svc_result);
+
+ if (SETUP_ASSERT_ENVIRONMENT(assert_env)) {
+ ffa_id_get(&id);
+ }
+}
+
+TEST(ffa_api, ffa_msg_wait_success)
+{
+ svc_result.a0 = 0x84000061;
+ expect_ffa_svc(0x8400006B, 0, 0, 0, 0, 0, 0, 0, &svc_result);
+ ffa_result result = ffa_msg_wait(&msg);
+ LONGS_EQUAL(0, result);
+ msg_equal(0x84000061, 0, 0, 0, 0, 0, 0, 0);
+}
+
+TEST(ffa_api, ffa_msg_wait_error)
+{
+ setup_error_response(-1);
+ expect_ffa_svc(0x8400006B, 0, 0, 0, 0, 0, 0, 0, &svc_result);
+ ffa_result result = ffa_msg_wait(&msg);
+ LONGS_EQUAL(-1, result);
+ msg_equal(0, 0, 0, 0, 0, 0, 0, 0);
+}
+
+TEST(ffa_api, ffa_msg_wait_direct_req)
+{
+ const uint16_t source_id = 0x1122;
+ const uint16_t dest_id = 0x3344;
+ const uint32_t arg0 = 0x01234567ULL;
+ const uint32_t arg1 = 0x12345678ULL;
+ const uint32_t arg2 = 0x23456789ULL;
+ const uint32_t arg3 = 0x3456789aULL;
+ const uint32_t arg4 = 0x456789abULL;
+
+ svc_result.a0 = 0x8400006F;
+ svc_result.a1 = ((uint32_t)source_id) << 16 | dest_id;
+ svc_result.a3 = arg0;
+ svc_result.a4 = arg1;
+ svc_result.a5 = arg2;
+ svc_result.a6 = arg3;
+ svc_result.a7 = arg4;
+ expect_ffa_svc(0x8400006B, 0, 0, 0, 0, 0, 0, 0, &svc_result);
+ ffa_result result = ffa_msg_wait(&msg);
+ LONGS_EQUAL(0, result);
+ msg_equal(0x8400006F, source_id, dest_id, arg0, arg1, arg2, arg3,
+ arg4);
+}
+
+TEST(ffa_api, ffa_msg_wait_one_interrupt_success)
+{
+ const uint32_t interrupt_id = 0x12345678;
+ struct ffa_params interrupt_params;
+
+ interrupt_params.a0 = 0x84000062;
+ interrupt_params.a2 = interrupt_id;
+ expect_ffa_svc(0x8400006B, 0, 0, 0, 0, 0, 0, 0, &interrupt_params);
+ expect_ffa_interrupt_handler(interrupt_id);
+
+ svc_result.a0 = 0x84000061;
+ expect_ffa_svc(0x8400006B, 0, 0, 0, 0, 0, 0, 0, &svc_result);
+ ffa_result result = ffa_msg_wait(&msg);
+ LONGS_EQUAL(0, result);
+ msg_equal(0x84000061, 0, 0, 0, 0, 0, 0, 0);
+}
+
+TEST(ffa_api, ffa_msg_wait_two_interrupt_success)
+{
+ const uint32_t interrupt_id0 = 0x12345678;
+ const uint32_t interrupt_id1 = 0x81234567;
+ struct ffa_params interrupt_params0;
+ struct ffa_params interrupt_params1;
+
+ interrupt_params0.a0 = 0x84000062;
+ interrupt_params0.a2 = interrupt_id0;
+ expect_ffa_svc(0x8400006B, 0, 0, 0, 0, 0, 0, 0, &interrupt_params0);
+ expect_ffa_interrupt_handler(interrupt_id0);
+
+ interrupt_params1.a0 = 0x84000062;
+ interrupt_params1.a2 = interrupt_id1;
+ expect_ffa_svc(0x8400006B, 0, 0, 0, 0, 0, 0, 0, &interrupt_params1);
+ expect_ffa_interrupt_handler(interrupt_id1);
+
+ svc_result.a0 = 0x84000061;
+ expect_ffa_svc(0x8400006B, 0, 0, 0, 0, 0, 0, 0, &svc_result);
+ ffa_result result = ffa_msg_wait(&msg);
+ LONGS_EQUAL(0, result);
+ msg_equal(0x84000061, 0, 0, 0, 0, 0, 0, 0);
+}
+
+TEST(ffa_api, ffa_msg_wait_unknown_response)
+{
+ assert_environment_t assert_env;
+
+ svc_result.a0 = 0x12345678;
+ expect_ffa_svc(0x8400006B, 0, 0, 0, 0, 0, 0, 0, &svc_result);
+ if (SETUP_ASSERT_ENVIRONMENT(assert_env)) {
+ ffa_msg_wait(&msg);
+ }
+}
+
+TEST(ffa_api, ffa_msg_send_direct_req_success)
+{
+ const uint16_t source_id = 0x1122;
+ const uint16_t dest_id = 0x3344;
+ const uint32_t arg0 = 0x01234567ULL;
+ const uint32_t arg1 = 0x12345678ULL;
+ const uint32_t arg2 = 0x23456789ULL;
+ const uint32_t arg3 = 0x3456789aULL;
+ const uint32_t arg4 = 0x456789abULL;
+
+ svc_result.a0 = 0x84000061;
+ expect_ffa_svc(0x8400006F, ((uint32_t)source_id << 16) | dest_id, 0,
+ arg0, arg1, arg2, arg3, arg4, &svc_result);
+ ffa_result result = ffa_msg_send_direct_req(
+ source_id, dest_id, arg0, arg1, arg2, arg3, arg4, &msg);
+ LONGS_EQUAL(0, result);
+ msg_equal(0x84000061, 0, 0, 0, 0, 0, 0, 0);
+}
+
+TEST(ffa_api, ffa_msg_send_direct_req_error)
+{
+ const uint16_t source_id = 0x1122;
+ const uint16_t dest_id = 0x3344;
+ const uint32_t arg0 = 0x01234567ULL;
+ const uint32_t arg1 = 0x12345678ULL;
+ const uint32_t arg2 = 0x23456789ULL;
+ const uint32_t arg3 = 0x3456789aULL;
+ const uint32_t arg4 = 0x456789abULL;
+
+ setup_error_response(-1);
+ expect_ffa_svc(0x8400006F, ((uint32_t)source_id << 16) | dest_id, 0,
+ arg0, arg1, arg2, arg3, arg4, &svc_result);
+ ffa_result result = ffa_msg_send_direct_req(
+ source_id, dest_id, arg0, arg1, arg2, arg3, arg4, &msg);
+ LONGS_EQUAL(-1, result);
+ msg_equal(0, 0, 0, 0, 0, 0, 0, 0);
+}
+
+TEST(ffa_api, ffa_msg_send_direct_req_direct_resp)
+{
+ const uint16_t source_id = 0x1122;
+ const uint16_t dest_id = 0x3344;
+ const uint32_t arg0 = 0x01234567ULL;
+ const uint32_t arg1 = 0x12345678ULL;
+ const uint32_t arg2 = 0x23456789ULL;
+ const uint32_t arg3 = 0x3456789aULL;
+ const uint32_t arg4 = 0x456789abULL;
+ const uint16_t resp_source_id = 0x1221;
+ const uint16_t resp_dest_id = 0x3443;
+ const uint32_t resp_arg0 = 0x90123456ULL;
+ const uint32_t resp_arg1 = 0xa1234567ULL;
+ const uint32_t resp_arg2 = 0xb2345678ULL;
+ const uint32_t resp_arg3 = 0xc3456789ULL;
+ const uint32_t resp_arg4 = 0xd456789aULL;
+
+ svc_result.a0 = 0x84000070;
+ svc_result.a1 = ((uint32_t)resp_source_id) << 16 | resp_dest_id;
+ svc_result.a3 = resp_arg0;
+ svc_result.a4 = resp_arg1;
+ svc_result.a5 = resp_arg2;
+ svc_result.a6 = resp_arg3;
+ svc_result.a7 = resp_arg4;
+ expect_ffa_svc(0x8400006F, ((uint32_t)source_id << 16) | dest_id, 0,
+ arg0, arg1, arg2, arg3, arg4, &svc_result);
+ ffa_result result = ffa_msg_send_direct_req(
+ source_id, dest_id, arg0, arg1, arg2, arg3, arg4, &msg);
+ LONGS_EQUAL(0, result);
+ msg_equal(0x84000070, resp_source_id, resp_dest_id, resp_arg0,
+ resp_arg1, resp_arg2, resp_arg3, resp_arg4);
+}
+
+TEST(ffa_api, ffa_msg_send_direct_req_one_interrupt_success)
+{
+ const uint16_t source_id = 0x1122;
+ const uint16_t dest_id = 0x3344;
+ const uint32_t arg0 = 0x01234567ULL;
+ const uint32_t arg1 = 0x12345678ULL;
+ const uint32_t arg2 = 0x23456789ULL;
+ const uint32_t arg3 = 0x3456789aULL;
+ const uint32_t arg4 = 0x456789abULL;
+ const uint32_t interrupt_id = 0x12345678;
+ struct ffa_params interrupt_params;
+
+ interrupt_params.a0 = 0x84000062;
+ interrupt_params.a2 = interrupt_id;
+ expect_ffa_svc(0x8400006F, ((uint32_t)source_id << 16) | dest_id, 0,
+ arg0, arg1, arg2, arg3, arg4, &interrupt_params);
+ expect_ffa_interrupt_handler(interrupt_id);
+
+ svc_result.a0 = 0x84000061;
+ expect_ffa_svc(0x8400006B, 0, 0, 0, 0, 0, 0, 0, &svc_result);
+ ffa_result result = ffa_msg_send_direct_req(
+ source_id, dest_id, arg0, arg1, arg2, arg3, arg4, &msg);
+ LONGS_EQUAL(0, result);
+ msg_equal(0x84000061, 0, 0, 0, 0, 0, 0, 0);
+}
+
+TEST(ffa_api, ffa_msg_send_direct_req_two_interrupt_success)
+{
+ const uint16_t source_id = 0x1122;
+ const uint16_t dest_id = 0x3344;
+ const uint32_t arg0 = 0x01234567ULL;
+ const uint32_t arg1 = 0x12345678ULL;
+ const uint32_t arg2 = 0x23456789ULL;
+ const uint32_t arg3 = 0x3456789aULL;
+ const uint32_t arg4 = 0x456789abULL;
+ const uint32_t interrupt_id = 0x12345678;
+ const uint32_t interrupt_id0 = 0x12345678;
+ const uint32_t interrupt_id1 = 0x81234567;
+ struct ffa_params interrupt_params0;
+ struct ffa_params interrupt_params1;
+
+ interrupt_params0.a0 = 0x84000062;
+ interrupt_params0.a2 = interrupt_id0;
+ expect_ffa_svc(0x8400006F, ((uint32_t)source_id << 16) | dest_id, 0,
+ arg0, arg1, arg2, arg3, arg4, &interrupt_params0);
+ expect_ffa_interrupt_handler(interrupt_id0);
+
+ interrupt_params1.a0 = 0x84000062;
+ interrupt_params1.a2 = interrupt_id1;
+ expect_ffa_svc(0x8400006B, 0, 0, 0, 0, 0, 0, 0, &interrupt_params1);
+ expect_ffa_interrupt_handler(interrupt_id1);
+
+ svc_result.a0 = 0x84000061;
+ expect_ffa_svc(0x8400006B, 0, 0, 0, 0, 0, 0, 0, &svc_result);
+ ffa_result result = ffa_msg_send_direct_req(
+ source_id, dest_id, arg0, arg1, arg2, arg3, arg4, &msg);
+ LONGS_EQUAL(0, result);
+ msg_equal(0x84000061, 0, 0, 0, 0, 0, 0, 0);
+}
+
+TEST(ffa_api, ffa_msg_send_direct_req_unknown_response)
+{
+ const uint16_t source_id = 0x1122;
+ const uint16_t dest_id = 0x3344;
+ const uint32_t arg0 = 0x01234567ULL;
+ const uint32_t arg1 = 0x12345678ULL;
+ const uint32_t arg2 = 0x23456789ULL;
+ const uint32_t arg3 = 0x3456789aULL;
+ const uint32_t arg4 = 0x456789abULL;
+ assert_environment_t assert_env;
+
+ svc_result.a0 = 0x12345678;
+ expect_ffa_svc(0x8400006F, ((uint32_t)source_id << 16) | dest_id, 0,
+ arg0, arg1, arg2, arg3, arg4, &svc_result);
+ if (SETUP_ASSERT_ENVIRONMENT(assert_env)) {
+ ffa_msg_send_direct_req(source_id, dest_id, arg0, arg1, arg2,
+ arg3, arg4, &msg);
+ }
+}
+
+TEST(ffa_api, ffa_msg_send_direct_resp_success)
+{
+ const uint16_t source_id = 0x1122;
+ const uint16_t dest_id = 0x3344;
+ const uint32_t arg0 = 0x01234567ULL;
+ const uint32_t arg1 = 0x12345678ULL;
+ const uint32_t arg2 = 0x23456789ULL;
+ const uint32_t arg3 = 0x3456789aULL;
+ const uint32_t arg4 = 0x456789abULL;
+
+ svc_result.a0 = 0x84000061;
+ expect_ffa_svc(0x84000070, ((uint32_t)source_id << 16) | dest_id, 0,
+ arg0, arg1, arg2, arg3, arg4, &svc_result);
+ ffa_result result = ffa_msg_send_direct_resp(
+ source_id, dest_id, arg0, arg1, arg2, arg3, arg4, &msg);
+ LONGS_EQUAL(0, result);
+ msg_equal(0x84000061, 0, 0, 0, 0, 0, 0, 0);
+}
+
+TEST(ffa_api, ffa_msg_send_direct_resp_error)
+{
+ const uint16_t source_id = 0x1122;
+ const uint16_t dest_id = 0x3344;
+ const uint32_t arg0 = 0x01234567ULL;
+ const uint32_t arg1 = 0x12345678ULL;
+ const uint32_t arg2 = 0x23456789ULL;
+ const uint32_t arg3 = 0x3456789aULL;
+ const uint32_t arg4 = 0x456789abULL;
+
+ setup_error_response(-1);
+ expect_ffa_svc(0x84000070, ((uint32_t)source_id << 16) | dest_id, 0,
+ arg0, arg1, arg2, arg3, arg4, &svc_result);
+ ffa_result result = ffa_msg_send_direct_resp(
+ source_id, dest_id, arg0, arg1, arg2, arg3, arg4, &msg);
+ LONGS_EQUAL(-1, result);
+ msg_equal(0, 0, 0, 0, 0, 0, 0, 0);
+}
+
+TEST(ffa_api, ffa_msg_send_direct_resp_then_get_direct_req_as_response)
+{
+ const uint16_t source_id = 0x1122;
+ const uint16_t dest_id = 0x3344;
+ const uint32_t arg0 = 0x01234567ULL;
+ const uint32_t arg1 = 0x12345678ULL;
+ const uint32_t arg2 = 0x23456789ULL;
+ const uint32_t arg3 = 0x3456789aULL;
+ const uint32_t arg4 = 0x456789abULL;
+ const uint16_t resp_source_id = 0x1221;
+ const uint16_t resp_dest_id = 0x3443;
+ const uint32_t resp_arg0 = 0x90123456ULL;
+ const uint32_t resp_arg1 = 0xa1234567ULL;
+ const uint32_t resp_arg2 = 0xb2345678ULL;
+ const uint32_t resp_arg3 = 0xc3456789ULL;
+ const uint32_t resp_arg4 = 0xd456789aULL;
+
+ svc_result.a0 = 0x8400006F;
+ svc_result.a1 = ((uint32_t)resp_source_id) << 16 | resp_dest_id;
+ svc_result.a3 = resp_arg0;
+ svc_result.a4 = resp_arg1;
+ svc_result.a5 = resp_arg2;
+ svc_result.a6 = resp_arg3;
+ svc_result.a7 = resp_arg4;
+ expect_ffa_svc(0x84000070, ((uint32_t)source_id << 16) | dest_id, 0,
+ arg0, arg1, arg2, arg3, arg4, &svc_result);
+ ffa_result result = ffa_msg_send_direct_resp(
+ source_id, dest_id, arg0, arg1, arg2, arg3, arg4, &msg);
+ LONGS_EQUAL(0, result);
+ msg_equal(0x8400006F, resp_source_id, resp_dest_id, resp_arg0,
+ resp_arg1, resp_arg2, resp_arg3, resp_arg4);
+}
+
+TEST(ffa_api, ffa_msg_send_direct_resp_one_interrupt_success)
+{
+ const uint16_t source_id = 0x1122;
+ const uint16_t dest_id = 0x3344;
+ const uint32_t arg0 = 0x01234567ULL;
+ const uint32_t arg1 = 0x12345678ULL;
+ const uint32_t arg2 = 0x23456789ULL;
+ const uint32_t arg3 = 0x3456789aULL;
+ const uint32_t arg4 = 0x456789abULL;
+ const uint32_t interrupt_id = 0x12345678;
+ struct ffa_params interrupt_params;
+
+ interrupt_params.a0 = 0x84000062;
+ interrupt_params.a2 = interrupt_id;
+ expect_ffa_svc(0x84000070, ((uint32_t)source_id << 16) | dest_id, 0,
+ arg0, arg1, arg2, arg3, arg4, &interrupt_params);
+ expect_ffa_interrupt_handler(interrupt_id);
+
+ svc_result.a0 = 0x84000061;
+ expect_ffa_svc(0x8400006B, 0, 0, 0, 0, 0, 0, 0, &svc_result);
+ ffa_result result = ffa_msg_send_direct_resp(
+ source_id, dest_id, arg0, arg1, arg2, arg3, arg4, &msg);
+ LONGS_EQUAL(0, result);
+ msg_equal(0x84000061, 0, 0, 0, 0, 0, 0, 0);
+}
+
+TEST(ffa_api, ffa_msg_send_direct_resp_two_interrupt_success)
+{
+ const uint16_t source_id = 0x1122;
+ const uint16_t dest_id = 0x3344;
+ const uint32_t arg0 = 0x01234567ULL;
+ const uint32_t arg1 = 0x12345678ULL;
+ const uint32_t arg2 = 0x23456789ULL;
+ const uint32_t arg3 = 0x3456789aULL;
+ const uint32_t arg4 = 0x456789abULL;
+ const uint32_t interrupt_id = 0x12345678;
+ const uint32_t interrupt_id0 = 0x12345678;
+ const uint32_t interrupt_id1 = 0x81234567;
+ struct ffa_params interrupt_params0;
+ struct ffa_params interrupt_params1;
+
+ interrupt_params0.a0 = 0x84000062;
+ interrupt_params0.a2 = interrupt_id0;
+ expect_ffa_svc(0x84000070, ((uint32_t)source_id << 16) | dest_id, 0,
+ arg0, arg1, arg2, arg3, arg4, &interrupt_params0);
+ expect_ffa_interrupt_handler(interrupt_id0);
+
+ interrupt_params1.a0 = 0x84000062;
+ interrupt_params1.a2 = interrupt_id1;
+ expect_ffa_svc(0x8400006B, 0, 0, 0, 0, 0, 0, 0, &interrupt_params1);
+ expect_ffa_interrupt_handler(interrupt_id1);
+
+ svc_result.a0 = 0x84000061;
+ expect_ffa_svc(0x8400006B, 0, 0, 0, 0, 0, 0, 0, &svc_result);
+ ffa_result result = ffa_msg_send_direct_resp(
+ source_id, dest_id, arg0, arg1, arg2, arg3, arg4, &msg);
+ LONGS_EQUAL(0, result);
+ msg_equal(0x84000061, 0, 0, 0, 0, 0, 0, 0);
+}
+
+TEST(ffa_api, ffa_msg_send_direct_resp_unknown_response)
+{
+ const uint16_t source_id = 0x1122;
+ const uint16_t dest_id = 0x3344;
+ const uint32_t arg0 = 0x01234567ULL;
+ const uint32_t arg1 = 0x12345678ULL;
+ const uint32_t arg2 = 0x23456789ULL;
+ const uint32_t arg3 = 0x3456789aULL;
+ const uint32_t arg4 = 0x456789abULL;
+ assert_environment_t assert_env;
+
+ svc_result.a0 = 0x12345678;
+ expect_ffa_svc(0x84000070, ((uint32_t)source_id << 16) | dest_id, 0,
+ arg0, arg1, arg2, arg3, arg4, &svc_result);
+ if (SETUP_ASSERT_ENVIRONMENT(assert_env)) {
+ ffa_msg_send_direct_resp(source_id, dest_id, arg0, arg1, arg2,
+ arg3, arg4, &msg);
+ }
+}
+
+TEST(ffa_api, ffa_mem_donate)
+{
+ const uint32_t total_length = 0xfedcba98UL;
+ const uint32_t fragment_length = 0xffeeddcc;
+ const uint64_t buffer_address = 0x0123456789abcdefULL;
+ const uint32_t page_count = 0x87654321;
+ uint64_t handle = 0;
+ const uint64_t handle_result = 0xaabbccdd11223344ULL;
+
+ svc_result.a0 = 0x84000061;
+ svc_result.a2 = (handle_result & 0xffffffffULL);
+ svc_result.a3 = (handle_result >> 32);
+ expect_ffa_svc(0x84000071, total_length, fragment_length,
+ buffer_address, page_count, 0, 0, 0, &svc_result);
+
+ ffa_result result =
+ ffa_mem_donate(total_length, fragment_length,
+ (void *)buffer_address, page_count, &handle);
+ LONGS_EQUAL(0, result);
+ UNSIGNED_LONGLONGS_EQUAL(handle_result, handle);
+}
+
+TEST(ffa_api, ffa_mem_donate_error)
+{
+ const uint32_t total_length = 0xfedcba98UL;
+ const uint32_t fragment_length = 0xffeeddcc;
+ const uint64_t buffer_address = 0x0123456789abcdefULL;
+ const uint32_t page_count = 0x87654321;
+ uint64_t handle = 0x1234567812345678;
+ const uint64_t handle_result = 0xaabbccdd11223344ULL;
+
+ setup_error_response(-1);
+ expect_ffa_svc(0x84000071, total_length, fragment_length,
+ buffer_address, page_count, 0, 0, 0, &svc_result);
+
+ ffa_result result =
+ ffa_mem_donate(total_length, fragment_length,
+ (void *)buffer_address, page_count, &handle);
+ LONGS_EQUAL(-1, result);
+ UNSIGNED_LONGLONGS_EQUAL(0, handle);
+}
+
+TEST(ffa_api, ffa_mem_donate_unknown_response)
+{
+ const uint32_t total_length = 0xfedcba98UL;
+ const uint32_t fragment_length = 0xffeeddcc;
+ const uint64_t buffer_address = 0x0123456789abcdefULL;
+ const uint32_t page_count = 0x87654321;
+ uint64_t handle = 0x1234567812345678;
+ const uint64_t handle_result = 0xaabbccdd11223344ULL;
+ assert_environment_t assert_env;
+
+ svc_result.a0 = 0x12345678;
+ expect_ffa_svc(0x84000071, total_length, fragment_length,
+ buffer_address, page_count, 0, 0, 0, &svc_result);
+
+ if (SETUP_ASSERT_ENVIRONMENT(assert_env)) {
+ ffa_mem_donate(total_length, fragment_length,
+ (void *)buffer_address, page_count, &handle);
+ }
+}
+
+TEST(ffa_api, ffa_mem_donate_rxtx)
+{
+ const uint32_t total_length = 0xfedcba98UL;
+ const uint32_t fragment_length = 0xffeeddcc;
+ uint64_t handle = 0;
+ const uint64_t handle_result = 0xaabbccdd11223344ULL;
+
+ svc_result.a0 = 0x84000061;
+ svc_result.a2 = (handle_result & 0xffffffffULL);
+ svc_result.a3 = (handle_result >> 32);
+ expect_ffa_svc(0x84000071, total_length, fragment_length, 0, 0, 0, 0, 0,
+ &svc_result);
+
+ ffa_result result =
+ ffa_mem_donate_rxtx(total_length, fragment_length, &handle);
+ LONGS_EQUAL(0, result);
+ UNSIGNED_LONGLONGS_EQUAL(handle_result, handle);
+}
+
+TEST(ffa_api, ffa_mem_lend)
+{
+ const uint32_t total_length = 0xfedcba98UL;
+ const uint32_t fragment_length = 0xffeeddcc;
+ const uint64_t buffer_address = 0x0123456789abcdefULL;
+ const uint32_t page_count = 0x87654321;
+ uint64_t handle = 0;
+ const uint64_t handle_result = 0xaabbccdd11223344ULL;
+
+ svc_result.a0 = 0x84000061;
+ svc_result.a2 = (handle_result & 0xffffffffULL);
+ svc_result.a3 = (handle_result >> 32);
+ expect_ffa_svc(0x84000072, total_length, fragment_length,
+ buffer_address, page_count, 0, 0, 0, &svc_result);
+
+ ffa_result result =
+ ffa_mem_lend(total_length, fragment_length,
+ (void *)buffer_address, page_count, &handle);
+ LONGS_EQUAL(0, result);
+ UNSIGNED_LONGLONGS_EQUAL(handle_result, handle);
+}
+
+TEST(ffa_api, ffa_mem_lend_error)
+{
+ const uint32_t total_length = 0xfedcba98UL;
+ const uint32_t fragment_length = 0xffeeddcc;
+ const uint64_t buffer_address = 0x0123456789abcdefULL;
+ const uint32_t page_count = 0x87654321;
+ uint64_t handle = 0x1234567812345678;
+ const uint64_t handle_result = 0xaabbccdd11223344ULL;
+
+ setup_error_response(-1);
+ expect_ffa_svc(0x84000072, total_length, fragment_length,
+ buffer_address, page_count, 0, 0, 0, &svc_result);
+
+ ffa_result result =
+ ffa_mem_lend(total_length, fragment_length,
+ (void *)buffer_address, page_count, &handle);
+ LONGS_EQUAL(-1, result);
+ UNSIGNED_LONGLONGS_EQUAL(0, handle);
+}
+
+TEST(ffa_api, ffa_mem_lend_unknown_response)
+{
+ const uint32_t total_length = 0xfedcba98UL;
+ const uint32_t fragment_length = 0xffeeddcc;
+ const uint64_t buffer_address = 0x0123456789abcdefULL;
+ const uint32_t page_count = 0x87654321;
+ uint64_t handle = 0x1234567812345678;
+ const uint64_t handle_result = 0xaabbccdd11223344ULL;
+ assert_environment_t assert_env;
+
+ svc_result.a0 = 0x12345678;
+ expect_ffa_svc(0x84000072, total_length, fragment_length,
+ buffer_address, page_count, 0, 0, 0, &svc_result);
+
+ if (SETUP_ASSERT_ENVIRONMENT(assert_env)) {
+ ffa_mem_lend(total_length, fragment_length,
+ (void *)buffer_address, page_count, &handle);
+ }
+}
+
+TEST(ffa_api, ffa_mem_lend_rxtx)
+{
+ const uint32_t total_length = 0xfedcba98UL;
+ const uint32_t fragment_length = 0xffeeddcc;
+ uint64_t handle = 0;
+ const uint64_t handle_result = 0xaabbccdd11223344ULL;
+
+ svc_result.a0 = 0x84000061;
+ svc_result.a2 = (handle_result & 0xffffffffULL);
+ svc_result.a3 = (handle_result >> 32);
+ expect_ffa_svc(0x84000072, total_length, fragment_length, 0, 0, 0, 0, 0,
+ &svc_result);
+
+ ffa_result result =
+ ffa_mem_lend_rxtx(total_length, fragment_length, &handle);
+ LONGS_EQUAL(0, result);
+ UNSIGNED_LONGLONGS_EQUAL(handle_result, handle);
+}
+
+TEST(ffa_api, ffa_mem_share)
+{
+ const uint32_t total_length = 0xfedcba98UL;
+ const uint32_t fragment_length = 0xffeeddcc;
+ const uint64_t buffer_address = 0x0123456789abcdefULL;
+ const uint32_t page_count = 0x87654321;
+ uint64_t handle = 0;
+ const uint64_t handle_result = 0xaabbccdd11223344ULL;
+
+ svc_result.a0 = 0x84000061;
+ svc_result.a2 = (handle_result & 0xffffffffULL);
+ svc_result.a3 = (handle_result >> 32);
+ expect_ffa_svc(0x84000073, total_length, fragment_length,
+ buffer_address, page_count, 0, 0, 0, &svc_result);
+
+ ffa_result result =
+ ffa_mem_share(total_length, fragment_length,
+ (void *)buffer_address, page_count, &handle);
+ LONGS_EQUAL(0, result);
+ UNSIGNED_LONGLONGS_EQUAL(handle_result, handle);
+}
+
+TEST(ffa_api, ffa_mem_share_error)
+{
+ const uint32_t total_length = 0xfedcba98UL;
+ const uint32_t fragment_length = 0xffeeddcc;
+ const uint64_t buffer_address = 0x0123456789abcdefULL;
+ const uint32_t page_count = 0x87654321;
+ uint64_t handle = 0x1234567812345678;
+ const uint64_t handle_result = 0xaabbccdd11223344ULL;
+
+ setup_error_response(-1);
+ expect_ffa_svc(0x84000073, total_length, fragment_length,
+ buffer_address, page_count, 0, 0, 0, &svc_result);
+
+ ffa_result result =
+ ffa_mem_share(total_length, fragment_length,
+ (void *)buffer_address, page_count, &handle);
+ LONGS_EQUAL(-1, result);
+ UNSIGNED_LONGLONGS_EQUAL(0, handle);
+}
+
+TEST(ffa_api, ffa_mem_share_unknown_response)
+{
+ const uint32_t total_length = 0xfedcba98UL;
+ const uint32_t fragment_length = 0xffeeddcc;
+ const uint64_t buffer_address = 0x0123456789abcdefULL;
+ const uint32_t page_count = 0x87654321;
+ uint64_t handle = 0x1234567812345678;
+ const uint64_t handle_result = 0xaabbccdd11223344ULL;
+ assert_environment_t assert_env;
+
+ svc_result.a0 = 0x12345678;
+ expect_ffa_svc(0x84000073, total_length, fragment_length,
+ buffer_address, page_count, 0, 0, 0, &svc_result);
+
+ if (SETUP_ASSERT_ENVIRONMENT(assert_env)) {
+ ffa_mem_share(total_length, fragment_length,
+ (void *)buffer_address, page_count, &handle);
+ }
+}
+
+TEST(ffa_api, ffa_mem_share_rxtx)
+{
+ const uint32_t total_length = 0xfedcba98UL;
+ const uint32_t fragment_length = 0xffeeddcc;
+ uint64_t handle = 0;
+ const uint64_t handle_result = 0xaabbccdd11223344ULL;
+
+ svc_result.a0 = 0x84000061;
+ svc_result.a2 = (handle_result & 0xffffffffULL);
+ svc_result.a3 = (handle_result >> 32);
+ expect_ffa_svc(0x84000073, total_length, fragment_length, 0, 0, 0, 0, 0,
+ &svc_result);
+
+ ffa_result result =
+ ffa_mem_share_rxtx(total_length, fragment_length, &handle);
+ LONGS_EQUAL(0, result);
+ UNSIGNED_LONGLONGS_EQUAL(handle_result, handle);
+}
+
+TEST(ffa_api, ffa_mem_retrieve_req)
+{
+ const uint32_t total_length = 0xfedcba98UL;
+ const uint32_t fragment_length = 0xffeeddcc;
+ const uint64_t buffer_address = 0x0123456789abcdefULL;
+ const uint32_t page_count = 0x87654321;
+ uint32_t resp_total_length = 0;
+ uint32_t resp_fragment_length = 0;
+ const uint32_t resp_total_length_result = 0xaabbccdd;
+ const uint32_t resp_frament_length_result = 0x11223344;
+
+ svc_result.a0 = 0x84000075;
+ svc_result.a1 = resp_total_length_result;
+ svc_result.a2 = resp_frament_length_result;
+ expect_ffa_svc(0x84000074, total_length, fragment_length,
+ buffer_address, page_count, 0, 0, 0, &svc_result);
+
+ ffa_result result =
+ ffa_mem_retrieve_req(total_length, fragment_length,
+ (void *)buffer_address, page_count,
+ &resp_total_length, &resp_fragment_length);
+ LONGS_EQUAL(0, result);
+ UNSIGNED_LONGS_EQUAL(resp_total_length_result, resp_total_length);
+ UNSIGNED_LONGS_EQUAL(resp_frament_length_result, resp_fragment_length);
+}
+
+TEST(ffa_api, ffa_mem_retrieve_req_error)
+{
+ const uint32_t total_length = 0xfedcba98UL;
+ const uint32_t fragment_length = 0xffeeddcc;
+ const uint64_t buffer_address = 0x0123456789abcdefULL;
+ const uint32_t page_count = 0x87654321;
+ uint32_t resp_total_length = 0;
+ uint32_t resp_fragment_length = 0;
+ const uint32_t resp_total_length_result = 0xaabbccdd;
+ const uint32_t resp_frament_length_result = 0x11223344;
+
+ setup_error_response(-1);
+ expect_ffa_svc(0x84000074, total_length, fragment_length,
+ buffer_address, page_count, 0, 0, 0, &svc_result);
+
+ ffa_result result =
+ ffa_mem_retrieve_req(total_length, fragment_length,
+ (void *)buffer_address, page_count,
+ &resp_total_length, &resp_fragment_length);
+ LONGS_EQUAL(-1, result);
+ UNSIGNED_LONGS_EQUAL(0, resp_total_length);
+ UNSIGNED_LONGS_EQUAL(0, resp_fragment_length);
+}
+
+TEST(ffa_api, ffa_mem_retrieve_req_unknown_response)
+{
+ const uint32_t total_length = 0xfedcba98UL;
+ const uint32_t fragment_length = 0xffeeddcc;
+ const uint64_t buffer_address = 0x0123456789abcdefULL;
+ const uint32_t page_count = 0x87654321;
+ uint32_t resp_total_length = 0;
+ uint32_t resp_fragment_length = 0;
+ const uint32_t resp_total_length_result = 0xaabbccdd;
+ const uint32_t resp_frament_length_result = 0x11223344;
+ assert_environment_t assert_env;
+
+ svc_result.a0 = 0x12345678;
+ expect_ffa_svc(0x84000074, total_length, fragment_length,
+ buffer_address, page_count, 0, 0, 0, &svc_result);
+
+ if (SETUP_ASSERT_ENVIRONMENT(assert_env)) {
+ ffa_mem_retrieve_req(total_length, fragment_length,
+ (void *)buffer_address, page_count,
+ &resp_total_length, &resp_fragment_length);
+ }
+}
+
+TEST(ffa_api, ffa_mem_retrieve_req_rxtx)
+{
+ const uint32_t total_length = 0xfedcba98UL;
+ const uint32_t fragment_length = 0xffeeddcc;
+ uint32_t resp_total_length = 0;
+ uint32_t resp_fragment_length = 0;
+ const uint32_t resp_total_length_result = 0xaabbccdd;
+ const uint32_t resp_frament_length_result = 0x11223344;
+
+ svc_result.a0 = 0x84000075;
+ svc_result.a1 = resp_total_length_result;
+ svc_result.a2 = resp_frament_length_result;
+ expect_ffa_svc(0x84000074, total_length, fragment_length, 0, 0, 0, 0, 0,
+ &svc_result);
+
+ ffa_result result =
+ ffa_mem_retrieve_req_rxtx(total_length, fragment_length,
+ &resp_total_length,
+ &resp_fragment_length);
+ LONGS_EQUAL(0, result);
+ UNSIGNED_LONGS_EQUAL(resp_total_length_result, resp_total_length);
+ UNSIGNED_LONGS_EQUAL(resp_frament_length_result, resp_fragment_length);
+}
+
+TEST(ffa_api, ffa_mem_relinquish)
+{
+ ffa_result result = FFA_OK;
+
+ svc_result.a0 = 0x84000061;
+ expect_ffa_svc(0x84000076, 0, 0, 0, 0, 0, 0, 0, &svc_result);
+
+ result = ffa_mem_relinquish();
+ LONGS_EQUAL(FFA_OK, result);
+}
+
+TEST(ffa_api, ffa_mem_relinquish_error)
+{
+ ffa_result result = FFA_OK;
+
+ setup_error_response(-1);
+ expect_ffa_svc(0x84000076, 0, 0, 0, 0, 0, 0, 0, &svc_result);
+
+ result = ffa_mem_relinquish();
+ LONGS_EQUAL(-1, result);
+}
+
+TEST(ffa_api, ffa_mem_relinquish_unknown_response)
+{
+ assert_environment_t assert_env;
+
+ svc_result.a0 = 0x12345678;
+ expect_ffa_svc(0x84000076, 0, 0, 0, 0, 0, 0, 0, &svc_result);
+
+ if (SETUP_ASSERT_ENVIRONMENT(assert_env)) {
+ ffa_mem_relinquish();
+ }
+}
+
+TEST(ffa_api, ffa_mem_reclaim)
+{
+ const uint64_t handle = 0x1234567812345678;
+ const uint32_t flags = 0x87654321;
+
+ svc_result.a0 = 0x84000061;
+ expect_ffa_svc(0x84000077, (handle & 0xffffffffULL), handle >> 32,
+ flags, 0, 0, 0, 0, &svc_result);
+
+ ffa_result result = ffa_mem_reclaim(handle, flags);
+ LONGS_EQUAL(0, result);
+}
+
+TEST(ffa_api, ffa_mem_reclaimerror)
+{
+ const uint64_t handle = 0x1234567812345678;
+ const uint32_t flags = 0x87654321;
+
+ setup_error_response(-1);
+ expect_ffa_svc(0x84000077, (handle & 0xffffffffULL), handle >> 32,
+ flags, 0, 0, 0, 0, &svc_result);
+
+ ffa_result result = ffa_mem_reclaim(handle, flags);
+ LONGS_EQUAL(-1, result);
+}
+
+TEST(ffa_api, ffa_mem_reclaim_unknown_response)
+{
+ const uint64_t handle = 0x1234567812345678;
+ const uint32_t flags = 0x87654321;
+ assert_environment_t assert_env;
+
+ svc_result.a0 = 0x12345678;
+ expect_ffa_svc(0x84000077, (handle & 0xffffffffULL), handle >> 32,
+ flags, 0, 0, 0, 0, &svc_result);
+
+ if (SETUP_ASSERT_ENVIRONMENT(assert_env)) {
+ ffa_mem_reclaim(handle, flags);
+ }
+}
diff --git a/components/messaging/ffa/libsp/tests.cmake b/components/messaging/ffa/libsp/tests.cmake
index 77153ff..d798621 100644
--- a/components/messaging/ffa/libsp/tests.cmake
+++ b/components/messaging/ffa/libsp/tests.cmake
@@ -30,3 +30,16 @@ unit_test_add_suite(
-DARM64
)
+unit_test_add_suite(
+ NAME libsp_ffa
+ SOURCES
+ ${CMAKE_CURRENT_LIST_DIR}/test/test_ffa_api.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/test/mock_ffa_internal_api.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/ffa.c
+ ${CMAKE_CURRENT_LIST_DIR}/test/mock_assert.cpp
+ INCLUDE_DIRECTORIES
+ ${CMAKE_CURRENT_LIST_DIR}/include/
+ ${PROJECT_PATH}/components/common/utils/include
+ COMPILE_DEFINITIONS
+ -DARM64
+)