test: add test to exercise secure interrupt handling while SP is waiting

A detailed description of the test is provided in the comments preceding
the definition of the test.

Signed-off-by: Madhukar Pappireddy <madhukar.pappireddy@arm.com>
Change-Id: Ibd66697a681ee87fd47340cc770c737b0e9a01c2
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 0dba0f5..7e4eac3 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
@@ -148,3 +148,105 @@
 
 	return TEST_RESULT_SUCCESS;
 }
+
+/*
+ * @Test_Aim@ Test secure interrupt handling while Secure Partition is waiting
+ * for a message.
+ *
+ * 1. Send a direct message request command to first Cactus SP to start the
+ *    trusted watchdog timer.
+ *
+ * 2. Once the SP returns with a direct response message, it moves to WAITING
+      state.
+ *
+ * 3. Execute a busy loop to sleep for NS_TIME_SLEEP ms.
+ *
+ * 4. Trusted watchdog timer expires during this time which leads to secure
+ *    interrupt being triggered while cpu is executing in normal world.
+ *
+ * 5. The interrupt is trapped to BL31/SPMD as FIQ and later synchronously
+ *    delivered to SPM.
+ *
+ * 6. SPM injects a virtual IRQ to first Cactus Secure Partition.
+ *
+ * 7. Once the SP handles the interrupt, it returns execution back to normal
+ *    world using FFA_MSG_WAIT call.
+ *
+ * 8. SPM, through the help of SPMD, resumes execution in normal world to
+ *    continue the busy loop.
+ *
+ * 9. We make sure the time elapsed in the sleep routine is not less than
+ *    the requested value.
+ *
+ * 10. For robustness of state transition checks, TFTF sends echo command using
+ *    a direct request message.
+ *
+ * 11. Further, TFTF expects SP to return with a success value through a direct
+ *    response message.
+ *
+ * 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_sp_waiting(void)
+{
+	uint64_t time1;
+	volatile uint64_t time2, time_lapsed;
+	uint64_t timer_freq = read_cntfrq_el0();
+	smc_ret_values ret_values;
+
+	CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
+
+	/* Enable trusted watchdog interrupt as IRQ in the secure side. */
+	if (!enable_trusted_wdog_interrupt(SENDER, RECEIVER)) {
+		return TEST_RESULT_FAIL;
+	}
+
+	/*
+	 * Send a message to SP1 through direct messaging.
+	 */
+	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;
+	}
+
+	time1 = syscounter_read();
+
+	/*
+	 * Sleep for NS_TIME_SLEEP ms. This ensures secure wdog timer triggers during this
+	 * time. We explicitly do not use tftf_timer_sleep();
+	 */
+	waitms(NS_TIME_SLEEP);
+	time2 = syscounter_read();
+
+	/* Lapsed time should be at least equal to sleep time */
+	time_lapsed = ((time2 - time1) * 1000) / timer_freq;
+
+	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;
+	}
+
+	ret_values = cactus_echo_send_cmd(SENDER, RECEIVER, ECHO_VAL1);
+
+	if (!is_ffa_direct_response(ret_values)) {
+		ERROR("Expected direct response for echo command\n");
+		return TEST_RESULT_FAIL;
+	}
+
+	if (cactus_get_response(ret_values) != CACTUS_SUCCESS ||
+	    cactus_echo_get_val(ret_values) != ECHO_VAL1) {
+		ERROR("Echo Failed!\n");
+		return TEST_RESULT_FAIL;
+	}
+
+	/* Disable Trusted Watchdog interrupt. */
+	if (!disable_trusted_wdog_interrupt(SENDER, RECEIVER)) {
+		return TEST_RESULT_FAIL;
+	}
+
+	return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/tests-spm.xml b/tftf/tests/tests-spm.xml
index fe7c3bd..9191716 100644
--- a/tftf/tests/tests-spm.xml
+++ b/tftf/tests/tests-spm.xml
@@ -94,6 +94,8 @@
                function="test_ffa_ns_interrupt" />
      <testcase name="Test Secure interrupt handling while SP running"
                function="test_ffa_sec_interrupt_sp_running" />
+     <testcase name="Test Secure interrupt handling while SP waiting"
+               function="test_ffa_sec_interrupt_sp_waiting" />
   </testsuite>
 
   <testsuite name="SMMUv3 tests"