diff --git a/arch/xtensa/src/esp32/Make.defs b/arch/xtensa/src/esp32/Make.defs index c957048920..8aef01a506 100644 --- a/arch/xtensa/src/esp32/Make.defs +++ b/arch/xtensa/src/esp32/Make.defs @@ -44,7 +44,7 @@ CMN_ASRCS = xtensa_context.S xtensa_irq.S xtensa_intvectors.S CMN_CSRCS = xtensa_assert.c xtensa_copystate.c CMN_CSRCS += xtensa_createstack.c xtensa_exit.c xtensa_idle.c CMN_CSRCS += xtensa_initialize.c xtensa_initialstate.c -CMN_CSRCS += xtensa_interruptcontext.c xtensa_intdecode.c xtensa_lowputs.c +CMN_CSRCS += xtensa_interruptcontext.c xtensa_irqdispatch.c xtensa_lowputs.c CMN_CSRCS += xtensa_mdelay.c xtensa_modifyreg8.c xtensa_modifyreg16.c CMN_CSRCS += xtensa_modifyreg32.c xtensa_puts.c xtensa_releasestack.c CMN_CSRCS += xtensa_stackframe.c xtensa_udelay.c xtensa_usestack.c @@ -73,7 +73,7 @@ endif # Required ESP32 files (arch/xtensa/src/lx6) CHIP_ASRCS = -CHIP_CSRCS = esp32_allocateheap.c esp32_start.c +CHIP_CSRCS = esp32_allocateheap.c esp32_intdecode.c esp32_start.c # Configuration-dependent ESP32 files diff --git a/arch/xtensa/src/common/xtensa_intdecode.c b/arch/xtensa/src/esp32/esp32_intdecode.c similarity index 66% rename from arch/xtensa/src/common/xtensa_intdecode.c rename to arch/xtensa/src/esp32/esp32_intdecode.c index 484d30f849..96bc4c8092 100644 --- a/arch/xtensa/src/common/xtensa_intdecode.c +++ b/arch/xtensa/src/esp32/esp32_intdecode.c @@ -1,5 +1,5 @@ /**************************************************************************** - * arch/xtensa/src/common/xtensa_intdecode.c + * arch/xtensa/src/esp32/esp32_intdecode.c * * Copyright (C) 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -64,6 +64,67 @@ uint32_t *xtensa_int_decode(uint32_t *regs) { -#warning Missing implementation + uintptr_t regaddr; + uint32_t regval; + uint32_t mask; + int regndx; + int bit; + int baseirq; + int irq; + +#ifdef CONFIG_SMP + int cpu; + + /* Select PRO or APP interrupt status registers */ + + cpu = up_cpu_index(); + if (cpu == 0) + { + regaddr = DPORT_PRO_INTR_STATUS_0_REG; + } + else +#endif + { + regaddr = DPORT_APP_INTR_STATUS_0_REG; + } + + /* Process each pending interrupt in each of the three interrupt status + * registers. + */ + + for (regndx = 0, baseirq = XTENSA_IRQ_SREG0; + regndx < 3; + regndx++, baseirq += 32, regaddr += sizeof(uint32_t)) + { + /* Fetch the next register status register */ + + regval = getreg32(regaddr); + + /* Decode and dispatch each pending bit in the interrupt status + * register. + */ + + for (bit = 0; regval != 0 && bit < 32; bit++) + { + /* Check if this interrupt is pending */ + + mask = (1 << bit); + if ((regval & mask) != 0) + { + /* Yes.. Dispatch the interrupt. Note that regs may be + * altered in the case of an interrupt level context switch. + */ + + regs = xtensa_irq_dispatch(baseirq + bit, regs); + + /* Clear this bit in the sampled status register so that + * perhaps we can exit this loop sooner. + */ + + regval &= ~mask; + } + } + } + return regs; }