feat(notifications): info get framework notifications

Include framework in the processing of FFA_NOTIFICATION_INFO_GET:
- Hypervisor only cares about notifications targeting VMs.
- SPMC retrieves information of notifications targeting SPs and VMs.

Change-Id: I6ea4a5cf1c14437e01666426c293e20c2f028110
Signed-off-by: J-Alves <joao.alves@arm.com>
diff --git a/src/arch/aarch64/plat/ffa/spmc.c b/src/arch/aarch64/plat/ffa/spmc.c
index e172e7e..442bc6b 100644
--- a/src/arch/aarch64/plat/ffa/spmc.c
+++ b/src/arch/aarch64/plat/ffa/spmc.c
@@ -653,43 +653,39 @@
 					uint32_t *lists_count,
 					const uint32_t ids_count_max)
 {
-	enum notifications_info_get_state info_get_state = INIT;
 	struct nwd_vms_locked nwd_vms_locked = nwd_vms_lock();
 	struct vm_locked other_world_locked = vm_find_locked(HF_OTHER_WORLD_ID);
+	/*
+	 * Variable to save return from 'vm_notifications_info_get'. To be
+	 * returned and used as indicator that scheduler should conduct more
+	 * calls to retrieve info of pending notifications.
+	 */
+	bool list_full_and_more_pending = false;
 
 	CHECK(other_world_locked.vm != NULL);
 
-	vm_notifications_info_get_pending(other_world_locked, false, ids,
-					  ids_count, lists_sizes, lists_count,
-					  ids_count_max, &info_get_state);
+	list_full_and_more_pending = vm_notifications_info_get(
+		other_world_locked, ids, ids_count, lists_sizes, lists_count,
+		ids_count_max);
 
 	vm_unlock(&other_world_locked);
 
-	if (info_get_state == FULL) {
-		goto out;
-	}
-
-	for (unsigned int i = 0; i < nwd_vms_size; i++) {
-		info_get_state = INIT;
-
+	for (ffa_vm_count_t i = 0;
+	     i < nwd_vms_size && !list_full_and_more_pending; i++) {
 		if (nwd_vms[i].id != HF_INVALID_VM_ID) {
 			struct vm_locked vm_locked = vm_lock(&nwd_vms[i]);
 
-			vm_notifications_info_get_pending(
-				vm_locked, false, ids, ids_count, lists_sizes,
-				lists_count, ids_count_max, &info_get_state);
+			list_full_and_more_pending = vm_notifications_info_get(
+				vm_locked, ids, ids_count, lists_sizes,
+				lists_count, ids_count_max);
 
 			vm_unlock(&vm_locked);
-
-			if (info_get_state == FULL) {
-				goto out;
-			}
 		}
 	}
-out:
+
 	nwd_vms_unlock(&nwd_vms_locked);
 
-	return info_get_state == FULL;
+	return list_full_and_more_pending;
 }
 
 bool plat_ffa_is_mem_perm_get_valid(const struct vcpu *current)
diff --git a/src/vm.c b/src/vm.c
index f5b8bbc..f67bdd6 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -905,12 +905,18 @@
 {
 	enum notifications_info_get_state current_state = INIT;
 
-	/* Get info of pending notifications from SPs */
+	/* Get info of pending notifications from the framework. */
+	vm_notifications_state_info_get(&vm_locked.vm->notifications.framework,
+					vm_locked.vm->id, false, 0, ids,
+					ids_count, lists_sizes, lists_count,
+					ids_max_count, &current_state);
+
+	/* Get info of pending notifications from SPs. */
 	vm_notifications_info_get_pending(vm_locked, false, ids, ids_count,
 					  lists_sizes, lists_count,
 					  ids_max_count, &current_state);
 
-	/* Get info of pending notifications from VMs */
+	/* Get info of pending notifications from VMs. */
 	vm_notifications_info_get_pending(vm_locked, true, ids, ids_count,
 					  lists_sizes, lists_count,
 					  ids_max_count, &current_state);
diff --git a/src/vm_test.cc b/src/vm_test.cc
index cffe5e6..e7934f8 100644
--- a/src/vm_test.cc
+++ b/src/vm_test.cc
@@ -688,4 +688,29 @@
 	vm_unlock(&current_vm_locked);
 }
 
+TEST_F(vm, vm_notifications_info_get_from_framework)
+{
+	struct vm_locked vm_locked = vm_lock(vm_find_index(0));
+	uint16_t ids[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {0};
+	uint32_t ids_count = 0;
+	uint32_t lists_sizes[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {0};
+	uint32_t lists_count = 0;
+
+	vm_notifications_framework_set_pending(vm_locked, 0x1U);
+
+	/* Get notifications info for the given notifications. */
+	vm_notifications_info_get(vm_locked, ids, &ids_count, lists_sizes,
+				  &lists_count,
+				  FFA_NOTIFICATIONS_INFO_GET_MAX_IDS);
+
+	EXPECT_EQ(ids[0], vm_locked.vm->id);
+	EXPECT_EQ(ids_count, 1);
+	EXPECT_EQ(lists_sizes[0], 0);
+	EXPECT_EQ(lists_count, 1);
+
+	EXPECT_EQ(vm_notifications_framework_get_pending(vm_locked), 0x1U);
+
+	vm_unlock(&vm_locked);
+}
+
 } /* namespace */