refactor(interrupts): enhance secure interrupt handling test

This test makes sure SPMC was able to handle back-to-back
secure interrupts targetting Cactus SP while the SP was in
RUNNING state.

Signed-off-by: Madhukar Pappireddy <madhukar.pappireddy@arm.com>
Change-Id: If2e93017e2c21ad91fe527fb140f0fd5e0252370
diff --git a/include/runtime_services/cactus_test_cmds.h b/include/runtime_services/cactus_test_cmds.h
index 130cfa5..97624f7 100644
--- a/include/runtime_services/cactus_test_cmds.h
+++ b/include/runtime_services/cactus_test_cmds.h
@@ -303,6 +303,29 @@
 }
 
 /**
+ * Command to request cactus to sleep for half the given time in ms, trigger
+ * trusted watchdog timer and then sleep again for another half the given time.
+ *
+ * The sender of this command expects to receive CACTUS_SUCCESS if the requested
+ * echo interaction happened successfully, or CACTUS_ERROR otherwise.
+ */
+#define CACTUS_SLEEP_TRIGGER_TWDOG_CMD (CACTUS_SLEEP_CMD + 2)
+
+static inline smc_ret_values cactus_sleep_trigger_wdog_cmd(
+	ffa_id_t source, ffa_id_t dest, uint32_t sleep_time,
+	uint64_t wdog_time)
+{
+	return cactus_send_cmd(source, dest, CACTUS_SLEEP_TRIGGER_TWDOG_CMD, sleep_time,
+			       wdog_time, 0, 0);
+}
+
+
+static inline uint32_t cactus_get_wdog_trigger_duration(smc_ret_values ret)
+{
+	return (uint32_t)ret.ret5;
+}
+
+/**
  * Command to request cactus to enable/disable an interrupt
  *
  * The command id is the hex representation of string "intr"
diff --git a/spm/cactus/cactus_tests/cactus_test_interrupts.c b/spm/cactus/cactus_tests/cactus_test_interrupts.c
index ced5dca..2d37f8a 100644
--- a/spm/cactus/cactus_tests/cactus_test_interrupts.c
+++ b/spm/cactus/cactus_tests/cactus_test_interrupts.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -101,3 +101,34 @@
 
 	return cactus_success_resp(vm_id, source, time_ms);
 }
+
+CACTUS_CMD_HANDLER(sleep_twdog_cmd, CACTUS_SLEEP_TRIGGER_TWDOG_CMD)
+{
+	uint64_t time_lapsed;
+	uint32_t sleep_time = cactus_get_sleep_time(*args) / 2;
+	uint64_t time_ms = cactus_get_wdog_trigger_duration(*args);
+
+	VERBOSE("Request to sleep %x for %ums.\n", ffa_dir_msg_dest(*args),
+		sleep_time);
+
+	time_lapsed = sp_sleep_elapsed_time(sleep_time);
+
+	/* Lapsed time should be at least equal to sleep time. */
+	VERBOSE("Sleep complete: %llu\n", time_lapsed);
+
+	VERBOSE("Starting TWDOG: %llums\n", time_ms);
+	sp805_twdog_refresh();
+	sp805_twdog_start((time_ms * ARM_SP805_TWDG_CLK_HZ) / 1000);
+
+	VERBOSE("2nd Request to sleep %x for %ums.\n", ffa_dir_msg_dest(*args),
+		sleep_time);
+
+	time_lapsed += sp_sleep_elapsed_time(sleep_time);
+
+	/* Lapsed time should be at least equal to sleep time. */
+	VERBOSE("2nd Sleep complete: %llu\n", time_lapsed);
+
+	return cactus_response(ffa_dir_msg_dest(*args),
+			       ffa_dir_msg_source(*args),
+			       time_lapsed);
+}
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 6ff30f6..ce9c809 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
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -59,10 +59,11 @@
  * 1. Send a direct message request command to first Cactus SP to start the
  *    trusted watchdog timer.
  *
- * 2. Send a command to SP to sleep by executing a busy loop.
+ * 2. Send a command to SP to first sleep( by executing a busy loop), then
+ *    restart trusted watchdog timer and then sleep again.
  *
- * 3. While SP is running the busy loop, Secure interrupt should trigger during
- *    this time.
+ * 3. While SP is running the first busy loop, Secure interrupt should trigger
+ *    during this time.
  *
  * 4. The interrupt will be trapped to SPM as IRQ. SPM will inject the virtual
  *    IRQ to the first SP through vIRQ conduit and perform eret to resume
@@ -74,22 +75,25 @@
  * 6. Cactus SP will perform End-Of-Interrupt and resume execution in the busy
  *    loop.
  *
- * 7. Cactus SP will send a direct response message with the elapsed time back
+ * 7. Trusted watchdog timer will trigger once again followed by steps 4 to 6.
+ *
+ * 8. Cactus SP will send a direct response message with the elapsed time back
  *    to the normal world.
  *
- * 8. We make sure the time elapsed in the sleep routine by SP is not less than
+ * 9. We make sure the time elapsed in the sleep routine by SP is not less than
  *    the requested value.
  *
- * 9. For robustness of state transition checks, TFTF sends echo command using
+ * 10. For robustness of state transition checks, TFTF sends echo command using
  *    a direct request message.
  *
- * 10. Further, TFTF expects SP to return with a success value through a direct
+ * 11. Further, TFTF expects SP to return with a success value through a direct
  *    response message.
  *
- * 11. Test finishes successfully once the TFTF disables the trusted watchdog
+ * 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_running(void)
 {
 	smc_ret_values ret_values;
@@ -109,7 +113,7 @@
 	}
 
 	/* Send request to first Cactus SP to sleep */
-	ret_values = cactus_sleep_cmd(SENDER, RECEIVER, SP_SLEEP_TIME);
+	ret_values = cactus_sleep_trigger_wdog_cmd(SENDER, RECEIVER, SP_SLEEP_TIME, 50);
 
 	/*
 	 * Secure interrupt should trigger during this time, Cactus
@@ -120,7 +124,7 @@
 		return TEST_RESULT_FAIL;
 	}
 
-	VERBOSE("Secure interrupt has preempted execution: %u\n",
+	INFO("Secure interrupt has preempted execution: %u\n",
 					cactus_get_response(ret_values));
 
 	/* Make sure elapsed time not less than sleep time */