diff options
Diffstat (limited to 'tftf')
-rw-r--r-- | tftf/tests/runtime_services/secure_service/test_ffa_interrupts.c | 150 | ||||
-rw-r--r-- | tftf/tests/runtime_services/secure_service/test_spci_blocking_interrupt.c | 121 | ||||
-rw-r--r-- | tftf/tests/tests-spm.mk | 1 | ||||
-rw-r--r-- | tftf/tests/tests-spm.xml | 6 |
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 000000000..7c70de2c3 --- /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 44ee0f9a9..000000000 --- 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 73d2baf3d..9364052b6 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 ee3429278..01ebceab2 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> |