summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plat/arm/fvp/include/platform_def.h3
-rw-r--r--spm/cactus/plat/arm/fvp/fdts/cactus.dts1
-rw-r--r--tftf/tests/runtime_services/secure_service/test_ffa_secure_interrupts.c229
3 files changed, 191 insertions, 42 deletions
diff --git a/plat/arm/fvp/include/platform_def.h b/plat/arm/fvp/include/platform_def.h
index b8871c4..ca391b3 100644
--- a/plat/arm/fvp/include/platform_def.h
+++ b/plat/arm/fvp/include/platform_def.h
@@ -308,4 +308,7 @@
#define ARM_SECURE_SERVICE_BUFFER_BASE 0xff600000ull
#define ARM_SECURE_SERVICE_BUFFER_SIZE 0x10000ull
+
+#define PLAT_INTERRUPT_MPIDR 0x81010300
+
#endif /* __PLATFORM_DEF_H__ */
diff --git a/spm/cactus/plat/arm/fvp/fdts/cactus.dts b/spm/cactus/plat/arm/fvp/fdts/cactus.dts
index 4d27c9c..d3b933d 100644
--- a/spm/cactus/plat/arm/fvp/fdts/cactus.dts
+++ b/spm/cactus/plat/arm/fvp/fdts/cactus.dts
@@ -119,6 +119,7 @@
pages-count = <32>; /* Two 64KB pages */
attributes = <0x3>; /* read-write */
interrupts = <56 0x900>;
+ interrupts-target = <56 0x00 0x81010300>;
};
};
};
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_secure_interrupts.c b/tftf/tests/runtime_services/secure_service/test_ffa_secure_interrupts.c
index 5977717..d672f08 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_secure_interrupts.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_secure_interrupts.c
@@ -21,9 +21,13 @@ static const struct ffa_uuid expected_sp_uuids[] = {
{PRIMARY_UUID}, {SECONDARY_UUID}
};
+static event_t cpu_reached_end_of_test[PLATFORM_CORE_COUNT];
+
/*
* @Test_Aim@ Test secure interrupt handling while first Secure Partition is
- * in RUNNING state.
+ * in RUNNING state. The interrupt is routed to the core defined by
+ * PLAT_INTERRUPT_MPIDR and runs only on that core. If PLAT_INTERRUPT_MPIDR is
+ * not defined, it defaults to current core.
*
* 1. Send a direct message request command to first Cactus SP to start the
* trusted watchdog timer.
@@ -62,23 +66,28 @@ static const struct ffa_uuid expected_sp_uuids[] = {
* interrupt through a direct message request command.
*
*/
-
-test_result_t test_ffa_sec_interrupt_sp_running(void)
+static test_result_t test_ffa_sec_interrupt_sp_running_handler(void)
{
struct ffa_value ret_values;
+ test_result_t test_ret = TEST_RESULT_FAIL;
- CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
+#ifdef PLAT_INTERRUPT_MPIDR
+ if (read_mpidr_el1() != PLAT_INTERRUPT_MPIDR) {
+ test_ret = TEST_RESULT_SUCCESS;
+ goto exit;
+ }
+#endif
/* Enable trusted watchdog interrupt as IRQ in the secure side. */
if (!enable_trusted_wdog_interrupt(SENDER, RECEIVER)) {
- return TEST_RESULT_FAIL;
+ goto exit;
}
ret_values = cactus_send_twdog_cmd(SENDER, RECEIVER, 50);
if (!is_ffa_direct_response(ret_values)) {
ERROR("Expected a direct response for starting TWDOG timer\n");
- return TEST_RESULT_FAIL;
+ goto exit;
}
/* Send request to first Cactus SP to sleep */
@@ -90,7 +99,7 @@ test_result_t test_ffa_sec_interrupt_sp_running(void)
*/
if (!is_ffa_direct_response(ret_values)) {
ERROR("Expected a direct response for sleep command\n");
- return TEST_RESULT_FAIL;
+ goto exit;
}
VERBOSE("Secure interrupt has preempted execution: %u\n",
@@ -99,7 +108,7 @@ test_result_t test_ffa_sec_interrupt_sp_running(void)
/* Make sure elapsed time not less than sleep time */
if (cactus_get_response(ret_values) < SP_SLEEP_TIME) {
ERROR("Lapsed time less than requested sleep time\n");
- return TEST_RESULT_FAIL;
+ goto exit;
}
/* Check for the last serviced secure virtual interrupt. */
@@ -108,26 +117,49 @@ test_result_t test_ffa_sec_interrupt_sp_running(void)
if (!is_ffa_direct_response(ret_values)) {
ERROR("Expected a direct response for last serviced interrupt"
" command\n");
- return TEST_RESULT_FAIL;
+ goto exit;
}
/* Make sure Trusted Watchdog timer interrupt was serviced*/
if (cactus_get_response(ret_values) != IRQ_TWDOG_INTID) {
ERROR("Trusted watchdog timer interrupt not serviced by SP\n");
- return TEST_RESULT_FAIL;
+ goto exit;
}
/* Disable Trusted Watchdog interrupt. */
if (!disable_trusted_wdog_interrupt(SENDER, RECEIVER)) {
- return TEST_RESULT_FAIL;
+ goto exit;
+ }
+
+ test_ret = TEST_RESULT_SUCCESS;
+exit:
+ if (test_ret != TEST_RESULT_SUCCESS) {
+ ERROR("%s - Test Failed - core - %d\n", __func__,
+ get_current_core_id());
}
+ tftf_send_event(&cpu_reached_end_of_test[get_current_core_id()]);
+ return test_ret;
+}
- return TEST_RESULT_SUCCESS;
+test_result_t test_ffa_sec_interrupt_sp_running(void)
+{
+ CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
+ memset(cpu_reached_end_of_test, 0, sizeof(cpu_reached_end_of_test));
+
+#ifdef PLAT_INTERRUPT_MPIDR
+ return spm_run_multi_core_test(
+ (uintptr_t)test_ffa_sec_interrupt_sp_running_handler,
+ cpu_reached_end_of_test);
+#else
+ return test_ffa_sec_interrupt_sp_running_handler();
+#endif
}
/*
* @Test_Aim@ Test secure interrupt handling while Secure Partition is waiting
- * for a message.
+ * for a message. The interrupt is routed to the core defined by
+ * PLAT_INTERRUPT_MPIDR and runs only on that core. If PLAT_INTERRUPT_MPIDR is
+ * not defined, it defaults to current core.
*
* 1. Send a direct message request command to first Cactus SP to start the
* trusted watchdog timer.
@@ -164,18 +196,24 @@ test_result_t test_ffa_sec_interrupt_sp_running(void)
* interrupt through a direct message request command.
*
*/
-test_result_t test_ffa_sec_interrupt_sp_waiting(void)
+static test_result_t test_ffa_sec_interrupt_sp_waiting_handler(void)
{
uint64_t time1;
volatile uint64_t time2, time_lapsed;
uint64_t timer_freq = read_cntfrq_el0();
struct ffa_value ret_values;
+ test_result_t test_ret = TEST_RESULT_FAIL;
- CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
+#ifdef PLAT_INTERRUPT_MPIDR
+ if (read_mpidr_el1() != PLAT_INTERRUPT_MPIDR) {
+ test_ret = TEST_RESULT_SUCCESS;
+ goto exit;
+ }
+#endif
/* Enable trusted watchdog interrupt as IRQ in the secure side. */
if (!enable_trusted_wdog_interrupt(SENDER, RECEIVER)) {
- return TEST_RESULT_FAIL;
+ goto exit;
}
/*
@@ -185,7 +223,7 @@ test_result_t test_ffa_sec_interrupt_sp_waiting(void)
if (!is_ffa_direct_response(ret_values)) {
ERROR("Expected a direct response for starting TWDOG timer\n");
- return TEST_RESULT_FAIL;
+ goto exit;
}
time1 = syscounter_read();
@@ -203,7 +241,7 @@ test_result_t test_ffa_sec_interrupt_sp_waiting(void)
if (time_lapsed < NS_TIME_SLEEP) {
ERROR("Time elapsed less than expected value: %llu vs %u\n",
time_lapsed, NS_TIME_SLEEP);
- return TEST_RESULT_FAIL;
+ goto exit;
}
/* Check for the last serviced secure virtual interrupt. */
@@ -212,26 +250,49 @@ test_result_t test_ffa_sec_interrupt_sp_waiting(void)
if (!is_ffa_direct_response(ret_values)) {
ERROR("Expected a direct response for last serviced interrupt"
" command\n");
- return TEST_RESULT_FAIL;
+ goto exit;
}
/* Make sure Trusted Watchdog timer interrupt was serviced*/
if (cactus_get_response(ret_values) != IRQ_TWDOG_INTID) {
ERROR("Trusted watchdog timer interrupt not serviced by SP\n");
- return TEST_RESULT_FAIL;
+ goto exit;
}
/* Disable Trusted Watchdog interrupt. */
if (!disable_trusted_wdog_interrupt(SENDER, RECEIVER)) {
- return TEST_RESULT_FAIL;
+ goto exit;
}
- return TEST_RESULT_SUCCESS;
+ test_ret = TEST_RESULT_SUCCESS;
+exit:
+ if (test_ret != TEST_RESULT_SUCCESS) {
+ ERROR("%s - Test Failed - core - %d\n", __func__,
+ get_current_core_id());
+ }
+ tftf_send_event(&cpu_reached_end_of_test[get_current_core_id()]);
+ return test_ret;
+}
+
+test_result_t test_ffa_sec_interrupt_sp_waiting(void)
+{
+ CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
+ memset(cpu_reached_end_of_test, 0, sizeof(cpu_reached_end_of_test));
+
+#ifdef PLAT_INTERRUPT_MPIDR
+ return spm_run_multi_core_test(
+ (uintptr_t)test_ffa_sec_interrupt_sp_waiting_handler,
+ cpu_reached_end_of_test);
+#else
+ return test_ffa_sec_interrupt_sp_waiting_handler();
+#endif
}
/*
* @Test_Aim@ Test secure interrupt handling while first Secure Partition is
- * in BLOCKED state.
+ * in BLOCKED state. The interrupt is routed to the core defined by
+ * PLAT_INTERRUPT_MPIDR and runs only on that core. If PLAT_INTERRUPT_MPIDR is
+ * not defined, it defaults to current core.
*
* 1. Send a direct message request command to first Cactus SP to start the
* trusted watchdog timer.
@@ -266,22 +327,41 @@ test_result_t test_ffa_sec_interrupt_sp_waiting(void)
* 11. Test finishes successfully once the TFTF disables the trusted watchdog
* interrupt through a direct message request command.
*/
-test_result_t test_ffa_sec_interrupt_sp_blocked(void)
+static test_result_t test_ffa_sec_interrupt_sp_blocked_handler(void)
{
struct ffa_value ret_values;
+ test_result_t test_ret = TEST_RESULT_FAIL;
- CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
+#ifdef PLAT_INTERRUPT_MPIDR
+ if (read_mpidr_el1() != PLAT_INTERRUPT_MPIDR) {
+ test_ret = TEST_RESULT_SUCCESS;
+ goto exit;
+ }
+#endif
/* Enable trusted watchdog interrupt as IRQ in the secure side. */
if (!enable_trusted_wdog_interrupt(SENDER, RECEIVER)) {
- return TEST_RESULT_FAIL;
+ goto exit;
}
ret_values = cactus_send_twdog_cmd(SENDER, RECEIVER, 100);
if (!is_ffa_direct_response(ret_values)) {
ERROR("Expected a direct response for starting TWDOG timer\n");
- return TEST_RESULT_FAIL;
+ goto exit;
+ }
+
+ /*
+ * Call FFA_RUN on the secondary vcpus to start it up. it is possible
+ * that another test has already started in, in which case we may get
+ * an error. We ignore the error and proceed, if the vcpu is not started
+ * the following direct requests would fail.
+ */
+ ret_values = ffa_run(RECEIVER_2, get_current_core_id());
+ if (ffa_func_id(ret_values) == FFA_ERROR) {
+ WARN("Failed to start secondary vcpu of RECEIVER_2, "
+ "may already be started by other tests. Ignoring"
+ " error\n");
}
/*
@@ -297,11 +377,12 @@ test_result_t test_ffa_sec_interrupt_sp_blocked(void)
*/
if (!is_ffa_direct_response(ret_values)) {
ERROR("Expected a direct response\n");
- return TEST_RESULT_FAIL;
+ goto exit;
}
if (cactus_get_response(ret_values) != CACTUS_SUCCESS) {
- return TEST_RESULT_FAIL;
+ ERROR("Expected CACTUS_SUCCESS %x\n", cactus_get_response(ret_values));
+ goto exit;
}
/* Check for the last serviced secure virtual interrupt. */
@@ -310,26 +391,50 @@ test_result_t test_ffa_sec_interrupt_sp_blocked(void)
if (!is_ffa_direct_response(ret_values)) {
ERROR("Expected a direct response for last serviced interrupt"
" command\n");
- return TEST_RESULT_FAIL;
+ goto exit;
}
/* Make sure Trusted Watchdog timer interrupt was serviced*/
if (cactus_get_response(ret_values) != IRQ_TWDOG_INTID) {
ERROR("Trusted watchdog timer interrupt not serviced by SP\n");
- return TEST_RESULT_FAIL;
+ goto exit;
}
/* Disable Trusted Watchdog interrupt. */
if (!disable_trusted_wdog_interrupt(SENDER, RECEIVER)) {
- return TEST_RESULT_FAIL;
+ goto exit;
+ }
+
+ test_ret = TEST_RESULT_SUCCESS;
+exit:
+ if (test_ret != TEST_RESULT_SUCCESS) {
+ ERROR("%s - Test Failed - core - %d\n", __func__,
+ get_current_core_id());
}
+ tftf_send_event(&cpu_reached_end_of_test[get_current_core_id()]);
+ return test_ret;
+}
- return TEST_RESULT_SUCCESS;
+test_result_t test_ffa_sec_interrupt_sp_blocked(void)
+{
+ CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
+ memset(cpu_reached_end_of_test, 0, sizeof(cpu_reached_end_of_test));
+
+#ifdef PLAT_INTERRUPT_MPIDR
+ return spm_run_multi_core_test(
+ (uintptr_t)test_ffa_sec_interrupt_sp_blocked_handler,
+ cpu_reached_end_of_test);
+#else
+ return test_ffa_sec_interrupt_sp_blocked_handler();
+#endif
}
/*
* @Test_Aim@ Test secure interrupt handling while first Secure Partition is
* in WAITING state while the second Secure Partition is running.
+ * The interrupt is routed to the core defined by PLAT_INTERRUPT_MPIDR and
+ * runs only on that core. If PLAT_INTERRUPT_MPIDR is not defined, it defaults
+ * to current core.
*
* 1. Send a direct message request command to first Cactus SP to start the
* trusted watchdog timer.
@@ -366,22 +471,41 @@ test_result_t test_ffa_sec_interrupt_sp_blocked(void)
* 12. Test finishes successfully once the TFTF disables the trusted watchdog
* interrupt through a direct message request command.
*/
-test_result_t test_ffa_sec_interrupt_sp1_waiting_sp2_running(void)
+static test_result_t test_ffa_sec_interrupt_sp1_waiting_sp2_running_handler(void)
{
struct ffa_value ret_values;
+ test_result_t test_ret = TEST_RESULT_FAIL;
- CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
+#ifdef PLAT_INTERRUPT_MPIDR
+ if (read_mpidr_el1() != PLAT_INTERRUPT_MPIDR) {
+ test_ret = TEST_RESULT_SUCCESS;
+ goto exit;
+ }
+#endif
/* Enable trusted watchdog interrupt as IRQ in the secure side. */
if (!enable_trusted_wdog_interrupt(SENDER, RECEIVER)) {
- return TEST_RESULT_FAIL;
+ goto exit;
}
ret_values = cactus_send_twdog_cmd(SENDER, RECEIVER, 100);
if (!is_ffa_direct_response(ret_values)) {
ERROR("Expected a direct response for starting TWDOG timer\n");
- return TEST_RESULT_FAIL;
+ goto exit;
+ }
+
+ /*
+ * Call FFA_RUN on the secondary vcpus to start it up. It is possible
+ * that another test has already started in, in which case we may get
+ * an error. We ignore the error and proceed, if the vcpu is not started
+ * the following direct requests would fail.
+ */
+ ret_values = ffa_run(RECEIVER_2, get_current_core_id());
+ if (ffa_func_id(ret_values) == FFA_ERROR) {
+ WARN("Failed to start secondary vcpu of RECEIVER_2, "
+ "may already be started by other tests. Ignoring"
+ " error\n");
}
/* Send request to Second Cactus SP to sleep. */
@@ -393,7 +517,7 @@ test_result_t test_ffa_sec_interrupt_sp1_waiting_sp2_running(void)
*/
if (!is_ffa_direct_response(ret_values)) {
ERROR("Expected a direct response for sleep command\n");
- return TEST_RESULT_FAIL;
+ goto exit;
}
/* Make sure elapsed time not less than sleep time. */
@@ -407,19 +531,40 @@ test_result_t test_ffa_sec_interrupt_sp1_waiting_sp2_running(void)
if (!is_ffa_direct_response(ret_values)) {
ERROR("Expected a direct response for last serviced interrupt"
" command\n");
- return TEST_RESULT_FAIL;
+ goto exit;
}
/* Make sure Trusted Watchdog timer interrupt was serviced*/
if (cactus_get_response(ret_values) != IRQ_TWDOG_INTID) {
ERROR("Trusted watchdog timer interrupt not serviced by SP\n");
- return TEST_RESULT_FAIL;
+ goto exit;
}
/* Disable Trusted Watchdog interrupt. */
if (!disable_trusted_wdog_interrupt(SENDER, RECEIVER)) {
- return TEST_RESULT_FAIL;
+ goto exit;
}
- return TEST_RESULT_SUCCESS;
+ test_ret = TEST_RESULT_SUCCESS;
+exit:
+ if (test_ret != TEST_RESULT_SUCCESS) {
+ ERROR("%s - Test Failed - core - %d\n", __func__,
+ get_current_core_id());
+ }
+ tftf_send_event(&cpu_reached_end_of_test[get_current_core_id()]);
+ return test_ret;
+}
+
+test_result_t test_ffa_sec_interrupt_sp1_waiting_sp2_running(void)
+{
+ CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
+ memset(cpu_reached_end_of_test, 0, sizeof(cpu_reached_end_of_test));
+
+#ifdef PLAT_INTERRUPT_MPIDR
+ return spm_run_multi_core_test(
+ (uintptr_t)test_ffa_sec_interrupt_sp1_waiting_sp2_running_handler,
+ cpu_reached_end_of_test);
+#else
+ return test_ffa_sec_interrupt_sp1_waiting_sp2_running_handler();
+#endif
}