diff options
-rw-r--r-- | plat/arm/fvp/include/platform_def.h | 3 | ||||
-rw-r--r-- | spm/cactus/plat/arm/fvp/fdts/cactus.dts | 1 | ||||
-rw-r--r-- | tftf/tests/runtime_services/secure_service/test_ffa_secure_interrupts.c | 229 |
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 } |