aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/common/fwu_nvm.h26
-rw-r--r--include/runtime_services/ffa_helpers.h19
-rw-r--r--plat/arm/fvp/include/platform_def.h25
-rw-r--r--plat/arm/juno/include/platform_def.h25
-rw-r--r--spm/cactus/cactus_def.h14
-rw-r--r--spm/cactus/cactus_ffa_tests.c154
-rw-r--r--spm/cactus/cactus_main.c21
-rw-r--r--spm/cactus/cactus_tests.h4
-rw-r--r--spm/cactus/cactus_tests_misc.c41
-rw-r--r--tftf/tests/runtime_services/secure_service/ffa_helpers.c83
-rw-r--r--tftf/tests/runtime_services/secure_service/test_ffa_direct_messaging.c63
-rw-r--r--tftf/tests/runtime_services/secure_service/test_ffa_features.c79
-rw-r--r--tftf/tests/tests-spm.mk1
-rw-r--r--tftf/tests/tests-spm.xml6
-rw-r--r--tftf/tests/tests.mk5
15 files changed, 417 insertions, 149 deletions
diff --git a/include/common/fwu_nvm.h b/include/common/fwu_nvm.h
index 3865d4b..d6557ae 100644
--- a/include/common/fwu_nvm.h
+++ b/include/common/fwu_nvm.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,32 +11,10 @@
#include <platform_def.h>
#define FIP_IMAGE_UPDATE_DONE_FLAG (0xDEADBEEF)
-/*
- * This is the temporary ddr address for loading backup fip.bin
- * image from NVM which is used for replacing original fip.bin
- * This address is chosen such that the NS_BL2U can be expanded
- * in future and also considering the large size of fip.bin.
- */
-#define FIP_IMAGE_TMP_DDR_ADDRESS (DRAM_BASE + 0x100000)
+
#define FWU_TFTF_TESTCASE_BUFFER_OFFSET \
(TFTF_NVM_OFFSET + TFTF_STATE_OFFSET(testcase_buffer))
-/*
- * This offset is used to corrupt data in fip.bin
- * The offset is from the base where fip.bin is
- * located in NVM. This particular value is chosen
- * to make sure the corruption is done beyond fip header.
- */
-#define FIP_CORRUPT_OFFSET (0x400)
-
-/*
- * This is the base address for backup fip.bin image in NVM
- * which is used for replacing original fip.bin
- * This address is chosen such that it can stay with all
- * the other images in the NVM.
- */
-#define FIP_BKP_ADDRESS (FLASH_BASE + 0x1000000)
-
/* Writes the buffer to the flash at offset with length equal to
* size
* Returns: STATUS_FAIL, STATUS_SUCCESS, STATUS_OUT_OF_RESOURCES
diff --git a/include/runtime_services/ffa_helpers.h b/include/runtime_services/ffa_helpers.h
index d4ef803..0692aa9 100644
--- a/include/runtime_services/ffa_helpers.h
+++ b/include/runtime_services/ffa_helpers.h
@@ -28,11 +28,25 @@ typedef unsigned short ffa_vcpu_count_t;
#include <stdint.h>
+struct mailbox_buffers {
+ const void *recv;
+ void *send;
+};
+
+struct ffa_partition_info {
+ /** The ID of the VM the information is about */
+ ffa_vm_id_t id;
+ /** The number of execution contexts implemented by the partition */
+ uint16_t exec_context;
+ /** The Partition's properties, e.g. supported messaging methods */
+ uint32_t properties;
+};
+
/*
* TODO: In the future this file should be placed in a common folder, and not
* under tftf. The functions in this file are also used by SPs for SPM tests.
*/
-
+bool check_spmc_execution_level(void);
smc_ret_values ffa_msg_send_direct_req(uint32_t source_id, uint32_t dest_id, uint32_t message);
smc_ret_values ffa_msg_send_direct_req64(uint32_t source_id, uint32_t dest_id, uint64_t message);
smc_ret_values ffa_run(uint32_t dest_id, uint32_t vcpu_id);
@@ -42,6 +56,9 @@ smc_ret_values ffa_msg_wait(void);
smc_ret_values ffa_msg_send_direct_resp(ffa_vm_id_t source_id,
ffa_vm_id_t dest_id, uint32_t message);
smc_ret_values ffa_error(int32_t error_code);
+smc_ret_values ffa_features(uint32_t feature);
+smc_ret_values ffa_partition_info_get(const uint32_t uuid[4]);
+smc_ret_values ffa_rx_release(void);
#endif /* __ASSEMBLY__ */
diff --git a/plat/arm/fvp/include/platform_def.h b/plat/arm/fvp/include/platform_def.h
index d5dc818..3abeb03 100644
--- a/plat/arm/fvp/include/platform_def.h
+++ b/plat/arm/fvp/include/platform_def.h
@@ -60,6 +60,31 @@
#define PLAT_ARM_FWU_FIP_SIZE (0x100000)
/*******************************************************************************
+ * This is the temporary DDR address for loading backup fip.bin
+ * image from NVM which is used for replacing original fip.bin
+ * This address is chosen such that the NS_BL2U can be expanded
+ * in future and also considering the large size of fip.bin.
+ ******************************************************************************/
+#define FIP_IMAGE_TMP_DDR_ADDRESS (DRAM_BASE + 0x100000)
+
+/*******************************************************************************
+ * This offset is used to corrupt data in fip.bin
+ * The offset is from the base where fip.bin is
+ * located in NVM. This particular value is chosen
+ * to make sure the corruption is done beyond fip header.
+ ******************************************************************************/
+#define FIP_CORRUPT_OFFSET (0x400)
+
+/*******************************************************************************
+ * This offset is used to corrupt data in fip.bin
+ * This is the base address for backup fip.bin image in NVM
+ * which is used for replacing original fip.bin
+ * This address is chosen such that it can stay with all
+ * the other images in the NVM.
+ ******************************************************************************/
+#define FIP_BKP_ADDRESS (FLASH_BASE + 0x1000000)
+
+/*******************************************************************************
* Base address and size for non-trusted SRAM.
******************************************************************************/
#define NSRAM_BASE (0x2e000000)
diff --git a/plat/arm/juno/include/platform_def.h b/plat/arm/juno/include/platform_def.h
index 03a7124..0f9bb77 100644
--- a/plat/arm/juno/include/platform_def.h
+++ b/plat/arm/juno/include/platform_def.h
@@ -71,6 +71,31 @@
#define PLAT_ARM_FWU_FIP_SIZE (0x100000)
/*******************************************************************************
+ * This is the temporary DDR address for loading backup fip.bin
+ * image from NVM which is used for replacing original fip.bin
+ * This address is chosen such that the NS_BL2U can be expanded
+ * in future and also considering the large size of fip.bin.
+ ******************************************************************************/
+#define FIP_IMAGE_TMP_DDR_ADDRESS (DRAM_BASE + 0x100000)
+
+/*******************************************************************************
+ * This offset is used to corrupt data in fip.bin
+ * The offset is from the base where fip.bin is
+ * located in NVM. This particular value is chosen
+ * to make sure the corruption is done beyond fip header.
+ ******************************************************************************/
+#define FIP_CORRUPT_OFFSET (0x400)
+
+/*******************************************************************************
+ * This offset is used to corrupt data in fip.bin
+ * This is the base address for backup fip.bin image in NVM
+ * which is used for replacing original fip.bin
+ * This address is chosen such that it can stay with all
+ * the other images in the NVM.
+ ******************************************************************************/
+#define FIP_BKP_ADDRESS (FLASH_BASE + 0x1000000)
+
+/*******************************************************************************
* Base address and size for non-trusted SRAM.
******************************************************************************/
#define NSRAM_BASE (0x2e000000)
diff --git a/spm/cactus/cactus_def.h b/spm/cactus/cactus_def.h
index a0adb23..0d3df2e 100644
--- a/spm/cactus/cactus_def.h
+++ b/spm/cactus/cactus_def.h
@@ -28,4 +28,18 @@
#define CACTUS_TX_BASE CACTUS_RX_BASE + PAGE_SIZE
#define CACTUS_RX_TX_SIZE PAGE_SIZE * 2
+/*
+ * RX/TX buffer helpers.
+ */
+#define get_sp_rx_start(sp_id) (CACTUS_RX_BASE + ((sp_id - 1) * CACTUS_RX_TX_SIZE))
+#define get_sp_rx_end(sp_id) (CACTUS_RX_BASE + ((sp_id - 1) * CACTUS_RX_TX_SIZE) + PAGE_SIZE)
+#define get_sp_tx_start(sp_id) (CACTUS_TX_BASE + ((sp_id - 1) * CACTUS_RX_TX_SIZE))
+#define get_sp_tx_end(sp_id) (CACTUS_TX_BASE + ((sp_id - 1) * CACTUS_RX_TX_SIZE) + PAGE_SIZE)
+
+/*
+ * UUID of secure partition as defined in the respective manifests.
+ */
+#define PRIMARY_UUID {0xb4b5671e, 0x4a904fe1, 0xb81ffb13, 0xdae1dacb}
+#define SECONDARY_UUID {0xd1582309, 0xf02347b9, 0x827c4464, 0xf5578fc8}
+
#endif /* CACTUS_DEF_H */
diff --git a/spm/cactus/cactus_ffa_tests.c b/spm/cactus/cactus_ffa_tests.c
index 411cc9f..25c20b0 100644
--- a/spm/cactus/cactus_ffa_tests.c
+++ b/spm/cactus/cactus_ffa_tests.c
@@ -4,8 +4,9 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
-#include <errno.h>
#include <debug.h>
+#include <errno.h>
+#include <cactus_def.h>
#include <ffa_helpers.h>
#include <sp_helpers.h>
@@ -13,20 +14,146 @@
#define FFA_MAJOR 1U
#define FFA_MINOR 0U
-void ffa_tests(void)
+static const uint32_t primary_uuid[4] = PRIMARY_UUID;
+static const uint32_t secondary_uuid[4] = SECONDARY_UUID;
+static const uint32_t null_uuid[4] = {0};
+
+struct feature_test {
+ const char *test_name;
+ unsigned int feature;
+ unsigned int expected_ret;
+};
+
+static const struct feature_test test_target[] = {
+ {"FFA_ERROR_32 check", FFA_ERROR, FFA_SUCCESS_SMC32},
+ {"FFA_SUCCESS_32 check", FFA_SUCCESS_SMC32, FFA_SUCCESS_SMC32},
+ {"FFA_INTERRUPT_32 check", FFA_INTERRUPT, FFA_SUCCESS_SMC32},
+ {"FFA_VERSION_32 check", FFA_VERSION, FFA_SUCCESS_SMC32},
+ {"FFA_FEATURES_32 check", FFA_FEATURES, FFA_SUCCESS_SMC32},
+ {"FFA_RX_RELEASE_32 check", FFA_RX_RELEASE, FFA_SUCCESS_SMC32},
+ {"FFA_RXTX_MAP_32 check", FFA_RXTX_MAP_SMC32, FFA_ERROR},
+ {"FFA_RXTX_MAP_64 check", FFA_RXTX_MAP_SMC64, FFA_SUCCESS_SMC32},
+ {"FFA_RXTX_UNMAP_32 check", FFA_RXTX_UNMAP, FFA_ERROR},
+ {"FFA_PARTITION_INFO_GET_32 check", FFA_PARTITION_INFO_GET, FFA_SUCCESS_SMC32},
+ {"FFA_ID_GET_32 check", FFA_ID_GET, FFA_SUCCESS_SMC32},
+ {"FFA_MSG_POLL_32 check", FFA_MSG_POLL, FFA_SUCCESS_SMC32},
+ {"FFA_MSG_WAIT_32 check", FFA_MSG_WAIT, FFA_SUCCESS_SMC32},
+ {"FFA_YIELD_32 check", FFA_MSG_YIELD, FFA_SUCCESS_SMC32},
+ {"FFA_RUN_32 check", FFA_MSG_RUN, FFA_SUCCESS_SMC32},
+ {"FFA_MSG_SEND_32 check", FFA_MSG_SEND, FFA_SUCCESS_SMC32},
+ {"FFA_MEM_DONATE_32 check", FFA_MEM_DONATE_SMC32, FFA_SUCCESS_SMC32},
+ {"FFA_MEM_LEND_32 check", FFA_MEM_LEND_SMC32, FFA_SUCCESS_SMC32},
+ {"FFA_MEM_SHARE_32 check", FFA_MEM_SHARE_SMC32, FFA_SUCCESS_SMC32},
+ {"FFA_MEM_RETRIEVE_REQ_32 check", FFA_MEM_RETRIEVE_REQ_SMC32, FFA_SUCCESS_SMC32},
+ {"FFA_MEM_RETRIEVE_RESP_32 check", FFA_MEM_RETRIEVE_RESP, FFA_SUCCESS_SMC32},
+ {"FFA_MEM_RELINQUISH_32 check", FFA_MEM_RELINQUISH, FFA_SUCCESS_SMC32},
+ {"FFA_MEM_RECLAIM_32 check", FFA_MEM_RECLAIM, FFA_SUCCESS_SMC32},
+ {"Check non-existent command", 0xFFFF, FFA_ERROR}
+};
+
+/*
+ * Test FFA_FEATURES interface.
+ */
+static void ffa_features_test(void)
{
- const char *test_ffa = "FFA Interfaces";
- const char *test_ffa_version = "FFA Version interface";
+ const char *test_features = "FFA Features interface";
+ smc_ret_values ffa_ret;
+ unsigned int i, test_target_size =
+ sizeof(test_target) / sizeof(struct feature_test);
- announce_test_section_start(test_ffa);
+ announce_test_section_start(test_features);
+
+ for (i = 0U; i < test_target_size; i++) {
+ announce_test_start(test_target[i].test_name);
+
+ ffa_ret = ffa_features(test_target[i].feature);
+ expect(ffa_ret.ret0, test_target[i].expected_ret);
+ if (test_target[i].expected_ret == FFA_ERROR) {
+ expect(ffa_ret.ret2, FFA_ERROR_NOT_SUPPORTED);
+ }
+
+ announce_test_end(test_target[i].test_name);
+ }
+
+ announce_test_section_end(test_features);
+}
+
+static void ffa_partition_info_helper(struct mailbox_buffers *mb, const uint32_t uuid[4],
+ const struct ffa_partition_info *expected,
+ const uint16_t expected_size)
+{
+ smc_ret_values ret = ffa_partition_info_get(uuid);
+ unsigned int i;
+ expect(ret.ret0, FFA_SUCCESS_SMC32);
+
+ struct ffa_partition_info *info = (struct ffa_partition_info *)(mb->recv);
+ for (i = 0U; i < expected_size; i++) {
+ expect(info[i].id, expected[i].id);
+ expect(info[i].exec_context, expected[i].exec_context);
+ expect(info[i].properties, expected[i].properties);
+ }
+
+ ret = ffa_rx_release();
+ expect(ret.ret0, FFA_SUCCESS_SMC32);
+}
+
+static void ffa_partition_info_wrong_test(void)
+{
+ const char *test_wrong_uuid = "Request wrong UUID";
+ uint32_t uuid[4] = {1};
+
+ announce_test_start(test_wrong_uuid);
+
+ smc_ret_values ret = ffa_partition_info_get(uuid);
+ expect(ret.ret0, FFA_ERROR);
+ expect(ret.ret2, FFA_ERROR_INVALID_PARAMETER);
+
+ announce_test_end(test_wrong_uuid);
+}
+
+static void ffa_partition_info_get_test(struct mailbox_buffers *mb)
+{
+ const char *test_partition_info = "FFA Partition info interface";
+ const char *test_primary = "Get primary partition info";
+ const char *test_secondary = "Get secondary partition info";
+ const char *test_all = "Get all partitions info";
+
+ const struct ffa_partition_info expected_info[] = {
+ {.id = SPM_VM_ID_FIRST, .exec_context = 8, .properties = 0}, /* Primary partition info */
+ {.id = 2, .exec_context = 2, .properties = 0} /* Secondary partition info */
+ };
+
+ announce_test_section_start(test_partition_info);
+
+ announce_test_start(test_secondary);
+ ffa_partition_info_helper(mb, secondary_uuid, &expected_info[1], 1);
+ announce_test_end(test_secondary);
+
+ announce_test_start(test_primary);
+ ffa_partition_info_helper(mb, primary_uuid, &expected_info[0], 1);
+ announce_test_end(test_primary);
+
+ announce_test_start(test_all);
+ ffa_partition_info_helper(mb, null_uuid, expected_info, 2);
+ announce_test_end(test_all);
+
+ ffa_partition_info_wrong_test();
+
+ announce_test_section_end(test_partition_info);
+}
+
+void ffa_version_test(void)
+{
+ const char *test_ffa_version = "FFA Version interface";
announce_test_start(test_ffa_version);
smc_ret_values ret = ffa_version(MAKE_FFA_VERSION(FFA_MAJOR, FFA_MINOR));
- uint32_t spm_version = (uint32_t)(0xFFFFFFFF & ret.ret0);
+ uint32_t spm_version = (uint32_t)ret.ret0;
- bool ffa_version_compatible = ((spm_version >> FFA_VERSION_MAJOR_SHIFT) == FFA_MAJOR &&
- (spm_version & FFA_VERSION_MINOR_MASK) >= FFA_MINOR);
+ bool ffa_version_compatible =
+ ((spm_version >> FFA_VERSION_MAJOR_SHIFT) == FFA_MAJOR &&
+ (spm_version & FFA_VERSION_MINOR_MASK) >= FFA_MINOR);
NOTICE("FFA_VERSION returned %u.%u; Compatible: %i\n",
spm_version >> FFA_VERSION_MAJOR_SHIFT,
@@ -36,6 +163,17 @@ void ffa_tests(void)
expect((int)ffa_version_compatible, (int)true);
announce_test_end(test_ffa_version);
+}
+
+void ffa_tests(struct mailbox_buffers *mb)
+{
+ const char *test_ffa = "FFA Interfaces";
+
+ announce_test_section_start(test_ffa);
+
+ ffa_features_test();
+ ffa_version_test();
+ ffa_partition_info_get_test(mb);
announce_test_section_end(test_ffa);
}
diff --git a/spm/cactus/cactus_main.c b/spm/cactus/cactus_main.c
index 49764ec..31906d5 100644
--- a/spm/cactus/cactus_main.c
+++ b/spm/cactus/cactus_main.c
@@ -102,12 +102,12 @@ static void cactus_print_memory_layout(unsigned int vm_id)
(void *)CACTUS_BSS_START, (void *)CACTUS_BSS_END);
NOTICE(" RX : %p - %p\n",
- (void *)(CACTUS_RX_BASE + ((vm_id - 1) * CACTUS_RX_TX_SIZE)),
- (void *)(CACTUS_TX_BASE + ((vm_id - 1) * CACTUS_RX_TX_SIZE)));
+ (void *)get_sp_rx_start(vm_id),
+ (void *)get_sp_rx_end(vm_id));
NOTICE(" TX : %p - %p\n",
- (void *)(CACTUS_TX_BASE + ((vm_id - 1) * CACTUS_RX_TX_SIZE)),
- (void *)(CACTUS_RX_BASE + (vm_id * CACTUS_RX_TX_SIZE)));
+ (void *)get_sp_tx_start(vm_id),
+ (void *)get_sp_tx_end(vm_id));
}
static void cactus_plat_configure_mmu(unsigned int vm_id)
@@ -129,13 +129,13 @@ static void cactus_plat_configure_mmu(unsigned int vm_id)
CACTUS_BSS_END - CACTUS_BSS_START,
MT_RW_DATA);
- mmap_add_region((CACTUS_RX_BASE + ((vm_id - 1) * CACTUS_RX_TX_SIZE)),
- (CACTUS_RX_BASE + ((vm_id - 1) * CACTUS_RX_TX_SIZE)),
+ mmap_add_region(get_sp_rx_start(vm_id),
+ get_sp_rx_start(vm_id),
(CACTUS_RX_TX_SIZE / 2),
MT_RO_DATA);
- mmap_add_region((CACTUS_TX_BASE + ((vm_id - 1) * CACTUS_RX_TX_SIZE)),
- (CACTUS_TX_BASE + ((vm_id - 1) * CACTUS_RX_TX_SIZE)),
+ mmap_add_region(get_sp_tx_start(vm_id),
+ get_sp_tx_start(vm_id),
(CACTUS_RX_TX_SIZE / 2),
MT_RW_DATA);
@@ -147,6 +147,7 @@ void __dead2 cactus_main(void)
{
assert(IS_IN_EL1() != 0);
+ struct mailbox_buffers mb;
/* Clear BSS */
memset((void *)CACTUS_BSS_START,
0, CACTUS_BSS_END - CACTUS_BSS_START);
@@ -159,6 +160,8 @@ void __dead2 cactus_main(void)
}
ffa_vm_id_t ffa_id = ffa_id_ret.ret2 & 0xffff;
+ mb.send = (void *) get_sp_tx_start(ffa_id);
+ mb.recv = (void *) get_sp_rx_start(ffa_id);
/* Configure and enable Stage-1 MMU, enable D-Cache */
cactus_plat_configure_mmu(ffa_id);
@@ -190,7 +193,7 @@ void __dead2 cactus_main(void)
cactus_print_memory_layout(ffa_id);
/* Invoking Tests */
- ffa_tests();
+ ffa_tests(&mb);
/* End up to message loop */
message_loop(ffa_id);
diff --git a/spm/cactus/cactus_tests.h b/spm/cactus/cactus_tests.h
index 23586f5..2e13a6f 100644
--- a/spm/cactus/cactus_tests.h
+++ b/spm/cactus/cactus_tests.h
@@ -7,6 +7,8 @@
#ifndef CACTUS_TESTS_H
#define CACTUS_TESTS_H
+#include <ffa_helpers.h>
+
/*
* Test functions
*/
@@ -14,7 +16,7 @@
/*
* Test to FFA interfaces.
*/
-void ffa_tests(void);
+void ffa_tests(struct mailbox_buffers *mb);
/*
* Test other things like the version number returned by SPM.
diff --git a/spm/cactus/cactus_tests_misc.c b/spm/cactus/cactus_tests_misc.c
deleted file mode 100644
index 39eb752..0000000
--- a/spm/cactus/cactus_tests_misc.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <debug.h>
-#include <errno.h>
-#include <sp_helpers.h>
-#include <spm_svc.h>
-#include <sprt_client.h>
-#include <sprt_svc.h>
-#include <stdint.h>
-
-#include "cactus.h"
-#include "cactus_tests.h"
-
-/*
- * Miscellaneous SPM tests.
- */
-void misc_tests(void)
-{
- int32_t ret;
-
- const char *test_sect_desc = "miscellaneous";
-
- announce_test_section_start(test_sect_desc);
-
- const char *test_version_sprt = "SPRT version check";
-
- announce_test_start(test_version_sprt);
- ret = sprt_version();
- INFO("Version = 0x%x (%u.%u)\n", ret,
- (ret >> SPRT_VERSION_MAJOR_SHIFT) & SPRT_VERSION_MAJOR_MASK,
- ret & SPRT_VERSION_MINOR_MASK);
- expect(ret, SPRT_VERSION_COMPILED);
- announce_test_end(test_version_sprt);
-
- announce_test_section_end(test_sect_desc);
-}
diff --git a/tftf/tests/runtime_services/secure_service/ffa_helpers.c b/tftf/tests/runtime_services/secure_service/ffa_helpers.c
index 9955c7c..c90cac8 100644
--- a/tftf/tests/runtime_services/secure_service/ffa_helpers.c
+++ b/tftf/tests/runtime_services/secure_service/ffa_helpers.c
@@ -9,6 +9,11 @@
#include <ffa_helpers.h>
#include <ffa_svc.h>
+#define OPTEE_FFA_GET_API_VERSION (0)
+#define OPTEE_FFA_GET_OS_VERSION (1)
+#define OPTEE_FFA_GET_OS_VERSION_MAJOR (3)
+#define OPTEE_FFA_GET_OS_VERSION_MINOR (8)
+
/*-----------------------------------------------------------------------------
* FFA_RUN
*
@@ -108,6 +113,49 @@ smc_ret_values ffa_msg_send_direct_req64(uint32_t source_id, uint32_t dest_id,
}
/*
+ * check_spmc_execution_level
+ *
+ * Attempt sending impdef protocol messages to OP-TEE through direct messaging.
+ * Criteria for detecting OP-TEE presence is that responses match defined
+ * version values. In the case of SPMC running at S-EL2 (and Cactus instances
+ * running at S-EL1) the response will not match the pre-defined version IDs.
+ *
+ * Returns true if SPMC is probed as being OP-TEE at S-EL1.
+ *
+ */
+bool check_spmc_execution_level(void)
+{
+ unsigned int is_optee_spmc_criteria = 0U;
+ smc_ret_values ret_values;
+
+ /*
+ * Send a first OP-TEE-defined protocol message through
+ * FFA direct message.
+ *
+ */
+ ret_values = ffa_msg_send_direct_req(HYP_ID, SP_ID(1),
+ OPTEE_FFA_GET_API_VERSION);
+ if ((ret_values.ret3 == FFA_VERSION_MAJOR) &&
+ (ret_values.ret4 == FFA_VERSION_MINOR)) {
+ is_optee_spmc_criteria++;
+ }
+
+ /*
+ * Send a second OP-TEE-defined protocol message through
+ * FFA direct message.
+ *
+ */
+ ret_values = ffa_msg_send_direct_req(HYP_ID, SP_ID(1),
+ OPTEE_FFA_GET_OS_VERSION);
+ if ((ret_values.ret3 == OPTEE_FFA_GET_OS_VERSION_MAJOR) &&
+ (ret_values.ret4 == OPTEE_FFA_GET_OS_VERSION_MINOR)) {
+ is_optee_spmc_criteria++;
+ }
+
+ return (is_optee_spmc_criteria == 2U);
+}
+
+/*
* FFA Version ABI helper.
* Version fields:
* -Bits[30:16]: Major version.
@@ -164,3 +212,38 @@ smc_ret_values ffa_error(int32_t error_code)
return tftf_smc(&args);
}
+
+/* Query the higher EL if the requested FF-A feature is implemented. */
+smc_ret_values ffa_features(uint32_t feature)
+{
+ smc_args args = {
+ .fid = FFA_FEATURES,
+ .arg1 = feature
+ };
+
+ return tftf_smc(&args);
+}
+
+/* Get information about VMs or SPs based on UUID */
+smc_ret_values ffa_partition_info_get(const uint32_t uuid[4])
+{
+ smc_args args = {
+ .fid = FFA_PARTITION_INFO_GET,
+ .arg1 = uuid[0],
+ .arg2 = uuid[1],
+ .arg3 = uuid[2],
+ .arg4 = uuid[3]
+ };
+
+ return tftf_smc(&args);
+}
+
+/* Query SPMD that the rx buffer of the partition can be released */
+smc_ret_values ffa_rx_release(void)
+{
+ smc_args args = {
+ .fid = FFA_RX_RELEASE
+ };
+
+ return tftf_smc(&args);
+}
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_direct_messaging.c b/tftf/tests/runtime_services/secure_service/test_ffa_direct_messaging.c
index d14374b..6008b78 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_direct_messaging.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_direct_messaging.c
@@ -16,11 +16,6 @@
#define DIRECT_MSG_TEST_PATTERN2 (0xbbbb0000)
#define DIRECT_MSG_TEST_PATTERN3 (0xcccc0000)
-#define OPTEE_FFA_GET_API_VERSION (0)
-#define OPTEE_FFA_GET_OS_VERSION (1)
-#define OPTEE_FFA_GET_OS_VERSION_MAJOR (3)
-#define OPTEE_FFA_GET_OS_VERSION_MINOR (8)
-
static test_result_t send_receive_direct_msg(unsigned int sp_id,
unsigned int test_pattern)
{
@@ -51,52 +46,8 @@ static test_result_t send_receive_direct_msg(unsigned int sp_id,
return TEST_RESULT_SUCCESS;
}
-/*
- * check_spmc_execution_level
- *
- * Attempt sending impdef protocol messages to OP-TEE through direct messaging.
- * Criteria for detecting OP-TEE presence is that responses match defined
- * version values. In the case of SPMC running at S-EL2 (and Cactus instances
- * running at S-EL1) the response will not match the pre-defined version IDs.
- *
- * Returns true if SPMC is probed as being OP-TEE at S-EL1.
- *
- */
-static bool check_spmc_execution_level(void)
-{
- unsigned int is_optee_spmc_criteria = 0;
- smc_ret_values ret_values;
-
- /*
- * Send a first OP-TEE-defined protocol message through
- * FFA direct message.
- *
- */
- ret_values = ffa_msg_send_direct_req(HYP_ID, SP_ID(1),
- OPTEE_FFA_GET_API_VERSION);
- if ((ret_values.ret3 == FFA_VERSION_MAJOR) &&
- (ret_values.ret4 == FFA_VERSION_MINOR)) {
- is_optee_spmc_criteria++;
- }
-
- /*
- * Send a second OP-TEE-defined protocol message through
- * FFA direct message.
- *
- */
- ret_values = ffa_msg_send_direct_req(HYP_ID, SP_ID(1),
- OPTEE_FFA_GET_OS_VERSION);
- if ((ret_values.ret3 == OPTEE_FFA_GET_OS_VERSION_MAJOR) &&
- (ret_values.ret4 == OPTEE_FFA_GET_OS_VERSION_MINOR)) {
- is_optee_spmc_criteria++;
- }
-
- return (is_optee_spmc_criteria == 2);
-}
-
test_result_t test_ffa_direct_messaging(void)
{
- smc_ret_values ret_values;
test_result_t result;
/**********************************************************************
@@ -127,20 +78,6 @@ test_result_t test_ffa_direct_messaging(void)
/**********************************************************************
* Send a message to SP2 through direct messaging
**********************************************************************/
- /*
- * NOTICE: for now, the SPM does not initially run each SP sequentially
- * on boot up so we explicitely run the SP once by invoking FFA_RUN so
- * it reaches ffa_msg_wait in the message loop function.
- */
-
- /* Request running SP2 on VCPU0 */
- ret_values = ffa_run(2, 0);
- if (ret_values.ret0 != FFA_MSG_WAIT) {
- tftf_testcase_printf("ffa_run returned %lx\n",
- (u_register_t)ret_values.ret0);
- return TEST_RESULT_FAIL;
- }
-
result = send_receive_direct_msg(2, DIRECT_MSG_TEST_PATTERN2);
if (result != TEST_RESULT_SUCCESS) {
return result;
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_features.c b/tftf/tests/runtime_services/secure_service/test_ffa_features.c
new file mode 100644
index 0000000..7d67bf8
--- /dev/null
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_features.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <ffa_helpers.h>
+#include <test_helpers.h>
+#include <tftf_lib.h>
+
+struct feature_test {
+ const char *test_name;
+ unsigned int feature;
+ u_register_t expected_ret;
+};
+
+static const struct feature_test test_target[] = {
+ {"FFA_ERROR_32 check", FFA_ERROR, FFA_SUCCESS_SMC32},
+ {"FFA_SUCCESS_32 check", FFA_SUCCESS_SMC32, FFA_SUCCESS_SMC32},
+ {"FFA_INTERRUPT_32 check", FFA_INTERRUPT, FFA_SUCCESS_SMC32},
+ {"FFA_VERSION_32 check", FFA_VERSION, FFA_SUCCESS_SMC32},
+ {"FFA_FEATURES_32 check", FFA_FEATURES, FFA_SUCCESS_SMC32},
+ {"FFA_RX_RELEASE_32 check", FFA_RX_RELEASE, FFA_SUCCESS_SMC32},
+ {"FFA_RXTX_MAP_32 check", FFA_RXTX_MAP_SMC32, FFA_ERROR},
+ {"FFA_RXTX_MAP_64 check", FFA_RXTX_MAP_SMC64, FFA_SUCCESS_SMC32},
+ {"FFA_RXTX_UNMAP_32 check", FFA_RXTX_UNMAP, FFA_ERROR},
+ {"FFA_PARTITION_INFO_GET_32 check", FFA_PARTITION_INFO_GET, FFA_SUCCESS_SMC32},
+ {"FFA_ID_GET_32 check", FFA_ID_GET, FFA_SUCCESS_SMC32},
+ {"FFA_MSG_POLL_32 check", FFA_MSG_POLL, FFA_SUCCESS_SMC32},
+ {"FFA_MSG_WAIT_32 check", FFA_MSG_WAIT, FFA_SUCCESS_SMC32},
+ {"FFA_YIELD_32 check", FFA_MSG_YIELD, FFA_SUCCESS_SMC32},
+ {"FFA_RUN_32 check", FFA_MSG_RUN, FFA_SUCCESS_SMC32},
+ {"FFA_MSG_SEND_32 check", FFA_MSG_SEND, FFA_SUCCESS_SMC32},
+ {"FFA_MEM_DONATE_32 check", FFA_MEM_DONATE_SMC32, FFA_SUCCESS_SMC32},
+ {"FFA_MEM_LEND_32 check", FFA_MEM_LEND_SMC32, FFA_SUCCESS_SMC32},
+ {"FFA_MEM_SHARE_32 check", FFA_MEM_SHARE_SMC32, FFA_SUCCESS_SMC32},
+ {"FFA_MEM_RETRIEVE_REQ_32 check", FFA_MEM_RETRIEVE_REQ_SMC32, FFA_SUCCESS_SMC32},
+ {"FFA_MEM_RETRIEVE_RESP_32 check", FFA_MEM_RETRIEVE_RESP, FFA_SUCCESS_SMC32},
+ {"FFA_MEM_RELINQUISH_32 check", FFA_MEM_RELINQUISH, FFA_SUCCESS_SMC32},
+ {"FFA_MEM_RECLAIM_32 check", FFA_MEM_RECLAIM, FFA_SUCCESS_SMC32},
+ {"Check non-existent command", 0xFFFF, FFA_ERROR}
+};
+
+test_result_t test_ffa_features(void)
+{
+ SKIP_TEST_IF_FFA_VERSION_LESS_THAN(1, 0);
+
+ /* Check if SPMC is OP-TEE at S-EL1 */
+ if (check_spmc_execution_level()) {
+ /* FFA_FEATURES is not yet supported in OP-TEE */
+ return TEST_RESULT_SUCCESS;
+ }
+
+ smc_ret_values ffa_ret;
+ unsigned int i, test_target_size =
+ sizeof(test_target) / sizeof(struct feature_test);
+
+ for (i = 0U; i < test_target_size; i++) {
+ ffa_ret = ffa_features(test_target[i].feature);
+ if (ffa_ret.ret0 != test_target[i].expected_ret) {
+ tftf_testcase_printf("%s returned %lx, expected %lx\n",
+ test_target[i].test_name,
+ ffa_ret.ret0,
+ test_target[i].expected_ret);
+ return TEST_RESULT_FAIL;
+ }
+ if ((test_target[i].expected_ret == (u_register_t)FFA_ERROR) &&
+ (ffa_ret.ret2 != (u_register_t)FFA_ERROR_NOT_SUPPORTED)) {
+ tftf_testcase_printf("%s failed for the wrong reason: "
+ "returned %lx, expected %lx\n",
+ test_target[i].test_name,
+ ffa_ret.ret2,
+ (u_register_t)FFA_ERROR_NOT_SUPPORTED);
+ return TEST_RESULT_FAIL;
+ }
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/tests-spm.mk b/tftf/tests/tests-spm.mk
index 0c54e1c..bef373f 100644
--- a/tftf/tests/tests-spm.mk
+++ b/tftf/tests/tests-spm.mk
@@ -9,4 +9,5 @@ TESTS_SOURCES += \
ffa_helpers.c \
test_ffa_direct_messaging.c \
test_ffa_version.c \
+ test_ffa_features.c \
)
diff --git a/tftf/tests/tests-spm.xml b/tftf/tests/tests-spm.xml
index 5ed2524..e2f29bf 100644
--- a/tftf/tests/tests-spm.xml
+++ b/tftf/tests/tests-spm.xml
@@ -30,4 +30,10 @@
</testsuite>
+ <testsuite name="PSA FF-A features"
+ description="Test FFA_FEATURES ABI" >
+ <testcase name="Test FFA_FEATURES"
+ function="test_ffa_features" />
+ </testsuite>
+
</testsuites>
diff --git a/tftf/tests/tests.mk b/tftf/tests/tests.mk
index f5414e2..ebe090c 100644
--- a/tftf/tests/tests.mk
+++ b/tftf/tests/tests.mk
@@ -8,11 +8,12 @@ TESTS ?= standard
tests_files := $(wildcard tftf/tests/*.xml)
tests_sets := $(patsubst tftf/tests/tests-%.xml,%,${tests_files})
+tests_sets := $(sort ${tests_sets})
PHONY: help_tests
help_tests:
- @echo "Available sets of tests:"
- @$(foreach t, ${tests_sets}, printf " - %s\n" ${t};)
+ @echo "Supported Tests:"
+ @$(foreach t, ${tests_sets}, printf " %s\n" ${t};)
TESTS_FILE := tftf/tests/tests-${TESTS}.xml
TESTS_MAKEFILE := tftf/tests/tests-${TESTS}.mk