diff options
author | Imre Kis <imre.kis@arm.com> | 2021-01-12 22:22:04 +0100 |
---|---|---|
committer | György Szing <gyorgy.szing@arm.com> | 2021-02-02 10:00:13 +0000 |
commit | f5f4a554d8d5e6917cbd31ad726e13e9ab055449 (patch) | |
tree | e8288bfcabb26e5b645a0823e0f545da83162680 /components/messaging/ffa/libsp | |
parent | b6a63bfe32d7c6fa4b973ba0ae3bd46cc5c23594 (diff) | |
download | trusted-services-f5f4a554d8d5e6917cbd31ad726e13e9ab055449.tar.gz |
libsp: Unit testing sp_memory_management.c
Testing the functions of sp_memory_management.c using the mocked FF-A
layer and SP RXTX implementation. The static functions of the file are
tested by exporting them through c-picker.
Signed-off-by: Imre Kis <imre.kis@arm.com>
Change-Id: Ie9995c83b7d9ceb98527bac6685e6f9d555471af
Diffstat (limited to 'components/messaging/ffa/libsp')
4 files changed, 2129 insertions, 0 deletions
diff --git a/components/messaging/ffa/libsp/test/sp_memory_management_internals.yml b/components/messaging/ffa/libsp/test/sp_memory_management_internals.yml new file mode 100644 index 000000000..25e41fd36 --- /dev/null +++ b/components/messaging/ffa/libsp/test/sp_memory_management_internals.yml @@ -0,0 +1,37 @@ +# +# Copyright (c) 2020-2021, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +elements: +- file: components/messaging/ffa/libsp/sp_memory_management.c + type: include +- file: components/messaging/ffa/libsp/sp_memory_management.c + type: function + name: is_valid_buffer + options: [remove_static] +- file: components/messaging/ffa/libsp/sp_memory_management.c + type: function + name: build_mem_region_attr + options: [remove_static] +- file: components/messaging/ffa/libsp/sp_memory_management.c + type: function + name: parse_mem_region_attr + options: [remove_static] +- file: components/messaging/ffa/libsp/sp_memory_management.c + type: function + name: build_mem_flags + options: [remove_static] +- file: components/messaging/ffa/libsp/sp_memory_management.c + type: function + name: parse_mem_flags + options: [remove_static] +- file: components/messaging/ffa/libsp/sp_memory_management.c + type: function + name: parse_mem_access_perm + options: [remove_static] +- file: components/messaging/ffa/libsp/sp_memory_management.c + type: function + name: parse_descriptors + options: [remove_static] diff --git a/components/messaging/ffa/libsp/test/test_sp_memory_management.cpp b/components/messaging/ffa/libsp/test/test_sp_memory_management.cpp new file mode 100644 index 000000000..72fd34cf2 --- /dev/null +++ b/components/messaging/ffa/libsp/test/test_sp_memory_management.cpp @@ -0,0 +1,1511 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2020-2021, Arm Limited. All rights reserved. + */ + +#include <CppUTestExt/MockSupport.h> +#include <CppUTest/TestHarness.h> +#include "../include/sp_memory_management.h" +#include "mock_assert.h" +#include "mock_ffa_api.h" +#include "mock_sp_rxtx.h" +#include <setjmp.h> +#include <stdint.h> +#include <string.h> + +static uint8_t tx_buffer_area[FFA_MEM_TRANSACTION_PAGE_SIZE] + __attribute__((aligned(FFA_MEM_TRANSACTION_PAGE_SIZE))); +static uint8_t rx_buffer_area[FFA_MEM_TRANSACTION_PAGE_SIZE] + __attribute__((aligned(FFA_MEM_TRANSACTION_PAGE_SIZE))); +static void *tx_buffer = tx_buffer_area; +static const void *rx_buffer = rx_buffer_area; +static size_t buffer_size = sizeof(tx_buffer_area); + +TEST_GROUP(sp_memory_management) +{ + TEST_SETUP() + { + memset(tx_buffer_area, 0xff, sizeof(tx_buffer_area)); + memset(rx_buffer_area, 0x00, sizeof(rx_buffer_area)); + + ffa_init_mem_transaction_buffer(tx_buffer_area, + sizeof(tx_buffer_area), + &tx_mem_transaction_buffer); + ffa_init_mem_transaction_buffer(rx_buffer_area, + sizeof(rx_buffer_area), + &rx_mem_transaction_buffer); + } + + TEST_TEARDOWN() + { + mock().checkExpectations(); + mock().clear(); + } + + uint32_t get_expected_size(uint32_t region_count) + { + uint32_t expected_size = + sizeof(struct ffa_mem_transaction_desc) + + sizeof(struct ffa_mem_access_desc); + if (region_count > 0) { + expected_size += + sizeof(struct ffa_composite_mem_region_desc); + expected_size += + sizeof(struct ffa_constituent_mem_region_desc) * + region_count; + } + + return expected_size; + } + + void check_descriptors( + const struct ffa_mem_transaction_desc *expected_transaction, + const struct ffa_mem_access_perm_desc *expected_access_perm_desc, + const struct ffa_constituent_mem_region_desc expected_regions[], + uint32_t region_count) + { + const struct ffa_mem_transaction_desc *transaction = NULL; + const struct ffa_mem_access_desc *mem_access_desc = NULL; + const struct ffa_mem_access_perm_desc *mem_access_perm_desc = + NULL; + const struct ffa_composite_mem_region_desc *composite_desc = + NULL; + + transaction = ffa_get_mem_transaction_desc( + &tx_mem_transaction_buffer); + UNSIGNED_LONGS_EQUAL(expected_transaction->sender_id, + transaction->sender_id); + BYTES_EQUAL(expected_transaction->mem_region_attr, + transaction->mem_region_attr); + UNSIGNED_LONGS_EQUAL(expected_transaction->flags, + transaction->flags); + UNSIGNED_LONGLONGS_EQUAL(expected_transaction->handle, + transaction->handle); + UNSIGNED_LONGLONGS_EQUAL(expected_transaction->tag, + transaction->tag); + + mem_access_desc = + ffa_get_mem_access_desc(&tx_mem_transaction_buffer, 0); + mem_access_perm_desc = &mem_access_desc->mem_access_perm_desc; + UNSIGNED_LONGS_EQUAL(expected_access_perm_desc->endpoint_id, + mem_access_perm_desc->endpoint_id); + BYTES_EQUAL(expected_access_perm_desc->mem_access_permissions, + mem_access_perm_desc->mem_access_permissions); + BYTES_EQUAL(expected_access_perm_desc->flags, + mem_access_perm_desc->flags); + + composite_desc = + ffa_get_memory_region(&tx_mem_transaction_buffer); + UNSIGNED_LONGS_EQUAL(region_count, + composite_desc->address_range_count); + uint32_t total_page_count = 0; + for (uint32_t i = 0; i < region_count; i++) { + const struct ffa_constituent_mem_region_desc *region = + &composite_desc->constituent_mem_region_desc[i]; + + UNSIGNED_LONGLONGS_EQUAL(expected_regions[i].address, + region->address); + UNSIGNED_LONGS_EQUAL(expected_regions[i].page_count, + region->page_count); + total_page_count += region->page_count; + } + UNSIGNED_LONGS_EQUAL(total_page_count, + composite_desc->total_page_count); + } + + struct ffa_mem_transaction_buffer tx_mem_transaction_buffer; + struct ffa_mem_transaction_buffer rx_mem_transaction_buffer; + + const uint16_t sender_id = 0x0123; + const uint16_t receiver_id = 0x4567; + const uint8_t mem_region_attr = 0x89; + const uint8_t mem_access_perm = 0xab; + const uint32_t flags = 0xcdeffedc; + const uint8_t flags2 = 0xc5; + const uint64_t handle = 0xefcdab8967452301ULL; + const uint64_t tag = 0x11223344556677ULL; + void *ptr = (void *)(0x0112233445566778ULL); + const uint32_t page_count = 0x12345678; + + const sp_result result = -1; +}; + +TEST(sp_memory_management, sp_memory_donate_descriptor_null) +{ + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint64_t handle = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_donate(NULL, &acc_desc, ®ions, 1, &handle)); + UNSIGNED_LONGLONGS_EQUAL(0, handle); +} + +TEST(sp_memory_management, sp_memory_donate_acc_descriptor_null) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint64_t handle = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_donate(&desc, NULL, ®ions, 1, &handle)); + UNSIGNED_LONGLONGS_EQUAL(0, handle); +} + +TEST(sp_memory_management, sp_memory_donate_regions_null) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + uint64_t handle = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_donate(&desc, &acc_desc, NULL, 1, &handle)); + UNSIGNED_LONGLONGS_EQUAL(0, handle); +} + +TEST(sp_memory_management, sp_memory_donate_region_count_zero) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint64_t handle = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_donate(&desc, &acc_desc, ®ions, 0, &handle)); + UNSIGNED_LONGLONGS_EQUAL(0, handle); +} + +TEST(sp_memory_management, sp_memory_donate_handle_null) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_donate(&desc, &acc_desc, ®ions, 1, NULL)); +} + +TEST(sp_memory_management, sp_memory_donate_get_tx_error) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint64_t handle = 1; + const sp_result result = SP_RESULT_INTERNAL_ERROR; + + expect_sp_rxtx_buffer_tx_get(&tx_buffer, &buffer_size, result); + LONGS_EQUAL(SP_RESULT_FFA(result), + sp_memory_donate(&desc, &acc_desc, ®ions, 1, &handle)); + UNSIGNED_LONGLONGS_EQUAL(0, handle); +} + +TEST(sp_memory_management, sp_memory_donate_ffa_error) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint32_t region_count = 1; + uint64_t handle = 1; + const uint64_t expected_handle = 0; + const sp_result result = FFA_ABORTED; + const uint32_t expected_size = get_expected_size(region_count); + + expect_sp_rxtx_buffer_tx_get(&tx_buffer, &buffer_size, SP_RESULT_OK); + expect_ffa_mem_donate_rxtx(expected_size, expected_size, + &expected_handle, result); + LONGS_EQUAL(SP_RESULT_FFA(result), + sp_memory_donate(&desc, &acc_desc, ®ions, region_count, + &handle)); + UNSIGNED_LONGLONGS_EQUAL(expected_handle, handle); +} + +TEST(sp_memory_management, sp_memory_donate) +{ + struct sp_memory_descriptor desc = { .sender_id = sender_id, + .tag = tag }; + struct sp_memory_access_descriptor acc_desc = { .receiver_id = + receiver_id }; + struct sp_memory_region regions = { .address = ptr, + .page_count = page_count }; + uint32_t region_count = 1; + uint64_t handle = 1; + const uint64_t expected_handle = 0x123456789abcdef0U; + const uint32_t expected_size = get_expected_size(region_count); + + expect_sp_rxtx_buffer_tx_get(&tx_buffer, &buffer_size, SP_RESULT_OK); + expect_ffa_mem_donate_rxtx(expected_size, expected_size, + &expected_handle, FFA_OK); + LONGS_EQUAL(SP_RESULT_OK, sp_memory_donate(&desc, &acc_desc, ®ions, + region_count, &handle)); + UNSIGNED_LONGLONGS_EQUAL(expected_handle, handle); + + const struct ffa_mem_transaction_desc expected_transaction = { + .sender_id = sender_id, .tag = tag + }; + const struct ffa_mem_access_perm_desc expected_access_perm_desc = { + .endpoint_id = receiver_id + }; + const struct ffa_constituent_mem_region_desc expected_regions = { + .address = (uint64_t)ptr, .page_count = page_count + }; + check_descriptors(&expected_transaction, &expected_access_perm_desc, + &expected_regions, 1); +} + +TEST(sp_memory_management, sp_memory_donate_dynamic_descriptor_null) +{ + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint64_t handle = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_donate_dynamic(NULL, &acc_desc, ®ions, 1, + &handle, + &tx_mem_transaction_buffer)); + UNSIGNED_LONGLONGS_EQUAL(0, handle); +} + +TEST(sp_memory_management, sp_memory_donate_dynamic_acc_descriptor_null) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint64_t handle = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_donate_dynamic(&desc, NULL, ®ions, 1, &handle, + &tx_mem_transaction_buffer)); + UNSIGNED_LONGLONGS_EQUAL(0, handle); +} + +TEST(sp_memory_management, sp_memory_donate_dynamic_regions_null) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + uint64_t handle = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_donate_dynamic(&desc, &acc_desc, NULL, 1, &handle, + &tx_mem_transaction_buffer)); + UNSIGNED_LONGLONGS_EQUAL(0, handle); +} + +TEST(sp_memory_management, sp_memory_donate_dynamic_region_count_zero) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint64_t handle = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_donate_dynamic(&desc, &acc_desc, ®ions, 0, + &handle, + &tx_mem_transaction_buffer)); + UNSIGNED_LONGLONGS_EQUAL(0, handle); +} + +TEST(sp_memory_management, sp_memory_donate_dynamic_handle_null) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_donate_dynamic(&desc, &acc_desc, ®ions, 1, + NULL, &tx_mem_transaction_buffer)); +} + +TEST(sp_memory_management, sp_memory_donate_dynamic_invalid_buffer) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint64_t handle = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_donate_dynamic(&desc, &acc_desc, ®ions, 1, + &handle, NULL)); + UNSIGNED_LONGLONGS_EQUAL(0, handle); +} + +TEST(sp_memory_management, sp_memory_donate_dynamic_ffa_error) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint32_t region_count = 1; + uint64_t handle = 1; + const uint64_t expected_handle = 0; + const sp_result result = FFA_ABORTED; + const uint32_t expected_size = get_expected_size(region_count); + + expect_ffa_mem_donate(expected_size, expected_size, tx_buffer, + buffer_size / FFA_MEM_TRANSACTION_PAGE_SIZE, + &expected_handle, result); + LONGS_EQUAL(SP_RESULT_FFA(result), + sp_memory_donate_dynamic(&desc, &acc_desc, ®ions, + region_count, &handle, + &tx_mem_transaction_buffer)); + UNSIGNED_LONGLONGS_EQUAL(expected_handle, handle); +} + +TEST(sp_memory_management, sp_memory_donate_dynamic) +{ + struct sp_memory_descriptor desc = { .sender_id = sender_id, + .tag = tag }; + struct sp_memory_access_descriptor acc_desc = { .receiver_id = + receiver_id }; + struct sp_memory_region regions = { .address = ptr, + .page_count = page_count }; + uint32_t region_count = 1; + uint64_t handle = 1; + const uint64_t expected_handle = 0x123456789abcdef0U; + const uint32_t expected_size = get_expected_size(region_count); + + expect_ffa_mem_donate(expected_size, expected_size, tx_buffer, + buffer_size / FFA_MEM_TRANSACTION_PAGE_SIZE, + &expected_handle, FFA_OK); + LONGS_EQUAL(SP_RESULT_OK, + sp_memory_donate_dynamic(&desc, &acc_desc, ®ions, + region_count, &handle, + &tx_mem_transaction_buffer)); + UNSIGNED_LONGLONGS_EQUAL(expected_handle, handle); + + const struct ffa_mem_transaction_desc expected_transaction = { + .sender_id = sender_id, .tag = tag + }; + const struct ffa_mem_access_perm_desc expected_access_perm_desc = { + .endpoint_id = receiver_id + }; + const struct ffa_constituent_mem_region_desc expected_regions = { + .address = (uint64_t)ptr, .page_count = page_count + }; + check_descriptors(&expected_transaction, &expected_access_perm_desc, + &expected_regions, 1); +} + +TEST(sp_memory_management, sp_memory_donate_dynamic_is_supported_null) +{ + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_donate_dynamic_is_supported(NULL)); +} + +TEST(sp_memory_management, sp_memory_donate_dynamic_is_supported_ffa_error) +{ + bool flag = true; + struct ffa_interface_properties props = { 0 }; + expect_ffa_features(FFA_MEM_DONATE_32, &props, result); + LONGS_EQUAL(SP_RESULT_FFA(result), + sp_memory_donate_dynamic_is_supported(&flag)); + CHECK_FALSE(flag); +} + +TEST(sp_memory_management, sp_memory_donate_dynamic_is_supported) +{ + bool flag = false; + struct ffa_interface_properties props = { 0 }; + props.interface_properties[FFA_FEATURES_MEM_DYNAMIC_BUFFER_SUPPORT_INDEX] = + FFA_FEATURES_MEM_DYNAMIC_BUFFER_SUPPORT; + expect_ffa_features(FFA_MEM_DONATE_32, &props, FFA_OK); + LONGS_EQUAL(SP_RESULT_OK, sp_memory_donate_dynamic_is_supported(&flag)); + CHECK_TRUE(flag); +} + +TEST(sp_memory_management, sp_memory_lend_descriptor_null) +{ + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint64_t handle = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_lend(NULL, &acc_desc, 1, ®ions, 1, &handle)); + UNSIGNED_LONGLONGS_EQUAL(0, handle); +} + +TEST(sp_memory_management, sp_memory_lend_acc_descriptor_null) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint64_t handle = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_lend(&desc, NULL, 1, ®ions, 1, &handle)); + UNSIGNED_LONGLONGS_EQUAL(0, handle); +} + +TEST(sp_memory_management, sp_memory_lend_acc_desc_count_zero) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint64_t handle = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_lend(&desc, &acc_desc, 0, ®ions, 1, &handle)); + UNSIGNED_LONGLONGS_EQUAL(0, handle); +} + +TEST(sp_memory_management, sp_memory_lend_regions_null) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + uint64_t handle = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_lend(&desc, &acc_desc, 1, NULL, 1, &handle)); + UNSIGNED_LONGLONGS_EQUAL(0, handle); +} + +TEST(sp_memory_management, sp_memory_lend_region_count_zero) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint64_t handle = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_lend(&desc, &acc_desc, 1, ®ions, 0, &handle)); + UNSIGNED_LONGLONGS_EQUAL(0, handle); +} + +TEST(sp_memory_management, sp_memory_lend_handle_null) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_lend(&desc, &acc_desc, 1, ®ions, 1, NULL)); +} + +TEST(sp_memory_management, sp_memory_lend_get_tx_error) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint64_t handle = 1; + const sp_result result = SP_RESULT_INTERNAL_ERROR; + + expect_sp_rxtx_buffer_tx_get(&tx_buffer, &buffer_size, result); + LONGS_EQUAL(SP_RESULT_FFA(result), + sp_memory_lend(&desc, &acc_desc, 1, ®ions, 1, &handle)); + UNSIGNED_LONGLONGS_EQUAL(0, handle); +} + +TEST(sp_memory_management, sp_memory_lend_ffa_error) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint32_t region_count = 1; + uint64_t handle = 1; + const uint64_t expected_handle = 0; + const sp_result result = FFA_ABORTED; + const uint32_t expected_size = get_expected_size(region_count); + + expect_sp_rxtx_buffer_tx_get(&tx_buffer, &buffer_size, SP_RESULT_OK); + expect_ffa_mem_lend_rxtx(expected_size, expected_size, &expected_handle, + result); + LONGS_EQUAL(SP_RESULT_FFA(result), + sp_memory_lend(&desc, &acc_desc, 1, ®ions, region_count, + &handle)); + UNSIGNED_LONGLONGS_EQUAL(expected_handle, handle); +} + +TEST(sp_memory_management, sp_memory_lend) +{ + struct sp_memory_descriptor desc = { .sender_id = sender_id, + .tag = tag }; + struct sp_memory_access_descriptor acc_desc = { .receiver_id = + receiver_id }; + struct sp_memory_region regions = { .address = ptr, + .page_count = page_count }; + uint32_t region_count = 1; + uint64_t handle = 1; + const uint64_t expected_handle = 0x123456789abcdef0U; + const uint32_t expected_size = get_expected_size(region_count); + + expect_sp_rxtx_buffer_tx_get(&tx_buffer, &buffer_size, SP_RESULT_OK); + expect_ffa_mem_lend_rxtx(expected_size, expected_size, &expected_handle, + FFA_OK); + LONGS_EQUAL(SP_RESULT_OK, sp_memory_lend(&desc, &acc_desc, 1, ®ions, + region_count, &handle)); + UNSIGNED_LONGLONGS_EQUAL(expected_handle, handle); + + const struct ffa_mem_transaction_desc expected_transaction = { + .sender_id = sender_id, .tag = tag + }; + const struct ffa_mem_access_perm_desc expected_access_perm_desc = { + .endpoint_id = receiver_id + }; + const struct ffa_constituent_mem_region_desc expected_regions = { + .address = (uint64_t)ptr, .page_count = page_count + }; + check_descriptors(&expected_transaction, &expected_access_perm_desc, + &expected_regions, 1); +} + +TEST(sp_memory_management, sp_memory_lend_dynamic_descriptor_null) +{ + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint64_t handle = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_lend_dynamic(NULL, &acc_desc, 1, ®ions, 1, + &handle, + &tx_mem_transaction_buffer)); + UNSIGNED_LONGLONGS_EQUAL(0, handle); +} + +TEST(sp_memory_management, sp_memory_lend_dynamic_acc_descriptor_null) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint64_t handle = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_lend_dynamic(&desc, NULL, 1, ®ions, 1, &handle, + &tx_mem_transaction_buffer)); + UNSIGNED_LONGLONGS_EQUAL(0, handle); +} + +TEST(sp_memory_management, sp_memory_lend_dynamic_acc_desc_count_zero) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint64_t handle = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_lend_dynamic(&desc, &acc_desc, 0, ®ions, 1, + &handle, + &tx_mem_transaction_buffer)); + UNSIGNED_LONGLONGS_EQUAL(0, handle); +} + +TEST(sp_memory_management, sp_memory_lend_dynamic_regions_null) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + uint64_t handle = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_lend_dynamic(&desc, &acc_desc, 1, NULL, 1, + &handle, + &tx_mem_transaction_buffer)); + UNSIGNED_LONGLONGS_EQUAL(0, handle); +} + +TEST(sp_memory_management, sp_memory_lend_dynamic_region_count_zero) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint64_t handle = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_lend_dynamic(&desc, &acc_desc, 1, ®ions, 0, + &handle, + &tx_mem_transaction_buffer)); + UNSIGNED_LONGLONGS_EQUAL(0, handle); +} + +TEST(sp_memory_management, sp_memory_lend_dynamic_handle_null) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_lend_dynamic(&desc, &acc_desc, 1, ®ions, 1, + NULL, &tx_mem_transaction_buffer)); +} + +TEST(sp_memory_management, sp_memory_lend_dynamic_invalid_buffer) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint64_t handle = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_lend_dynamic(&desc, &acc_desc, 1, ®ions, 1, + &handle, NULL)); +} + +TEST(sp_memory_management, sp_memory_lend_dynamic_ffa_error) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint32_t region_count = 1; + uint64_t handle = 1; + const uint64_t expected_handle = 0; + const sp_result result = FFA_ABORTED; + const uint32_t expected_size = get_expected_size(region_count); + + expect_ffa_mem_lend(expected_size, expected_size, tx_buffer, + buffer_size / FFA_MEM_TRANSACTION_PAGE_SIZE, + &expected_handle, result); + LONGS_EQUAL(SP_RESULT_FFA(result), + sp_memory_lend_dynamic(&desc, &acc_desc, 1, ®ions, + region_count, &handle, + &tx_mem_transaction_buffer)); + UNSIGNED_LONGLONGS_EQUAL(expected_handle, handle); +} + +TEST(sp_memory_management, sp_memory_lend_dynamic) +{ + struct sp_memory_descriptor desc = { .sender_id = sender_id, + .tag = tag }; + struct sp_memory_access_descriptor acc_desc = { .receiver_id = + receiver_id }; + struct sp_memory_region regions = { .address = ptr, + .page_count = page_count }; + uint32_t region_count = 1; + uint64_t handle = 1; + const uint64_t expected_handle = 0x123456789abcdef0U; + const uint32_t expected_size = get_expected_size(region_count); + + expect_ffa_mem_lend(expected_size, expected_size, tx_buffer, + buffer_size / FFA_MEM_TRANSACTION_PAGE_SIZE, + &expected_handle, FFA_OK); + LONGS_EQUAL(SP_RESULT_OK, + sp_memory_lend_dynamic(&desc, &acc_desc, 1, ®ions, + region_count, &handle, + &tx_mem_transaction_buffer)); + UNSIGNED_LONGLONGS_EQUAL(expected_handle, handle); + + const struct ffa_mem_transaction_desc expected_transaction = { + .sender_id = sender_id, .tag = tag + }; + const struct ffa_mem_access_perm_desc expected_access_perm_desc = { + .endpoint_id = receiver_id + }; + const struct ffa_constituent_mem_region_desc expected_regions = { + .address = (uint64_t)ptr, .page_count = page_count + }; + check_descriptors(&expected_transaction, &expected_access_perm_desc, + &expected_regions, region_count); +} + +TEST(sp_memory_management, sp_memory_lend_dynamic_is_supported_null) +{ + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_lend_dynamic_is_supported(NULL)); +} + +TEST(sp_memory_management, sp_memory_lend_dynamic_is_supported_ffa_error) +{ + bool flag = true; + struct ffa_interface_properties props = { 0 }; + expect_ffa_features(FFA_MEM_LEND_32, &props, result); + LONGS_EQUAL(SP_RESULT_FFA(result), + sp_memory_lend_dynamic_is_supported(&flag)); + CHECK_FALSE(flag); +} + +TEST(sp_memory_management, sp_memory_lend_dynamic_is_supported) +{ + bool flag = false; + struct ffa_interface_properties props = { 0 }; + props.interface_properties[FFA_FEATURES_MEM_DYNAMIC_BUFFER_SUPPORT_INDEX] = + FFA_FEATURES_MEM_DYNAMIC_BUFFER_SUPPORT; + expect_ffa_features(FFA_MEM_LEND_32, &props, FFA_OK); + LONGS_EQUAL(SP_RESULT_OK, sp_memory_lend_dynamic_is_supported(&flag)); + CHECK_TRUE(flag); +} + +TEST(sp_memory_management, sp_memory_share_descriptor_null) +{ + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint64_t handle = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_share(NULL, &acc_desc, 1, ®ions, 1, &handle)); + UNSIGNED_LONGLONGS_EQUAL(0, handle); +} + +TEST(sp_memory_management, sp_memory_share_acc_descriptor_null) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint64_t handle = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_share(&desc, NULL, 1, ®ions, 1, &handle)); + UNSIGNED_LONGLONGS_EQUAL(0, handle); +} + +TEST(sp_memory_management, sp_memory_share_acc_desc_count_zero) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint64_t handle = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_share(&desc, &acc_desc, 0, ®ions, 1, &handle)); + UNSIGNED_LONGLONGS_EQUAL(0, handle); +} + +TEST(sp_memory_management, sp_memory_share_regions_null) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + uint64_t handle = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_share(&desc, &acc_desc, 1, NULL, 1, &handle)); + UNSIGNED_LONGLONGS_EQUAL(0, handle); +} + +TEST(sp_memory_management, sp_memory_share_region_count_zero) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint64_t handle = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_share(&desc, &acc_desc, 1, ®ions, 0, &handle)); + UNSIGNED_LONGLONGS_EQUAL(0, handle); +} + +TEST(sp_memory_management, sp_memory_share_handle_null) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_share(&desc, &acc_desc, 1, ®ions, 1, NULL)); +} + +TEST(sp_memory_management, sp_memory_share_get_tx_error) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint64_t handle = 1; + const sp_result result = SP_RESULT_INTERNAL_ERROR; + + expect_sp_rxtx_buffer_tx_get(&tx_buffer, &buffer_size, result); + LONGS_EQUAL(SP_RESULT_FFA(result), + sp_memory_share(&desc, &acc_desc, 1, ®ions, 1, &handle)); + UNSIGNED_LONGLONGS_EQUAL(0, handle); +} + +TEST(sp_memory_management, sp_memory_share_ffa_error) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint32_t region_count = 1; + uint64_t handle = 1; + const uint64_t expected_handle = 0; + const sp_result result = FFA_ABORTED; + const uint32_t expected_size = get_expected_size(region_count); + + expect_sp_rxtx_buffer_tx_get(&tx_buffer, &buffer_size, SP_RESULT_OK); + expect_ffa_mem_share_rxtx(expected_size, expected_size, + &expected_handle, result); + LONGS_EQUAL(SP_RESULT_FFA(result), + sp_memory_share(&desc, &acc_desc, 1, ®ions, region_count, + &handle)); + UNSIGNED_LONGLONGS_EQUAL(expected_handle, handle); +} + +TEST(sp_memory_management, sp_memory_share) +{ + struct sp_memory_descriptor desc = { .sender_id = sender_id, + .tag = tag }; + struct sp_memory_access_descriptor acc_desc = { .receiver_id = + receiver_id }; + struct sp_memory_region regions = { .address = ptr, + .page_count = page_count }; + uint32_t region_count = 1; + uint64_t handle = 1; + const uint64_t expected_handle = 0x123456789abcdef0U; + const uint32_t expected_size = get_expected_size(region_count); + + expect_sp_rxtx_buffer_tx_get(&tx_buffer, &buffer_size, SP_RESULT_OK); + expect_ffa_mem_share_rxtx(expected_size, expected_size, + &expected_handle, FFA_OK); + LONGS_EQUAL(SP_RESULT_OK, sp_memory_share(&desc, &acc_desc, 1, ®ions, + region_count, &handle)); + UNSIGNED_LONGLONGS_EQUAL(expected_handle, handle); + + const struct ffa_mem_transaction_desc expected_transaction = { + .sender_id = sender_id, .tag = tag + }; + const struct ffa_mem_access_perm_desc expected_access_perm_desc = { + .endpoint_id = receiver_id + }; + const struct ffa_constituent_mem_region_desc expected_regions = { + .address = (uint64_t)ptr, .page_count = page_count + }; + check_descriptors(&expected_transaction, &expected_access_perm_desc, + &expected_regions, region_count); +} + +TEST(sp_memory_management, sp_memory_share_dynamic_descriptor_null) +{ + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint64_t handle = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_share_dynamic(NULL, &acc_desc, 1, ®ions, 1, + &handle, + &tx_mem_transaction_buffer)); + UNSIGNED_LONGLONGS_EQUAL(0, handle); +} + +TEST(sp_memory_management, sp_memory_share_dynamic_acc_descriptor_null) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint64_t handle = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_share_dynamic(&desc, NULL, 1, ®ions, 1, + &handle, + &tx_mem_transaction_buffer)); + UNSIGNED_LONGLONGS_EQUAL(0, handle); +} + +TEST(sp_memory_management, sp_memory_share_dynamic_acc_desc_count_zero) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint64_t handle = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_share_dynamic(&desc, &acc_desc, 0, ®ions, 1, + &handle, + &tx_mem_transaction_buffer)); + UNSIGNED_LONGLONGS_EQUAL(0, handle); +} + +TEST(sp_memory_management, sp_memory_share_dynamic_regions_null) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + uint64_t handle = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_share_dynamic(&desc, &acc_desc, 1, NULL, 1, + &handle, + &tx_mem_transaction_buffer)); + UNSIGNED_LONGLONGS_EQUAL(0, handle); +} + +TEST(sp_memory_management, sp_memory_share_dynamic_region_count_zero) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint64_t handle = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_share_dynamic(&desc, &acc_desc, 1, ®ions, 0, + &handle, + &tx_mem_transaction_buffer)); + UNSIGNED_LONGLONGS_EQUAL(0, handle); +} + +TEST(sp_memory_management, sp_memory_share_dynamic_handle_null) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_share_dynamic(&desc, &acc_desc, 1, ®ions, 1, + NULL, &tx_mem_transaction_buffer)); +} + +TEST(sp_memory_management, sp_memory_share_dynamic_invalid_buffer) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint64_t handle = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_share_dynamic(&desc, &acc_desc, 1, ®ions, 1, + &handle, NULL)); + UNSIGNED_LONGLONGS_EQUAL(0, handle); +} + +TEST(sp_memory_management, sp_memory_share_dynamic_ffa_error) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint32_t region_count = 1; + uint64_t handle = 1; + const uint64_t expected_handle = 0; + const sp_result result = FFA_ABORTED; + const uint32_t expected_size = get_expected_size(region_count); + + expect_ffa_mem_share(expected_size, expected_size, tx_buffer, + buffer_size / FFA_MEM_TRANSACTION_PAGE_SIZE, + &expected_handle, result); + LONGS_EQUAL(SP_RESULT_FFA(result), + sp_memory_share_dynamic(&desc, &acc_desc, 1, ®ions, + region_count, &handle, + &tx_mem_transaction_buffer)); + UNSIGNED_LONGLONGS_EQUAL(expected_handle, handle); +} + +TEST(sp_memory_management, sp_memory_share_dynamic) +{ + struct sp_memory_descriptor desc = { .sender_id = sender_id, + .tag = tag }; + struct sp_memory_access_descriptor acc_desc = { .receiver_id = + receiver_id }; + struct sp_memory_region regions = { .address = ptr, + .page_count = page_count }; + uint32_t region_count = 1; + uint64_t handle = 1; + const uint64_t expected_handle = 0x123456789abcdef0U; + const uint32_t expected_size = get_expected_size(region_count); + + expect_ffa_mem_share(expected_size, expected_size, tx_buffer, + buffer_size / FFA_MEM_TRANSACTION_PAGE_SIZE, + &expected_handle, FFA_OK); + LONGS_EQUAL(SP_RESULT_OK, + sp_memory_share_dynamic(&desc, &acc_desc, 1, ®ions, + region_count, &handle, + &tx_mem_transaction_buffer)); + UNSIGNED_LONGLONGS_EQUAL(expected_handle, handle); + + const struct ffa_mem_transaction_desc expected_transaction = { + .sender_id = sender_id, .tag = tag + }; + const struct ffa_mem_access_perm_desc expected_access_perm_desc = { + .endpoint_id = receiver_id + }; + const struct ffa_constituent_mem_region_desc expected_regions = { + .address = (uint64_t)ptr, .page_count = page_count + }; + check_descriptors(&expected_transaction, &expected_access_perm_desc, + &expected_regions, region_count); +} + +TEST(sp_memory_management, sp_memory_share_dynamic_is_supported_null) +{ + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_share_dynamic_is_supported(NULL)); +} + +TEST(sp_memory_management, sp_memory_share_dynamic_is_supported_ffa_error) +{ + bool flag = true; + struct ffa_interface_properties props = { 0 }; + expect_ffa_features(FFA_MEM_SHARE_32, &props, result); + LONGS_EQUAL(SP_RESULT_FFA(result), + sp_memory_share_dynamic_is_supported(&flag)); + CHECK_FALSE(flag); +} + +TEST(sp_memory_management, sp_memory_share_dynamic_is_supported) +{ + bool flag = false; + struct ffa_interface_properties props = { 0 }; + props.interface_properties[FFA_FEATURES_MEM_DYNAMIC_BUFFER_SUPPORT_INDEX] = + FFA_FEATURES_MEM_DYNAMIC_BUFFER_SUPPORT; + expect_ffa_features(FFA_MEM_SHARE_32, &props, FFA_OK); + LONGS_EQUAL(SP_RESULT_OK, sp_memory_share_dynamic_is_supported(&flag)); + CHECK_TRUE(flag); +} + +TEST(sp_memory_management, sp_memory_retrieve_descriptor_null) +{ + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint32_t out_region_count = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_retrieve(NULL, &acc_desc, ®ions, 1, + &out_region_count, handle)); + UNSIGNED_LONGS_EQUAL(0, out_region_count); +} + +TEST(sp_memory_management, sp_memory_retrieve_acc_desc_null) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint32_t out_region_count = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_retrieve(&desc, NULL, ®ions, 1, + &out_region_count, handle)); + UNSIGNED_LONGS_EQUAL(0, out_region_count); +} + +TEST(sp_memory_management, sp_memory_retrieve_regions_null) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + uint32_t out_region_count = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_retrieve(&desc, &acc_desc, NULL, 1, + &out_region_count, handle)); + UNSIGNED_LONGS_EQUAL(0, out_region_count); +} + +TEST(sp_memory_management, sp_memory_retrieve_out_region_count_null) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_retrieve(&desc, &acc_desc, ®ions, 1, NULL, + handle)); +} + +TEST(sp_memory_management, sp_memory_retrieve_get_tx_error) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint32_t out_region_count = 1; + + expect_sp_rxtx_buffer_tx_get(&tx_buffer, &buffer_size, result); + LONGS_EQUAL(result, sp_memory_retrieve(&desc, &acc_desc, ®ions, 1, + &out_region_count, handle)); + UNSIGNED_LONGS_EQUAL(0, out_region_count); +} + +TEST(sp_memory_management, sp_memory_retrieve_get_rx_error) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint32_t out_region_count = 1; + + expect_sp_rxtx_buffer_tx_get(&tx_buffer, &buffer_size, SP_RESULT_OK); + expect_sp_rxtx_buffer_rx_get(&rx_buffer, &buffer_size, result); + LONGS_EQUAL(result, sp_memory_retrieve(&desc, &acc_desc, ®ions, 1, + &out_region_count, handle)); + UNSIGNED_LONGS_EQUAL(0, out_region_count); +} + +TEST(sp_memory_management, sp_memory_retrieve_ffa_error) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint32_t in_region_count = 1; + uint32_t out_region_count = 1; + ffa_result result = FFA_ABORTED; + const uint32_t expected_size = get_expected_size(in_region_count); + const uint32_t resp_total_length = 0; + const uint32_t resp_fragment_length = 0; + + expect_sp_rxtx_buffer_tx_get(&tx_buffer, &buffer_size, SP_RESULT_OK); + expect_sp_rxtx_buffer_rx_get(&rx_buffer, &buffer_size, SP_RESULT_OK); + expect_ffa_mem_retrieve_req_rxtx(expected_size, expected_size, + &resp_total_length, + &resp_fragment_length, result); + LONGS_EQUAL(SP_RESULT_FFA(result), + sp_memory_retrieve(&desc, &acc_desc, ®ions, + in_region_count, &out_region_count, + handle)); + UNSIGNED_LONGS_EQUAL(0, out_region_count); +} + +TEST(sp_memory_management, sp_memory_retrieve_fragmented_response) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint32_t in_region_count = 1; + uint32_t out_region_count = 1; + const uint32_t expected_size = get_expected_size(in_region_count); + const uint32_t resp_total_length = 1; + const uint32_t resp_fragment_length = 0; + + expect_sp_rxtx_buffer_tx_get(&tx_buffer, &buffer_size, SP_RESULT_OK); + expect_sp_rxtx_buffer_rx_get(&rx_buffer, &buffer_size, SP_RESULT_OK); + expect_ffa_mem_retrieve_req_rxtx(expected_size, expected_size, + &resp_total_length, + &resp_fragment_length, FFA_OK); + LONGS_EQUAL(SP_RESULT_INTERNAL_ERROR, + sp_memory_retrieve(&desc, &acc_desc, ®ions, + in_region_count, &out_region_count, + handle)); + UNSIGNED_LONGS_EQUAL(0, out_region_count); +} + +TEST(sp_memory_management, sp_memory_retrieve_in_out) +{ + struct sp_memory_descriptor desc = { .sender_id = sender_id, + .tag = tag }; + struct sp_memory_access_descriptor acc_desc = { .receiver_id = + receiver_id }; + struct sp_memory_region regions = { .address = ptr, + .page_count = page_count }; + uint32_t in_region_count = 1; + uint32_t out_region_count = 1; + ffa_result result = FFA_ABORTED; + const uint32_t expected_size = get_expected_size(in_region_count); + const uint32_t resp_total_length = expected_size; + const uint32_t resp_fragment_length = expected_size; + + /* Filling RX buffer */ + ffa_init_mem_transaction_desc(&rx_mem_transaction_buffer, sender_id + 1, + 0, 0, handle, tag); + ffa_add_mem_access_desc(&rx_mem_transaction_buffer, receiver_id + 1, 0, + 0); + ffa_add_memory_region(&rx_mem_transaction_buffer, ptr, page_count); + + /* Exercising */ + expect_sp_rxtx_buffer_tx_get(&tx_buffer, &buffer_size, SP_RESULT_OK); + expect_sp_rxtx_buffer_rx_get(&rx_buffer, &buffer_size, SP_RESULT_OK); + expect_ffa_mem_retrieve_req_rxtx(expected_size, expected_size, + &resp_total_length, + &resp_fragment_length, FFA_OK); + LONGS_EQUAL(SP_RESULT_OK, + sp_memory_retrieve(&desc, &acc_desc, ®ions, + in_region_count, &out_region_count, + handle)); + UNSIGNED_LONGS_EQUAL(1, out_region_count); + + /* Checking TX buffer */ + const struct ffa_mem_transaction_desc expected_transaction = { + .sender_id = sender_id, .handle = handle, .tag = tag + }; + const struct ffa_mem_access_perm_desc expected_access_perm_desc = { + .endpoint_id = receiver_id + }; + const struct ffa_constituent_mem_region_desc expected_regions = { + .address = (uint64_t)ptr, .page_count = page_count + }; + check_descriptors(&expected_transaction, &expected_access_perm_desc, + &expected_regions, in_region_count); + + /* Checking output */ + UNSIGNED_LONGS_EQUAL(sender_id + 1, desc.sender_id); + UNSIGNED_LONGS_EQUAL(receiver_id + 1, acc_desc.receiver_id); + UNSIGNED_LONGLONGS_EQUAL(tag, desc.tag); +} + +TEST(sp_memory_management, sp_memory_retrieve_dynamic_descriptor_null) +{ + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint32_t out_region_count = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_retrieve_dynamic(NULL, &acc_desc, ®ions, 1, + &out_region_count, handle, + &tx_mem_transaction_buffer)); + UNSIGNED_LONGS_EQUAL(0, out_region_count); +} + +TEST(sp_memory_management, sp_memory_retrieve_dynamic_acc_desc_null) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint32_t out_region_count = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_retrieve_dynamic(&desc, NULL, ®ions, 1, + &out_region_count, handle, + &tx_mem_transaction_buffer)); + UNSIGNED_LONGS_EQUAL(0, out_region_count); +} + +TEST(sp_memory_management, sp_memory_retrieve_dynamic_regions_null) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + uint32_t out_region_count = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_retrieve_dynamic(&desc, &acc_desc, NULL, 1, + &out_region_count, handle, + &tx_mem_transaction_buffer)); + UNSIGNED_LONGS_EQUAL(0, out_region_count); +} + +TEST(sp_memory_management, sp_memory_retrieve_dynamic_out_region_count_null) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_retrieve_dynamic(&desc, &acc_desc, ®ions, 1, + NULL, handle, + &tx_mem_transaction_buffer)); +} + +TEST(sp_memory_management, sp_memory_retrieve_dynamic_handle_zero) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint32_t out_region_count = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_retrieve_dynamic(&desc, &acc_desc, ®ions, 1, + &out_region_count, 0, + &tx_mem_transaction_buffer)); +} + +TEST(sp_memory_management, sp_memory_retrieve_dynamic_buffer_null) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint32_t out_region_count = 1; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_retrieve_dynamic(&desc, &acc_desc, ®ions, 1, + &out_region_count, handle, + NULL)); +} + +TEST(sp_memory_management, sp_memory_retrieve_dynamic_ffa_error) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint32_t in_region_count = 1; + uint32_t out_region_count = 1; + ffa_result result = FFA_ABORTED; + const uint32_t expected_size = get_expected_size(in_region_count); + const uint32_t resp_total_length = 0; + const uint32_t resp_fragment_length = 0; + + expect_ffa_mem_retrieve_req(expected_size, expected_size, tx_buffer, + buffer_size / FFA_MEM_TRANSACTION_PAGE_SIZE, + &resp_total_length, &resp_fragment_length, + result); + LONGS_EQUAL(SP_RESULT_FFA(result), + sp_memory_retrieve_dynamic(&desc, &acc_desc, ®ions, + in_region_count, + &out_region_count, handle, + &tx_mem_transaction_buffer)); + UNSIGNED_LONGS_EQUAL(0, out_region_count); +} + +TEST(sp_memory_management, sp_memory_retrieve_dynamic_fragmented_response) +{ + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + struct sp_memory_region regions = { 0 }; + uint32_t in_region_count = 1; + uint32_t out_region_count = 1; + ffa_result result = FFA_ABORTED; + const uint32_t expected_size = get_expected_size(in_region_count); + const uint32_t resp_total_length = 1; + const uint32_t resp_fragment_length = 0; + + expect_ffa_mem_retrieve_req(expected_size, expected_size, tx_buffer, + buffer_size / FFA_MEM_TRANSACTION_PAGE_SIZE, + &resp_total_length, &resp_fragment_length, + FFA_OK); + LONGS_EQUAL(SP_RESULT_INTERNAL_ERROR, + sp_memory_retrieve_dynamic(&desc, &acc_desc, ®ions, + in_region_count, + &out_region_count, handle, + &tx_mem_transaction_buffer)); + UNSIGNED_LONGS_EQUAL(0, out_region_count); +} + +TEST(sp_memory_management, sp_memory_retrieve_dynamic_in_out) +{ + struct sp_memory_descriptor desc = { .sender_id = sender_id, + .tag = tag }; + struct sp_memory_access_descriptor acc_desc = { .receiver_id = + receiver_id }; + struct sp_memory_region regions = { .address = ptr, + .page_count = page_count }; + uint32_t in_region_count = 1; + uint32_t out_region_count = 1; + ffa_result result = FFA_ABORTED; + const uint32_t expected_size = get_expected_size(in_region_count); + const uint32_t resp_total_length = expected_size; + const uint32_t resp_fragment_length = expected_size; + + /* Exercising */ + expect_ffa_mem_retrieve_req(expected_size, expected_size, tx_buffer, + buffer_size / FFA_MEM_TRANSACTION_PAGE_SIZE, + &resp_total_length, &resp_fragment_length, + FFA_OK); + LONGS_EQUAL(SP_RESULT_OK, sp_memory_retrieve_dynamic( + &desc, &acc_desc, ®ions, + in_region_count, &out_region_count, + handle, &tx_mem_transaction_buffer)); + UNSIGNED_LONGS_EQUAL(1, out_region_count); + + /* Checking TX buffer */ + const struct ffa_mem_transaction_desc expected_transaction = { + .sender_id = sender_id, .handle = handle, .tag = tag + }; + const struct ffa_mem_access_perm_desc expected_access_perm_desc = { + .endpoint_id = receiver_id + }; + const struct ffa_constituent_mem_region_desc expected_regions = { + .address = (uint64_t)ptr, .page_count = page_count + }; + check_descriptors(&expected_transaction, &expected_access_perm_desc, + &expected_regions, in_region_count); + + /* Checking output */ + UNSIGNED_LONGS_EQUAL(sender_id, desc.sender_id); + UNSIGNED_LONGS_EQUAL(receiver_id, acc_desc.receiver_id); + UNSIGNED_LONGLONGS_EQUAL(tag, desc.tag); +} + +TEST(sp_memory_management, sp_memory_retrieve_dynamic_is_supported_null) +{ + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_retrieve_dynamic_is_supported(NULL)); +} + +TEST(sp_memory_management, sp_memory_retrieve_dynamic_is_supported_ffa_error) +{ + bool flag = true; + struct ffa_interface_properties props = { 0 }; + expect_ffa_features(FFA_MEM_RETRIEVE_REQ_32, &props, result); + LONGS_EQUAL(SP_RESULT_FFA(result), + sp_memory_retrieve_dynamic_is_supported(&flag)); + CHECK_FALSE(flag); +} + +TEST(sp_memory_management, sp_memory_retrieve_dynamic_is_supported) +{ + bool flag = false; + struct ffa_interface_properties props = { 0 }; + props.interface_properties[FFA_FEATURES_MEM_DYNAMIC_BUFFER_SUPPORT_INDEX] = + FFA_FEATURES_MEM_DYNAMIC_BUFFER_SUPPORT; + expect_ffa_features(FFA_MEM_RETRIEVE_REQ_32, &props, FFA_OK); + LONGS_EQUAL(SP_RESULT_OK, + sp_memory_retrieve_dynamic_is_supported(&flag)); + CHECK_TRUE(flag); +} + +TEST(sp_memory_management, sp_memory_relinquish_endpoints_null) +{ + struct sp_memory_transaction_flags flags = { 0 }; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_relinquish(handle, NULL, 1, &flags)); +} + +TEST(sp_memory_management, sp_memory_relinquish_endpoints_count_zero) +{ + uint16_t endpoints = 0; + struct sp_memory_transaction_flags flags = { 0 }; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_relinquish(handle, &endpoints, 0, &flags)); +} + +TEST(sp_memory_management, sp_memory_relinquish_endpoints_flags_null) +{ + uint16_t endpoints = 0; + struct sp_memory_transaction_flags flags = { 0 }; + + LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, + sp_memory_relinquish(handle, &endpoints, 1, NULL)); +} + +TEST(sp_memory_management, sp_memory_relinquish_get_tx_error) +{ + uint16_t endpoints = 0; + struct sp_memory_transaction_flags flags = { 0 }; + + expect_sp_rxtx_buffer_tx_get(&tx_buffer, &buffer_size, result); + LONGS_EQUAL(result, + sp_memory_relinquish(handle, &endpoints, 1, &flags)); +} + +TEST(sp_memory_management, sp_memory_relinquish_small_buffer) +{ + assert_environment_t env; + uint16_t endpoints = 0; + struct sp_memory_transaction_flags flags = { 0 }; + size_t small_buffer_size = 1; + + expect_sp_rxtx_buffer_tx_get(&tx_buffer, &small_buffer_size, + SP_RESULT_OK); + if (SETUP_ASSERT_ENVIRONMENT(env)) { + LONGS_EQUAL(result, sp_memory_relinquish(handle, &endpoints, 1, + &flags)); + } +} + +TEST(sp_memory_management, sp_memory_relinquish_ffa_error) +{ + uint16_t endpoints = 0; + struct sp_memory_transaction_flags flags = { 0 }; + const ffa_result result = FFA_ABORTED; + + expect_sp_rxtx_buffer_tx_get(&tx_buffer, &buffer_size, SP_RESULT_OK); + expect_ffa_mem_relinquish(result); + LONGS_EQUAL(SP_RESULT_FFA(result), + sp_memory_relinquish(handle, &endpoints, 1, &flags)); +} + +TEST(sp_memory_management, sp_memory_relinquish) +{ + uint16_t endpoints = 12345; + struct sp_memory_transaction_flags flags = { 0 }; + struct ffa_mem_relinquish_desc *relinquish_desc = NULL; + + expect_sp_rxtx_buffer_tx_get(&tx_buffer, &buffer_size, SP_RESULT_OK); + expect_ffa_mem_relinquish(FFA_OK); + LONGS_EQUAL(SP_RESULT_OK, + sp_memory_relinquish(handle, &endpoints, 1, &flags)); + + relinquish_desc = (struct ffa_mem_relinquish_desc *)tx_buffer; + UNSIGNED_LONGLONGS_EQUAL(handle, relinquish_desc->handle); + UNSIGNED_LONGS_EQUAL(0, relinquish_desc->flags); + UNSIGNED_LONGS_EQUAL(1, relinquish_desc->endpoint_count); + UNSIGNED_LONGS_EQUAL(endpoints, relinquish_desc->endpoints[0]); +} + +TEST(sp_memory_management, sp_memory_relinquish_two_endpoints) +{ + uint16_t endpoints[] = { 12345, 5432 }; + struct sp_memory_transaction_flags flags = { 0 }; + struct ffa_mem_relinquish_desc *relinquish_desc = NULL; + + expect_sp_rxtx_buffer_tx_get(&tx_buffer, &buffer_size, SP_RESULT_OK); + expect_ffa_mem_relinquish(FFA_OK); + LONGS_EQUAL(SP_RESULT_OK, + sp_memory_relinquish(handle, endpoints, 2, &flags)); + + relinquish_desc = (struct ffa_mem_relinquish_desc *)tx_buffer; + UNSIGNED_LONGLONGS_EQUAL(handle, relinquish_desc->handle); + UNSIGNED_LONGS_EQUAL(0, relinquish_desc->flags); + UNSIGNED_LONGS_EQUAL(2, relinquish_desc->endpoint_count); + UNSIGNED_LONGS_EQUAL(endpoints[0], relinquish_desc->endpoints[0]); + UNSIGNED_LONGS_EQUAL(endpoints[1], relinquish_desc->endpoints[1]); +} + +TEST(sp_memory_management, sp_memory_reclaim_ffa_error) +{ + ffa_result result = FFA_ABORTED; + + expect_ffa_mem_reclaim(handle, flags, result); + LONGS_EQUAL(SP_RESULT_FFA(result), sp_memory_reclaim(handle, flags)); +} + +TEST(sp_memory_management, sp_memory_reclaim) +{ + expect_ffa_mem_reclaim(handle, flags, FFA_OK); + LONGS_EQUAL(SP_RESULT_OK, sp_memory_reclaim(handle, flags)); +} diff --git a/components/messaging/ffa/libsp/test/test_sp_memory_management_internals.cpp b/components/messaging/ffa/libsp/test/test_sp_memory_management_internals.cpp new file mode 100644 index 000000000..99366efab --- /dev/null +++ b/components/messaging/ffa/libsp/test/test_sp_memory_management_internals.cpp @@ -0,0 +1,551 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2020-2021, Arm Limited. All rights reserved. + */ + +#include <CppUTestExt/MockSupport.h> +#include <CppUTest/TestHarness.h> +#include "../include/sp_memory_management.h" +#include "mock_assert.h" +#include "mock_ffa_api.h" +#include "mock_sp_rxtx.h" +#include <setjmp.h> +#include <stdint.h> +#include <string.h> + +/* Picked functions */ +extern "C" { +bool is_valid_buffer(struct ffa_mem_transaction_buffer *buffer); +uint8_t build_mem_region_attr(enum sp_memory_type type, + union sp_memory_attr *sp_mem_attr); +void parse_mem_region_attr(uint8_t attr, enum sp_memory_type *type, + union sp_memory_attr *sp_mem_attr); +uint32_t build_mem_flags(struct sp_memory_transaction_flags *flags); +void parse_mem_flags(uint32_t raw, struct sp_memory_transaction_flags *flags); +void parse_descriptors(struct ffa_mem_transaction_buffer *buffer, + struct sp_memory_descriptor *descriptor, + struct sp_memory_access_descriptor *acc_desc, + uint32_t acc_desc_count, + struct sp_memory_region regions[], + uint32_t *region_count); +} + +TEST_GROUP(sp_memory_management_internals) +{ + TEST_SETUP() + { + memset(&attr, 0x00, sizeof(attr)); + memset(&flags, 0x00, sizeof(flags)); + } + + union sp_memory_attr attr; + struct sp_memory_transaction_flags flags; +}; + +TEST(sp_memory_management_internals, is_valid_buffer_null) +{ + CHECK_FALSE(is_valid_buffer(NULL)); +} + +TEST(sp_memory_management_internals, is_valid_buffer_address_not_aligned) +{ + struct ffa_mem_transaction_buffer buffer = { .buffer = (void *)1, + .length = 0 }; + CHECK_FALSE(is_valid_buffer(&buffer)); +} + +TEST(sp_memory_management_internals, is_valid_buffer_size_not_aligned) +{ + struct ffa_mem_transaction_buffer buffer = { .buffer = (void *)0, + .length = 1 }; + CHECK_FALSE(is_valid_buffer(&buffer)); +} + +TEST(sp_memory_management_internals, is_valid_buffer) +{ + struct ffa_mem_transaction_buffer buffer = { .buffer = (void *)0, + .length = 0 }; + CHECK_TRUE(is_valid_buffer(&buffer)); +} + +TEST(sp_memory_management_internals, build_mem_region_attr_reserved_type) +{ + assert_environment_t env; + uint8_t result = 0; + + attr.device_memory = sp_device_memory_nGnRnE; + + if (SETUP_ASSERT_ENVIRONMENT(env)) { + build_mem_region_attr(sp_memory_type_reserved, &attr); + } +} + +TEST(sp_memory_management_internals, build_mem_region_attr_device_nGnRnE) +{ + uint8_t result = 0; + uint8_t expected_result = 0; + + attr.device_memory = sp_device_memory_nGnRnE; + + expected_result = FFA_MEM_REGION_ATTR_MEMORY_TYPE_DEVICE + << FFA_MEM_REGION_ATTR_MEMORY_TYPE_SHIFT; + expected_result |= FFA_MEM_REGION_ATTR_DEVICE_MEM_ATTR_NGNRNE + << FFA_MEM_REGION_ATTR_DEVICE_MEM_ATTR_SHIFT; + + result = build_mem_region_attr(sp_memory_type_device_memory, &attr); + BYTES_EQUAL(expected_result, result); +} + +TEST(sp_memory_management_internals, build_mem_region_attr_device_nGnRE) +{ + uint8_t result = 0; + uint8_t expected_result = 0; + + attr.device_memory = sp_device_memory_nGnRE; + + expected_result = FFA_MEM_REGION_ATTR_MEMORY_TYPE_DEVICE + << FFA_MEM_REGION_ATTR_MEMORY_TYPE_SHIFT; + expected_result |= FFA_MEM_REGION_ATTR_DEVICE_MEM_ATTR_NGNRE + << FFA_MEM_REGION_ATTR_DEVICE_MEM_ATTR_SHIFT; + + result = build_mem_region_attr(sp_memory_type_device_memory, &attr); + BYTES_EQUAL(expected_result, result); +} + +TEST(sp_memory_management_internals, build_mem_region_attr_device_nGRE) +{ + uint8_t result = 0; + uint8_t expected_result = 0; + + attr.device_memory = sp_device_memory_nGRE; + + expected_result = FFA_MEM_REGION_ATTR_MEMORY_TYPE_DEVICE + << FFA_MEM_REGION_ATTR_MEMORY_TYPE_SHIFT; + expected_result |= FFA_MEM_REGION_ATTR_DEVICE_MEM_ATTR_NGRE + << FFA_MEM_REGION_ATTR_DEVICE_MEM_ATTR_SHIFT; + + result = build_mem_region_attr(sp_memory_type_device_memory, &attr); + BYTES_EQUAL(expected_result, result); +} + +TEST(sp_memory_management_internals, build_mem_region_attr_device_GRE) +{ + uint8_t result = 0; + uint8_t expected_result = 0; + + attr.device_memory = sp_device_memory_GRE; + + expected_result = FFA_MEM_REGION_ATTR_MEMORY_TYPE_DEVICE + << FFA_MEM_REGION_ATTR_MEMORY_TYPE_SHIFT; + expected_result |= FFA_MEM_REGION_ATTR_DEVICE_MEM_ATTR_GRE + << FFA_MEM_REGION_ATTR_DEVICE_MEM_ATTR_SHIFT; + + result = build_mem_region_attr(sp_memory_type_device_memory, &attr); + BYTES_EQUAL(expected_result, result); +} + +TEST(sp_memory_management_internals, + build_mem_region_attr_normal_cache_reserved0) +{ + assert_environment_t env; + uint8_t result = 0; + uint8_t expected_result = 0; + + attr.normal_memory.cacheability = sp_cacheability_reserved0; + attr.normal_memory.shareability = sp_shareability_non_shareable; + + if (SETUP_ASSERT_ENVIRONMENT(env)) { + build_mem_region_attr(sp_memory_type_normal_memory, &attr); + } +} + +TEST(sp_memory_management_internals, + build_mem_region_attr_normal_cache_reserved2) +{ + assert_environment_t env; + uint8_t result = 0; + uint8_t expected_result = 0; + + attr.normal_memory.cacheability = sp_cacheability_reserved2; + attr.normal_memory.shareability = sp_shareability_non_shareable; + + if (SETUP_ASSERT_ENVIRONMENT(env)) { + build_mem_region_attr(sp_memory_type_normal_memory, &attr); + } +} + +TEST(sp_memory_management_internals, + build_mem_region_attr_normal_share_reserved) +{ + assert_environment_t env; + uint8_t result = 0; + uint8_t expected_result = 0; + + attr.normal_memory.cacheability = sp_cacheability_non_cacheable; + attr.normal_memory.shareability = sp_shareability_reserved; + + if (SETUP_ASSERT_ENVIRONMENT(env)) { + build_mem_region_attr(sp_memory_type_normal_memory, &attr); + } +} + +TEST(sp_memory_management_internals, build_mem_region_attr_normal_non_non) +{ + uint8_t result = 0; + uint8_t expected_result = 0; + + attr.normal_memory.cacheability = sp_cacheability_non_cacheable; + attr.normal_memory.shareability = sp_shareability_non_shareable; + + expected_result = FFA_MEM_REGION_ATTR_MEMORY_TYPE_NORMAL + << FFA_MEM_REGION_ATTR_MEMORY_TYPE_SHIFT; + expected_result |= FFA_MEM_REGION_ATTR_CACHEABILITY_NON_CACHEABLE + << FFA_MEM_REGION_ATTR_CACHEABILITY_SHIFT; + expected_result |= FFA_MEM_REGION_ATTR_SHAREABILITY_NON_SHAREABLE + << FFA_MEM_REGION_ATTR_SHAREABILITY_SHIFT; + + result = build_mem_region_attr(sp_memory_type_normal_memory, &attr); + BYTES_EQUAL(expected_result, result); +} + +TEST(sp_memory_management_internals, build_mem_region_attr_normal_writeback_non) +{ + uint8_t result = 0; + uint8_t expected_result = 0; + + attr.normal_memory.cacheability = sp_cacheability_write_back; + attr.normal_memory.shareability = sp_shareability_non_shareable; + + expected_result = FFA_MEM_REGION_ATTR_MEMORY_TYPE_NORMAL + << FFA_MEM_REGION_ATTR_MEMORY_TYPE_SHIFT; + expected_result |= FFA_MEM_REGION_ATTR_CACHEABILITY_WRITE_BACK + << FFA_MEM_REGION_ATTR_CACHEABILITY_SHIFT; + expected_result |= FFA_MEM_REGION_ATTR_SHAREABILITY_NON_SHAREABLE + << FFA_MEM_REGION_ATTR_SHAREABILITY_SHIFT; + + result = build_mem_region_attr(sp_memory_type_normal_memory, &attr); + BYTES_EQUAL(expected_result, result); +} + +TEST(sp_memory_management_internals, build_mem_region_attr_normal_non_inner) +{ + uint8_t result = 0; + uint8_t expected_result = 0; + + attr.normal_memory.cacheability = sp_cacheability_non_cacheable; + attr.normal_memory.shareability = sp_shareability_inner_shareable; + + expected_result = FFA_MEM_REGION_ATTR_MEMORY_TYPE_NORMAL + << FFA_MEM_REGION_ATTR_MEMORY_TYPE_SHIFT; + expected_result |= FFA_MEM_REGION_ATTR_CACHEABILITY_NON_CACHEABLE + << FFA_MEM_REGION_ATTR_CACHEABILITY_SHIFT; + expected_result |= FFA_MEM_REGION_ATTR_SHAREABILITY_INNER_SHAREABLE + << FFA_MEM_REGION_ATTR_SHAREABILITY_SHIFT; + + result = build_mem_region_attr(sp_memory_type_normal_memory, &attr); + BYTES_EQUAL(expected_result, result); +} + +TEST(sp_memory_management_internals, build_mem_region_attr_normal_non_outer) +{ + uint8_t result = 0; + uint8_t expected_result = 0; + + attr.normal_memory.cacheability = sp_cacheability_non_cacheable; + attr.normal_memory.shareability = sp_shareability_outer_shareable; + + expected_result = FFA_MEM_REGION_ATTR_MEMORY_TYPE_NORMAL + << FFA_MEM_REGION_ATTR_MEMORY_TYPE_SHIFT; + expected_result |= FFA_MEM_REGION_ATTR_CACHEABILITY_NON_CACHEABLE + << FFA_MEM_REGION_ATTR_CACHEABILITY_SHIFT; + expected_result |= FFA_MEM_REGION_ATTR_SHAREABILITY_OUTER_SHAREABLE + << FFA_MEM_REGION_ATTR_SHAREABILITY_SHIFT; + + result = build_mem_region_attr(sp_memory_type_normal_memory, &attr); + BYTES_EQUAL(expected_result, result); +} + +TEST(sp_memory_management_internals, parse_mem_region_attr_not_specified) +{ + enum sp_memory_type type = sp_memory_type_reserved; + uint8_t raw = 0; + + parse_mem_region_attr(raw, &type, &attr); + CHECK_EQUAL(sp_memory_type_not_specified, type); +} + +TEST(sp_memory_management_internals, parse_mem_region_attr_device) +{ + enum sp_memory_type type = sp_memory_type_reserved; + uint8_t raw = 0; + + raw = FFA_MEM_REGION_ATTR_MEMORY_TYPE_DEVICE + << FFA_MEM_REGION_ATTR_MEMORY_TYPE_SHIFT; + raw |= FFA_MEM_REGION_ATTR_DEVICE_MEM_ATTR_GRE + << FFA_MEM_REGION_ATTR_DEVICE_MEM_ATTR_SHIFT; + + parse_mem_region_attr(raw, &type, &attr); + CHECK_EQUAL(sp_memory_type_device_memory, type); + CHECK_EQUAL(sp_device_memory_GRE, attr.device_memory); +} + +TEST(sp_memory_management_internals, parse_mem_region_attr_normal) +{ + enum sp_memory_type type = sp_memory_type_reserved; + uint8_t raw = 0; + + raw = FFA_MEM_REGION_ATTR_MEMORY_TYPE_NORMAL + << FFA_MEM_REGION_ATTR_MEMORY_TYPE_SHIFT; + raw |= FFA_MEM_REGION_ATTR_CACHEABILITY_WRITE_BACK + << FFA_MEM_REGION_ATTR_CACHEABILITY_SHIFT; + raw |= FFA_MEM_REGION_ATTR_SHAREABILITY_INNER_SHAREABLE + << FFA_MEM_REGION_ATTR_SHAREABILITY_SHIFT; + + parse_mem_region_attr(raw, &type, &attr); + CHECK_EQUAL(sp_memory_type_normal_memory, type); + CHECK_EQUAL(sp_cacheability_write_back, + attr.normal_memory.cacheability); + CHECK_EQUAL(sp_shareability_inner_shareable, + attr.normal_memory.shareability); +} + +TEST(sp_memory_management_internals, build_mem_flags_none) +{ + uint32_t result = 0; + + result = build_mem_flags(&flags); + UNSIGNED_LONGS_EQUAL(0, result); +} + +TEST(sp_memory_management_internals, build_mem_flags_zero_memory) +{ + uint32_t result = 0; + + flags.zero_memory = true; + result = build_mem_flags(&flags); + UNSIGNED_LONGS_EQUAL(FFA_MEM_TRANSACTION_FLAGS_ZERO_MEMORY, result); +} + +TEST(sp_memory_management_internals, build_mem_flags_time_slicing) +{ + uint32_t result = 0; + + flags.operation_time_slicing = true; + result = build_mem_flags(&flags); + UNSIGNED_LONGS_EQUAL(FFA_MEM_TRANSACTION_FLAGS_OPERATION_TIME_SLICING, + result); +} + +TEST(sp_memory_management_internals, build_mem_flags_zero_mem_after_relinquish) +{ + uint32_t result = 0; + + flags.zero_memory_after_relinquish = true; + result = build_mem_flags(&flags); + UNSIGNED_LONGS_EQUAL( + FFA_MEM_TRANSACTION_FLAGS_ZERO_MEMORY_AFTER_RELINQIUSH, result); +} + +TEST(sp_memory_management_internals, build_mem_flags_type) +{ + uint32_t result = 0; + uint32_t expected_result = 0; + + expected_result = FFA_MEM_TRANSACTION_FLAGS_TYPE_DONATE + << FFA_MEM_TRANSACTION_FLAGS_TYPE_SHIFT; + + flags.transaction_type = sp_memory_transaction_type_donate; + result = build_mem_flags(&flags); + UNSIGNED_LONGS_EQUAL(expected_result, result); +} + +TEST(sp_memory_management_internals, build_mem_flags_alignment_hint_invalid) +{ + assert_environment_t env; + uint32_t result = 0; + + flags.alignment_hint = + FFA_MEM_TRANSACTION_FLAGS_ALIGNMENT_HINT_MASK + 1; + + if (SETUP_ASSERT_ENVIRONMENT(env)) { + build_mem_flags(&flags); + } +} + +TEST(sp_memory_management_internals, build_mem_flags_alignment_hint) +{ + uint32_t result = 0; + uint32_t expected_result = 0; + + expected_result = FFA_MEM_TRANSACTION_FLAGS_ALIGNMENT_HINT_VALID; + expected_result |= FFA_MEM_TRANSACTION_FLAGS_ALIGNMENT_HINT_MASK + << FFA_MEM_TRANSACTION_FLAGS_ALIGNMENT_HINT_SHIFT; + + flags.alignment_hint = FFA_MEM_TRANSACTION_FLAGS_ALIGNMENT_HINT_MASK; + result = build_mem_flags(&flags); + UNSIGNED_LONGS_EQUAL(expected_result, result); +} + +TEST(sp_memory_management_internals, parse_mem_flags_none) +{ + uint32_t raw = 0; + + parse_mem_flags(raw, &flags); + CHECK_FALSE(flags.zero_memory); + CHECK_FALSE(flags.operation_time_slicing); + CHECK_FALSE(flags.zero_memory_after_relinquish); + CHECK_EQUAL(sp_memory_transaction_type_relayer_specified, + flags.transaction_type); + UNSIGNED_LONGS_EQUAL(0, flags.alignment_hint); +} + +TEST(sp_memory_management_internals, parse_mem_flags_zero_memory) +{ + uint32_t raw = 0; + + raw |= FFA_MEM_TRANSACTION_FLAGS_ZERO_MEMORY; + + parse_mem_flags(raw, &flags); + CHECK_TRUE(flags.zero_memory); + CHECK_FALSE(flags.operation_time_slicing); + CHECK_FALSE(flags.zero_memory_after_relinquish); + CHECK_EQUAL(sp_memory_transaction_type_relayer_specified, + flags.transaction_type); + UNSIGNED_LONGS_EQUAL(0, flags.alignment_hint); +} + +TEST(sp_memory_management_internals, parse_mem_flags_operation_time_slicing) +{ + uint32_t raw = 0; + + raw |= FFA_MEM_TRANSACTION_FLAGS_OPERATION_TIME_SLICING; + + parse_mem_flags(raw, &flags); + CHECK_FALSE(flags.zero_memory); + CHECK_TRUE(flags.operation_time_slicing); + CHECK_FALSE(flags.zero_memory_after_relinquish); + CHECK_EQUAL(sp_memory_transaction_type_relayer_specified, + flags.transaction_type); + UNSIGNED_LONGS_EQUAL(0, flags.alignment_hint); +} + +TEST(sp_memory_management_internals, + parse_mem_flags_zero_memory_after_relinquish) +{ + uint32_t raw = 0; + + raw |= FFA_MEM_TRANSACTION_FLAGS_ZERO_MEMORY_AFTER_RELINQIUSH; + + parse_mem_flags(raw, &flags); + CHECK_FALSE(flags.zero_memory); + CHECK_FALSE(flags.operation_time_slicing); + CHECK_TRUE(flags.zero_memory_after_relinquish); + CHECK_EQUAL(sp_memory_transaction_type_relayer_specified, + flags.transaction_type); + UNSIGNED_LONGS_EQUAL(0, flags.alignment_hint); +} + +TEST(sp_memory_management_internals, parse_mem_flags_type) +{ + uint32_t raw = 0; + + raw |= FFA_MEM_TRANSACTION_FLAGS_TYPE_DONATE + << FFA_MEM_TRANSACTION_FLAGS_TYPE_SHIFT; + + parse_mem_flags(raw, &flags); + CHECK_FALSE(flags.zero_memory); + CHECK_FALSE(flags.operation_time_slicing); + CHECK_FALSE(flags.zero_memory_after_relinquish); + CHECK_EQUAL(sp_memory_transaction_type_donate, flags.transaction_type); + UNSIGNED_LONGS_EQUAL(0, flags.alignment_hint); +} + +TEST(sp_memory_management_internals, parse_mem_flags_alignment_hint) +{ + uint32_t raw = 0; + + raw |= FFA_MEM_TRANSACTION_FLAGS_ALIGNMENT_HINT_VALID; + raw |= FFA_MEM_TRANSACTION_FLAGS_ALIGNMENT_HINT_MASK + << FFA_MEM_TRANSACTION_FLAGS_ALIGNMENT_HINT_SHIFT; + + parse_mem_flags(raw, &flags); + CHECK_FALSE(flags.zero_memory); + CHECK_FALSE(flags.operation_time_slicing); + CHECK_FALSE(flags.zero_memory_after_relinquish); + CHECK_EQUAL(sp_memory_transaction_type_relayer_specified, + flags.transaction_type); + UNSIGNED_LONGS_EQUAL(FFA_MEM_TRANSACTION_FLAGS_ALIGNMENT_HINT_MASK, + flags.alignment_hint); +} + +TEST(sp_memory_management_internals, parse_descriptors_different_tag) +{ + assert_environment_t env; + uint8_t buffer_area[FFA_MEM_TRANSACTION_PAGE_SIZE] = { 0 }; + struct ffa_mem_transaction_buffer buffer = { 0 }; + struct sp_memory_descriptor desc = { 0 }; + + desc.tag = 1; + + ffa_init_mem_transaction_buffer(buffer_area, sizeof(buffer_area), + &buffer); + ffa_init_mem_transaction_desc(&buffer, 0, 0, 0, 0, 2); + + if (SETUP_ASSERT_ENVIRONMENT(env)) { + parse_descriptors(&buffer, &desc, NULL, 0, NULL, 0); + } +} + +TEST(sp_memory_management_internals, parse_descriptors_zero_descriptors) +{ + assert_environment_t env; + uint8_t buffer_area[FFA_MEM_TRANSACTION_PAGE_SIZE] = { 0 }; + struct ffa_mem_transaction_buffer buffer = { 0 }; + struct sp_memory_descriptor desc = { 0 }; + + ffa_init_mem_transaction_buffer(buffer_area, sizeof(buffer_area), + &buffer); + ffa_init_mem_transaction_desc(&buffer, 0, 0, 0, 0, 0); + + if (SETUP_ASSERT_ENVIRONMENT(env)) { + parse_descriptors(&buffer, &desc, NULL, 0, NULL, 0); + } +} + +TEST(sp_memory_management_internals, parse_descriptors_invalid_desc_count) +{ + assert_environment_t env; + uint8_t buffer_area[FFA_MEM_TRANSACTION_PAGE_SIZE] = { 0 }; + struct ffa_mem_transaction_buffer buffer = { 0 }; + struct sp_memory_descriptor desc = { 0 }; + + ffa_init_mem_transaction_buffer(buffer_area, sizeof(buffer_area), + &buffer); + ffa_init_mem_transaction_desc(&buffer, 0, 0, 0, 0, 0); + ffa_add_mem_access_desc(&buffer, 1, 0, 0); + + if (SETUP_ASSERT_ENVIRONMENT(env)) { + parse_descriptors(&buffer, &desc, NULL, 0, NULL, 0); + } +} + +TEST(sp_memory_management_internals, parse_descriptors_invalid_region_count) +{ + assert_environment_t env; + uint8_t buffer_area[FFA_MEM_TRANSACTION_PAGE_SIZE] = { 0 }; + struct ffa_mem_transaction_buffer buffer = { 0 }; + struct sp_memory_descriptor desc = { 0 }; + struct sp_memory_access_descriptor acc_desc = { 0 }; + uint32_t region_count = 0; + + ffa_init_mem_transaction_buffer(buffer_area, sizeof(buffer_area), + &buffer); + ffa_init_mem_transaction_desc(&buffer, 0, 0, 0, 0, 0); + ffa_add_mem_access_desc(&buffer, 1, 0, 0); + ffa_add_memory_region(&buffer, 0, 0); + + if (SETUP_ASSERT_ENVIRONMENT(env)) { + parse_descriptors(&buffer, &desc, &acc_desc, 1, NULL, + ®ion_count); + } +} diff --git a/components/messaging/ffa/libsp/tests.cmake b/components/messaging/ffa/libsp/tests.cmake index 39adc9734..7096916b8 100644 --- a/components/messaging/ffa/libsp/tests.cmake +++ b/components/messaging/ffa/libsp/tests.cmake @@ -96,3 +96,33 @@ unit_test_add_suite( COMPILE_DEFINITIONS -DARM64 ) + +unit_test_add_suite( + NAME libsp_sp_memory_management + SOURCES + ${CMAKE_CURRENT_LIST_DIR}/test/test_sp_memory_management.cpp + ${CMAKE_CURRENT_LIST_DIR}/sp_memory_management.c + ${CMAKE_CURRENT_LIST_DIR}/ffa_memory_descriptors.c + ${CMAKE_CURRENT_LIST_DIR}/test/mock_assert.cpp + ${CMAKE_CURRENT_LIST_DIR}/test/mock_ffa_api.cpp + ${CMAKE_CURRENT_LIST_DIR}/test/mock_sp_rxtx.cpp + INCLUDE_DIRECTORIES + ${CMAKE_CURRENT_LIST_DIR}/include/ + ${PROJECT_PATH}/components/common/utils/include + COMPILE_DEFINITIONS + -DARM64 +) + +unit_test_add_suite( + NAME libsp_sp_memory_management_internals + SOURCES + ${CMAKE_CURRENT_LIST_DIR}/test/test_sp_memory_management_internals.cpp + ${CMAKE_CURRENT_LIST_DIR}/test/sp_memory_management_internals.yml + ${CMAKE_CURRENT_LIST_DIR}/ffa_memory_descriptors.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 +) |