diff --git a/arch/xtensa/src/esp32/Make.defs b/arch/xtensa/src/esp32/Make.defs index 7d6a681e5e7..d5d1c2ff2b9 100644 --- a/arch/xtensa/src/esp32/Make.defs +++ b/arch/xtensa/src/esp32/Make.defs @@ -70,7 +70,7 @@ endif # Required ESP32 files (arch/xtensa/src/lx6) CHIP_CSRCS = esp32_allocateheap.c esp32_clockconfig.c esp32_gpio.c -CHIP_CSRCS += esp32_intdecode.c esp32_irq.c esp32_region.c +CHIP_CSRCS += esp32_irq.c esp32_region.c CHIP_CSRCS += esp32_user.c CHIP_CSRCS += esp32_dma.c diff --git a/arch/xtensa/src/esp32/esp32_intdecode.c b/arch/xtensa/src/esp32/esp32_intdecode.c deleted file mode 100644 index 1bdfc6d9f70..00000000000 --- a/arch/xtensa/src/esp32/esp32_intdecode.c +++ /dev/null @@ -1,137 +0,0 @@ -/**************************************************************************** - * arch/xtensa/src/esp32/esp32_intdecode.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include - -#include -#include - -#include "xtensa.h" -#include "esp32_irq.h" - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: xtensa_intclear - ****************************************************************************/ - -static inline void xtensa_intclear(uint32_t mask) -{ - __asm__ __volatile__ - ( - "wsr %0, INTCLEAR\n" - : "=r"(mask) : : - ); -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: xtensa_int_decode - * - * Description: - * Determine the peripheral that generated the interrupt and dispatch - * handling to the registered interrupt handler via xtensa_irq_dispatch(). - * - * Input Parameters: - * cpuints - Set of pending interrupts valid for this level - * regs - Saves processor state on the stack - * - * Returned Value: - * Normally the same value as regs is returned. But, in the event of an - * interrupt level context switch, the returned value will, instead point - * to the saved processor state in the TCB of the newly started task. - * - ****************************************************************************/ - -uint32_t *xtensa_int_decode(uint32_t cpuints, uint32_t *regs) -{ - uint8_t *intmap; - uint32_t mask; - int bit; -#ifdef CONFIG_SMP - int cpu; -#endif - -#ifdef CONFIG_SMP - /* Select PRO or APP CPU interrupt mapping table */ - - cpu = up_cpu_index(); - if (cpu != 0) - { - intmap = g_cpu1_intmap; - } - else -#endif - { - intmap = g_cpu0_intmap; - } - - /* Skip over zero bits, eight at a time */ - - for (bit = 0, mask = 0xff; - bit < ESP32_NCPUINTS && (cpuints & mask) == 0; - bit += 8, mask <<= 8); - - /* Process each pending CPU interrupt */ - - for (; bit < ESP32_NCPUINTS && cpuints != 0; bit++) - { - mask = (1 << bit); - if ((cpuints & mask) != 0) - { - /* Extract the IRQ number from the mapping table */ - - uint8_t irq = intmap[bit]; - DEBUGASSERT(irq != CPUINT_UNASSIGNED); - - /* Clear software or edge-triggered interrupt */ - - xtensa_intclear(mask); - - /* Dispatch the CPU interrupt. - * - * NOTE that regs may be altered in the case of an interrupt - * level context switch. - */ - - regs = xtensa_irq_dispatch((int)irq, regs); - - /* Clear the bit in the pending interrupt so that perhaps - * we can exit the look early. - */ - - cpuints &= ~mask; - } - } - - return regs; -} diff --git a/arch/xtensa/src/esp32/esp32_irq.c b/arch/xtensa/src/esp32/esp32_irq.c index a0b873f7790..6c14e076a56 100644 --- a/arch/xtensa/src/esp32/esp32_irq.c +++ b/arch/xtensa/src/esp32/esp32_irq.c @@ -122,29 +122,29 @@ uintptr_t g_cpu_intstack_top[CONFIG_SMP_NCPUS] = }; #endif /* defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 15 */ -static volatile uint8_t g_irqmap[NR_IRQS]; +/**************************************************************************** + * Private Data + ****************************************************************************/ /* Maps a CPU interrupt to the IRQ of the attached peripheral interrupt */ -uint8_t g_cpu0_intmap[ESP32_NCPUINTS]; +static uint8_t g_cpu0_intmap[ESP32_NCPUINTS]; #ifdef CONFIG_SMP -uint8_t g_cpu1_intmap[ESP32_NCPUINTS]; +static uint8_t g_cpu1_intmap[ESP32_NCPUINTS]; #endif +static volatile uint8_t g_irqmap[NR_IRQS]; + /* g_intenable[] is a shadow copy of the per-CPU INTENABLE register * content. */ #ifdef CONFIG_SMP -uint32_t g_intenable[CONFIG_SMP_NCPUS]; +static uint32_t g_intenable[CONFIG_SMP_NCPUS]; #else -uint32_t g_intenable[1]; +static uint32_t g_intenable[1]; #endif -/**************************************************************************** - * Private Data - ****************************************************************************/ - /* Bitsets for free, unallocated CPU interrupts available to peripheral * devices. */ @@ -230,6 +230,19 @@ static inline void xtensa_disable_all(void) ); } +/**************************************************************************** + * Name: xtensa_intclear + ****************************************************************************/ + +static inline void xtensa_intclear(uint32_t mask) +{ + __asm__ __volatile__ + ( + "wsr %0, INTCLEAR\n" + : "=r"(mask) : : + ); +} + /**************************************************************************** * Name: esp32_intinfo * @@ -828,3 +841,85 @@ void esp32_teardown_irq(int cpu, int periphid, int cpuint) leave_critical_section(irqstate); } +/**************************************************************************** + * Name: xtensa_int_decode + * + * Description: + * Determine the peripheral that generated the interrupt and dispatch + * handling to the registered interrupt handler via xtensa_irq_dispatch(). + * + * Input Parameters: + * cpuints - Set of pending interrupts valid for this level + * regs - Saves processor state on the stack + * + * Returned Value: + * Normally the same value as regs is returned. But, in the event of an + * interrupt level context switch, the returned value will, instead point + * to the saved processor state in the TCB of the newly started task. + * + ****************************************************************************/ + +uint32_t *xtensa_int_decode(uint32_t cpuints, uint32_t *regs) +{ + uint8_t *intmap; + uint32_t mask; + int bit; +#ifdef CONFIG_SMP + int cpu; +#endif + +#ifdef CONFIG_SMP + /* Select PRO or APP CPU interrupt mapping table */ + + cpu = up_cpu_index(); + if (cpu != 0) + { + intmap = g_cpu1_intmap; + } + else +#endif + { + intmap = g_cpu0_intmap; + } + + /* Skip over zero bits, eight at a time */ + + for (bit = 0, mask = 0xff; + bit < ESP32_NCPUINTS && (cpuints & mask) == 0; + bit += 8, mask <<= 8); + + /* Process each pending CPU interrupt */ + + for (; bit < ESP32_NCPUINTS && cpuints != 0; bit++) + { + mask = (1 << bit); + if ((cpuints & mask) != 0) + { + /* Extract the IRQ number from the mapping table */ + + uint8_t irq = intmap[bit]; + DEBUGASSERT(irq != CPUINT_UNASSIGNED); + + /* Clear software or edge-triggered interrupt */ + + xtensa_intclear(mask); + + /* Dispatch the CPU interrupt. + * + * NOTE that regs may be altered in the case of an interrupt + * level context switch. + */ + + regs = xtensa_irq_dispatch((int)irq, regs); + + /* Clear the bit in the pending interrupt so that perhaps + * we can exit the look early. + */ + + cpuints &= ~mask; + } + } + + return regs; +} + diff --git a/arch/xtensa/src/esp32/esp32_irq.h b/arch/xtensa/src/esp32/esp32_irq.h index 5357f2b47e7..cd0dd1310ff 100644 --- a/arch/xtensa/src/esp32/esp32_irq.h +++ b/arch/xtensa/src/esp32/esp32_irq.h @@ -53,27 +53,6 @@ extern "C" #define ESP32_CPUINT_LEVEL 0 #define ESP32_CPUINT_EDGE 1 -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/* Maps a CPU interrupt to the IRQ of the attached peripheral interrupt */ - -extern uint8_t g_cpu0_intmap[ESP32_NCPUINTS]; -#ifdef CONFIG_SMP -extern uint8_t g_cpu1_intmap[ESP32_NCPUINTS]; -#endif - -/* g_intenable[] is a shadow copy of the per-CPU INTENABLE register - * content. - */ - -#ifdef CONFIG_SMP -extern uint32_t g_intenable[CONFIG_SMP_NCPUS]; -#else -extern uint32_t g_intenable[1]; -#endif - /**************************************************************************** * Public Functions Prototypes ****************************************************************************/