blob: eb0e9612851b57be9f8dd28d9d431d542248f00a [file] [log] [blame]
/*
* Copyright (c) 2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <drivers/arm/arm_gic.h>
#include <sdei.h>
#include <smccc.h>
#include <stdint.h>
#include <tftf_lib.h>
int64_t sdei_version(void)
{
smc_args args = { SDEI_VERSION };
smc_ret_values ret;
ret = tftf_smc(&args);
return ret.ret0;
}
int64_t sdei_interrupt_bind(int intr, struct sdei_intr_ctx *intr_ctx)
{
smc_args args = { 0 };
smc_ret_values ret;
assert(intr_ctx);
intr_ctx->priority = arm_gic_get_intr_priority(intr);
intr_ctx->num = intr;
intr_ctx->enabled = arm_gic_intr_enabled(intr);
arm_gic_intr_disable(intr);
args.fid = SDEI_INTERRUPT_BIND;
args.arg1 = intr;
ret = tftf_smc(&args);
if (ret.ret0 < 0) {
arm_gic_set_intr_priority(intr_ctx->num, intr_ctx->priority);
if (intr_ctx->enabled)
arm_gic_intr_enable(intr_ctx->num);
}
return ret.ret0;
}
int64_t sdei_interrupt_release(int ev, const struct sdei_intr_ctx *intr_ctx)
{
smc_args args = { 0 };
smc_ret_values ret;
assert(intr_ctx);
args.fid = SDEI_INTERRUPT_RELEASE;
args.arg1 = ev;
ret = tftf_smc(&args);
if (ret.ret0 == 0) {
arm_gic_set_intr_priority(intr_ctx->num, intr_ctx->priority);
if (intr_ctx->enabled)
arm_gic_intr_enable(intr_ctx->num);
}
return ret.ret0;
}
int64_t sdei_event_register(int ev, sdei_handler_t *ep,
uint64_t ep_arg, int flags, uint64_t mpidr)
{
smc_args args = { 0 };
smc_ret_values ret;
args.fid = SDEI_EVENT_REGISTER;
args.arg1 = ev;
args.arg2 = (u_register_t)ep;
args.arg3 = ep_arg;
args.arg4 = flags;
args.arg5 = mpidr;
ret = tftf_smc(&args);
return ret.ret0;
}
int64_t sdei_event_unregister(int ev)
{
smc_args args = { 0 };
smc_ret_values ret;
args.fid = SDEI_EVENT_UNREGISTER;
args.arg1 = ev;
ret = tftf_smc(&args);
return ret.ret0;
}
int64_t sdei_event_enable(int ev)
{
smc_args args = { 0 };
smc_ret_values ret;
args.fid = SDEI_EVENT_ENABLE;
args.arg1 = ev;
ret = tftf_smc(&args);
return ret.ret0;
}
int64_t sdei_event_disable(int ev)
{
smc_args args = { 0 };
smc_ret_values ret;
args.fid = SDEI_EVENT_DISABLE;
args.arg1 = ev;
ret = tftf_smc(&args);
return ret.ret0;
}
int64_t sdei_pe_mask(void)
{
smc_args args = { 0 };
smc_ret_values ret;
args.fid = SDEI_PE_MASK;
ret = tftf_smc(&args);
return ret.ret0;
}
int64_t sdei_pe_unmask(void)
{
smc_args args = { 0 };
smc_ret_values ret;
args.fid = SDEI_PE_UNMASK;
ret = tftf_smc(&args);
return ret.ret0;
}
int64_t sdei_private_reset(void)
{
smc_args args = { 0 };
smc_ret_values ret;
args.fid = SDEI_PRIVATE_RESET;
ret = tftf_smc(&args);
return ret.ret0;
}
int64_t sdei_shared_reset(void)
{
smc_args args = { 0 };
smc_ret_values ret;
args.fid = SDEI_SHARED_RESET;
ret = tftf_smc(&args);
return ret.ret0;
}
int64_t sdei_event_signal(uint64_t mpidr)
{
smc_args args = { 0 };
smc_ret_values ret;
args.fid = SDEI_EVENT_SIGNAL;
args.arg1 = 0; /* must be event 0 */
args.arg2 = mpidr;
ret = tftf_smc(&args);
return ret.ret0;
}
int64_t sdei_event_status(int32_t ev)
{
smc_args args = { 0 };
smc_ret_values ret;
args.fid = SDEI_EVENT_STATUS;
args.arg1 = ev;
ret = tftf_smc(&args);
return ret.ret0;
}
int64_t sdei_event_routing_set(int32_t ev, uint64_t flags)
{
smc_args args = { 0 };
smc_ret_values ret;
args.fid = SDEI_EVENT_ROUTING_SET;
args.arg1 = ev;
args.arg2 = flags;
ret = tftf_smc(&args);
return ret.ret0;
}
int64_t sdei_event_context(uint32_t param)
{
smc_args args = { 0 };
smc_ret_values ret;
args.fid = SDEI_EVENT_CONTEXT;
args.arg1 = param;
ret = tftf_smc(&args);
return ret.ret0;
}
int64_t sdei_event_complete(uint32_t flags)
{
smc_args args = { 0 };
smc_ret_values ret;
args.fid = SDEI_EVENT_COMPLETE;
args.arg1 = flags;
ret = tftf_smc(&args);
return ret.ret0;
}
int64_t sdei_event_complete_and_resume(uint64_t addr)
{
smc_args args = { 0 };
smc_ret_values ret;
args.fid = SDEI_EVENT_COMPLETE_AND_RESUME;
args.arg1 = addr;
ret = tftf_smc(&args);
return ret.ret0;
}
int64_t sdei_features(uint32_t feature)
{
smc_args args = { 0 };
smc_ret_values ret;
args.fid = SDEI_FEATURES;
args.arg1 = feature;
ret = tftf_smc(&args);
return ret.ret0;
}
int64_t sdei_event_get_info(int32_t event, uint32_t info)
{
smc_args args = { 0 };
smc_ret_values ret;
args.fid = SDEI_EVENT_GET_INFO;
args.arg1 = event;
args.arg2 = info;
ret = tftf_smc(&args);
return ret.ret0;
}