aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManish Pandey <manish.pandey2@arm.com>2020-09-11 10:31:28 +0100
committerOlivier Deprez <olivier.deprez@arm.com>2021-04-13 18:23:31 +0200
commitdfe3ab3c656ad190c06c4b71cfe4526607aa293e (patch)
treee66103545cbf0e9b7794e7ef63d6343e1eb3ae75
parent9ee6a8dc99d7d93a6b487ca505bb1d63e8733791 (diff)
downloadtf-a-tests-dfe3ab3c656ad190c06c4b71cfe4526607aa293e.tar.gz
SPM: test handling of non-secure interrupt while running SP
This patch introduces following test scenario 1. Start a NS timer of 100ms from test framework(TFTF) 2. Send a command to Cactus to block for 200ms so that when NS timer expires, Cactus is still executing. 3. NS timer interrupt traped as FIQ in SPMC which injects Managed exit interrupt in Cactus. 4. Cactus interrupt handler acknowledges handling of interrupt by sending MSG_SEND_DIRECT_RESP to SPMC which in turn forwards it to TFTF. 5. PASS condition for the test is to make sure that - Interrupt occured in Cactus. - Timer interrupt has been forwarded/handled in TFTF. - Time lapsed in whole test is more than 200ms. Change-Id: Iac7a35ac7fa8dd57a1d6bbc0c0797498e09c9b65 Signed-off-by: Manish Pandey <manish.pandey2@arm.com> Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
-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>