diff --git a/arch/Kconfig b/arch/Kconfig index eb4eb1deb4b..4d7088ec257 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -1296,6 +1296,19 @@ config ARCH_MINIMAL_VECTORTABLE_DYNAMIC ---help--- Use a minimum amount of RAM for the vector table. +config ARCH_IRQ_TO_NDX + bool "IRQ to index mapping" + default n + depends on ARCH_MINIMAL_VECTORTABLE_DYNAMIC + ---help--- + Use architecture-specific up_irq_to_ndx() interface to map IRQ + numbers to vector table indices, instead of using a RAM-based + g_irqmap[] array. + + This feature allows architectures to leverage hardware resources + (such as registers or other storage) to maintain the IRQ-to-index + mapping, significantly reducing RAM usage. + config ARCH_NUSER_INTERRUPTS int "Number of interrupts" default 0 diff --git a/arch/tricore/src/common/tricore_irq.c b/arch/tricore/src/common/tricore_irq.c index f7466bea9a7..c42c7b8e3b2 100644 --- a/arch/tricore/src/common/tricore_irq.c +++ b/arch/tricore/src/common/tricore_irq.c @@ -32,6 +32,7 @@ #include #include +#include #include "tricore_internal.h" @@ -69,6 +70,13 @@ static inline void tricore_color_intstack(void) # define tricore_color_intstack() #endif +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static spinlock_t g_irqlock = SP_UNLOCKED; +static int g_irqmap_count = 1; + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -156,8 +164,16 @@ void up_irqinitialize(void) void up_disable_irq(int irq) { volatile Ifx_SRC_SRCR *src = &SRC_CPU_CPU0_SB + irq; + Ifx_SRC_SRCR srctmp; IfxSrc_disable(src); + + /* Clear, keep SRPN */ + + srctmp.U = 0U; + srctmp.B.TOS = ~0; + srctmp.B.SRPN = src->B.SRPN; + src->U = srctmp.U; } /**************************************************************************** @@ -232,4 +248,41 @@ void up_trigger_irq(int irq, cpu_set_t cpuset) volatile Ifx_INT_SRB *srb = &INT_SRB0 + up_cpu_index(); srb->U = cpuset; } -#endif \ No newline at end of file +#endif + +/**************************************************************************** + * Name: up_irq_to_ndx + * + * Description: + * Irq to ndx + * + ****************************************************************************/ + +int up_irq_to_ndx(int irq) +{ + volatile Ifx_SRC_SRCR *src = &SRC_CPU_CPU0_SB + irq; + Ifx_SRC_SRCR srctmp; + irqstate_t flags; + int ndx; + + ndx = src->B.SRPN; + if (ndx != 0) + { + return ndx; + } + + flags = spin_lock_irqsave(&g_irqlock); + ndx = src->B.SRPN; + if (ndx == 0) + { + ndx = g_irqmap_count++; + g_irqrevmap[ndx] = irq; + srctmp.U = src->U; + srctmp.B.SRPN = ndx; + src->U = srctmp.U; + } + + spin_unlock_irqrestore(&g_irqlock, flags); + + return ndx; +} diff --git a/include/nuttx/arch.h b/include/nuttx/arch.h index eaf14260eae..45cbe9f0176 100644 --- a/include/nuttx/arch.h +++ b/include/nuttx/arch.h @@ -1764,6 +1764,18 @@ int up_shmdt(uintptr_t vaddr, unsigned int npages); void up_irqinitialize(void); +/**************************************************************************** + * Name: up_irq_to_ndx + * + * Description: + * Irq to ndx + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_IRQ_TO_NDX +int up_irq_to_ndx(int irq); +#endif + /**************************************************************************** * Name: up_enable_irq * diff --git a/include/nuttx/irq.h b/include/nuttx/irq.h index 4565f3021b0..6f722481176 100644 --- a/include/nuttx/irq.h +++ b/include/nuttx/irq.h @@ -77,7 +77,11 @@ #endif #if defined(CONFIG_ARCH_MINIMAL_VECTORTABLE_DYNAMIC) -# define IRQ_TO_NDX(irq) (g_irqmap[irq] ? g_irqmap[irq] : irq_to_ndx(irq)) +# if defined(CONFIG_ARCH_IRQ_TO_NDX) +# define IRQ_TO_NDX(irq) up_irq_to_ndx(irq) +# else +# define IRQ_TO_NDX(irq) (g_irqmap[irq] ? g_irqmap[irq] : irq_to_ndx(irq)) +# endif # define NDX_TO_IRQ(ndx) g_irqrevmap[ndx] #elif defined(CONFIG_ARCH_MINIMAL_VECTORTABLE) # define IRQ_TO_NDX(irq) \ @@ -214,7 +218,9 @@ extern "C" */ #if defined(CONFIG_ARCH_MINIMAL_VECTORTABLE_DYNAMIC) +# if !defined(CONFIG_ARCH_IRQ_TO_NDX) extern irq_mapped_t g_irqmap[]; +# endif extern int g_irqrevmap[]; int irq_to_ndx(int irq); #elif defined(CONFIG_ARCH_MINIMAL_VECTORTABLE) diff --git a/sched/irq/irq_attach.c b/sched/irq/irq_attach.c index 690d059ad99..3f1e534bf49 100644 --- a/sched/irq/irq_attach.c +++ b/sched/irq/irq_attach.c @@ -37,7 +37,8 @@ ****************************************************************************/ static spinlock_t g_irqlock = SP_UNLOCKED; -#ifdef CONFIG_ARCH_MINIMAL_VECTORTABLE_DYNAMIC +#if defined(CONFIG_ARCH_MINIMAL_VECTORTABLE_DYNAMIC) && \ + !defined(CONFIG_ARCH_IRQ_TO_NDX) static int g_irqmap_count = 1; #endif @@ -56,7 +57,9 @@ static int g_irqmap_count = 1; * declaration is here for the time being. */ +# if !defined(CONFIG_ARCH_IRQ_TO_NDX) irq_mapped_t g_irqmap[NR_IRQS]; +# endif int g_irqrevmap[CONFIG_ARCH_NUSER_INTERRUPTS]; #endif @@ -64,7 +67,8 @@ int g_irqrevmap[CONFIG_ARCH_NUSER_INTERRUPTS]; * Public Functions ****************************************************************************/ -#ifdef CONFIG_ARCH_MINIMAL_VECTORTABLE_DYNAMIC +#if defined(CONFIG_ARCH_MINIMAL_VECTORTABLE_DYNAMIC) && \ + !defined(CONFIG_ARCH_IRQ_TO_NDX) int irq_to_ndx(int irq) { DEBUGASSERT(g_irqmap_count < CONFIG_ARCH_NUSER_INTERRUPTS); @@ -80,7 +84,8 @@ int irq_to_ndx(int irq) spin_unlock_irqrestore(&g_irqlock, flags); return g_irqmap[irq]; } -#elif defined(CONFIG_ARCH_MINIMAL_VECTORTABLE) +#elif defined(CONFIG_ARCH_MINIMAL_VECTORTABLE) && \ + !defined(CONFIG_ARCH_IRQ_TO_NDX) int ndx_to_irq(int ndx) { int i; diff --git a/sched/irq/irq_chain.c b/sched/irq/irq_chain.c index a7ef808ac8a..d2eed6f9778 100644 --- a/sched/irq/irq_chain.c +++ b/sched/irq/irq_chain.c @@ -77,15 +77,9 @@ static int irqchain_dispatch(int irq, FAR void *context, FAR void *arg) { FAR struct irqchain_s *curr; FAR struct irqchain_s *prev; - int ndx; + int ndx = IRQ_TO_NDX(irq); int ret = 0; -#ifdef CONFIG_ARCH_MINIMAL_VECTORTABLE - ndx = g_irqmap[irq]; -#else - ndx = irq; -#endif - curr = g_irqvector[ndx].arg; while (curr != NULL) { diff --git a/sched/irq/irq_dispatch.c b/sched/irq/irq_dispatch.c index 0b8cde958d6..4885e771f8f 100644 --- a/sched/irq/irq_dispatch.c +++ b/sched/irq/irq_dispatch.c @@ -102,13 +102,12 @@ void irq_dispatch(int irq, FAR void *context) #endif xcpt_t vector = irq_unexpected_isr; FAR void *arg = NULL; - int ndx = irq; + unsigned int ndx = IRQ_TO_NDX(irq); #if NR_IRQS > 0 if (irq >= 0 && irq < NR_IRQS) { #ifdef CONFIG_ARCH_MINIMAL_VECTORTABLE - ndx = g_irqmap[irq]; if (ndx < CONFIG_ARCH_NUSER_INTERRUPTS) { if (g_irqvector[ndx].handler)