arch/tricore: support minimal vectortalbe in tricore

The SRN number in TriCore far exceeds the PN number.
Using IRQ as the PN number would result in an overflow.
Therefore, MINIMAL_VECTORTABLE is used to ensure that
the PN number does not overflow.

Signed-off-by: zhangyuan29 <zhangyuan29@xiaomi.com>
This commit is contained in:
zhangyuan29
2024-12-09 16:54:20 +08:00
committed by Xiang Xiao
parent f40dfc7234
commit f44060ca9f
9 changed files with 76 additions and 81 deletions
+2
View File
@@ -26,6 +26,8 @@ config ARCH_TC3XX
bool bool
select ARCH_HAVE_TESTSET select ARCH_HAVE_TESTSET
select ARCH_HAVE_IRQTRIGGER select ARCH_HAVE_IRQTRIGGER
select ARCH_MINIMAL_VECTORTABLE
select ARCH_MINIMAL_VECTORTABLE_DYNAMIC
default n default n
config ARCH_FAMILY config ARCH_FAMILY
+4 -1
View File
@@ -88,7 +88,7 @@
#define XCPTCONTEXT_REGS (TC_CONTEXT_REGS * 2) #define XCPTCONTEXT_REGS (TC_CONTEXT_REGS * 2)
#define XCPTCONTEXT_SIZE (sizeof(void *) * XCPTCONTEXT_REGS) #define XCPTCONTEXT_SIZE (sizeof(void *) * XCPTCONTEXT_REGS)
#define NR_IRQS (255) #define NR_IRQS (2048)
/* PSW: Program Status Word Register */ /* PSW: Program Status Word Register */
@@ -112,6 +112,9 @@
#define FCX_FCXS_MASK (0xf << FCX_FCXS) #define FCX_FCXS_MASK (0xf << FCX_FCXS)
#define FCX_FREE (FCX_FCXS_MASK | FCX_FCXO_MASK) /* Free CSA manipulation */ #define FCX_FREE (FCX_FCXS_MASK | FCX_FCXO_MASK) /* Free CSA manipulation */
#define TRICORE_SRC2IRQ(src_addr) \
(((uintptr_t)(src_addr) - (uintptr_t)&MODULE_SRC) / 4)
/**************************************************************************** /****************************************************************************
* Public Types * Public Types
****************************************************************************/ ****************************************************************************/
+1 -1
View File
@@ -75,7 +75,7 @@ IFX_INTERRUPT_INTERNAL(tricore_doirq, 0, 255)
/* Deliver the IRQ */ /* Deliver the IRQ */
irq_dispatch(icr.B.CCPN, regs); irq_dispatch(NDX_TO_IRQ(icr.B.CCPN), regs);
/* Check for a context switch. */ /* Check for a context switch. */
+6 -21
View File
@@ -122,30 +122,15 @@ void up_enable_irq(int irq)
{ {
volatile Ifx_SRC_SRCR *src = &SRC_CPU_CPU0_SB + irq; volatile Ifx_SRC_SRCR *src = &SRC_CPU_CPU0_SB + irq;
IfxSrc_init(src, IfxSrc_Tos_cpu0, irq); #ifdef CONFIG_ARCH_TC3XX
IfxSrc_init(src, IfxSrc_Tos_cpu0, IRQ_TO_NDX(irq));
#else
IfxSrc_init(src, IfxSrc_Tos_cpu0, IRQ_TO_NDX(irq), IfxSrc_VmId_none);
#endif
IfxSrc_enable(src); IfxSrc_enable(src);
} }
#ifdef CONFIG_ARCH_HAVE_IRQTRIGGER
/****************************************************************************
* Name: up_trigger_irq
*
* Description:
* Trigger an IRQ by software.
*
****************************************************************************/
void up_trigger_irq(int irq, cpu_set_t cpuset)
{
(void) cpuset;
volatile Ifx_SRC_SRCR *src = &SRC_CPU_CPU0_SB + irq;
IfxSrc_setRequest(src);
}
#endif
/**************************************************************************** /****************************************************************************
* Name: up_affinity_irq * Name: up_affinity_irq
* *
+3 -1
View File
@@ -51,7 +51,9 @@ void up_timer_initialize(void)
{ {
struct oneshot_lowerhalf_s *lower; struct oneshot_lowerhalf_s *lower;
lower = tricore_systimer_initialize(&MODULE_STM0, 192, SCU_FREQUENCY); lower = tricore_systimer_initialize(&MODULE_STM0,
TRICORE_SRC2IRQ(&SRC_STM0SR0),
SCU_FREQUENCY);
DEBUGASSERT(lower != NULL); DEBUGASSERT(lower != NULL);
@@ -12,6 +12,7 @@ CONFIG_ARCH_BOARD_A2G_TC397_5V_TFT=y
CONFIG_ARCH_CHIP="tc397" CONFIG_ARCH_CHIP="tc397"
CONFIG_ARCH_CHIP_TC397=y CONFIG_ARCH_CHIP_TC397=y
CONFIG_ARCH_INTERRUPTSTACK=2048 CONFIG_ARCH_INTERRUPTSTACK=2048
CONFIG_ARCH_NUSER_INTERRUPTS=48
CONFIG_ARCH_STACKDUMP=y CONFIG_ARCH_STACKDUMP=y
CONFIG_ARCH_TRICORE=y CONFIG_ARCH_TRICORE=y
CONFIG_BOARD_LOOPSPERMSEC=99369 CONFIG_BOARD_LOOPSPERMSEC=99369
+24 -6
View File
@@ -42,7 +42,6 @@
* Pre-processor Definitions * Pre-processor Definitions
****************************************************************************/ ****************************************************************************/
#ifndef __ASSEMBLY__
/* IRQ detach is a convenience definition, it detach all the handlers /* IRQ detach is a convenience definition, it detach all the handlers
* sharing the same IRQ. Detaching an interrupt handler is equivalent to * sharing the same IRQ. Detaching an interrupt handler is equivalent to
* setting a NULL interrupt handler. * setting a NULL interrupt handler.
@@ -50,8 +49,7 @@
#define irq_detach(irq) irq_attach(irq, NULL, NULL) #define irq_detach(irq) irq_attach(irq, NULL, NULL)
#define irq_detach_wqueue(irq) irq_attach_wqueue(irq, NULL, NULL, NULL, 0) #define irq_detach_wqueue(irq) irq_attach_wqueue(irq, NULL, NULL, NULL, 0)
# define irq_detach_thread(irq) \ #define irq_detach_thread(irq) irq_attach_thread(irq, NULL, NULL, NULL, 0, 0)
irq_attach_thread(irq, NULL, NULL, NULL, 0, 0)
/* Maximum/minimum values of IRQ integer types */ /* Maximum/minimum values of IRQ integer types */
@@ -73,7 +71,22 @@
# endif # endif
#endif #endif
#endif /* __ASSEMBLY__ */ #if defined(CONFIG_ARCH_MINIMAL_VECTORTABLE) && \
!defined(CONFIG_ARCH_NUSER_INTERRUPTS)
# error CONFIG_ARCH_NUSER_INTERRUPTS is not defined
#endif
#if defined(CONFIG_ARCH_MINIMAL_VECTORTABLE_DYNAMIC)
# define IRQ_TO_NDX(irq) (g_irqmap[irq] ? g_irqmap[irq] : irq_to_ndx(irq))
# define NDX_TO_IRQ(ndx) g_irqrevmap[ndx]
#elif defined(CONFIG_ARCH_MINIMAL_VECTORTABLE)
# define IRQ_TO_NDX(irq) \
(g_irqmap[(irq)] < CONFIG_ARCH_NUSER_INTERRUPTS ? g_irqmap[(irq)] : -EINVAL)
# define NDX_TO_IRQ(ndx) ndx_to_irq(ndx)
#else
# define IRQ_TO_NDX(irq) (irq)
# define NDX_TO_IRQ(ndx) (ndx)
#endif
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
# define cpu_irqlock_clear() \ # define cpu_irqlock_clear() \
@@ -168,7 +181,6 @@ extern "C"
#define EXTERN extern #define EXTERN extern
#endif #endif
#ifdef CONFIG_ARCH_MINIMAL_VECTORTABLE
/* This is the interrupt vector mapping table. This must be provided by /* This is the interrupt vector mapping table. This must be provided by
* architecture specific logic if CONFIG_ARCH_MINIMAL_VECTORTABLE is define * architecture specific logic if CONFIG_ARCH_MINIMAL_VECTORTABLE is define
* in the configuration. * in the configuration.
@@ -179,7 +191,13 @@ extern "C"
* here with NR_IRQS undefined. * here with NR_IRQS undefined.
*/ */
/* EXTERN const irq_mapped_t g_irqmap[NR_IRQS]; */ #if defined(CONFIG_ARCH_MINIMAL_VECTORTABLE_DYNAMIC)
extern irq_mapped_t g_irqmap[];
extern int g_irqrevmap[];
int irq_to_ndx(int irq);
#elif defined(CONFIG_ARCH_MINIMAL_VECTORTABLE)
extern const irq_mapped_t g_irqmap[];
int ndx_to_irq(int ndx);
#endif #endif
/**************************************************************************** /****************************************************************************
-34
View File
@@ -37,24 +37,6 @@
#include <nuttx/irq.h> #include <nuttx/irq.h>
#include <nuttx/spinlock.h> #include <nuttx/spinlock.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#if defined(CONFIG_ARCH_MINIMAL_VECTORTABLE) && \
!defined(CONFIG_ARCH_NUSER_INTERRUPTS)
# error CONFIG_ARCH_NUSER_INTERRUPTS is not defined
#endif
#if defined(CONFIG_ARCH_MINIMAL_VECTORTABLE_DYNAMIC)
# define IRQ_TO_NDX(irq) (g_irqmap[irq] ? g_irqmap[irq] : irq_to_ndx(irq))
#elif defined(CONFIG_ARCH_MINIMAL_VECTORTABLE)
# define IRQ_TO_NDX(irq) \
(g_irqmap[(irq)] < CONFIG_ARCH_NUSER_INTERRUPTS ? g_irqmap[(irq)] : -EINVAL)
#else
# define IRQ_TO_NDX(irq) (irq)
#endif
/**************************************************************************** /****************************************************************************
* Public Types * Public Types
****************************************************************************/ ****************************************************************************/
@@ -98,22 +80,6 @@ extern struct irq_info_s g_irqvector[CONFIG_ARCH_NUSER_INTERRUPTS];
extern struct irq_info_s g_irqvector[NR_IRQS]; extern struct irq_info_s g_irqvector[NR_IRQS];
#endif #endif
/* This is the interrupt vector mapping table. This must be provided by
* architecture specific logic if CONFIG_ARCH_MINIMAL_VECTORTABLE is define
* in the configuration.
*
* REVISIT: This should be declared in include/nuttx/irq.h. The declaration
* at that location, however, introduces a circular include dependency so the
* declaration is here for the time being.
*/
#if defined(CONFIG_ARCH_MINIMAL_VECTORTABLE_DYNAMIC)
extern irq_mapped_t g_irqmap[NR_IRQS];
int irq_to_ndx(int irq);
#elif defined(CONFIG_ARCH_MINIMAL_VECTORTABLE)
extern const irq_mapped_t g_irqmap[NR_IRQS];
#endif
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
/* This is the spinlock that enforces critical sections when interrupts are /* This is the spinlock that enforces critical sections when interrupts are
* disabled. * disabled.
+19 -1
View File
@@ -57,6 +57,7 @@ static int g_irqmap_count = 1;
*/ */
irq_mapped_t g_irqmap[NR_IRQS]; irq_mapped_t g_irqmap[NR_IRQS];
int g_irqrevmap[CONFIG_ARCH_NUSER_INTERRUPTS];
#endif #endif
/**************************************************************************** /****************************************************************************
@@ -71,12 +72,29 @@ int irq_to_ndx(int irq)
irqstate_t flags = spin_lock_irqsave(&g_irqlock); irqstate_t flags = spin_lock_irqsave(&g_irqlock);
if (g_irqmap[irq] == 0) if (g_irqmap[irq] == 0)
{ {
g_irqmap[irq] = g_irqmap_count++; int ndx = g_irqmap_count++;
g_irqmap[irq] = ndx;
g_irqrevmap[ndx] = irq;
} }
spin_unlock_irqrestore(&g_irqlock, flags); spin_unlock_irqrestore(&g_irqlock, flags);
return g_irqmap[irq]; return g_irqmap[irq];
} }
#elif defined(CONFIG_ARCH_MINIMAL_VECTORTABLE)
int ndx_to_irq(int ndx)
{
int i;
for (i = 0; i < NR_IRQS; i++)
{
if (g_irqmap[i] == ndx)
{
return i;
}
}
return -EINVAL;
}
#endif #endif
/**************************************************************************** /****************************************************************************