mirror of
https://github.com/apache/nuttx.git
synced 2026-09-09 02:16:35 +00:00
Use small lock to protect resources related to irq in arch risc-V and xtensa.
Signed-off-by: wangzhi16 <wangzhi16@xiaomi.com>
This commit is contained in:
parent
0b542ff824
commit
099801630d
5 changed files with 173 additions and 110 deletions
|
|
@ -28,11 +28,12 @@
|
|||
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
#include <sched.h>
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/spinlock.h>
|
||||
#include <nuttx/arch.h>
|
||||
|
||||
#include "riscv_internal.h"
|
||||
|
|
@ -145,6 +146,10 @@ static bool non_iram_int_disabled_flag[CONFIG_ESPRESSIF_NUM_CPUS];
|
|||
static uint64_t g_iram_count[NR_IRQS];
|
||||
#endif
|
||||
|
||||
/* Spinlock */
|
||||
|
||||
static spinlock_t g_irq_lock = SP_UNLOCKED;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
|
@ -307,11 +312,11 @@ static void esp_cpuint_initialize(void)
|
|||
|
||||
IRAM_ATTR void esp_irq_iram_interrupt_record(int irq)
|
||||
{
|
||||
irqstate_t flags = enter_critical_section();
|
||||
irqstate_t flags = spin_lock_irqsave(&g_irq_lock);
|
||||
|
||||
g_iram_count[irq]++;
|
||||
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&g_irq_lock, flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -402,12 +407,12 @@ void up_enable_irq(int irq)
|
|||
|
||||
DEBUGASSERT(cpuint >= 0 && cpuint < ESP_NCPUINTS);
|
||||
|
||||
irqstate_t irqstate = enter_critical_section();
|
||||
irqstate_t flags = spin_lock_irqsave(&g_irq_lock);
|
||||
|
||||
CPUINT_ENABLE(g_cpuint_map[cpuint]);
|
||||
esprv_intc_int_enable(BIT(cpuint));
|
||||
|
||||
leave_critical_section(irqstate);
|
||||
spin_unlock_irqrestore(&g_irq_lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -434,12 +439,12 @@ void up_disable_irq(int irq)
|
|||
|
||||
DEBUGASSERT(cpuint >= 0 && cpuint < ESP_NCPUINTS);
|
||||
|
||||
irqstate_t irqstate = enter_critical_section();
|
||||
irqstate_t flags = spin_lock_irqsave(&g_irq_lock);
|
||||
|
||||
CPUINT_DISABLE(g_cpuint_map[cpuint]);
|
||||
esprv_intc_int_disable(BIT(cpuint));
|
||||
|
||||
leave_critical_section(irqstate);
|
||||
spin_unlock_irqrestore(&g_irq_lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -508,7 +513,7 @@ void esp_route_intr(int source, int cpuint, irq_priority_t priority,
|
|||
|
||||
int esp_setup_irq(int source, irq_priority_t priority, int type)
|
||||
{
|
||||
irqstate_t irqstate;
|
||||
irqstate_t flags;
|
||||
int irq;
|
||||
int cpuint;
|
||||
|
||||
|
|
@ -516,7 +521,8 @@ int esp_setup_irq(int source, irq_priority_t priority, int type)
|
|||
|
||||
DEBUGASSERT(source >= 0 && source < ESP_NSOURCES);
|
||||
|
||||
irqstate = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_irq_lock);
|
||||
sched_lock();
|
||||
|
||||
/* Setting up an IRQ includes the following steps:
|
||||
* 1. Allocate a CPU interrupt.
|
||||
|
|
@ -546,7 +552,8 @@ int esp_setup_irq(int source, irq_priority_t priority, int type)
|
|||
esp_irq_unset_iram_isr(irq);
|
||||
}
|
||||
|
||||
leave_critical_section(irqstate);
|
||||
spin_unlock_irqrestore(&g_irq_lock, flags);
|
||||
sched_unlock();
|
||||
|
||||
return cpuint;
|
||||
}
|
||||
|
|
@ -572,7 +579,7 @@ int esp_setup_irq(int source, irq_priority_t priority, int type)
|
|||
|
||||
void esp_teardown_irq(int source, int cpuint)
|
||||
{
|
||||
irqstate_t irqstate = enter_critical_section();
|
||||
irqstate_t flags = spin_lock_irqsave(&g_irq_lock);
|
||||
|
||||
/* Tearing down an IRQ includes the following steps:
|
||||
* 1. Free the previously allocated CPU interrupt.
|
||||
|
|
@ -586,7 +593,7 @@ void esp_teardown_irq(int source, int cpuint)
|
|||
|
||||
esp_rom_route_intr_matrix(PRO_CPU_NUM, source, NO_CPUINT);
|
||||
|
||||
leave_critical_section(irqstate);
|
||||
spin_unlock_irqrestore(&g_irq_lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -693,11 +700,11 @@ irqstate_t up_irq_enable(void)
|
|||
void esp_intr_noniram_disable(void)
|
||||
{
|
||||
uint32_t oldint;
|
||||
irqstate_t irqstate;
|
||||
irqstate_t flags;
|
||||
uint32_t cpu;
|
||||
uint32_t non_iram_ints;
|
||||
|
||||
irqstate = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_irq_lock);
|
||||
cpu = esp_cpu_get_core_id();
|
||||
non_iram_ints = non_iram_int_mask[cpu];
|
||||
|
||||
|
|
@ -713,7 +720,7 @@ void esp_intr_noniram_disable(void)
|
|||
/* Save disabled ints */
|
||||
|
||||
non_iram_int_disabled[cpu] = oldint & non_iram_ints;
|
||||
leave_critical_section(irqstate);
|
||||
spin_unlock_irqrestore(&g_irq_lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -732,11 +739,11 @@ void esp_intr_noniram_disable(void)
|
|||
|
||||
void esp_intr_noniram_enable(void)
|
||||
{
|
||||
irqstate_t irqstate;
|
||||
irqstate_t flags;
|
||||
uint32_t cpu;
|
||||
int non_iram_ints;
|
||||
|
||||
irqstate = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_irq_lock);
|
||||
cpu = esp_cpu_get_core_id();
|
||||
non_iram_ints = non_iram_int_disabled[cpu];
|
||||
|
||||
|
|
@ -747,7 +754,7 @@ void esp_intr_noniram_enable(void)
|
|||
|
||||
non_iram_int_disabled_flag[cpu] = false;
|
||||
esp_cpu_intr_enable(non_iram_ints);
|
||||
leave_critical_section(irqstate);
|
||||
spin_unlock_irqrestore(&g_irq_lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -895,10 +902,10 @@ int esp_irq_unset_iram_isr(int irq)
|
|||
#ifdef CONFIG_ESPRESSIF_IRAM_ISR_DEBUG
|
||||
void esp_get_iram_interrupt_records(uint64_t *irq_count)
|
||||
{
|
||||
irqstate_t flags = enter_critical_section();
|
||||
irqstate_t flags = spin_lock_irqsave(&g_irq_lock);
|
||||
|
||||
memcpy(irq_count, &g_iram_count, sizeof(uint64_t) * NR_IRQS);
|
||||
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&g_irq_lock, flags);
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -31,8 +31,9 @@
|
|||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
#include <sched.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/spinlock.h>
|
||||
#include <nuttx/arch.h>
|
||||
|
||||
#include "riscv_internal.h"
|
||||
|
|
@ -117,6 +118,10 @@ static uint32_t g_cpu_freeints = ESP32C3_CPUINT_PERIPHSET &
|
|||
(~ESP32C3_WIFI_RESERVE_INT &
|
||||
~ESP32C3_BLE_RESERVE_INT);
|
||||
|
||||
/* Spinlock */
|
||||
|
||||
static spinlock_t g_irq_lock = SP_UNLOCKED;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
|
@ -191,6 +196,45 @@ static int esp32c3_getcpuint(void)
|
|||
return cpuint;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_free_cpuint_nolock
|
||||
*
|
||||
* Description:
|
||||
* The version of public function esp32c3_free_cpuint without spinlock.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void esp32c3_free_cpuint_nolock(uint8_t periphid)
|
||||
{
|
||||
uint8_t cpuint;
|
||||
|
||||
DEBUGASSERT(periphid < ESP32C3_NPERIPHERALS);
|
||||
|
||||
/* Get the CPU interrupt ID mapped to this peripheral. */
|
||||
|
||||
cpuint = getreg32(DR_REG_INTERRUPT_BASE + periphid * 4) & 0x1f;
|
||||
|
||||
irqinfo("INFO: irq[%" PRIu8 "]=%" PRIu8 "\n", periphid, cpuint);
|
||||
|
||||
if (cpuint != 0)
|
||||
{
|
||||
/* Undo the allocation process:
|
||||
* 1. Unmap the peripheral from the CPU interrupt ID.
|
||||
* 2. Reset the interrupt type.
|
||||
* 3. Reset the interrupt priority.
|
||||
* 4. Clear the CPU interrupt.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(g_cpu_intmap[cpuint] != CPUINT_UNASSIGNED);
|
||||
|
||||
g_cpu_intmap[cpuint] = CPUINT_UNASSIGNED;
|
||||
putreg32(0, DR_REG_INTERRUPT_BASE + periphid * 4);
|
||||
resetbits(1 << cpuint, INTERRUPT_CPU_INT_TYPE_REG);
|
||||
putreg32(0, INTERRUPT_CPU_INT_PRI_0_REG + cpuint * 4);
|
||||
resetbits(1 << cpuint, INTERRUPT_CPU_INT_ENABLE_REG);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
|
@ -260,15 +304,15 @@ void up_irqinitialize(void)
|
|||
void up_enable_irq(int irq)
|
||||
{
|
||||
int cpuint = g_irqmap[irq];
|
||||
irqstate_t irqstate;
|
||||
irqstate_t flags;
|
||||
|
||||
irqinfo("irq=%d | cpuint=%d \n", irq, cpuint);
|
||||
|
||||
DEBUGASSERT(cpuint >= 1 && cpuint <= ESP32C3_CPUINT_MAX);
|
||||
|
||||
irqstate = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_irq_lock);
|
||||
setbits(1 << cpuint, INTERRUPT_CPU_INT_ENABLE_REG);
|
||||
leave_critical_section(irqstate);
|
||||
spin_unlock_irqrestore(&g_irq_lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -295,13 +339,13 @@ void up_disable_irq(int irq)
|
|||
}
|
||||
else
|
||||
{
|
||||
irqstate_t irqstate;
|
||||
irqstate_t flags;
|
||||
|
||||
g_cpu_intmap[cpuint] = CPUINT_DISABLE(g_cpu_intmap[cpuint]);
|
||||
|
||||
irqstate = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_irq_lock);
|
||||
resetbits(1 << cpuint, INTERRUPT_CPU_INT_ENABLE_REG);
|
||||
leave_critical_section(irqstate);
|
||||
spin_unlock_irqrestore(&g_irq_lock, flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -321,38 +365,13 @@ void up_disable_irq(int irq)
|
|||
|
||||
void esp32c3_free_cpuint(uint8_t periphid)
|
||||
{
|
||||
irqstate_t irqstate;
|
||||
uint8_t cpuint;
|
||||
irqstate_t flags;
|
||||
|
||||
DEBUGASSERT(periphid < ESP32C3_NPERIPHERALS);
|
||||
|
||||
irqstate = enter_critical_section();
|
||||
|
||||
/* Get the CPU interrupt ID mapped to this peripheral. */
|
||||
|
||||
cpuint = getreg32(DR_REG_INTERRUPT_BASE + periphid * 4) & 0x1f;
|
||||
|
||||
irqinfo("INFO: irq[%" PRIu8 "]=%" PRIu8 "\n", periphid, cpuint);
|
||||
|
||||
if (cpuint != 0)
|
||||
{
|
||||
/* Undo the allocation process:
|
||||
* 1. Unmap the peripheral from the CPU interrupt ID.
|
||||
* 2. Reset the interrupt type.
|
||||
* 3. Reset the interrupt priority.
|
||||
* 4. Clear the CPU interrupt.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(g_cpu_intmap[cpuint] != CPUINT_UNASSIGNED);
|
||||
|
||||
g_cpu_intmap[cpuint] = CPUINT_UNASSIGNED;
|
||||
putreg32(0, DR_REG_INTERRUPT_BASE + periphid * 4);
|
||||
resetbits(1 << cpuint, INTERRUPT_CPU_INT_TYPE_REG);
|
||||
putreg32(0, INTERRUPT_CPU_INT_PRI_0_REG + cpuint * 4);
|
||||
resetbits(1 << cpuint, INTERRUPT_CPU_INT_ENABLE_REG);
|
||||
}
|
||||
|
||||
leave_critical_section(irqstate);
|
||||
flags = spin_lock_irqsave(&g_irq_lock);
|
||||
sched_lock();
|
||||
esp32c3_free_cpuint_nolock(periphid);
|
||||
spin_unlock_irqrestore(&g_irq_lock, flags);
|
||||
sched_unlock();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -462,13 +481,14 @@ void esp32c3_bind_irq(uint8_t cpuint, uint8_t periphid, uint8_t prio,
|
|||
|
||||
int esp32c3_setup_irq(int periphid, int priority, int type)
|
||||
{
|
||||
irqstate_t irqstate;
|
||||
irqstate_t flags;
|
||||
int irq;
|
||||
int cpuint;
|
||||
|
||||
irqinfo("periphid = %d\n", periphid);
|
||||
|
||||
irqstate = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_irq_lock);
|
||||
sched_lock();
|
||||
|
||||
/* Setting up an IRQ includes the following steps:
|
||||
* 1. Allocate a CPU interrupt.
|
||||
|
|
@ -481,7 +501,8 @@ int esp32c3_setup_irq(int periphid, int priority, int type)
|
|||
{
|
||||
irqerr("Unable to allocate CPU interrupt for priority=%d and type=%d",
|
||||
priority, type);
|
||||
leave_critical_section(irqstate);
|
||||
spin_unlock_irqrestore(&g_irq_lock, flags);
|
||||
sched_unlock();
|
||||
|
||||
return cpuint;
|
||||
}
|
||||
|
|
@ -497,7 +518,8 @@ int esp32c3_setup_irq(int periphid, int priority, int type)
|
|||
|
||||
esp32c3_bind_irq(cpuint, periphid, priority, type);
|
||||
|
||||
leave_critical_section(irqstate);
|
||||
spin_unlock_irqrestore(&g_irq_lock, flags);
|
||||
sched_unlock();
|
||||
|
||||
return cpuint;
|
||||
}
|
||||
|
|
@ -523,11 +545,12 @@ int esp32c3_setup_irq(int periphid, int priority, int type)
|
|||
|
||||
void esp32c3_teardown_irq(int periphid, int cpuint)
|
||||
{
|
||||
irqstate_t irqstate;
|
||||
irqstate_t flags;
|
||||
uintptr_t regaddr;
|
||||
int irq;
|
||||
|
||||
irqstate = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_irq_lock);
|
||||
sched_lock();
|
||||
|
||||
/* Tearing down an IRQ includes the following steps:
|
||||
* 1. Free the previously allocated CPU interrupt.
|
||||
|
|
@ -535,7 +558,7 @@ void esp32c3_teardown_irq(int periphid, int cpuint)
|
|||
* 3. Unmap the IRQ from the IRQ-to-cpuint map.
|
||||
*/
|
||||
|
||||
esp32c3_free_cpuint(cpuint);
|
||||
esp32c3_free_cpuint_nolock(cpuint);
|
||||
|
||||
irq = ESP32C3_PERIPH2IRQ(periphid);
|
||||
|
||||
|
|
@ -548,7 +571,8 @@ void esp32c3_teardown_irq(int periphid, int cpuint)
|
|||
|
||||
putreg32(NO_CPUINT, regaddr);
|
||||
|
||||
leave_critical_section(irqstate);
|
||||
spin_unlock_irqrestore(&g_irq_lock, flags);
|
||||
sched_unlock();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
|||
|
|
@ -29,8 +29,9 @@
|
|||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
#include <sched.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/spinlock.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/board.h>
|
||||
#include <arch/irq.h>
|
||||
|
|
@ -114,6 +115,14 @@
|
|||
# define ESP32_BLE_RESERVE_INT 0
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* Spinlock */
|
||||
|
||||
static spinlock_t g_irq_lock = SP_UNLOCKED;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
|
@ -221,9 +230,11 @@ static void esp32_irq_dump(const char *msg, int irq)
|
|||
{
|
||||
irqstate_t flags;
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_irq_lock);
|
||||
sched_lock();
|
||||
#warning Missing logic
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&g_irq_lock, flags);
|
||||
sched_unlock();
|
||||
}
|
||||
#else
|
||||
# define esp32_irq_dump(msg, irq)
|
||||
|
|
@ -480,11 +491,11 @@ static void esp32_free_cpuint(int cpuint)
|
|||
|
||||
void esp32_irq_iram_interrupt_record(int irq)
|
||||
{
|
||||
irqstate_t flags = enter_critical_section();
|
||||
irqstate_t flags = spin_lock_irqsave(&g_irq_lock);
|
||||
|
||||
g_iram_count[irq]++;
|
||||
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&g_irq_lock, flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -870,7 +881,8 @@ int esp32_setup_irq(int cpu, int periphid, int priority, int flags)
|
|||
int irq;
|
||||
int cpuint;
|
||||
|
||||
irqstate = enter_critical_section();
|
||||
irqstate = spin_lock_irqsave(&g_irq_lock);
|
||||
sched_lock();
|
||||
|
||||
/* Setting up an IRQ includes the following steps:
|
||||
* 1. Allocate a CPU interrupt.
|
||||
|
|
@ -884,7 +896,8 @@ int esp32_setup_irq(int cpu, int periphid, int priority, int flags)
|
|||
{
|
||||
irqerr("Unable to allocate CPU interrupt for priority=%d and flags=%d",
|
||||
priority, flags);
|
||||
leave_critical_section(irqstate);
|
||||
spin_unlock_irqrestore(&g_irq_lock, irqstate);
|
||||
sched_unlock();
|
||||
|
||||
return cpuint;
|
||||
}
|
||||
|
|
@ -921,7 +934,8 @@ int esp32_setup_irq(int cpu, int periphid, int priority, int flags)
|
|||
|
||||
putreg32(cpuint, regaddr);
|
||||
|
||||
leave_critical_section(irqstate);
|
||||
spin_unlock_irqrestore(&g_irq_lock, irqstate);
|
||||
sched_unlock();
|
||||
|
||||
return cpuint;
|
||||
}
|
||||
|
|
@ -948,12 +962,13 @@ int esp32_setup_irq(int cpu, int periphid, int priority, int flags)
|
|||
|
||||
void esp32_teardown_irq(int cpu, int periphid, int cpuint)
|
||||
{
|
||||
irqstate_t irqstate;
|
||||
irqstate_t flags;
|
||||
uintptr_t regaddr;
|
||||
uint8_t *intmap;
|
||||
int irq;
|
||||
|
||||
irqstate = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_irq_lock);
|
||||
sched_lock();
|
||||
|
||||
/* Tearing down an IRQ includes the following steps:
|
||||
* 1. Free the previously allocated CPU interrupt.
|
||||
|
|
@ -975,7 +990,8 @@ void esp32_teardown_irq(int cpu, int periphid, int cpuint)
|
|||
|
||||
putreg32(NO_CPUINT, regaddr);
|
||||
|
||||
leave_critical_section(irqstate);
|
||||
spin_unlock_irqrestore(&g_irq_lock, flags);
|
||||
sched_unlock();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -1153,12 +1169,12 @@ uint32_t *xtensa_int_decode(uint32_t cpuints, uint32_t *regs)
|
|||
|
||||
void esp32_irq_noniram_disable(void)
|
||||
{
|
||||
irqstate_t irqstate;
|
||||
irqstate_t flags;
|
||||
int cpu;
|
||||
uint32_t oldint;
|
||||
uint32_t non_iram_ints;
|
||||
|
||||
irqstate = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_irq_lock);
|
||||
cpu = this_cpu();
|
||||
non_iram_ints = g_non_iram_int_mask[cpu];
|
||||
|
||||
|
|
@ -1171,7 +1187,7 @@ void esp32_irq_noniram_disable(void)
|
|||
|
||||
g_non_iram_int_disabled[cpu] = oldint & non_iram_ints;
|
||||
|
||||
leave_critical_section(irqstate);
|
||||
spin_unlock_irqrestore(&g_irq_lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -1190,11 +1206,11 @@ void esp32_irq_noniram_disable(void)
|
|||
|
||||
void esp32_irq_noniram_enable(void)
|
||||
{
|
||||
irqstate_t irqstate;
|
||||
irqstate_t flags;
|
||||
int cpu;
|
||||
uint32_t non_iram_ints;
|
||||
|
||||
irqstate = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_irq_lock);
|
||||
cpu = this_cpu();
|
||||
non_iram_ints = g_non_iram_int_disabled[cpu];
|
||||
|
||||
|
|
@ -1204,7 +1220,7 @@ void esp32_irq_noniram_enable(void)
|
|||
|
||||
xtensa_enable_cpuint(&g_intenable[cpu], non_iram_ints);
|
||||
|
||||
leave_critical_section(irqstate);
|
||||
spin_unlock_irqrestore(&g_irq_lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -1307,10 +1323,10 @@ int esp32_irq_unset_iram_isr(int irq)
|
|||
|
||||
void esp32_get_iram_interrupt_records(uint64_t *irq_count)
|
||||
{
|
||||
irqstate_t flags = enter_critical_section();
|
||||
irqstate_t flags = spin_lock_irqsave(&g_irq_lock);
|
||||
|
||||
memcpy(irq_count, &g_iram_count, sizeof(uint64_t) * NR_IRQS);
|
||||
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&g_irq_lock, flags);
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -26,11 +26,12 @@
|
|||
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
#include <sched.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/spinlock.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/board.h>
|
||||
#include <arch/irq.h>
|
||||
|
|
@ -119,6 +120,10 @@ static const uint32_t g_priority[5] =
|
|||
ESP32S2_INTPRI5_MASK
|
||||
};
|
||||
|
||||
/* Spinlock */
|
||||
|
||||
static spinlock_t g_irq_lock = SP_UNLOCKED;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
|
@ -490,12 +495,13 @@ int esp32s2_cpuint_initialize(void)
|
|||
|
||||
int esp32s2_setup_irq(int periphid, int priority, int type)
|
||||
{
|
||||
irqstate_t irqstate;
|
||||
irqstate_t flags;
|
||||
uintptr_t regaddr;
|
||||
int irq;
|
||||
int cpuint;
|
||||
|
||||
irqstate = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_irq_lock);
|
||||
sched_lock();
|
||||
|
||||
/* Setting up an IRQ includes the following steps:
|
||||
* 1. Allocate a CPU interrupt.
|
||||
|
|
@ -508,7 +514,8 @@ int esp32s2_setup_irq(int periphid, int priority, int type)
|
|||
{
|
||||
irqerr("Unable to allocate CPU interrupt for priority=%d and type=%d",
|
||||
priority, type);
|
||||
leave_critical_section(irqstate);
|
||||
spin_unlock_irqrestore(&g_irq_lock, flags);
|
||||
sched_unlock();
|
||||
|
||||
return cpuint;
|
||||
}
|
||||
|
|
@ -525,7 +532,8 @@ int esp32s2_setup_irq(int periphid, int priority, int type)
|
|||
|
||||
putreg32(cpuint, regaddr);
|
||||
|
||||
leave_critical_section(irqstate);
|
||||
spin_unlock_irqrestore(&g_irq_lock, flags);
|
||||
sched_unlock();
|
||||
|
||||
return cpuint;
|
||||
}
|
||||
|
|
@ -551,11 +559,11 @@ int esp32s2_setup_irq(int periphid, int priority, int type)
|
|||
|
||||
void esp32s2_teardown_irq(int periphid, int cpuint)
|
||||
{
|
||||
irqstate_t irqstate;
|
||||
irqstate_t flags;
|
||||
uintptr_t regaddr;
|
||||
int irq;
|
||||
|
||||
irqstate = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_irq_lock);
|
||||
|
||||
/* Tearing down an IRQ includes the following steps:
|
||||
* 1. Free the previously allocated CPU interrupt.
|
||||
|
|
@ -576,7 +584,7 @@ void esp32s2_teardown_irq(int periphid, int cpuint)
|
|||
|
||||
putreg32(NO_CPUINT, regaddr);
|
||||
|
||||
leave_critical_section(irqstate);
|
||||
spin_unlock_irqrestore(&g_irq_lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
|||
|
|
@ -29,8 +29,9 @@
|
|||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
#include <sched.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/spinlock.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/board.h>
|
||||
#include <nuttx/kmalloc.h>
|
||||
|
|
@ -204,6 +205,10 @@ static const uint32_t g_priority[5] =
|
|||
static uint64_t g_iram_count[NR_IRQS];
|
||||
#endif
|
||||
|
||||
/* Spinlock */
|
||||
|
||||
static spinlock_t g_irq_lock = SP_UNLOCKED;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
|
@ -445,11 +450,11 @@ static void esp32s3_free_cpuint(int cpuint)
|
|||
|
||||
void esp32s3_irq_iram_interrupt_record(int irq)
|
||||
{
|
||||
irqstate_t flags = enter_critical_section();
|
||||
irqstate_t flags = spin_lock_irqsave(&g_irq_lock);
|
||||
|
||||
g_iram_count[irq]++;
|
||||
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&g_irq_lock, flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -810,7 +815,8 @@ int esp32s3_setup_irq(int cpu, int periphid, int priority, int flags)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
irqstate = enter_critical_section();
|
||||
irqstate = spin_lock_irqsave(&g_irq_lock);
|
||||
sched_lock();
|
||||
|
||||
/* Setting up an IRQ includes the following steps:
|
||||
* 1. Allocate a CPU interrupt.
|
||||
|
|
@ -824,7 +830,8 @@ int esp32s3_setup_irq(int cpu, int periphid, int priority, int flags)
|
|||
{
|
||||
irqerr("Unable to allocate CPU interrupt for priority=%d and flags=%d",
|
||||
priority, flags);
|
||||
leave_critical_section(irqstate);
|
||||
spin_unlock_irqrestore(&g_irq_lock, irqstate);
|
||||
sched_unlock();
|
||||
|
||||
return cpuint;
|
||||
}
|
||||
|
|
@ -852,7 +859,8 @@ int esp32s3_setup_irq(int cpu, int periphid, int priority, int flags)
|
|||
|
||||
putreg32(cpuint, regaddr);
|
||||
|
||||
leave_critical_section(irqstate);
|
||||
spin_unlock_irqrestore(&g_irq_lock, irqstate);
|
||||
sched_unlock();
|
||||
|
||||
return cpuint;
|
||||
}
|
||||
|
|
@ -879,12 +887,12 @@ int esp32s3_setup_irq(int cpu, int periphid, int priority, int flags)
|
|||
|
||||
void esp32s3_teardown_irq(int cpu, int periphid, int cpuint)
|
||||
{
|
||||
irqstate_t irqstate;
|
||||
irqstate_t flags;
|
||||
uintptr_t regaddr;
|
||||
uint8_t *intmap;
|
||||
int irq;
|
||||
|
||||
irqstate = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_irq_lock);
|
||||
|
||||
/* Tearing down an IRQ includes the following steps:
|
||||
* 1. Free the previously allocated CPU interrupt.
|
||||
|
|
@ -906,7 +914,7 @@ void esp32s3_teardown_irq(int cpu, int periphid, int cpuint)
|
|||
|
||||
putreg32(NO_CPUINT, regaddr);
|
||||
|
||||
leave_critical_section(irqstate);
|
||||
spin_unlock_irqrestore(&g_irq_lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -1083,12 +1091,12 @@ uint32_t *xtensa_int_decode(uint32_t cpuints, uint32_t *regs)
|
|||
|
||||
void esp32s3_irq_noniram_disable(void)
|
||||
{
|
||||
irqstate_t irqstate;
|
||||
irqstate_t flags;
|
||||
int cpu;
|
||||
uint32_t oldint;
|
||||
uint32_t non_iram_ints;
|
||||
|
||||
irqstate = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_irq_lock);
|
||||
cpu = this_cpu();
|
||||
non_iram_ints = g_non_iram_int_mask[cpu];
|
||||
|
||||
|
|
@ -1101,7 +1109,7 @@ void esp32s3_irq_noniram_disable(void)
|
|||
|
||||
g_non_iram_int_disabled[cpu] = oldint & non_iram_ints;
|
||||
|
||||
leave_critical_section(irqstate);
|
||||
spin_unlock_irqrestore(&g_irq_lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -1120,11 +1128,11 @@ void esp32s3_irq_noniram_disable(void)
|
|||
|
||||
void esp32s3_irq_noniram_enable(void)
|
||||
{
|
||||
irqstate_t irqstate;
|
||||
irqstate_t flags;
|
||||
int cpu;
|
||||
uint32_t non_iram_ints;
|
||||
|
||||
irqstate = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_irq_lock);
|
||||
cpu = this_cpu();
|
||||
non_iram_ints = g_non_iram_int_disabled[cpu];
|
||||
|
||||
|
|
@ -1134,7 +1142,7 @@ void esp32s3_irq_noniram_enable(void)
|
|||
|
||||
xtensa_enable_cpuint(&g_intenable[cpu], non_iram_ints);
|
||||
|
||||
leave_critical_section(irqstate);
|
||||
spin_unlock_irqrestore(&g_irq_lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -1237,10 +1245,10 @@ int esp32s3_irq_unset_iram_isr(int irq)
|
|||
|
||||
void esp32s3_get_iram_interrupt_records(uint64_t *irq_count)
|
||||
{
|
||||
irqstate_t flags = enter_critical_section();
|
||||
irqstate_t flags = spin_lock_irqsave(&g_irq_lock);
|
||||
|
||||
memcpy(irq_count, &g_iram_count, sizeof(uint64_t) * NR_IRQS);
|
||||
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&g_irq_lock, flags);
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue