test(notifications): test schedule receiver interrupt

Refactor slightly tests that signal global notifications from SP to SP,
from VM to SP, and from SP to VM, to verify if SRI has been set
after the notifications set.
In this test the flag to delay sending SRI is being used, however no
validation interrupt sending has been delayed yet.

Signed-off-by: J-Alves <joao.alves@arm.com>
Change-Id: I28403bb1e09f2c2090eb9913d5b07b7eb245fb4d
diff --git a/include/runtime_services/ffa_helpers.h b/include/runtime_services/ffa_helpers.h
index b25b6a1..1774848 100644
--- a/include/runtime_services/ffa_helpers.h
+++ b/include/runtime_services/ffa_helpers.h
@@ -80,6 +80,12 @@
 #define FFA_NOTIFICATIONS_FLAG_BITMAP_SPM	UINT32_C(0x1 << 2)
 #define FFA_NOTIFICATIONS_FLAG_BITMAP_HYP	UINT32_C(0x1 << 3)
 
+/**
+ * The following is an SGI ID, that the SPMC configures as non-secure, as
+ * suggested by the FF-A v1.1 specification, in section 9.4.1.
+ */
+#define FFA_SCHEDULE_RECEIVER_INTERRUPT_ID 8
+
 #define FFA_NOTIFICATIONS_BITMAP(lo, hi)	\
 	(ffa_notification_bitmap_t)(lo) | 	\
 	(((ffa_notification_bitmap_t)hi << 32) & 0xFFFFFFFF00000000ULL)
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 5a77057..e77b8b0 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_notifications.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_notifications.c
@@ -5,6 +5,7 @@
  */
 
 #include <debug.h>
+#include <irq.h>
 #include <smccc.h>
 
 #include <arch_helpers.h>
@@ -598,6 +599,49 @@
 						      expected_more_pending);
 }
 
+static volatile int schedule_receiver_interrupt_received;
+
+static int schedule_receiver_interrupt_handler(void *data)
+{
+	assert(schedule_receiver_interrupt_received == 0);
+	schedule_receiver_interrupt_received = 1;
+	return 0;
+}
+
+/**
+ * Enable the Schedule Receiver Interrupt and register the respective
+ * handler.
+ */
+static void schedule_receiver_interrupt_init(void)
+{
+	tftf_irq_register_handler(FFA_SCHEDULE_RECEIVER_INTERRUPT_ID,
+				  schedule_receiver_interrupt_handler);
+
+	tftf_irq_enable(FFA_SCHEDULE_RECEIVER_INTERRUPT_ID, 0xA);
+}
+
+/**
+ * Disable the Schedule Receiver Interrupt and unregister the respective
+ * handler.
+ */
+static void schedule_receiver_interrupt_deinit(void)
+{
+	tftf_irq_disable(FFA_SCHEDULE_RECEIVER_INTERRUPT_ID);
+	tftf_irq_unregister_handler(FFA_SCHEDULE_RECEIVER_INTERRUPT_ID);
+	schedule_receiver_interrupt_received = 0;
+}
+
+bool check_schedule_receiver_interrupt_handled(void)
+{
+	if (schedule_receiver_interrupt_received == 1) {
+		VERBOSE("Schedule Receiver Interrupt handled!\n");
+		schedule_receiver_interrupt_received = 0;
+		return true;
+	}
+	VERBOSE("Schedule Receiver Interrupt NOT handled!\n");
+	return false;
+}
+
 /**
  * Test to validate a VM can signal an SP.
  */
@@ -617,10 +661,14 @@
 
 	CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
 
+	schedule_receiver_interrupt_init();
+
 	if (!notification_bind_and_set(sender, receiver, notifications, 0)) {
 		return TEST_RESULT_FAIL;
 	}
 
+	check_schedule_receiver_interrupt_handled();
+
 	/**
 	 * Simple list of IDs expected on return from FFA_NOTIFICATION_INFO_GET.
 	 */
@@ -643,6 +691,8 @@
 		return TEST_RESULT_FAIL;
 	}
 
+	schedule_receiver_interrupt_deinit();
+
 	return TEST_RESULT_SUCCESS;
 }
 
@@ -662,12 +712,15 @@
 
 	CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
 
