summaryrefslogtreecommitdiff
path: root/plat/nvidia
diff options
context:
space:
mode:
authorVarun Wadekar <vwadekar@nvidia.com>2018-01-04 13:41:27 -0800
committerVarun Wadekar <vwadekar@nvidia.com>2019-01-31 08:46:03 -0800
commit23ae8094ec61168de40de3d5b9203869f53ed62e (patch)
tree3eaffe4f926f80f5ad0a28a21616068a07f35f89 /plat/nvidia
parentff605ba2eecb0d5dd640790eec6faae8836177b4 (diff)
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 <vwadekar@nvidia.com>
Diffstat (limited to 'plat/nvidia')
-rw-r--r--plat/nvidia/tegra/common/tegra_fiq_glue.c45
1 files changed, 28 insertions, 17 deletions
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);
}