diff options
author | Madhukar Pappireddy <madhukar.pappireddy@arm.com> | 2022-06-22 17:15:45 -0500 |
---|---|---|
committer | Madhukar Pappireddy <madhukar.pappireddy@arm.com> | 2022-09-29 16:56:09 -0500 |
commit | e9c9093bae2328f16d0d35c1f2d16212a07ab29f (patch) | |
tree | 3160db49b45cfd0442c0baf0332ee487fa3a3f4f | |
parent | ca1e2017932411a91722512b1b5dd1fe4a9855ad (diff) |
feat(interrupts): add support for handling managed exit through vIRQ
An SP could specify, through its partition manifest, that the
preferred signaling mechanism for it to handle managed exit is
vIRQ instead of the default choice (vFIQ).
Hence, separate the vIRQ and vFIQ handlers and add support for
identifying the source of the direct message request for the current
endpoint to send the managed exit response.
Signed-off-by: Madhukar Pappireddy <madhukar.pappireddy@arm.com>
Change-Id: I06d6d81232de58779f81f40d4c6d2a96df0da27a
-rw-r--r-- | spm/cactus/aarch64/cactus_exceptions.S | 30 | ||||
-rw-r--r-- | spm/cactus/cactus_interrupt.c | 96 | ||||
-rw-r--r-- | spm/cactus/cactus_tests/cactus_message_loop.c | 9 | ||||
-rw-r--r-- | spm/cactus/plat/arm/fvp/fdts/cactus-tertiary.dts | 1 |
4 files changed, 94 insertions, 42 deletions
diff --git a/spm/cactus/aarch64/cactus_exceptions.S b/spm/cactus/aarch64/cactus_exceptions.S index 9b024f8..06df31c 100644 --- a/spm/cactus/aarch64/cactus_exceptions.S +++ b/spm/cactus/aarch64/cactus_exceptions.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Arm Limited. All rights reserved. + * Copyright (c) 2021-2022, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -18,6 +18,15 @@ end_vector_entry \name .endm +.macro interrupt_vector _type + sub sp, sp, #0x100 + save_gp_regs + bl cactus_interrupt_handler_\_type + restore_gp_regs + add sp, sp, #0x100 + eret +.endm + vector_base cactus_vector /* @@ -36,11 +45,11 @@ vector_entry sync_spx end_vector_entry sync_spx vector_entry irq_spx - b interrupt_vector_entry + b irq_vector_entry end_vector_entry irq_spx vector_entry fiq_spx - b interrupt_vector_entry + b fiq_vector_entry end_vector_entry fiq_spx unhandled_exception serr_spx @@ -116,14 +125,13 @@ func sync_exception_vector_entry eret endfunc sync_exception_vector_entry -func interrupt_vector_entry - sub sp, sp, #0x100 - save_gp_regs - bl cactus_interrupt_handler - restore_gp_regs - add sp, sp, #0x100 - eret -endfunc interrupt_vector_entry +func irq_vector_entry + interrupt_vector irq +endfunc irq_vector_entry + +func fiq_vector_entry + interrupt_vector fiq +endfunc fiq_vector_entry func crash_dump /* Save general-purpose registers on the stack. */ diff --git a/spm/cactus/cactus_interrupt.c b/spm/cactus/cactus_interrupt.c index e08c4dd..35fdf30 100644 --- a/spm/cactus/cactus_interrupt.c +++ b/spm/cactus/cactus_interrupt.c @@ -21,6 +21,7 @@ extern void notification_pending_interrupt_handler(void); extern ffa_id_t g_ffa_id; +extern ffa_id_t g_dir_req_source_id; static uint32_t managed_exit_interrupt_id; /* Secure virtual interrupt that was last handled by Cactus SP. */ @@ -44,11 +45,66 @@ void discover_managed_exit_interrupt_id(void) managed_exit_interrupt_id); } -void cactus_interrupt_handler(void) +static void post_interrupt_handler(uint32_t intid) { - uint32_t intid = spm_interrupt_get(); unsigned int core_pos = get_current_core_id(); + last_serviced_interrupt[core_pos] = intid; + + /* Invoke the tail end handler registered by the SP. */ + spin_lock(&sp_handler_lock[intid]); + if (sp_interrupt_tail_end_handler[intid]) { + sp_interrupt_tail_end_handler[intid](); + } + spin_unlock(&sp_handler_lock[intid]); +} + +void cactus_interrupt_handler_irq(void) +{ + uint32_t intid = spm_interrupt_get(); + + if (intid == managed_exit_interrupt_id) { + /* + * A secure partition performs its housekeeping and + * sends a direct response to signal interrupt + * completion. This is a pure virtual interrupt, no + * need for deactivation. + */ + VERBOSE("vIRQ: Sending ME response to %x\n", + g_dir_req_source_id); + cactus_response(g_ffa_id, g_dir_req_source_id, + managed_exit_interrupt_id); + } else { + switch (intid) { + case IRQ_TWDOG_INTID: + /* + * Interrupt triggered due to Trusted watchdog timer expiry. + * Clear the interrupt and stop the timer. + */ + VERBOSE("Trusted WatchDog timer stopped\n"); + sp805_twdog_stop(); + + /* Perform secure interrupt de-activation. */ + spm_interrupt_deactivate(intid); + + break; + case NOTIFICATION_PENDING_INTERRUPT_INTID: + notification_pending_interrupt_handler(); + break; + default: + ERROR("%s: Interrupt ID %x not handled!\n", __func__, + intid); + panic(); + break; + } + } + post_interrupt_handler(intid); +} + +void cactus_interrupt_handler_fiq(void) +{ + uint32_t intid = spm_interrupt_get(); + switch (intid) { case MANAGED_EXIT_INTERRUPT_ID: /* @@ -56,39 +112,17 @@ void cactus_interrupt_handler(void) * direct response to signal interrupt completion. * This is a pure virtual interrupt, no need for deactivation. */ - cactus_response(g_ffa_id, HYP_ID, MANAGED_EXIT_INTERRUPT_ID); - break; - case IRQ_TWDOG_INTID: - /* - * Interrupt triggered due to Trusted watchdog timer expiry. - * Clear the interrupt and stop the timer. - */ - VERBOSE("Trusted WatchDog timer stopped\n"); - sp805_twdog_stop(); - - /* Perform secure interrupt de-activation. */ - spm_interrupt_deactivate(intid); - - break; - case NOTIFICATION_PENDING_INTERRUPT_INTID: - notification_pending_interrupt_handler(); + VERBOSE("vFIQ: Sending ME response to %x\n", + g_dir_req_source_id); + cactus_response(g_ffa_id, g_dir_req_source_id, + MANAGED_EXIT_INTERRUPT_ID); break; default: /* - * Currently the only source of secure interrupt is Trusted - * Watchdog timer. + * Currently only managed exit interrupt is supported by vFIQ. */ - ERROR("%s: Interrupt ID %x not handled!\n", __func__, - intid); panic(); + break; } - - last_serviced_interrupt[core_pos] = intid; - - /* Invoke the tail end handler registered by the SP. */ - spin_lock(&sp_handler_lock[intid]); - if (sp_interrupt_tail_end_handler[intid]) { - sp_interrupt_tail_end_handler[intid](); - } - spin_unlock(&sp_handler_lock[intid]); + post_interrupt_handler(intid); } diff --git a/spm/cactus/cactus_tests/cactus_message_loop.c b/spm/cactus/cactus_tests/cactus_message_loop.c index 01ea32f..e56e51e 100644 --- a/spm/cactus/cactus_tests/cactus_message_loop.c +++ b/spm/cactus/cactus_tests/cactus_message_loop.c @@ -31,6 +31,9 @@ extern struct cactus_cmd_handler cactus_cmd_handler_end[]; smc_ret.arg3, smc_ret.arg4, smc_ret.arg5, \ smc_ret.arg6, smc_ret.arg7) +/* Global FFA_MSG_DIRECT_REQ source ID */ +ffa_id_t g_dir_req_source_id; + /** * Traverses command table from section ".cactus_handler", searches for a * registered command and invokes the respective handler. @@ -49,6 +52,12 @@ bool cactus_handle_cmd(struct ffa_value *cmd_args, struct ffa_value *ret, return false; } + /* Get the source of the Direct Request message. */ + if (ffa_func_id(*cmd_args) == FFA_MSG_SEND_DIRECT_REQ_SMC32 || + ffa_func_id(*cmd_args) == FFA_MSG_SEND_DIRECT_REQ_SMC64) { + g_dir_req_source_id = ffa_dir_msg_source(*cmd_args); + } + PRINT_CMD((*cmd_args)); in_cmd = cactus_get_cmd(*cmd_args); diff --git a/spm/cactus/plat/arm/fvp/fdts/cactus-tertiary.dts b/spm/cactus/plat/arm/fvp/fdts/cactus-tertiary.dts index 856be85..b7632da 100644 --- a/spm/cactus/plat/arm/fvp/fdts/cactus-tertiary.dts +++ b/spm/cactus/plat/arm/fvp/fdts/cactus-tertiary.dts @@ -30,6 +30,7 @@ notification-support; messaging-method = <3>; /* Direct messaging only */ managed-exit; /* Managed exit is supported */ + managed-exit-virq; memory-regions { compatible = "arm,ffa-manifest-memory-regions"; |