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
/* 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
*
* The Interrupt Matrix embedded in the ESP32-S3 independently allocates
@@ -386,17 +396,13 @@
* 26 can be mapped to peripheral interrupts:
*
* Level triggered peripherals (21 total):
* 0-5, 8-9, 12-13, 17-18 - Priority 1
* 19-21 - Priority 2
* 23, 27 - Priority 3
* 24-25 - Priority 4
* 26, 31 - Priority 5
* Edge triggered peripherals (4 total):
* 10 - Priority 1
* 22 - Priority 3
* 28, 30 - Priority 4
* 0-5, 8-10, 12-13, 17-18 - Priority 1
* 19-21 - Priority 2
* 22-23, 27 - Priority 3
* 24-25, 28, 30 - Priority 4
* 26, 31 - Priority 5
* NMI (1 total):
* 14 - NMI
* 14 - NMI
*
* 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
+24
View File
@@ -734,6 +734,19 @@ menuconfig ESP32S3_WIFI_BT_COEXIST
depends on ESP32S3_WIFI && ESP32S3_BLE
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"
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
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
endmenu # SPI Flash configuration
+323 -15
View File
@@ -33,8 +33,10 @@
#include <nuttx/irq.h>
#include <nuttx/arch.h>
#include <nuttx/board.h>
#include <nuttx/kmalloc.h>
#include <arch/irq.h>
#include <arch/board/board.h>
#include <irq/irq.h>
#include "xtensa.h"
@@ -161,6 +163,24 @@ static volatile uint8_t g_irqmap[NR_IRQS];
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
* devices.
*/
@@ -184,6 +204,14 @@ static const uint32_t g_priority[5] =
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
****************************************************************************/
@@ -406,6 +434,33 @@ static void esp32s3_free_cpuint(int cpuint)
*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
****************************************************************************/
@@ -418,6 +473,15 @@ void up_irqinitialize(void)
{
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++)
{
g_irqmap[i] = IRQ_UNMAPPED;
@@ -588,6 +652,21 @@ void up_enable_irq(int 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);
/* 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_TIMER1 15 XTENSA_IRQ_TIMER1 1
* 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);
@@ -732,14 +811,16 @@ int esp32s3_cpuint_initialize(void)
*
* Description:
* 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:
* cpu - The CPU to receive the interrupt 0=PRO CPU 1=APP CPU
* periphid - The peripheral number from irq.h to be assigned to
* a CPU interrupt.
* 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:
* 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;
uintptr_t regaddr;
@@ -755,19 +836,26 @@ int esp32s3_setup_irq(int cpu, int periphid, int priority, int type)
int irq;
int cpuint;
if ((flags & ESP32S3_CPUINT_EDGE) != 0)
{
irqerr("Only level-enabled interrupts are available");
return -EINVAL;
}
irqstate = enter_critical_section();
/* Setting up an IRQ includes the following steps:
* 1. Allocate a CPU interrupt.
* 2. Attach that CPU interrupt to the peripheral.
* 3. Map the CPU interrupt to the IRQ to ease searching later.
* 2. Check if its ISR is intended to run from IRAM.
* 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)
{
irqerr("Unable to allocate CPU interrupt for priority=%d and type=%d",
priority, type);
irqerr("Unable to allocate CPU interrupt for priority=%d and flags=%d",
priority, flags);
leave_critical_section(irqstate);
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);
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);
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
*
* Input Parameters:
* cpu - The CPU to receive the interrupt 0=PRO CPU 1=APP CPU
* cpuint - The CPU interrupt associated to the IRQ
* cpu - The CPU core of the IRQ being queried
* cpuint - The CPU interrupt associated to the IRQ
*
* Returned Value:
* 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]);
}
/****************************************************************************
* 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
*
@@ -903,18 +1023,16 @@ 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_ARCH_LEDS_CPU_ACTIVITY
board_autoled_on(LED_CPU);
#endif
#ifdef CONFIG_SMP
/* Select PRO or APP CPU interrupt mapping table */
cpu = up_cpu_index();
#ifdef CONFIG_SMP
if (cpu != 0)
{
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(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 */
xtensa_intclear(mask);
@@ -965,6 +1094,185 @@ uint32_t *xtensa_int_decode(uint32_t cpuints, uint32_t *regs)
}
}
UNUSED(cpu);
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. */
#define ESP32S3_CPUINT_LEVEL 0
#define ESP32S3_CPUINT_EDGE 1
#define ESP32S3_CPUINT_LEVEL ESP32S3_CPUINT_FLAG_LEVEL
#define ESP32S3_CPUINT_EDGE ESP32S3_CPUINT_FLAG_EDGE
/****************************************************************************
* Public Functions Prototypes
@@ -82,7 +82,9 @@ int esp32s3_cpuint_initialize(void);
* periphid - The peripheral number from irq.h to be assigned to
* a CPU interrupt.
* 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:
* 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
@@ -121,8 +123,8 @@ void esp32s3_teardown_irq(int cpu, int periphid, int cpuint);
* This function returns the IRQ associated with a CPU interrupt
*
* Input Parameters:
* cpu - The CPU to receive the interrupt 0=PRO CPU 1=APP CPU
* cpuint - The CPU interrupt associated to the IRQ
* cpu - The CPU core of the IRQ being queried
* cpuint - The CPU interrupt associated to the IRQ
*
* Returned Value:
* 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);
/****************************************************************************
* 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
#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);
}
/****************************************************************************
* 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
*
@@ -76,24 +76,30 @@ SECTIONS
*(.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: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_irqdispatch.*(.literal .text .literal.* .text.*)
*libarch.a:xtensa_modifyreg32.*(.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_dispatch.*(.literal .text .literal.* .text.*)
*libsched.a:irq_spinlock.*(.literal .text .literal.* .text.*)
*libsched.a:sched_note.*(.literal .text .literal.* .text.*)
*libsched.a:sched_suspendscheduler.*(.literal .text .literal.* .text.*)
*libsched.a:sched_thistask.*(.literal .text .literal.* .text.*)
*libsched.a:spinlock.*(.literal .text .literal.* .text.*)
#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_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_idle.*(.literal.up_idle .text.up_idle)
*libarch.a:esp32s3_dma.*(.literal.esp32s3_dma_load .text.esp32s3_dma_load \
@@ -195,6 +201,7 @@ SECTIONS
*(.dram1 .dram1.*)
*libphy.a:(.rodata .rodata.*)
*libarch.a:xtensa_context.*(.rodata .rodata.*)
_edata = ABSOLUTE(.);
. = ALIGN(4);