This is an automated email from the ASF dual-hosted git repository. GUIDINGLI pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit d81ef1753fe3cff1662952d6383acf302533ae88 Author: zhangyu117 <[email protected]> AuthorDate: Mon Apr 13 20:20:43 2026 +0800 arch/tricore: use ICR.CCPN instead of ICR.IE for interrupt masking Replace global interrupt disable (ICR.IE) with ICR.CCPN threshold masking when CONFIG_ARCH_HIPRI_INTERRUPT is enabled, similar to ARM BASEPRI. High-priority interrupts above the threshold remain unmasked. This prepares for the later CONFIG_ARCH_HIPRI_INTERRUPT support. Signed-off-by: zhangyu117 <[email protected]> --- arch/tricore/Kconfig | 13 +++++++++ arch/tricore/include/irq.h | 50 +++++++++++++++++++++++++++++++++-- arch/tricore/src/common/tricore_irq.c | 6 +++++ 3 files changed, 67 insertions(+), 2 deletions(-) diff --git a/arch/tricore/Kconfig b/arch/tricore/Kconfig index 829820b69c9..db70cfbd8b2 100644 --- a/arch/tricore/Kconfig +++ b/arch/tricore/Kconfig @@ -26,6 +26,8 @@ config ARCH_TC1V6 bool select ARCH_HAVE_DEBUG select ARCH_HAVE_MPU + select ARCH_HAVE_HIPRI_INTERRUPT + select ARCH_HAVE_IRQPRIO select ARCH_HAVE_IRQTRIGGER select ARCH_HAVE_PERF_EVENTS select ARCH_HAVE_POWEROFF @@ -41,6 +43,8 @@ config ARCH_TC1V8 select ARCH_HAVE_DEBUG select ARCH_ICACHE select ARCH_HAVE_MPU + select ARCH_HAVE_HIPRI_INTERRUPT + select ARCH_HAVE_IRQPRIO select ARCH_HAVE_IRQTRIGGER select ARCH_HAVE_PERF_EVENTS select ARCH_HAVE_PERF_EVENTS_USER_ACCESS @@ -88,6 +92,15 @@ config ARCH_CHIP default "tc3xx" if ARCH_CHIP_TC3XX default "tc4xx" if ARCH_CHIP_TC4XX +config ARCH_IRQ_DISABLE_PRIORITY + int "IRQ disable priority threshold" + default 250 + range 1 255 + depends on ARCH_HIPRI_INTERRUPT + ---help--- + Interrupts with SRPN > this value are treated as + high-priority and will not be masked. + config ARCH_DCACHE_ADDR hex "AURIX Dcache base address" default 0x7003C000 diff --git a/arch/tricore/include/irq.h b/arch/tricore/include/irq.h index 16e0b058041..80dfac216ce 100644 --- a/arch/tricore/include/irq.h +++ b/arch/tricore/include/irq.h @@ -140,6 +140,10 @@ TRICORE_SRC2IRQ(TRICORE_SRC_GPSR_BASE + \ ((src_cpu) * TRICORE_SRCNUM_PER_GPSR + (dest_cpu)) * 4) +#ifdef CONFIG_ARCH_HIPRI_INTERRUPT + #define TRICORE_IRQ_DISABLE_PRIORITY CONFIG_ARCH_IRQ_DISABLE_PRIORITY +#endif + /* For use with EABI and floating point, the stack must be aligned to 8-byte * addresses. */ @@ -243,30 +247,72 @@ noinstrument_function static inline_function uintptr_t up_getsp(void) * Name: up_irq_save * * Description: - * Disable interrupts and return the previous value of the mstatus register + * Disable interrupts and return the previous interrupt state. + * + * When CONFIG_ARCH_HIPRI_INTERRUPT is enabled, this raises ICR.CCPN + * to TRICORE_IRQ_DISABLE_PRIORITY so that high-priority interrupts + * (SRPN > TRICORE_IRQ_DISABLE_PRIORITY) remain unmasked. up_irq_save + * only raises CCPN, up_irq_restore only lowers it. This prevents the + * masking level from being accidentally lowered. + * + * Otherwise, uses the hardware disable instruction (ICR.IE = 0) + * for minimal overhead. * ****************************************************************************/ noinstrument_function static inline_function irqstate_t up_irq_save(void) { +#ifdef CONFIG_ARCH_HIPRI_INTERRUPT + irqstate_t icr; + irqstate_t ccpn; + + icr = tricore_mfcr(TRICORE_CPU_ICR); + ccpn = icr & TRICORE_ICR_CCPN_MASK; + + if (TRICORE_IRQ_DISABLE_PRIORITY > ccpn) + { + icr = (icr & ~TRICORE_ICR_CCPN_MASK) | + TRICORE_IRQ_DISABLE_PRIORITY; + tricore_mtcr(TRICORE_CPU_ICR, icr); + UP_ISB(); + } + + return ccpn; +#else irqstate_t flags; __asm__ volatile ("disable %0" : "=d"(flags) : : "memory"); return flags; +#endif } /**************************************************************************** * Name: up_irq_restore * * Description: - * Restore the value of the mstatus register + * Restore the previous interrupt state saved by up_irq_save(). + * + * When CONFIG_ARCH_HIPRI_INTERRUPT is enabled, restores ICR.CCPN. + * Otherwise, restores ICR.IE via the hardware restore instruction. * ****************************************************************************/ noinstrument_function static inline_function void up_irq_restore(irqstate_t flags) { +#ifdef CONFIG_ARCH_HIPRI_INTERRUPT + irqstate_t icr; + + icr = tricore_mfcr(TRICORE_CPU_ICR); + if (flags < (icr & TRICORE_ICR_CCPN_MASK)) + { + icr = (icr & ~TRICORE_ICR_CCPN_MASK) | flags; + tricore_mtcr(TRICORE_CPU_ICR, icr); + UP_ISB(); + } +#else __asm__ volatile ("restore %0" : : "d"(flags) : "memory"); +#endif } /**************************************************************************** diff --git a/arch/tricore/src/common/tricore_irq.c b/arch/tricore/src/common/tricore_irq.c index df5c919b570..7902a1c742e 100644 --- a/arch/tricore/src/common/tricore_irq.c +++ b/arch/tricore/src/common/tricore_irq.c @@ -148,6 +148,12 @@ static void tricore_gpsrinitialize(void) void up_irq_enable(void) { +#ifdef CONFIG_ARCH_HIPRI_INTERRUPT + tricore_mtcr(TRICORE_CPU_ICR, + tricore_mfcr(TRICORE_CPU_ICR) & ~TRICORE_ICR_CCPN_MASK); + UP_ISB(); +#endif + __asm__ volatile ("enable" : : : "memory"); }
