arch/xtensa/esp32: Merge esp32_intdecode with esp32_irq.
Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
This commit is contained in:
parent
79cc12c034
commit
04cd520293
@ -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
|
||||
|
||||
|
@ -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 <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <arch/irq.h>
|
||||
|
||||
#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;
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
****************************************************************************/
|
||||
|
Loading…
Reference in New Issue
Block a user