feat(notifications): notifications set and get
Handle FF-A calls FFA_NOTIFICATION_SET and FFA_NOTIFICATION_GET.
The former is used for a sender to signal a notification to the
receiver; the latter is for the receiver to get whichever notifications
there are pending.
Change-Id: I7e9db94201d0d78ceecd599cd350eeb37a8cb1f8
Signed-off-by: J-Alves <joao.alves@arm.com>
diff --git a/src/vm.c b/src/vm.c
index f7fb390..147a8ec 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -538,3 +538,44 @@
return is_per_vcpu ? (~to_check->bindings_per_vcpu & notif) == 0U
: (to_check->bindings_per_vcpu & notif) == 0U;
}
+
+void vm_notifications_set(struct vm_locked vm_locked, bool is_from_vm,
+ ffa_notifications_bitmap_t notifications,
+ ffa_vcpu_index_t vcpu_id, bool is_per_vcpu)
+{
+ CHECK(vm_locked.vm != NULL);
+ struct notifications *to_set =
+ vm_get_notifications(vm_locked, is_from_vm);
+ CHECK(vcpu_id < MAX_CPUS);
+
+ if (is_per_vcpu) {
+ to_set->per_vcpu[vcpu_id].pending |= notifications;
+ } else {
+ to_set->global.pending |= notifications;
+ }
+}
+
+/**
+ * Get Global notifications and per CPU only of the current VCPU.
+ */
+ffa_notifications_bitmap_t vm_notifications_get_pending_and_clear(
+ struct vm_locked vm_locked, bool is_from_vm,
+ ffa_vcpu_index_t cur_vcpu_id)
+{
+ ffa_notifications_bitmap_t to_ret = 0;
+
+ CHECK(vm_locked.vm != NULL);
+ struct notifications *to_get =
+ vm_get_notifications(vm_locked, is_from_vm);
+ CHECK(cur_vcpu_id < MAX_CPUS);
+
+ to_ret |= to_get->global.pending;
+ to_get->global.pending = 0U;
+ to_get->global.info_get_retrieved = 0U;
+
+ to_ret |= to_get->per_vcpu[cur_vcpu_id].pending;
+ to_get->per_vcpu[cur_vcpu_id].pending = 0U;
+ to_get->per_vcpu[cur_vcpu_id].info_get_retrieved = 0U;
+
+ return to_ret;
+}