ESP32: Add interrupt decode logic

This commit is contained in:
Gregory Nutt 2016-10-20 16:22:37 -06:00
parent bd6633dd84
commit 7a89808deb
2 changed files with 65 additions and 4 deletions

View File

@ -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

View File

@ -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 <gnutt@nuttx.org>
@ -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;
}