Implement FFA ABI-s for notification handling

This change implements the listed FFA ABI-s:
- FFA_NOTIFICATION_BIND
- FFA_NOTIFICATION_UNBIND
- FFA_NOTIFICATION_SET
- FFA_NOTIFICATION_GET

Change-Id: Ifc231e3d60427b1c838cf622d8338d3e112209c1
Signed-off-by: Gabor Toth <gabor.toth2@arm.com>
diff --git a/components/messaging/ffa/libsp/sp_notification.c b/components/messaging/ffa/libsp/sp_notification.c
new file mode 100644
index 0000000..ed25649
--- /dev/null
+++ b/components/messaging/ffa/libsp/sp_notification.c
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
+ */
+
+#include "sp_notification.h"
+#include "sp_api.h"
+#include <assert.h>
+#include <string.h>
+
+static uint32_t build_notif_bind_flags(struct sp_notif_bind_flags *flags)
+{
+	uint32_t res = 0;
+
+	if (flags->per_cpu)
+		res |= FFA_NOTIF_BIND_FLAGS_PER_VCPU_NOTIFICATIONS;
+
+	return res;
+}
+
+static uint32_t build_notif_set_flags(struct sp_notif_set_flags *flags)
+{
+	uint32_t res = 0;
+
+	if (flags->per_cpu) {
+		res |= FFA_NOTIF_SET_FLAGS_PER_VCPU_NOTIFICATIONS;
+		res |= SHIFT_U32(flags->receiver_vcpu_id, FFA_NOTIF_SET_FLAGS_RECEIVER_VCPU_SHIFT);
+	}
+
+	if (flags->delay_sched_rec_intr)
+		res |= FFA_NOTIF_SET_FLAGS_DELAY_SCHEDULE_RECEIVER;
+
+	return res;
+}
+
+sp_result sp_notification_bind(uint16_t sender, uint16_t receiver,
+			       struct sp_notif_bind_flags *flags, uint64_t notification_bitmap)
+{
+	return SP_RESULT_FFA(ffa_notification_bind(sender, receiver, build_notif_bind_flags(flags),
+						   notification_bitmap));
+}
+
+sp_result sp_notification_unbind(uint16_t sender, uint16_t receiver, uint64_t notification_bitmap)
+{
+	return SP_RESULT_FFA(ffa_notification_unbind(sender, receiver, notification_bitmap));
+}
+
+sp_result sp_notification_set(uint16_t sender, uint16_t receiver, struct sp_notif_set_flags *flags,
+			      uint64_t notification_bitmap)
+{
+	if (!flags->per_cpu && flags->receiver_vcpu_id)
+		return SP_RESULT_INVALID_PARAMETERS;
+
+	return SP_RESULT_FFA(ffa_notification_set(sender, receiver, build_notif_set_flags(flags),
+						  notification_bitmap));
+}
+
+sp_result sp_notification_get(uint16_t sender, uint16_t receiver, uint64_t *sp_notification_bitmap,
+			      uint64_t *vm_notification_bitmap, uint32_t *spm_notification_bitmap,
+			      uint32_t *hv_notification_bitmap)
+{
+	uint32_t flags = 0;
+	uint64_t buff_framework_notification_bitmap = 0;
+	uint64_t buff_sp_notification_bitmap = 0;
+	uint64_t buff_vm_notification_bitmap = 0;
+	sp_result result = 0;
+
+	if (sp_notification_bitmap)
+		flags |= FFA_NOTIF_GET_FLAGS_PENDING_SP_NOTIF;
+	if (vm_notification_bitmap)
+		flags |= FFA_NOTIF_GET_FLAGS_PENDING_VM_NOTIF;
+	if (spm_notification_bitmap)
+		flags |= FFA_NOTIF_GET_FLAGS_PENDING_SPM_NOTIF;
+	if (hv_notification_bitmap)
+		flags |= FFA_NOTIF_GET_FLAGS_PENDING_HV_NOTIF;
+
+	result = SP_RESULT_FFA(ffa_notification_get(sender, receiver, flags, &buff_sp_notification_bitmap,
+						    &buff_vm_notification_bitmap,
+						    &buff_framework_notification_bitmap));
+	if (sp_notification_bitmap)
+		*sp_notification_bitmap = buff_sp_notification_bitmap;
+	if (vm_notification_bitmap)
+		*vm_notification_bitmap = buff_vm_notification_bitmap;
+	if (spm_notification_bitmap)
+		*spm_notification_bitmap = buff_framework_notification_bitmap & 0xFFFFFFFF;
+	if (hv_notification_bitmap)
+		*hv_notification_bitmap = buff_framework_notification_bitmap >> 32 & 0xFFFFFFFF;
+
+	return result;
+}