aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tftf/tests/runtime_services/secure_service/test_ffa_interrupts.c150
-rw-r--r--tftf/tests/runtime_services/secure_service/test_spci_blocking_interrupt.c121
-rw-r--r--tftf/tests/tests-spm.mk1
-rw-r--r--tftf/tests/tests-spm.xml6
4 files changed, 157 insertions, 121 deletions
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_interrupts.c b/tftf/tests/runtime_services/secure_service/test_ffa_interrupts.c
new file mode 100644
index 00000000..7c70de2c
--- /dev/null
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_interrupts.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <cactus_test_cmds.h>
+#include <ffa_endpoints.h>
+#include <ffa_helpers.h>
+#include <test_helpers.h>
+#include <timer.h>
+
+static volatile int timer_irq_received;
+
+#define SENDER HYP_ID
+#define RECEIVER SP_ID(1)
+#define SLEEP_TIME 200U
+
+static const struct ffa_uuid expected_sp_uuids[] = {
+ {PRIMARY_UUID}
+ };
+
+/*
+ * ISR for the timer interrupt. Update a global variable to check it has been
+ * called.
+ */
+static int timer_handler(void *data)
+{
+ assert(timer_irq_received == 0);
+ timer_irq_received = 1;
+ return 0;
+}
+
+/*
+ * @Test_Aim@ Test non-secure interrupts while executing Secure Partition.
+ *
+ * 1. Enable managed exit interrupt by sending interrupt_enable command to
+ * Cactus.
+ *
+ * 2. Register a handler for the non-secure timer interrupt. Program it to fire
+ * in a certain time.
+ *
+ * 3. Send a blocking request to Cactus to execute in busy loop.
+ *
+ * 4. While executing in busy loop, the non-secure timer should
+ * fire and trap into SPM running at S-EL2 as FIQ.
+ *
+ * 5. SPM injects a managed exit virtual FIQ into Cactus (as configured in the
+ * interrupt enable call), causing it to run its interrupt handler.
+ *
+ * 6. Cactus's managed exit handler acknowledges interrupt arrival by
+ * requesting the interrupt id to the SPMC, and check if it is the
+ * MANAGED_EXIT_INTERRUPT_ID.
+ *
+ * 7. Check whether the pending non-secure timer interrupt successfully got
+ * handled in TFTF.
+ *
+ * 8. Send a direct message request command to resume Cactus's execution.
+ * It resumes in the sleep loop and completes it. It then returns with
+ * a direct message response. Check if time lapsed is greater than
+ * sleeping time.
+ *
+ */
+test_result_t test_ffa_ns_interrupt(void)
+{
+ int ret;
+ smc_ret_values ret_values;
+
+ CHECK_SPMC_TESTING_SETUP(1, 0, expected_sp_uuids);
+
+ /* Enable managed exit interrupt as FIQ in the secure side. */
+ ret_values = cactus_interrupt_cmd(SENDER, RECEIVER, MANAGED_EXIT_INTERRUPT_ID,
+ true, INTERRUPT_TYPE_FIQ);
+
+ if (!is_ffa_direct_response(ret_values)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ if (cactus_get_response(ret_values) != CACTUS_SUCCESS) {
+ ERROR("Failed to enable Managed exit interrupt\n");
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Program timer */
+ timer_irq_received = 0;
+ tftf_timer_register_handler(timer_handler);
+
+ ret = tftf_program_timer(100);
+ if (ret < 0) {
+ ERROR("Failed to program timer (%d)\n", ret);
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Send request to primary Cactus to sleep for 200ms */
+ ret_values = cactus_sleep_cmd(SENDER, RECEIVER, SLEEP_TIME);
+
+ if (!is_ffa_direct_response(ret_values)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ /*
+ * Managed exit interrupt occurs during this time, Cactus
+ * will respond with interrupt ID.
+ */
+ if (cactus_get_response(ret_values) != MANAGED_EXIT_INTERRUPT_ID) {
+ ERROR("Managed exit interrupt did not occur!\n");
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Check that the timer interrupt has been handled in NS-world (TFTF) */
+ tftf_cancel_timer();
+ tftf_timer_unregister_handler();
+
+ if (timer_irq_received == 0) {
+ ERROR("Timer interrupt hasn't actually been handled.\n");
+ return TEST_RESULT_FAIL;
+ }
+
+ /*
+ * Send a dummy direct message request to relinquish CPU cycles.
+ * This resumes Cactus in the sleep routine.
+ */
+ ret_values = ffa_msg_send_direct_req64(SENDER, RECEIVER,
+ 0, 0, 0, 0, 0);
+
+ if (!is_ffa_direct_response(ret_values)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Make sure elapsed time not less than sleep time */
+ if (cactus_get_response(ret_values) < SLEEP_TIME) {
+ ERROR("Lapsed time less than requested sleep time\n");
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Disable Managed exit interrupt */
+ ret_values = cactus_interrupt_cmd(SENDER, RECEIVER, MANAGED_EXIT_INTERRUPT_ID,
+ false, 0);
+
+ if (!is_ffa_direct_response(ret_values)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ if (cactus_get_response(ret_values) != CACTUS_SUCCESS) {
+ ERROR("Failed to disable Managed exit interrupt\n");
+ return TEST_RESULT_FAIL;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/runtime_services/secure_service/test_spci_blocking_interrupt.c b/tftf/tests/runtime_services/secure_service/test_spci_blocking_interrupt.c
deleted file mode 100644
index 44ee0f9a..00000000
--- a/tftf/tests/runtime_services/secure_service/test_spci_blocking_interrupt.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch_helpers.h>
-#include <assert.h>
-#include <cactus_def.h>
-#include <debug.h>
-#include <smccc.h>
-#include <spci_helpers.h>
-#include <spci_svc.h>
-#include <string.h>
-#include <test_helpers.h>
-#include <tftf_lib.h>
-#include <timer.h>
-
-static volatile int timer_irq_received;
-
-/*
- * ISR for the timer interrupt. Update a global variable to check it has been
- * called.
- */
-static int timer_handler(void *data)
-{
- assert(timer_irq_received == 0);
- timer_irq_received = 1;
- return 0;
-}
-
-/*
- * @Test_Aim@ Test that non-secure interrupts do not interrupt blocking
- * requests.
- *
- * 1. Register a handler for the non-secure timer interrupt. Program it to fire
- * in a certain time.
- *
- * 2. Send a blocking request to Cactus to sleep for more time than the timer.
- *
- * 3. While servicing the timer sleep request, the non-secure timer should
- * fire but not interrupt Cactus.
- *
- * 4. Once back in TFTF, check the response from Cactus, which shows whether the
- * secure service indeed ran to completion.
- *
- * 5. Also check whether the pending non-secure timer interrupt successfully got
- * handled in TFTF.
- */
-test_result_t test_spci_blocking_interrupt_by_ns(void)
-{
- int ret;
- uint16_t handle_cactus;
- test_result_t result = TEST_RESULT_SUCCESS;
-
- SKIP_TEST_IF_SPCI_VERSION_LESS_THAN(0, 1);
-
- /* Open handle */
-
- ret = spci_service_handle_open(TFTF_SPCI_CLIENT_ID, &handle_cactus,
- CACTUS_SERVICE1_UUID);
- if (ret != SPCI_SUCCESS) {
- tftf_testcase_printf("%d: SPM failed to return a valid handle. Returned: %d\n",
- __LINE__, ret);
- return TEST_RESULT_FAIL;
- }
-
- /* Program timer */
-
- timer_irq_received = 0;
- tftf_timer_register_handler(timer_handler);
-
- ret = tftf_program_timer(100);
- if (ret < 0) {
- tftf_testcase_printf("Failed to program timer (%d)\n", ret);
- result = TEST_RESULT_FAIL;
- }
-
- /* Send request to Cactus */
-
- ret = spci_service_request_blocking(CACTUS_SLEEP_MS, 200U,
- 0, 0, 0, 0,
- TFTF_SPCI_CLIENT_ID,
- handle_cactus,
- NULL, NULL, NULL);
- if (ret != SPCI_SUCCESS) {
- /*
- * If the interrupt is handled during the blocking call, there
- * will be a crash in EL3 because the function that invokes a
- * blocking call doesn't know how to handle it. The CPU won't
- * come back here (because it should never happen!).
- */
- tftf_testcase_printf("%d: SPM should have returned SPCI_SUCCESS. Returned: %d\n",
- __LINE__, ret);
- result = TEST_RESULT_FAIL;
- }
-
- /* Check that the interrupt has been handled */
-
- tftf_cancel_timer();
- tftf_timer_unregister_handler();
-
- if (timer_irq_received == 0) {
- tftf_testcase_printf("%d: Timer interrupt hasn't actually been handled.\n",
- __LINE__);
- result = TEST_RESULT_FAIL;
- }
-
- /* Close handle */
-
- ret = spci_service_handle_close(TFTF_SPCI_CLIENT_ID, handle_cactus);
- if (ret != SPCI_SUCCESS) {
- tftf_testcase_printf("%d: SPM failed to close the handle. Returned: %d\n",
- __LINE__, ret);
- result = TEST_RESULT_FAIL;
- }
-
- /* All tests finished */
-
- return result;
-}
diff --git a/tftf/tests/tests-spm.mk b/tftf/tests/tests-spm.mk
index 73d2baf3..9364052b 100644
--- a/tftf/tests/tests-spm.mk
+++ b/tftf/tests/tests-spm.mk
@@ -10,6 +10,7 @@ TESTS_SOURCES += \
spm_common.c \
test_ffa_direct_messaging.c \
test_ffa_features.c \
+ test_ffa_interrupts.c \
test_ffa_memory_sharing.c \
test_ffa_rxtx_map.c \
test_ffa_version.c \
diff --git a/tftf/tests/tests-spm.xml b/tftf/tests/tests-spm.xml
index ee342927..01ebceab 100644
--- a/tftf/tests/tests-spm.xml
+++ b/tftf/tests/tests-spm.xml
@@ -78,4 +78,10 @@
function="test_simd_vectors_preserved" />
</testsuite>
+ <testsuite name="FF-A Interrupt"
+ description="Test non-secure Interrupts" >
+ <testcase name="Test NS interrupts"
+ function="test_ffa_ns_interrupt" />
+ </testsuite>
+
</testsuites>