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");
 }
 

Reply via email to