esp32s3/irq: Allow IRAM ISRs to run during SPI flash operation

This commit provides an interface to register ISRs that run from
IRAM and keeps track of the non-IRAM interrupts. It enables, for
instance, to avoid disabling all the interrupts during a SPI flash
operation: IRAM-enabled ISRs are, then, able to run during these
operations.
This commit is contained in:
Tiago Medicci Serrano
2023-09-13 09:10:06 -03:00
committed by Xiang Xiao
parent 86b118854e
commit 0ddb64555a
7 changed files with 836 additions and 93 deletions
+16 -10
View File
@@ -37,6 +37,16 @@
#define ESP32S3_INT_PRIO_DEF 1 #define ESP32S3_INT_PRIO_DEF 1
/* CPU interrupt flags:
* These flags can be used to specify which interrupt qualities the
* code calling esp32s3_setup_irq needs.
*/
#define ESP32S3_CPUINT_FLAG_LEVEL (1 << 0) /* Level-triggered interrupt */
#define ESP32S3_CPUINT_FLAG_EDGE (1 << 1) /* Edge-triggered interrupt */
#define ESP32S3_CPUINT_FLAG_SHARED (1 << 2) /* Interrupt can be shared between ISRs */
#define ESP32S3_CPUINT_FLAG_IRAM (1 << 3) /* ISR can be called if cache is disabled */
/* Interrupt Matrix /* Interrupt Matrix
* *
* The Interrupt Matrix embedded in the ESP32-S3 independently allocates * The Interrupt Matrix embedded in the ESP32-S3 independently allocates
@@ -386,17 +396,13 @@
* 26 can be mapped to peripheral interrupts: * 26 can be mapped to peripheral interrupts:
* *
* Level triggered peripherals (21 total): * Level triggered peripherals (21 total):
* 0-5, 8-9, 12-13, 17-18 - Priority 1 * 0-5, 8-10, 12-13, 17-18 - Priority 1
* 19-21 - Priority 2 * 19-21 - Priority 2
* 23, 27 - Priority 3 * 22-23, 27 - Priority 3
* 24-25 - Priority 4 * 24-25, 28, 30 - Priority 4
* 26, 31 - Priority 5 * 26, 31 - Priority 5
* Edge triggered peripherals (4 total):
* 10 - Priority 1
* 22 - Priority 3
* 28, 30 - Priority 4
* NMI (1 total): * NMI (1 total):
* 14 - NMI * 14 - NMI
* *
* CPU peripheral interrupts can be a assigned to a CPU interrupt using the * CPU peripheral interrupts can be a assigned to a CPU interrupt using the
* PRO_*_MAP_REG or APP_*_MAP_REG. There are a pair of these registers for * PRO_*_MAP_REG or APP_*_MAP_REG. There are a pair of these registers for
+24
View File
@@ -734,6 +734,19 @@ menuconfig ESP32S3_WIFI_BT_COEXIST
depends on ESP32S3_WIFI && ESP32S3_BLE depends on ESP32S3_WIFI && ESP32S3_BLE
select ESP32S3_WIFI_STA_DISCONNECT_PM select ESP32S3_WIFI_STA_DISCONNECT_PM
menu "Interrupt Configuration"
config ESP32S3_IRAM_ISR_DEBUG
bool "Enable debugging of the IRAM-enabled interrupts"
default n
---help---
This option enables keeping track of the IRAM-enabled interrupts by
registering its execution when non-IRAM interrupts are disabled. It
keeps track of the IRQ executed and register how many times since
boot it was executed.
endmenu # Interrupt Configuration
menu "SPI RAM Configuration" menu "SPI RAM Configuration"
depends on ESP32S3_SPIRAM depends on ESP32S3_SPIRAM
@@ -1605,6 +1618,17 @@ config ESP32S3_STORAGE_MTD_DEBUG
If this option is enabled, Storage MTD driver read and write functions If this option is enabled, Storage MTD driver read and write functions
will output input parameters and return values (if applicable). will output input parameters and return values (if applicable).
config ESP32S3_SPIFLASH_OP_TASK_STACKSIZE
int "The SPI flash operation task stack size"
default 768
depends on SMP
---help---
When SMP is enabled, it is needed to create two tasks (one for each
core) to be able to run IRAM-enabled interrupts. These tasks ensures
that the core that isn't performing the SPI flash operation is able
to disable non-IRAM interrupts and wait for the SPI flash operation
to be finished.
endif # ESP32S3_SPIFLASH endif # ESP32S3_SPIFLASH
endmenu # SPI Flash configuration endmenu # SPI Flash configuration
+323 -15
View File
@@ -33,8 +33,10 @@
#include <nuttx/irq.h> #include <nuttx/irq.h>
#include <nuttx/arch.h> #include <nuttx/arch.h>
#include <nuttx/board.h> #include <nuttx/board.h>
#include <nuttx/kmalloc.h>
#include <arch/irq.h> #include <arch/irq.h>
#include <arch/board/board.h> #include <arch/board/board.h>
#include <irq/irq.h>
#include "xtensa.h" #include "xtensa.h"
@@ -161,6 +163,24 @@ static volatile uint8_t g_irqmap[NR_IRQS];
static uint32_t g_intenable[CONFIG_SMP_NCPUS]; static uint32_t g_intenable[CONFIG_SMP_NCPUS];
/* g_non_iram_int_mask[] is a bitmask of the interrupts that should be
* disabled during a SPI flash operation. Non-IRAM interrupts should always
* be disabled, but interrupts place on IRAM are able to run during a SPI
* flash operation.
*/
static uint32_t g_non_iram_int_mask[CONFIG_SMP_NCPUS];
/* g_non_iram_int_disabled[] keeps track of the interrupts disabled during
* a SPI flash operation.
*/
static uint32_t g_non_iram_int_disabled[CONFIG_SMP_NCPUS];
/* Per-CPU flag to indicate that non-IRAM interrupts were disabled */
static bool g_non_iram_int_disabled_flag[CONFIG_SMP_NCPUS];
/* Bitsets for free, unallocated CPU interrupts available to peripheral /* Bitsets for free, unallocated CPU interrupts available to peripheral
* devices. * devices.
*/ */
@@ -184,6 +204,14 @@ static const uint32_t g_priority[5] =
ESP32S3_INTPRI5_MASK ESP32S3_INTPRI5_MASK
}; };
#ifdef CONFIG_ESP32S3_IRAM_ISR_DEBUG
/* The g_iram_count keeps track of how many times such an IRQ ran when the
* non-IRAM interrupts were disabled.
*/
static uint64_t g_iram_count[NR_IRQS];
#endif
/**************************************************************************** /****************************************************************************
* Private Functions * Private Functions
****************************************************************************/ ****************************************************************************/
@@ -406,6 +434,33 @@ static void esp32s3_free_cpuint(int cpuint)
*freeints |= bitmask; *freeints |= bitmask;
} }
#ifdef CONFIG_ESP32S3_IRAM_ISR_DEBUG
/****************************************************************************
* Name: esp32s3_iram_interrupt_record
*
* Description:
* This function keeps track of the IRQs that ran when non-IRAM interrupts
* are disabled and enables debugging of the IRAM-enabled interrupts.
*
* Input Parameters:
* irq - The IRQ associated with a CPU interrupt
*
* Returned Value:
* None.
*
****************************************************************************/
void esp32s3_irq_iram_interrupt_record(int irq)
{
irqstate_t flags = enter_critical_section();
g_iram_count[irq]++;
leave_critical_section(flags);
}
#endif
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
@@ -418,6 +473,15 @@ void up_irqinitialize(void)
{ {
int i; int i;
/* All CPU ints are non-IRAM interrupts at the beginning and should be
* disabled during a SPI flash operation
*/
for (i = 0; i < CONFIG_SMP_NCPUS; i++)
{
g_non_iram_int_mask[i] = UINT32_MAX;
}
for (i = 0; i < NR_IRQS; i++) for (i = 0; i < NR_IRQS; i++)
{ {
g_irqmap[i] = IRQ_UNMAPPED; g_irqmap[i] = IRQ_UNMAPPED;
@@ -588,6 +652,21 @@ void up_enable_irq(int irq)
int cpu = IRQ_GETCPU(g_irqmap[irq]); int cpu = IRQ_GETCPU(g_irqmap[irq]);
/* Check if the registered ISR for this IRQ is intended to be run from
* IRAM. If so, check if its interrupt handler is located in IRAM.
*/
bool isr_in_iram = !((g_non_iram_int_mask[cpu] & (1 << cpuint)) > 0);
xcpt_t handler = g_irqvector[irq].handler;
if (isr_in_iram && handler && !esp32s3_ptr_iram(handler))
{
irqerr("Interrupt handler isn't in IRAM (%08" PRIx32 ")",
(intptr_t)handler);
PANIC();
}
DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS); DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS);
/* For peripheral interrupts, attach the interrupt to the peripheral; /* For peripheral interrupts, attach the interrupt to the peripheral;
@@ -716,7 +795,7 @@ int esp32s3_cpuint_initialize(void)
* ESP32S3_CPUINT_PROFILING 11 Not yet defined * ESP32S3_CPUINT_PROFILING 11 Not yet defined
* ESP32S3_CPUINT_TIMER1 15 XTENSA_IRQ_TIMER1 1 * ESP32S3_CPUINT_TIMER1 15 XTENSA_IRQ_TIMER1 1
* ESP32S3_CPUINT_TIMER2 16 XTENSA_IRQ_TIMER2 2 * ESP32S3_CPUINT_TIMER2 16 XTENSA_IRQ_TIMER2 2
* ESP32S2_CPUINT_SOFTWARE1 29 XTENSA_IRQ_SWINT 4 * ESP32S3_CPUINT_SOFTWARE1 29 XTENSA_IRQ_SWINT 4
*/ */
intmap[ESP32S3_CPUINT_TIMER0] = CPUINT_ASSIGN(XTENSA_IRQ_TIMER0); intmap[ESP32S3_CPUINT_TIMER0] = CPUINT_ASSIGN(XTENSA_IRQ_TIMER0);
@@ -732,14 +811,16 @@ int esp32s3_cpuint_initialize(void)
* *
* Description: * Description:
* This function sets up the IRQ. It allocates a CPU interrupt of the given * This function sets up the IRQ. It allocates a CPU interrupt of the given
* priority and type and attaches it to the given peripheral. * priority and associated flags and attaches it to the given peripheral.
* *
* Input Parameters: * Input Parameters:
* cpu - The CPU to receive the interrupt 0=PRO CPU 1=APP CPU * cpu - The CPU to receive the interrupt 0=PRO CPU 1=APP CPU
* periphid - The peripheral number from irq.h to be assigned to * periphid - The peripheral number from irq.h to be assigned to
* a CPU interrupt. * a CPU interrupt.
* priority - Interrupt's priority (1 - 5). * priority - Interrupt's priority (1 - 5).
* type - Interrupt's type (level or edge). * flags - An ORred mask of the ESP32S3_CPUINT_FLAG_* defines. These
* restrict the choice of interrupts that this routine can
* choose from.
* *
* Returned Value: * Returned Value:
* The allocated CPU interrupt on success, a negated errno value on * The allocated CPU interrupt on success, a negated errno value on
@@ -747,7 +828,7 @@ int esp32s3_cpuint_initialize(void)
* *
****************************************************************************/ ****************************************************************************/
int esp32s3_setup_irq(int cpu, int periphid, int priority, int type) int esp32s3_setup_irq(int cpu, int periphid, int priority, int flags)
{ {
irqstate_t irqstate; irqstate_t irqstate;
uintptr_t regaddr; uintptr_t regaddr;
@@ -755,19 +836,26 @@ int esp32s3_setup_irq(int cpu, int periphid, int priority, int type)
int irq; int irq;
int cpuint; int cpuint;
if ((flags & ESP32S3_CPUINT_EDGE) != 0)
{
irqerr("Only level-enabled interrupts are available");
return -EINVAL;
}
irqstate = enter_critical_section(); irqstate = enter_critical_section();
/* Setting up an IRQ includes the following steps: /* Setting up an IRQ includes the following steps:
* 1. Allocate a CPU interrupt. * 1. Allocate a CPU interrupt.
* 2. Attach that CPU interrupt to the peripheral. * 2. Check if its ISR is intended to run from IRAM.
* 3. Map the CPU interrupt to the IRQ to ease searching later. * 3. Attach that CPU interrupt to the peripheral.
* 4. Map the CPU interrupt to the IRQ to ease searching later.
*/ */
cpuint = esp32s3_alloc_cpuint(cpu, priority, type); cpuint = esp32s3_alloc_cpuint(cpu, priority, ESP32S3_CPUINT_LEVEL);
if (cpuint < 0) if (cpuint < 0)
{ {
irqerr("Unable to allocate CPU interrupt for priority=%d and type=%d", irqerr("Unable to allocate CPU interrupt for priority=%d and flags=%d",
priority, type); priority, flags);
leave_critical_section(irqstate); leave_critical_section(irqstate);
return cpuint; return cpuint;
@@ -785,6 +873,15 @@ int esp32s3_setup_irq(int cpu, int periphid, int priority, int type)
intmap[cpuint] = CPUINT_ASSIGN(periphid + XTENSA_IRQ_FIRSTPERIPH); intmap[cpuint] = CPUINT_ASSIGN(periphid + XTENSA_IRQ_FIRSTPERIPH);
g_irqmap[irq] = IRQ_MKMAP(cpu, cpuint); g_irqmap[irq] = IRQ_MKMAP(cpu, cpuint);
if ((flags & ESP32S3_CPUINT_FLAG_IRAM) != 0)
{
esp32s3_irq_set_iram_isr(irq);
}
else
{
esp32s3_irq_unset_iram_isr(irq);
}
putreg32(cpuint, regaddr); putreg32(cpuint, regaddr);
leave_critical_section(irqstate); leave_critical_section(irqstate);
@@ -851,8 +948,8 @@ void esp32s3_teardown_irq(int cpu, int periphid, int cpuint)
* This function returns the IRQ associated with a CPU interrupt * This function returns the IRQ associated with a CPU interrupt
* *
* Input Parameters: * Input Parameters:
* cpu - The CPU to receive the interrupt 0=PRO CPU 1=APP CPU * cpu - The CPU core of the IRQ being queried
* cpuint - The CPU interrupt associated to the IRQ * cpuint - The CPU interrupt associated to the IRQ
* *
* Returned Value: * Returned Value:
* The IRQ associated with such CPU interrupt or CPUINT_UNASSIGNED if * The IRQ associated with such CPU interrupt or CPUINT_UNASSIGNED if
@@ -880,6 +977,29 @@ int esp32s3_getirq(int cpu, int cpuint)
return CPUINT_GETIRQ(intmap[cpuint]); return CPUINT_GETIRQ(intmap[cpuint]);
} }
/****************************************************************************
* Name: esp32s3_getcpuint_from_irq
*
* Description:
* This function returns the CPU interrupt associated with an IRQ
*
* Input Parameters:
* irq - The IRQ associated with a CPU interrupt
* cpu - Pointer to store the CPU core of the CPU interrupt
*
* Returned Value:
* The CPU interrupt associated with such IRQ or IRQ_UNMAPPED if
* CPU interrupt is not mapped to an IRQ.
*
****************************************************************************/
int esp32s3_getcpuint_from_irq(int irq, int *cpu)
{
(*cpu) = (int)IRQ_GETCPU(g_irqmap[irq]);
return IRQ_GETCPUINT(g_irqmap[irq]);
}
/**************************************************************************** /****************************************************************************
* Name: xtensa_int_decode * Name: xtensa_int_decode
* *
@@ -903,18 +1023,16 @@ uint32_t *xtensa_int_decode(uint32_t cpuints, uint32_t *regs)
uint8_t *intmap; uint8_t *intmap;
uint32_t mask; uint32_t mask;
int bit; int bit;
#ifdef CONFIG_SMP
int cpu; int cpu;
#endif
#ifdef CONFIG_ARCH_LEDS_CPU_ACTIVITY #ifdef CONFIG_ARCH_LEDS_CPU_ACTIVITY
board_autoled_on(LED_CPU); board_autoled_on(LED_CPU);
#endif #endif
#ifdef CONFIG_SMP
/* Select PRO or APP CPU interrupt mapping table */ /* Select PRO or APP CPU interrupt mapping table */
cpu = up_cpu_index(); cpu = up_cpu_index();
#ifdef CONFIG_SMP
if (cpu != 0) if (cpu != 0)
{ {
intmap = g_cpu1_intmap; intmap = g_cpu1_intmap;
@@ -945,6 +1063,17 @@ uint32_t *xtensa_int_decode(uint32_t cpuints, uint32_t *regs)
DEBUGASSERT(CPUINT_GETEN(intmap[bit])); DEBUGASSERT(CPUINT_GETEN(intmap[bit]));
DEBUGASSERT(irq != CPUINT_UNASSIGNED); DEBUGASSERT(irq != CPUINT_UNASSIGNED);
#ifdef CONFIG_ESP32S3_IRAM_ISR_DEBUG
/* Check if non-IRAM interrupts are disabled */
if (esp32s3_irq_noniram_status(cpu) == 0)
{
/* Sum-up the IRAM-enabled counter associated with the IRQ */
esp32s3_irq_iram_interrupt_record(irq);
}
#endif
/* Clear software or edge-triggered interrupt */ /* Clear software or edge-triggered interrupt */
xtensa_intclear(mask); xtensa_intclear(mask);
@@ -965,6 +1094,185 @@ uint32_t *xtensa_int_decode(uint32_t cpuints, uint32_t *regs)
} }
} }
UNUSED(cpu);
return regs; return regs;
} }
/****************************************************************************
* Name: esp32s3_irq_noniram_disable
*
* Description:
* Disable interrupts that aren't specifically marked as running from IRAM
*
* Input Parameters:
* None
*
* Input Parameters:
* None
*
****************************************************************************/
void esp32s3_irq_noniram_disable(void)
{
irqstate_t irqstate;
int cpu;
uint32_t oldint;
uint32_t non_iram_ints;
irqstate = enter_critical_section();
cpu = up_cpu_index();
non_iram_ints = g_non_iram_int_mask[cpu];
ASSERT(!g_non_iram_int_disabled_flag[cpu]);
g_non_iram_int_disabled_flag[cpu] = true;
oldint = g_intenable[cpu];
xtensa_disable_cpuint(&g_intenable[cpu], non_iram_ints);
g_non_iram_int_disabled[cpu] = oldint & non_iram_ints;
leave_critical_section(irqstate);
}
/****************************************************************************
* Name: esp32s3_irq_noniram_enable
*
* Description:
* Re-enable interrupts disabled by esp32s3_irq_noniram_disable
*
* Input Parameters:
* None
*
* Input Parameters:
* None
*
****************************************************************************/
void esp32s3_irq_noniram_enable(void)
{
irqstate_t irqstate;
int cpu;
uint32_t non_iram_ints;
irqstate = enter_critical_section();
cpu = up_cpu_index();
non_iram_ints = g_non_iram_int_disabled[cpu];
ASSERT(g_non_iram_int_disabled_flag[cpu]);
g_non_iram_int_disabled_flag[cpu] = false;
xtensa_enable_cpuint(&g_intenable[cpu], non_iram_ints);
leave_critical_section(irqstate);
}
/****************************************************************************
* Name: esp32s3_irq_noniram_status
*
* Description:
* Get the current status of non-IRAM interrupts on a specific CPU core
*
* Input Parameters:
* cpu - The CPU to check the non-IRAM interrupts state
*
* Returned Value:
* true if non-IRAM interrupts are enabled, false otherwise.
*
****************************************************************************/
bool esp32s3_irq_noniram_status(int cpu)
{
DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS);
return !g_non_iram_int_disabled_flag[cpu];
}
/****************************************************************************
* Name: esp32s3_irq_set_iram_isr
*
* Description:
* Set the ISR associated to an IRQ as a IRAM-enabled ISR.
*
* Input Parameters:
* irq - The associated IRQ to set
*
* Returned Value:
* OK on success; A negated errno value on failure.
*
****************************************************************************/
int esp32s3_irq_set_iram_isr(int irq)
{
int cpu;
int cpuint = esp32s3_getcpuint_from_irq(irq, &cpu);
if (cpuint == IRQ_UNMAPPED)
{
return -EINVAL;
}
g_non_iram_int_mask[cpu] &= ~(1 << cpuint);
return OK;
}
/****************************************************************************
* Name: esp32s3_irq_unset_iram_isr
*
* Description:
* Set the ISR associated to an IRQ as a non-IRAM ISR.
*
* Input Parameters:
* irq - The associated IRQ to set
*
* Returned Value:
* OK on success; A negated errno value on failure.
*
****************************************************************************/
int esp32s3_irq_unset_iram_isr(int irq)
{
int cpu;
int cpuint = esp32s3_getcpuint_from_irq(irq, &cpu);
if (cpuint == IRQ_UNMAPPED)
{
return -EINVAL;
}
g_non_iram_int_mask[cpu] |= (1 << cpuint);
return OK;
}
#ifdef CONFIG_ESP32S3_IRAM_ISR_DEBUG
/****************************************************************************
* Name: esp32s3_get_iram_interrupt_records
*
* Description:
* This function copies the vector that keeps track of the IRQs that ran
* when non-IRAM interrupts were disabled.
*
* Input Parameters:
*
* irq_count - A previously allocated pointer to store the counter of the
* interrupts that ran when non-IRAM interrupts were disabled.
*
* Returned Value:
* None
*
****************************************************************************/
void esp32s3_get_iram_interrupt_records(uint64_t *irq_count)
{
irqstate_t flags = enter_critical_section();
memcpy(irq_count, &g_iram_count, sizeof(uint64_t) * NR_IRQS);
leave_critical_section(flags);
}
#endif
+128 -6
View File
@@ -46,8 +46,8 @@ extern "C"
/* CPU interrupt types. */ /* CPU interrupt types. */
#define ESP32S3_CPUINT_LEVEL 0 #define ESP32S3_CPUINT_LEVEL ESP32S3_CPUINT_FLAG_LEVEL
#define ESP32S3_CPUINT_EDGE 1 #define ESP32S3_CPUINT_EDGE ESP32S3_CPUINT_FLAG_EDGE
/**************************************************************************** /****************************************************************************
* Public Functions Prototypes * Public Functions Prototypes
@@ -82,7 +82,9 @@ int esp32s3_cpuint_initialize(void);
* periphid - The peripheral number from irq.h to be assigned to * periphid - The peripheral number from irq.h to be assigned to
* a CPU interrupt. * a CPU interrupt.
* priority - Interrupt's priority (1 - 5). * priority - Interrupt's priority (1 - 5).
* type - Interrupt's type (level or edge). * flags - An ORred mask of the ESP32S3_CPUINT_FLAG_* defines. These
* restrict the choice of interrupts that this routine can
* choose from.
* *
* Returned Value: * Returned Value:
* The allocated CPU interrupt on success, a negated errno value on * The allocated CPU interrupt on success, a negated errno value on
@@ -90,7 +92,7 @@ int esp32s3_cpuint_initialize(void);
* *
****************************************************************************/ ****************************************************************************/
int esp32s3_setup_irq(int cpu, int periphid, int priority, int type); int esp32s3_setup_irq(int cpu, int periphid, int priority, int flags);
/**************************************************************************** /****************************************************************************
* Name: esp32s3_teardown_irq * Name: esp32s3_teardown_irq
@@ -121,8 +123,8 @@ void esp32s3_teardown_irq(int cpu, int periphid, int cpuint);
* This function returns the IRQ associated with a CPU interrupt * This function returns the IRQ associated with a CPU interrupt
* *
* Input Parameters: * Input Parameters:
* cpu - The CPU to receive the interrupt 0=PRO CPU 1=APP CPU * cpu - The CPU core of the IRQ being queried
* cpuint - The CPU interrupt associated to the IRQ * cpuint - The CPU interrupt associated to the IRQ
* *
* Returned Value: * Returned Value:
* The IRQ associated with such CPU interrupt or CPUINT_UNASSIGNED if * The IRQ associated with such CPU interrupt or CPUINT_UNASSIGNED if
@@ -132,6 +134,126 @@ void esp32s3_teardown_irq(int cpu, int periphid, int cpuint);
int esp32s3_getirq(int cpu, int cpuint); int esp32s3_getirq(int cpu, int cpuint);
/****************************************************************************
* Name: esp32s3_getcpuint_from_irq
*
* Description:
* This function returns the CPU interrupt associated with an IRQ
*
* Input Parameters:
* irq - The IRQ associated with a CPU interrupt
* cpu - Pointer to store the CPU core of the CPU interrupt
*
* Returned Value:
* The CPU interrupt associated with such IRQ or IRQ_UNMAPPED if
* CPU interrupt is not mapped to an IRQ.
*
****************************************************************************/
int esp32s3_getcpuint_from_irq(int irq, int *cpu);
/****************************************************************************
* Name: esp32s3_irq_noniram_disable
*
* Description:
* Disable interrupts that aren't specifically marked as running from IRAM
*
* Input Parameters:
* None
*
* Input Parameters:
* None
*
****************************************************************************/
void esp32s3_irq_noniram_disable(void);
/****************************************************************************
* Name: esp32s3_irq_noniram_enable
*
* Description:
* Re-enable interrupts disabled by esp32s3_irq_noniram_disable
*
* Input Parameters:
* None
*
* Input Parameters:
* None
*
****************************************************************************/
void esp32s3_irq_noniram_enable(void);
/****************************************************************************
* Name: esp32s3_irq_noniram_status
*
* Description:
* Get the current status of non-IRAM interrupts on a specific CPU core
*
* Input Parameters:
* cpu - The CPU to check the non-IRAM interrupts state
*
* Returned Value:
* true if non-IRAM interrupts are enabled, false otherwise.
*
****************************************************************************/
bool esp32s3_irq_noniram_status(int cpu);
/****************************************************************************
* Name: esp32s3_irq_set_iram_isr
*
* Description:
* Set the ISR associated to an IRQ as a IRAM-enabled ISR.
*
* Input Parameters:
* irq - The associated IRQ to set
*
* Returned Value:
* OK on success; A negated errno value on failure.
*
****************************************************************************/
int esp32s3_irq_set_iram_isr(int irq);
/****************************************************************************
* Name: esp32s3_irq_unset_iram_isr
*
* Description:
* Set the ISR associated to an IRQ as a non-IRAM ISR.
*
* Input Parameters:
* irq - The associated IRQ to set
*
* Returned Value:
* OK on success; A negated errno value on failure.
*
****************************************************************************/
int esp32s3_irq_unset_iram_isr(int irq);
#ifdef CONFIG_ESP32S3_IRAM_ISR_DEBUG
/****************************************************************************
* Name: esp32s3_get_iram_interrupt_records
*
* Description:
* This function copies the vector that keeps track of the IRQs that ran
* when non-IRAM interrupts were disabled.
*
* Input Parameters:
*
* irq_count - A previously allocated pointer to store the counter of the
* interrupts that ran when non-IRAM interrupts were disabled.
*
* Returned Value:
* None
*
****************************************************************************/
void esp32s3_get_iram_interrupt_records(uint64_t *irq_count);
#endif
#undef EXTERN #undef EXTERN
#if defined(__cplusplus) #if defined(__cplusplus)
} }
File diff suppressed because it is too large Load Diff
@@ -521,6 +521,19 @@ static inline bool IRAM_ATTR esp32s3_ptr_extram(const void *p)
(intptr_t)p < SOC_EXTRAM_DATA_HIGH); (intptr_t)p < SOC_EXTRAM_DATA_HIGH);
} }
/****************************************************************************
* Name: esp32s3_ptr_iram
*
* Description:
* Check if the pointer is in IRAM
*
****************************************************************************/
static inline bool IRAM_ATTR esp32s3_ptr_iram(const void *p)
{
return ((intptr_t)p >= SOC_IRAM_LOW && (intptr_t)p < SOC_IRAM_HIGH);
}
/**************************************************************************** /****************************************************************************
* Name: esp32s3_ptr_exec * Name: esp32s3_ptr_exec
* *
@@ -76,24 +76,30 @@ SECTIONS
*(.iram1 .iram1.*) *(.iram1 .iram1.*)
*libarch.a:esp32s3_cpuindex.*(.literal .text .literal.* .text.*)
*libarch.a:esp32s3_irq.*(.literal .text .literal.* .text.*)
*libarch.a:esp32s3_spiflash.*(.literal .text .literal.* .text.*) *libarch.a:esp32s3_spiflash.*(.literal .text .literal.* .text.*)
*libarch.a:xtensa_assert.*(.literal .text .literal.* .text.*)
*libarch.a:xtensa_cpuint.*(.literal .text .literal.* .text.*)
*libarch.a:xtensa_cpupause.*(.literal .text .literal.* .text.*) *libarch.a:xtensa_cpupause.*(.literal .text .literal.* .text.*)
*libarch.a:xtensa_irqdispatch.*(.literal .text .literal.* .text.*)
*libarch.a:xtensa_modifyreg32.*(.literal .text .literal.* .text.*)
*libarch.a:xtensa_testset.*(.literal .text .literal.* .text.*) *libarch.a:xtensa_testset.*(.literal .text .literal.* .text.*)
*libarch.a:xtensa_modifyreg32.*(.literal.modifyreg32 .text.modifyreg32)
*libdrivers.a:syslog_flush.*(.literal .text .literal.* .text.*)
*libsched.a:assert.*(.literal .text .literal.* .text.*)
*libsched.a:irq_csection.*(.literal .text .literal.* .text.*) *libsched.a:irq_csection.*(.literal .text .literal.* .text.*)
*libsched.a:irq_dispatch.*(.literal .text .literal.* .text.*) *libsched.a:irq_dispatch.*(.literal .text .literal.* .text.*)
*libsched.a:irq_spinlock.*(.literal .text .literal.* .text.*)
*libsched.a:sched_note.*(.literal .text .literal.* .text.*) *libsched.a:sched_note.*(.literal .text .literal.* .text.*)
*libsched.a:sched_suspendscheduler.*(.literal .text .literal.* .text.*) *libsched.a:sched_suspendscheduler.*(.literal .text .literal.* .text.*)
*libsched.a:sched_thistask.*(.literal .text .literal.* .text.*) *libsched.a:sched_thistask.*(.literal .text .literal.* .text.*)
*libsched.a:spinlock.*(.literal .text .literal.* .text.*) *libsched.a:spinlock.*(.literal .text .literal.* .text.*)
#ifdef CONFIG_ESP32S3_SPEED_UP_ISR #ifdef CONFIG_ESP32S3_SPEED_UP_ISR
*libarch.a:xtensa_irqdispatch.*(.literal.xtensa_irq_dispatch .text.xtensa_irq_dispatch)
*libarch.a:xtensa_switchcontext.*(.literal.up_switch_context .text.up_switch_context) *libarch.a:xtensa_switchcontext.*(.literal.up_switch_context .text.up_switch_context)
*libarch.a:xtensa_modifyreg32.*(.literal.modifyreg32 .text.modifyreg32)
*libarch.a:esp32s3_irq.*(.literal.xtensa_int_decode .text.xtensa_int_decode)
*libarch.a:esp32s3_timerisr.*(.literal.systimer_isr .text.systimer_isr) *libarch.a:esp32s3_timerisr.*(.literal.systimer_isr .text.systimer_isr)
*libarch.a:esp32s3_idle.*(.literal.up_idle .text.up_idle) *libarch.a:esp32s3_idle.*(.literal.up_idle .text.up_idle)
*libarch.a:esp32s3_dma.*(.literal.esp32s3_dma_load .text.esp32s3_dma_load \ *libarch.a:esp32s3_dma.*(.literal.esp32s3_dma_load .text.esp32s3_dma_load \
@@ -195,6 +201,7 @@ SECTIONS
*(.dram1 .dram1.*) *(.dram1 .dram1.*)
*libphy.a:(.rodata .rodata.*) *libphy.a:(.rodata .rodata.*)
*libarch.a:xtensa_context.*(.rodata .rodata.*)
_edata = ABSOLUTE(.); _edata = ABSOLUTE(.);
. = ALIGN(4); . = ALIGN(4);