+	schedule_receiver_interrupt_init();
+
 	/* Request receiver to bind a set of notifications to the sender. */
-	if (!notification_bind_and_set(sender, receiver,
-					       g_notifications, 0)) {
+	if (!notification_bind_and_set(sender, receiver, g_notifications, 0)) {
 		return TEST_RESULT_FAIL;
 	}
 
+	check_schedule_receiver_interrupt_handled();
+
 	/*
 	 * FFA_NOTIFICATION_INFO_GET return list should be simple, containing
 	 * only the receiver's ID.
@@ -691,6 +744,8 @@
 		return TEST_RESULT_FAIL;
 	}
 
+	schedule_receiver_interrupt_deinit();
+
 	return TEST_RESULT_SUCCESS;
 }
 
@@ -704,6 +759,7 @@
 	const ffa_id_t receiver = 1;
 	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};
@@ -712,14 +768,18 @@
 
 	/* Ask SPMC to allocate notifications bitmap. */
 	if (!notifications_bitmap_create(receiver, 1)) {
-		return TEST_RESULT_FAIL;
+		result = TEST_RESULT_FAIL;
 	}
 
+	schedule_receiver_interrupt_init();
+
 	/* Request receiver to bind a set of notifications to the sender. */
 	if (!notification_bind_and_set(sender, receiver, g_notifications, 0)) {
 		return TEST_RESULT_FAIL;
 	}
 
+	check_schedule_receiver_interrupt_handled();
+
 	/*
 	 * FFA_NOTIFICATION_INFO_GET return list should be simple, containing
 	 * only the receiver's ID.
@@ -730,7 +790,7 @@
 	if (!notifications_info_get(ids, lists_count, lists_sizes,
 				    FFA_NOTIFICATIONS_INFO_GET_MAX_IDS,
 				    false)) {
-		return TEST_RESULT_FAIL;
+		result = TEST_RESULT_FAIL;
 	}
 
 	/* Get pending notifications, and retrieve response. */
@@ -742,14 +802,16 @@
 	ret = ffa_notification_unbind(sender, receiver, g_notifications);
 
 	if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32)) {
-		return TEST_RESULT_FAIL;
+		result = TEST_RESULT_FAIL;
 	}
 
 	if (!notifications_bitmap_destroy(receiver)) {
-		return TEST_RESULT_FAIL;
+		result = TEST_RESULT_FAIL;
 	}
 
-	return TEST_RESULT_SUCCESS;
+	schedule_receiver_interrupt_deinit();
+
+	return result;
 }
 
 /**
@@ -764,6 +826,8 @@
 				       FFA_NOTIFICATION(35);
 	uint32_t get_flags = FFA_NOTIFICATIONS_FLAG_BITMAP_VM;
 
+	schedule_receiver_interrupt_init();
+
 	/* Request receiver to bind a set of notifications to the sender. */
 	if (!notification_bind_and_set(sender, receiver, notifications, 0)) {
 		return TEST_RESULT_FAIL;
@@ -779,6 +843,10 @@
 		return TEST_RESULT_FAIL;
 	}
 
+	if (!check_schedule_receiver_interrupt_handled()) {
+		return TEST_RESULT_FAIL;
+	}
+
 	/*
 	 * Request receiver partition to get pending notifications from VMs.
 	 * Only notification 30 is expected.
@@ -794,6 +862,8 @@
 		return TEST_RESULT_FAIL;
 	}
 
+	schedule_receiver_interrupt_deinit();
+
 	return TEST_RESULT_SUCCESS;
 }
 
@@ -920,7 +990,8 @@
 	for (unsigned int i = 0; i < PLATFORM_CORE_COUNT; i++) {
 		notifications_to_unbind |= FFA_NOTIFICATION(i);
 
-		uint32_t flags = FFA_NOTIFICATIONS_FLAG_PER_VCPU |
+		uint32_t flags = FFA_NOTIFICATIONS_FLAG_DELAY_SRI |
+				 FFA_NOTIFICATIONS_FLAG_PER_VCPU  |
 				 FFA_NOTIFICATIONS_FLAGS_VCPU_ID((uint16_t)i);
 
 		if (!notification_bind_and_set(sender,