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>
This commit is contained in:
parent
ff605ba2ee
commit
23ae8094ec
|
@ -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
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -46,33 +46,44 @@ static uint64_t tegra_fiq_interrupt_handler(uint32_t id,
|
||||||
(void)handle;
|
(void)handle;
|
||||||
(void)cookie;
|
(void)cookie;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read the pending interrupt ID
|
||||||
|
*/
|
||||||
|
irq = plat_ic_get_pending_interrupt_id();
|
||||||
|
|
||||||
bakery_lock_get(&tegra_fiq_lock);
|
bakery_lock_get(&tegra_fiq_lock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The FIQ was generated when the execution was in the non-secure
|
* Jump to NS world only if the NS world's FIQ handler has
|
||||||
* world. Save the context registers to start with.
|
* been registered
|
||||||
*/
|
*/
|
||||||
cm_el1_sysregs_context_save(NON_SECURE);
|
if (ns_fiq_handler_addr != 0U) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Save elr_el3 and spsr_el3 from the saved context, and overwrite
|
* The FIQ was generated when the execution was in the non-secure
|
||||||
* the context with the NS fiq_handler_addr and SPSR value.
|
* world. Save the context registers to start with.
|
||||||
*/
|
*/
|
||||||
fiq_state[cpu].elr_el3 = read_ctx_reg((el3state_ctx), (uint32_t)(CTX_ELR_EL3));
|
cm_el1_sysregs_context_save(NON_SECURE);
|
||||||
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
|
* Save elr_el3 and spsr_el3 from the saved context, and overwrite
|
||||||
* FIQ handler registered earlier.
|
* the context with the NS fiq_handler_addr and SPSR value.
|
||||||
*/
|
*/
|
||||||
assert(ns_fiq_handler_addr != 0ULL);
|
fiq_state[cpu].elr_el3 = read_ctx_reg((el3state_ctx), (uint32_t)(CTX_ELR_EL3));
|
||||||
write_ctx_reg((el3state_ctx), (uint32_t)(CTX_ELR_EL3), (ns_fiq_handler_addr));
|
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.
|
* Mark this interrupt as complete to avoid a FIQ storm.
|
||||||
*/
|
*/
|
||||||
irq = plat_ic_acknowledge_interrupt();
|
|
||||||
if (irq < 1022U) {
|
if (irq < 1022U) {
|
||||||
|
(void)plat_ic_acknowledge_interrupt();
|
||||||
plat_ic_end_of_interrupt(irq);
|
plat_ic_end_of_interrupt(irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue