mirror of
https://github.com/apache/nuttx.git
synced 2026-06-04 14:53:47 +08:00
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:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|||||||
@@ -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. */
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
+40
-22
@@ -42,38 +42,51 @@
|
|||||||
* 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.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
# 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 */
|
||||||
|
|
||||||
# if NR_IRQS <= 256
|
#if NR_IRQS <= 256
|
||||||
# define IRQT_MAX UINT8_MAX
|
# define IRQT_MAX UINT8_MAX
|
||||||
# elif NR_IRQS <= 65536
|
#elif NR_IRQS <= 65536
|
||||||
# define IRQT_MAX UINT16_MAX
|
# define IRQT_MAX UINT16_MAX
|
||||||
|
#else
|
||||||
|
# define IRQT_MAX UINT32_MAX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARCH_MINIMAL_VECTORTABLE
|
||||||
|
# if CONFIG_ARCH_NUSER_INTERRUPTS <= 256
|
||||||
|
# define IRQMAPPED_MAX UINT8_MAX
|
||||||
|
# elif CONFIG_ARCH_NUSER_INTERRUPTS <= 65536
|
||||||
|
# define IRQMAPPED_MAX UINT16_MAX
|
||||||
# else
|
# else
|
||||||
# define IRQT_MAX UINT32_MAX
|
# define IRQMAPPED_MAX UINT32_MAX
|
||||||
# endif
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
# ifdef CONFIG_ARCH_MINIMAL_VECTORTABLE
|
#if defined(CONFIG_ARCH_MINIMAL_VECTORTABLE) && \
|
||||||
# if CONFIG_ARCH_NUSER_INTERRUPTS <= 256
|
!defined(CONFIG_ARCH_NUSER_INTERRUPTS)
|
||||||
# define IRQMAPPED_MAX UINT8_MAX
|
# error CONFIG_ARCH_NUSER_INTERRUPTS is not defined
|
||||||
# elif CONFIG_ARCH_NUSER_INTERRUPTS <= 65536
|
#endif
|
||||||
# define IRQMAPPED_MAX UINT16_MAX
|
|
||||||
# else
|
|
||||||
# define IRQMAPPED_MAX UINT32_MAX
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
#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
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|||||||
Reference in New Issue
Block a user