From 1c308296a15ae6002306671beeec23ef68f0e7c8 Mon Sep 17 00:00:00 2001 From: Eero Nurkkala Date: Wed, 15 May 2024 14:32:37 +0300 Subject: [PATCH] arm64: provide EL3 interrupt support via FIQs Value 1021, when read from ICC_IAR0_EL1 means: "The GIC returns this value in response to a read of ICC_IAR0_EL1 or ICC_HPPIR0_EL1 at EL3, to indicate that the interrupt being acknowledged is one which is expected to be handled at Non-secure EL1 or EL2. This INTID is only returned when the PE is executing at EL3 using AArch64 state, or when the PE is executing in AArch32 state in Monitor mode." When this happens: - FIQ is fired on group0 - IRQ is pending at group1 So simply check and handle the interrupt. In short, this provides interrupt support for EL3. Signed-off-by: Eero Nurkkala --- arch/arm64/src/common/arm64_gicv3.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/arch/arm64/src/common/arm64_gicv3.c b/arch/arm64/src/common/arm64_gicv3.c index 117a3b048d..016e9aceef 100644 --- a/arch/arm64/src/common/arm64_gicv3.c +++ b/arch/arm64/src/common/arm64_gicv3.c @@ -71,6 +71,9 @@ #define SMP_FUNC_CALL_IPI GIC_IRQ_SGI3 +#define PENDING_GRP1NS_INTID 1021 +#define SPURIOUS_INT 1023 + /*************************************************************************** * Private Data ***************************************************************************/ @@ -765,7 +768,7 @@ uint64_t * arm64_decodeirq(uint64_t * regs) * interrupt. */ - DEBUGASSERT(irq < NR_IRQS || irq == 1023); + DEBUGASSERT(irq < NR_IRQS || irq == SPURIOUS_INT); if (irq < NR_IRQS) { /* Dispatch the interrupt */ @@ -789,11 +792,33 @@ uint64_t * arm64_decodefiq(uint64_t * regs) irq = arm64_gic_get_active_fiq(); +#ifdef CONFIG_ARCH_BOOT_EL3 + /* FIQ is group0 interrupt */ + + if (irq == PENDING_GRP1NS_INTID) + { + /* irq 1021 indicates that the irq being acked is expected at EL1/EL2. + * However, EL3 has no interrupts, only FIQs, see: + * 'ArmĀ® Generic Interrupt Controller, Architecture Specification GIC + * architecture version 3 and version 4' Arm IHI 0069G (ID011821) + * 'Table 4-3 Interrupt signals for two Security states when EL3 is + * using AArch64 state' + * + * Thus we know there's an interrupt so let's handle it from group1. + */ + + regs = arm64_decodeirq(regs); + arm64_gic_eoi_fiq(irq); + + return regs; + } +#endif + /* Ignore spurions IRQs. ICCIAR will report 1023 if there is no pending * interrupt. */ - DEBUGASSERT(irq < NR_IRQS || irq == 1023); + DEBUGASSERT(irq < NR_IRQS || irq == SPURIOUS_INT); if (irq < NR_IRQS) { /* Dispatch the interrupt */