aboutsummaryrefslogtreecommitdiff
path: root/tftf
diff options
context:
space:
mode:
authorOlivier Deprez <olivier.deprez@arm.com>2019-12-06 17:45:07 +0100
committerOlivier Deprez <olivier.deprez@arm.com>2020-03-20 14:37:01 +0100
commit61be4c1ce08b68577d6ea3df2c34357b5b98a547 (patch)
tree19498c7a6ad5fb41e5ed4bc0a5bf1b0d7d61058b /tftf
parent55f79d6a83dc642b281f2df95b268417fef75cae (diff)
downloadtf-a-tests-61be4c1ce08b68577d6ea3df2c34357b5b98a547.tar.gz
tftf: SPCI Beta1 add direct messaging test
This patch strips out former SPCI Alpha sample test code. Removing SPRT references will be done in another coming patch. Version check is adapted to SPCI Beta1. Version is now returned in x2. The first test is a direct messaging test using SPCI_MSG_SEND_DIRECT_REQ targetting a bare-metal cactus SP. TFTF expects a response from the SP returning with SPCI_MSG_SEND_DIRECT_RESP. Note: this patch also provides an initial SPCI_RUN interface. This API may not be used in the mid-term because VM to SP communication is supposed to be done only through direct messaging. Though the SPM boot-up for now is only launching the first SP in the list of declared SP in SPMC manifest. In order to make 2nd-VM ready, TFTF has to "boot-up" the SP through a single SPCI_RUN invocation till it reaches SPCI_MSG_WAIT in the SP. Once SPM implements boot up through all SPs, this SPCI_RUN invocation will no longer be required. Signed-off-by: Olivier Deprez <olivier.deprez@arm.com> Change-Id: I141abd3e348409b3d34a911d0552570f49e85846
Diffstat (limited to 'tftf')
-rw-r--r--tftf/tests/runtime_services/secure_service/spci_helpers.c227
-rw-r--r--tftf/tests/runtime_services/secure_service/test_spci_direct_messaging.c107
-rw-r--r--tftf/tests/tests-spm.mk9
-rw-r--r--tftf/tests/tests-spm.xml22
4 files changed, 190 insertions, 175 deletions
diff --git a/tftf/tests/runtime_services/secure_service/spci_helpers.c b/tftf/tests/runtime_services/secure_service/spci_helpers.c
index 268c26f6..1370a387 100644
--- a/tftf/tests/runtime_services/secure_service/spci_helpers.c
+++ b/tftf/tests/runtime_services/secure_service/spci_helpers.c
@@ -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
*/
@@ -8,172 +8,101 @@
#include <smccc.h>
#include <spci_helpers.h>
#include <spci_svc.h>
-#include <tftf_lib.h>
-/* Returns a SPCI error code. On success, it also returns a 16 bit handle. */
-int spci_service_handle_open(uint16_t client_id, uint16_t *handle,
- uint32_t uuid1, uint32_t uuid2,
- uint32_t uuid3, uint32_t uuid4)
-{
- int32_t ret;
-
- smc_args get_handle_smc_args = {
- SPCI_SERVICE_HANDLE_OPEN,
- uuid1, uuid2, uuid3, uuid4,
- 0, 0, /* Reserved - MBZ */
- client_id
- };
-
- smc_ret_values smc_ret = tftf_smc(&get_handle_smc_args);
-
- ret = smc_ret.ret0;
- if (ret != SPCI_SUCCESS)
- return ret;
-
- uint32_t x1 = smc_ret.ret1;
-
- if ((x1 & 0x0000FFFF) != 0) {
- tftf_testcase_printf("SPCI_SERVICE_HANDLE_OPEN returned x1 = 0x%08x\n", x1);
- return SPCI_TFTF_ERROR;
- }
-
- /* The handle is returned in the top 16 bits */
- *handle = (x1 >> 16) & 0xFFFF;
-
- return SPCI_SUCCESS;
-}
-
-/* Invokes SPCI_SERVICE_HANDLE_CLOSE. Returns a SPCI error code. */
-int spci_service_handle_close(uint16_t client_id, uint16_t handle)
+/*-----------------------------------------------------------------------------
+ * SPCI_RUN
+ *
+ * Parameters
+ * uint32 Function ID (w0): 0x8400006D
+ * uint32 Target information (w1): Information to identify target SP/VM
+ * -Bits[31:16]: ID of SP/VM.
+ * -Bits[15:0]: ID of vCPU of SP/VM to run.
+ * Other Parameter registers w2-w7/x2-x7: Reserved (MBZ)
+ *
+ * On failure, returns SPCI_ERROR in w0 and error code in w2:
+ * -INVALID_PARAMETERS: Unrecognized endpoint or vCPU ID
+ * -NOT_SUPPORTED: This function is not implemented at this SPCI instance
+ * -DENIED: Callee is not in a state to handle this request
+ * -BUSY: vCPU is busy and caller must retry later
+ * -ABORTED: vCPU or VM ran into an unexpected error and has aborted
+ */
+smc_ret_values spci_run(uint32_t dest_id, uint32_t vcpu_id)
{
- smc_args close_handle_smc_args = {
- SPCI_SERVICE_HANDLE_CLOSE,
- client_id | (handle << 16)
+ smc_args args = {
+ SPCI_MSG_RUN,
+ (dest_id << 16) | vcpu_id,
+ 0, 0, 0, 0, 0, 0
};
- smc_ret_values smc_ret = tftf_smc(&close_handle_smc_args);
-
- return (int32_t)(uint32_t)smc_ret.ret0;
+ return tftf_smc(&args);
}
-/* Returns a SPCI error code. On success, it also returns a token. */
-int spci_service_request_start(u_register_t x1, u_register_t x2,
- u_register_t x3, u_register_t x4,
- u_register_t x5, u_register_t x6,
- uint16_t client_id, uint16_t handle,
- uint32_t *token)
+/*-----------------------------------------------------------------------------
+ * SPCI_MSG_SEND_DIRECT_REQ
+ *
+ * Parameters
+ * uint32 Function ID (w0): 0x8400006F / 0xC400006F
+ * uint32 Source/Destination IDs (w1): Source and destination endpoint IDs
+ * -Bit[31:16]: Source endpoint ID
+ * -Bit[15:0]: Destination endpoint ID
+ * uint32/uint64 (w2/x2) - RFU MBZ
+ * w3-w7 - Implementation defined
+ *
+ * On failure, returns SPCI_ERROR in w0 and error code in w2:
+ * -INVALID_PARAMETERS: Invalid endpoint ID or non-zero reserved register
+ * -DENIED: Callee is not in a state to handle this request
+ * -NOT_SUPPORTED: This function is not implemented at this SPCI instance
+ * -BUSY: Message target is busy
+ * -ABORTED: Message target ran into an unexpected error and has aborted
+ */
+static smc_ret_values __spci_msg_send_direct_req32_5(uint32_t source_id,
+ uint32_t dest_id,
+ uint32_t arg0,
+ uint32_t arg1,
+ uint32_t arg2,
+ uint32_t arg3,
+ uint32_t arg4)
{
- int32_t ret;
-
- smc_args request_smc_args = {
- SPCI_SERVICE_REQUEST_START_AARCH64,
- x1, x2, x3, x4, x5, x6,
- client_id | (handle << 16)
+ smc_args args = {
+ SPCI_MSG_SEND_DIRECT_REQ_SMC32,
+ (source_id << 16) | dest_id,
+ 0,
+ arg0, arg1, arg2, arg3, arg4
};
- smc_ret_values smc_ret = tftf_smc(&request_smc_args);
-
- ret = (int32_t)(uint32_t)smc_ret.ret0;
- if (ret != SPCI_SUCCESS)
- return ret;
-
- *token = smc_ret.ret1;
-
- return SPCI_SUCCESS;
+ return tftf_smc(&args);
}
-/*
- * Returns a SPCI error code. On success, it also returns x1-x3. Any of the
- * pointers x1-x3 may be NULL in case the caller doesn't need that value.
- */
-int spci_service_request_resume(uint16_t client_id, uint16_t handle,
- uint32_t token, u_register_t *x1,
- u_register_t *x2, u_register_t *x3)
+/* Direct message send helper accepting a single 32b message argument */
+smc_ret_values spci_msg_send_direct_req(uint32_t source_id, uint32_t dest_id,
+ uint32_t message)
{
- int32_t ret;
-
- smc_args request_resume_smc = {
- SPCI_SERVICE_REQUEST_RESUME_AARCH64,
- token, 0, 0, 0, 0, 0,
- client_id | (handle << 16)
- };
-
- smc_ret_values smc_ret = tftf_smc(&request_resume_smc);
-
- ret = (int32_t)(uint32_t)smc_ret.ret0;
- if (ret != SPCI_SUCCESS)
- return ret;
-
- if (x1 != NULL)
- *x1 = smc_ret.ret1;
- if (x2 != NULL)
- *x2 = smc_ret.ret2;
- if (x3 != NULL)
- *x3 = smc_ret.ret3;
-
- return SPCI_SUCCESS;
+ return __spci_msg_send_direct_req32_5(source_id, dest_id,
+ message, 0, 0, 0, 0);
}
-/*
- * Returns a SPCI error code. On success, it also returns x1-x3. Any of the
- * pointers x1-x3 may be NULL in case the caller doesn't need that value.
- */
-int spci_service_get_response(uint16_t client_id, uint16_t handle,
- uint32_t token, u_register_t *x1,
- u_register_t *x2, u_register_t *x3)
+static smc_ret_values __spci_msg_send_direct_req64_5(uint32_t source_id,
+ uint32_t dest_id,
+ uint64_t arg0,
+ uint64_t arg1,
+ uint64_t arg2,
+ uint64_t arg3,
+ uint64_t arg4)
{
- int32_t ret;
-
- smc_args get_response_smc = {
- SPCI_SERVICE_GET_RESPONSE_AARCH64,
- token, 0, 0, 0, 0, 0,
- client_id | (handle << 16)
+ smc_args args = {
+ SPCI_MSG_SEND_DIRECT_REQ_SMC64,
+ (source_id << 16) | dest_id,
+ 0,
+ arg0, arg1, arg2, arg3, arg4
};
- smc_ret_values smc_ret = tftf_smc(&get_response_smc);
-
- ret = (int32_t)(uint32_t)smc_ret.ret0;
- if (ret != SPCI_SUCCESS)
- return ret;
-
- if (x1 != NULL)
- *x1 = smc_ret.ret1;
- if (x2 != NULL)
- *x2 = smc_ret.ret2;
- if (x3 != NULL)
- *x3 = smc_ret.ret3;
-
- return SPCI_SUCCESS;
+ return tftf_smc(&args);
}
-/* Returns a SPCI error code. On success, it also returns the returned values. */
-int spci_service_request_blocking(u_register_t x1, u_register_t x2,
- u_register_t x3, u_register_t x4,
- u_register_t x5, u_register_t x6,
- uint16_t client_id, uint16_t handle,
- u_register_t *rx1, u_register_t *rx2,
- u_register_t *rx3)
+/* Direct message send helper accepting a single 64b message argument */
+smc_ret_values spci_msg_send_direct_req64(uint32_t source_id, uint32_t dest_id,
+ uint64_t message)
{
- int32_t ret;
-
- smc_args request_smc_args = {
- SPCI_SERVICE_REQUEST_BLOCKING_AARCH64,
- x1, x2, x3, x4, x5, x6,
- client_id | (handle << 16)
- };
-
- smc_ret_values smc_ret = tftf_smc(&request_smc_args);
-
- ret = (int32_t)(uint32_t)smc_ret.ret0;
- if (ret != SPCI_SUCCESS)
- return ret;
-
- if (rx1 != NULL)
- *rx1 = smc_ret.ret1;
- if (rx2 != NULL)
- *rx2 = smc_ret.ret2;
- if (rx3 != NULL)
- *rx3 = smc_ret.ret3;
-
- return SPCI_SUCCESS;
+ return __spci_msg_send_direct_req64_5(source_id, dest_id,
+ message, 0, 0, 0, 0);
}
diff --git a/tftf/tests/runtime_services/secure_service/test_spci_direct_messaging.c b/tftf/tests/runtime_services/secure_service/test_spci_direct_messaging.c
new file mode 100644
index 00000000..7c0e9738
--- /dev/null
+++ b/tftf/tests/runtime_services/secure_service/test_spci_direct_messaging.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <cactus_def.h>
+#include <platform.h>
+#include <smccc.h>
+#include <spci_helpers.h>
+#include <spci_svc.h>
+#include <test_helpers.h>
+
+/* Hypervisor ID at physical SPCI instance */
+#define HYP_ID (0)
+
+/* By convention, SP IDs (as opposed to VM IDs) have bit 15 set */
+#define SP_ID(x) (x | (1 << 15))
+
+#define DIRECT_MSG_TEST_PATTERN1 (0xaaaa0000)
+#define DIRECT_MSG_TEST_PATTERN2 (0xbbbb0000)
+#define DIRECT_MSG_TEST_PATTERN3 (0xcccc0000)
+
+static test_result_t send_receive_direct_msg(unsigned int sp_id,
+ unsigned int test_pattern)
+{
+ smc_ret_values ret_values;
+
+ /* Send a message to SP through direct messaging */
+ ret_values = spci_msg_send_direct_req(HYP_ID, SP_ID(sp_id),
+ test_pattern);
+
+ /*
+ * Return responses may be SPCI_MSG_SEND_DIRECT_RESP or SPCI_INTERRUPT,
+ * but only expect the former. Expect SMC32 convention from SP.
+ */
+ if (ret_values.ret0 != SPCI_MSG_SEND_DIRECT_RESP_SMC32) {
+ tftf_testcase_printf("spci_msg_send_direct_req returned %lx\n",
+ (u_register_t)ret_values.ret0);
+ return TEST_RESULT_FAIL;
+ }
+
+ /*
+ * Message loop in SP returns initial message with the running VM id
+ * into the lower 16 bits of initial message.
+ */
+ if (ret_values.ret3 != (test_pattern | sp_id)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
+test_result_t test_spci_direct_messaging(void)
+{
+ smc_ret_values ret_values;
+ test_result_t result;
+
+ /**********************************************************************
+ * Verify that SPCI is there and that it has the correct version.
+ **********************************************************************/
+ SKIP_TEST_IF_SPCI_VERSION_LESS_THAN(0, 9);
+
+ /**********************************************************************
+ * Send a message to SP1 through direct messaging
+ **********************************************************************/
+ result = send_receive_direct_msg(1, DIRECT_MSG_TEST_PATTERN1);
+ if (result != TEST_RESULT_SUCCESS) {
+ return result;
+ }
+
+ /**********************************************************************
+ * 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 SPCI_RUN so
+ * it reaches spci_msg_wait in the message loop function.
+ */
+
+ /* Request running SP2 on VCPU0 */
+ ret_values = spci_run(2, 0);
+ if (ret_values.ret0 != SPCI_MSG_WAIT) {
+ tftf_testcase_printf("spci_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;
+ }
+
+ /**********************************************************************
+ * Send a message to SP1 through direct messaging
+ **********************************************************************/
+ result = send_receive_direct_msg(1, DIRECT_MSG_TEST_PATTERN3);
+ if (result != TEST_RESULT_SUCCESS) {
+ return result;
+ }
+
+ /**********************************************************************
+ * All tests passed.
+ **********************************************************************/
+ return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/tests-spm.mk b/tftf/tests/tests-spm.mk
index c4876879..40c9b87d 100644
--- a/tftf/tests/tests-spm.mk
+++ b/tftf/tests/tests-spm.mk
@@ -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
#
@@ -7,10 +7,5 @@
TESTS_SOURCES += \
$(addprefix tftf/tests/runtime_services/secure_service/, \
spci_helpers.c \
- test_spci_handle_open.c \
- test_spci_blocking_request.c \
- test_spci_non_blocking_request.c \
- test_spci_blocking_while_busy.c \
- test_spci_blocking_interrupt.c \
- test_spci_non_blocking_interrupt.c \
+ test_spci_direct_messaging.c \
)
diff --git a/tftf/tests/tests-spm.xml b/tftf/tests/tests-spm.xml
index 9afc6afd..beac7dd6 100644
--- a/tftf/tests/tests-spm.xml
+++ b/tftf/tests/tests-spm.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright (c) 2018, Arm Limited. All rights reserved.
+ Copyright (c) 2018-2020, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-3-Clause
-->
@@ -11,24 +11,8 @@
<testsuite name="Secure Partition Manager"
description="Test SPM APIs">
- <testcase name="SPCI handle open and close"
- function="test_spci_handle_open" />
-
- <testcase name="SPCI non-blocking requests"
- function="test_spci_request" />
-
- <testcase name="SPCI blocking requests multicore"
- function="test_spci_blocking_request_multicore" />
- <testcase name="SPCI non-blocking requests multicore"
- function="test_spci_request_multicore" />
-
- <testcase name="SPCI blocking request while busy"
- function="test_spci_blocking_while_busy" />
-
- <testcase name="SPCI blocking request fail to preempt"
- function="test_spci_blocking_interrupt_by_ns" />
- <testcase name="SPCI non-blocking request succeed to preempt"
- function="test_spci_non_blocking_interrupt_by_ns" />
+ <testcase name="SPCI direct messaging API"
+ function="test_spci_direct_messaging" />
</testsuite>