diff options
author | Achin Gupta <achin.gupta@arm.com> | 2021-10-04 20:17:45 +0100 |
---|---|---|
committer | Marc Bonnici <marc.bonnici@arm.com> | 2021-10-07 12:35:38 +0100 |
commit | 4a512d3f059b7915a6f3e92b22765d833416b36a (patch) | |
tree | ed10464f1c43af9040824b3add459ab9e74fb216 | |
parent | d5db27f56be68fdea929ef00d6c0970ec2056347 (diff) | |
download | arm-trusted-firmware-4a512d3f059b7915a6f3e92b22765d833416b36a.tar.gz |
Add support for forwarding a secure interrupt to the SP
This patch adds support for forwarding a secure interrupt that preempts the
normal world to a SP for top-half interrupt handling.
Signed-off-by: Achin Gupta <achin.gupta@arm.com>
Change-Id: Iaa6e96f4cf8922ba5b6d128a19359df15e44158d
-rw-r--r-- | services/std_svc/spm/spmc/spmc_main.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/services/std_svc/spm/spmc/spmc_main.c b/services/std_svc/spm/spmc/spmc_main.c index 8b56d73a8..45f9820f9 100644 --- a/services/std_svc/spm/spmc/spmc_main.c +++ b/services/std_svc/spm/spmc/spmc_main.c @@ -11,6 +11,7 @@ #include <bl31/bl31.h> #include <bl31/ehf.h> +#include <bl31/interrupt_mgmt.h> #include <common/debug.h> #include <common/fdt_wrappers.h> #include <common/runtime_svc.h> @@ -45,6 +46,10 @@ static sp_desc_t sp_desc[SECURE_PARTITION_COUNT]; */ static ns_ep_desc_t ns_ep_desc[NS_PARTITION_COUNT]; +static uint64_t spmc_sp_interrupt_handler(uint32_t id, + uint32_t flags, + void *handle, + void *cookie); el3_lp_desc_t* get_el3_lp_array(void) { el3_lp_desc_t *el3_lp_descs; @@ -1252,6 +1257,19 @@ int32_t spmc_setup(void) /* Register power management hooks with PSCI */ psci_register_spd_pm_hook(&spmc_pm); + /* + * Register an interrupt handler for S-EL1 interrupts + * when generated during code executing in the + * non-secure state. + */ + flags = 0; + set_interrupt_rm_flag(flags, NON_SECURE); + ret = register_interrupt_type_handler(INTR_TYPE_S_EL1, + spmc_sp_interrupt_handler, + flags); + if (ret) + panic(); + /* Register init function for deferred init. */ bl31_register_bl32_init(&sp_init); @@ -1318,9 +1336,59 @@ uint64_t spmc_smc_handler(uint32_t smc_fid, case FFA_MSG_RUN: return ffa_run_handler(smc_fid, secure_origin, x1, x2, x3, x4, cookie, handle, flags); + default: WARN("Not Supported 0x%x (0x%llx, 0x%llx, 0x%llx, 0x%llx) FFA Request ID\n", smc_fid, x1, x2, x3, x4); break; } return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED); } + +/******************************************************************************* + * This function is the handler registered for S-EL1 interrupts by the SPMC. It + * validates the interrupt and upon success arranges entry into the SP for + * handling the interrupt. + ******************************************************************************/ +static uint64_t spmc_sp_interrupt_handler(uint32_t id, + uint32_t flags, + void *handle, + void *cookie) +{ + sp_desc_t *sp = spmc_get_current_sp_ctx(); + sp_exec_ctx_t *ec; + uint32_t linear_id = plat_my_core_pos(); + + /* Sanity check for a NULL pointer dereference */ + assert (NULL != sp); + + /* Panic in case of a S-EL0 SP */ + if (sp->runtime_el == EL0) { + ERROR("Yikes! Interrupt received for a S-EL0 SP on core%u \n", linear_id); + panic(); + } + + /* Obtain a reference to the SP execution context */ + ec = &sp->ec[get_ec_index(sp)]; + + /* Ensure that the execution context is in a waiting state else panic. */ + if (ec->rt_state != RT_STATE_WAITING) { + ERROR("Yikes! S-EL1 SP context on core%u is in %u state\n", linear_id, + ec->rt_state); + panic(); + } + + /* Update the runtime model and state of the partition */ + ec->rt_model = RT_MODEL_INTR; + ec->rt_state = RT_STATE_RUNNING; + + VERBOSE("SP (0x%x) interrupt start on core%u \n", sp->sp_id, linear_id); + + /* + * Forward the interrupt to the S-EL1 SP. The interrupt ID is not + * populated as the SP can determine this by itself. + * TODO: Add support for handing interrupts to a S-EL0 SP. + */ + return ffa_smc_forward(FFA_INTERRUPT, is_caller_secure(flags), FFA_PARAM_MBZ, + FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, + cookie, handle, flags); +} |