test(notifications): validate SRI is delayed

This test aims at validating that when flag to delay SRI is set,
effectively the SWd is not preempted upon a call to the interface
FFA_NOTIFICATION_SET.
Leveraging the commits [1] and [2], the cactus SP that is setting the
notifications is also sending an echo test command to another SP.
With the help of [2], TFTF can request the counting of test commands
to the echo destination prior and after the setting of notifications,
evaluating that before execution returning to TFTF the counting has
been incremented.

[1] https://review.trustedfirmware.org/c/TF-A/tf-a-tests/+/11596/36
[2] https://review.trustedfirmware.org/c/TF-A/tf-a-tests/+/11595/36

Signed-off-by: J-Alves <joao.alves@arm.com>
Change-Id: If343db29517ad64533e98bc6fab5127283ffbf94
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_notifications.c b/tftf/tests/runtime_services/secure_service/test_ffa_notifications.c
index dbdf724..007a774 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_notifications.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_notifications.c
@@ -418,8 +418,8 @@
 
 static bool request_notification_set(
 	ffa_id_t cmd_dest, ffa_id_t receiver, ffa_id_t sender, uint32_t flags,
-	ffa_notification_bitmap_t notifications, uint32_t exp_resp,
-	int32_t exp_error)
+	ffa_notification_bitmap_t notifications, ffa_id_t echo_dest,
+	uint32_t exp_resp, int32_t exp_error)
 {
 	smc_ret_values ret;
 
@@ -427,7 +427,8 @@
 		cmd_dest, sender, receiver);
 
 	ret = cactus_notifications_set_send_cmd(HYP_ID, cmd_dest, receiver,
-						sender, flags, notifications, 0);
+						sender, flags, notifications,
+						echo_dest);
 
 	if (!is_expected_cactus_response(ret, exp_resp, exp_error)) {
 		ERROR("Failed notifications set. receiver: %x; sender: %x\n",
@@ -555,7 +556,7 @@
 	}
 
 	return request_notification_set(sender, receiver, sender, flags,
-					notifications, CACTUS_SUCCESS, 0);
+					notifications, 0, CACTUS_SUCCESS, 0);
 }
 
 /**
@@ -1242,8 +1243,8 @@
 	 * MANAGED_EXIT_INTERRUPT_ID.
 	 */
 	if (!request_notification_set(sender, receiver, sender, 0,
-				      g_notifications, MANAGED_EXIT_INTERRUPT_ID,
-				      0)) {
+				      g_notifications, 0,
+				      MANAGED_EXIT_INTERRUPT_ID, 0)) {
 		ERROR("SRI not handled immediately!\n");
 		result = TEST_RESULT_FAIL;
 	} else {
@@ -1293,3 +1294,119 @@
 
 	return result;
 }
