feat(notifications): schedule receiver interrupt

Configuring Schedule Receiver Interrupt for each CPU, and send
respective SGI to the NWd. If flag FFA_NOTIFICATIONS_FLAG_DELAY_SRI
is set, the SGI will be sent upon context switch from the SWd to the NWd
else it will be sent immediately, the sender SP execution will be
preempted.
A state machine was implemented to coordinate handling and sending of
the SRI.

Change-Id: If05a6535094f5da7189d8dbb55b04e7c1a1f80d7
Signed-off-by: J-Alves <joao.alves@arm.com>
diff --git a/src/api.c b/src/api.c
index cb27a58..54bde1d 100644
--- a/src/api.c
+++ b/src/api.c
@@ -2758,11 +2758,6 @@
 	bool is_per_vcpu = (flags & FFA_NOTIFICATION_FLAG_PER_VCPU) != 0U;
 	ffa_vcpu_index_t vcpu_id = (uint16_t)(flags >> 16);
 
-	/*
-	 * TODO: cater for the delay_schedule_receiver flag when dealing with
-	 * schedule receiver interrupt.
-	 */
-
 	if (!plat_ffa_is_notification_set_valid(current, sender_vm_id,
 						receiver_vm_id)) {
 		dlog_verbose("Invalid use of notifications set interface.\n");
@@ -2819,8 +2814,15 @@
 			     notifications, vcpu_id, is_per_vcpu);
 	dlog_verbose("Set the notifications: %x.\n", notifications);
 
-	ret = (struct ffa_value){.func = FFA_SUCCESS_32};
+	if ((FFA_NOTIFICATIONS_FLAG_DELAY_SRI & flags) == 0) {
+		dlog_verbose("SRI was NOT delayed. vcpu: %u!\n",
+			     vcpu_index(current));
+		plat_ffa_sri_trigger_not_delayed(current->cpu);
+	} else {
+		plat_ffa_sri_state_set(DELAYED);
+	}
 
+	ret = (struct ffa_value){.func = FFA_SUCCESS_32};
 out:
 	vm_unlock(&receiver_locked);
 
@@ -2957,6 +2959,7 @@
 	uint32_t lists_count = 0;
 	uint32_t ids_count = 0;
 	bool list_is_full = false;
+	struct ffa_value result;
 
 	/*
 	 * This interface can only be called at NS virtual/physical FF-A
@@ -3004,11 +3007,14 @@
 	if (ids_count == 0) {
 		dlog_verbose(
 			"Notification info get has no data to retrieve.\n");
-		return ffa_error(FFA_NO_DATA);
+		result = ffa_error(FFA_NO_DATA);
+	} else {
+		result = api_ffa_notification_info_get_success_return(
+			ids, ids_count, lists_sizes, lists_count, list_is_full);
+		plat_ffa_sri_state_set(HANDLED);
 	}
 
-	return api_ffa_notification_info_get_success_return(
-		ids, ids_count, lists_sizes, lists_count, list_is_full);
+	return result;
 }
 
 struct ffa_value api_ffa_mem_perm_get(vaddr_t base_addr, struct vcpu *current)