From: Varun Wadekar Date: Thu, 4 Jan 2018 21:41:27 +0000 (-0800) Subject: Tegra: handle FIQ interrupts when NS handler is not registered X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=23ae8094ec61168de40de3d5b9203869f53ed62e;p=project%2Fbcm63xx%2Fatf.git Tegra: handle FIQ interrupts when NS handler is not registered This patch updates the secure interrupt handler to mark the interrupt as complete in case the NS world has not registered a handler. Change-Id: Iebe952305f7db46375303699b6150611439475df Signed-off-by: Varun Wadekar --- diff --git a/plat/nvidia/tegra/common/tegra_fiq_glue.c b/plat/nvidia/tegra/common/tegra_fiq_glue.c index cab2e5ec..b0366904 100644 --- a/plat/nvidia/tegra/common/tegra_fiq_glue.c +++ b/plat/nvidia/tegra/common/tegra_fiq_glue.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -46,33 +46,44 @@ static uint64_t tegra_fiq_interrupt_handler(uint32_t id, (void)handle; (void)cookie; - bakery_lock_get(&tegra_fiq_lock); - /* - * The FIQ was generated when the execution was in the non-secure - * world. Save the context registers to start with. + * Read the pending interrupt ID */ - cm_el1_sysregs_context_save(NON_SECURE); + irq = plat_ic_get_pending_interrupt_id(); - /* - * Save elr_el3 and spsr_el3 from the saved context, and overwrite - * the context with the NS fiq_handler_addr and SPSR value. - */ - fiq_state[cpu].elr_el3 = read_ctx_reg((el3state_ctx), (uint32_t)(CTX_ELR_EL3)); - fiq_state[cpu].spsr_el3 = read_ctx_reg((el3state_ctx), (uint32_t)(CTX_SPSR_EL3)); + bakery_lock_get(&tegra_fiq_lock); /* - * Set the new ELR to continue execution in the NS world using the - * FIQ handler registered earlier. + * Jump to NS world only if the NS world's FIQ handler has + * been registered */ - assert(ns_fiq_handler_addr != 0ULL); - write_ctx_reg((el3state_ctx), (uint32_t)(CTX_ELR_EL3), (ns_fiq_handler_addr)); + if (ns_fiq_handler_addr != 0U) { + + /* + * The FIQ was generated when the execution was in the non-secure + * world. Save the context registers to start with. + */ + cm_el1_sysregs_context_save(NON_SECURE); + + /* + * Save elr_el3 and spsr_el3 from the saved context, and overwrite + * the context with the NS fiq_handler_addr and SPSR value. + */ + fiq_state[cpu].elr_el3 = read_ctx_reg((el3state_ctx), (uint32_t)(CTX_ELR_EL3)); + fiq_state[cpu].spsr_el3 = read_ctx_reg((el3state_ctx), (uint32_t)(CTX_SPSR_EL3)); + + /* + * Set the new ELR to continue execution in the NS world using the + * FIQ handler registered earlier. + */ + cm_set_elr_el3(NON_SECURE, ns_fiq_handler_addr); + } /* * Mark this interrupt as complete to avoid a FIQ storm. */ - irq = plat_ic_acknowledge_interrupt(); if (irq < 1022U) { + (void)plat_ic_acknowledge_interrupt(); plat_ic_end_of_interrupt(irq); }