+
+/**
+ * Test to validate behavior in SWd if the SRI is delayed.
+ */
+test_result_t test_ffa_notifications_sp_signals_sp_delayed_sri(void)
+{
+	CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
+	const ffa_id_t sender = SP_ID(3);
+	const ffa_id_t receiver = SP_ID(2);
+	const ffa_id_t echo_dest = SP_ID(1);
+	uint32_t echo_dest_cmd_count = 0;
+	uint32_t get_flags = FFA_NOTIFICATIONS_FLAG_BITMAP_SP;
+	smc_ret_values ret;
+	test_result_t result = TEST_RESULT_SUCCESS;
+
+	/** Variables to validate calls to FFA_NOTIFICATION_INFO_GET. */
+	uint16_t ids[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {0};
+	uint32_t lists_count;
+	uint32_t lists_sizes[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {0};
+
+	ids[0] = receiver;
+	lists_count = 1;
+
+	/* Enable managed exit interrupt as FIQ in the secure side. */
+	if (!spm_set_managed_exit_int(sender, true)) {
+		return TEST_RESULT_FAIL;
+	}
+
+	schedule_receiver_interrupt_init();
+
+	/* Request receiver to bind a set of notifications to the sender. */
+	if (!request_notification_bind(receiver, receiver, sender,
+				       g_notifications, 0, CACTUS_SUCCESS, 0)) {
+		result = TEST_RESULT_FAIL;
+	}
+
+	ret = cactus_get_req_count_send_cmd(HYP_ID, echo_dest);
+
+	if (cactus_get_response(ret) == CACTUS_SUCCESS) {
+		/*
+		 * Save the command count from the echo_dest, to validate it
+		 * has been incremented after the request to set notifications.
+		 */
+		echo_dest_cmd_count = cactus_get_req_count(ret);
+		VERBOSE("Partition %x command count %u.\n", echo_dest,
+			echo_dest_cmd_count);
+	} else {
+		VERBOSE("Failed to get cmds count from %u\n", echo_dest);
+		result = TEST_RESULT_FAIL;
+	}
+
+	/*
+	 * Request sender to set notification with Delay SRI flag, and specify
+	 * echo destination.
+	 */
+	if (!request_notification_set(sender, receiver, sender,
+				      FFA_NOTIFICATIONS_FLAG_DELAY_SRI,
+				      g_notifications, echo_dest,
+				      CACTUS_SUCCESS, 0)) {
+		VERBOSE("Failed to set notifications!\n");
+		result = TEST_RESULT_FAIL;
+	}
+
+	if (!check_schedule_receiver_interrupt_handled()) {
+		result = TEST_RESULT_FAIL;
+	}
+
+	/*
+	 * Get command count again from echo_dest, to validate that it has been
+	 * incremented by one. This should indicate the notification setter has
+	 * issued a request to echo_dest right after the notification set, thus
+	 * proving the SRI hasn't been sent right after FFA_NOTIFICATION_SET.
+	 */
+	ret = cactus_get_req_count_send_cmd(HYP_ID, echo_dest);
+	if (cactus_get_response(ret) == CACTUS_SUCCESS) {
+		if (cactus_get_req_count(ret) == echo_dest_cmd_count + 1) {
+			VERBOSE("SRI successfully delayed.\n");
+		} else {
+			VERBOSE("Failed to get cmds count from %u.\n",
+				echo_dest);
+			result = TEST_RESULT_FAIL;
+		}
+	} else {
+		VERBOSE("Failed to get cmds count from %x\n", echo_dest);
+		result = TEST_RESULT_FAIL;
+	}
+
+	/* Call FFA_NOTIFICATION_INFO_GET and validate return. */
+	if (!notifications_info_get(ids, lists_count, lists_sizes,
+				    FFA_NOTIFICATIONS_INFO_GET_MAX_IDS,
+				    false)) {
+		result = TEST_RESULT_FAIL;
+	}
+
+	/* Validate notification get. */
+	if (!request_notification_get(receiver, receiver, 0, get_flags, &ret) ||
+	    !is_notifications_get_as_expected(&ret, g_notifications, 0,
+					      receiver)) {
+		result = TEST_RESULT_FAIL;
+	}
+
+	/* Unbind for clean-up. */
+	if (!request_notification_unbind(receiver, receiver, sender,
+					 g_notifications, CACTUS_SUCCESS, 0)) {
+		result = TEST_RESULT_FAIL;
+	}
+
+	schedule_receiver_interrupt_deinit();
+
+	/* Disable managed exit interrupt as FIQ in the secure side. */
+	if (!spm_set_managed_exit_int(sender, false)) {
+		return TEST_RESULT_FAIL;
+	}
+
+	return result;
+}
diff --git a/tftf/tests/tests-spm.xml b/tftf/tests/tests-spm.xml
index 52ceb8a..e8bbb5d 100644
--- a/tftf/tests/tests-spm.xml
+++ b/tftf/tests/tests-spm.xml
@@ -136,6 +136,8 @@
                function="test_ffa_notifications_sp_signals_vm" />
      <testcase name="Notifications SP signals SP with immediate SRI"
                function="test_ffa_notifications_sp_signals_sp_immediate_sri" />
+     <testcase name="Notifications SP signals SP with delayed SRI"
+               function="test_ffa_notifications_sp_signals_sp_delayed_sri" />
      <testcase name="Notifications unbind while pending"
                function="test_ffa_notifications_unbind_pending" />
      <testcase name="Notifications info get no data"