blob: ed25649a11d432c12cb622a98359abf259aad446 [file] [log] [blame]
// 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;
}