This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 886718ade1 xtensa: support more than 32 cpu interrupts
886718ade1 is described below

commit 886718ade15c43d479ca5f9cdaa713826b473308
Author: chenxiaoyi <chenxia...@xiaomi.com>
AuthorDate: Tue Jun 24 16:25:49 2025 +0800

    xtensa: support more than 32 cpu interrupts
    
    The architecture defines maximum of 128 interrupts, whereas previous
    code only supported 32 interrupts.  For every 32 interrupts added,
    there are three additional registers: INTERRUPT, INTCLEAR, and INTENABLE.
    This patch adds support for handling these registers.
    
    Signed-off-by: chenxiaoyi <chenxia...@xiaomi.com>
---
 arch/xtensa/include/irq.h                    |  73 +++++++++--
 arch/xtensa/src/common/CMakeLists.txt        |   2 +-
 arch/xtensa/src/common/Make.defs             |   4 +-
 arch/xtensa/src/common/xtensa.h              |   6 +-
 arch/xtensa/src/common/xtensa_cpuint.S       | 128 -------------------
 arch/xtensa/src/common/xtensa_cpuint.c       | 183 +++++++++++++++++++++++++++
 arch/xtensa/src/common/xtensa_int_handlers.S | 120 ++++++++++++++++--
 arch/xtensa/src/esp32/esp32_irq.c            |  48 ++++---
 arch/xtensa/src/esp32s2/esp32s2_irq.c        |  20 +--
 arch/xtensa/src/esp32s3/esp32s3_irq.c        |  42 ++++--
 10 files changed, 436 insertions(+), 190 deletions(-)

diff --git a/arch/xtensa/include/irq.h b/arch/xtensa/include/irq.h
index f62ae25078..9bff4d0bd1 100644
--- a/arch/xtensa/include/irq.h
+++ b/arch/xtensa/include/irq.h
@@ -331,7 +331,16 @@ static inline_function void xtensa_disable_all(void)
   __asm__ __volatile__
   (
     "movi a2, 0\n"
-    "xsr a2, INTENABLE\n"
+    "wsr a2, INTENABLE\n"
+#if XCHAL_NUM_INTERRUPTS > 32
+    "wsr a2, INTENABLE1\n"
+#endif
+#if XCHAL_NUM_INTERRUPTS > 64
+    "wsr a2, INTENABLE2\n"
+#endif
+#if XCHAL_NUM_INTERRUPTS > 96
+    "wsr a2, INTENABLE3\n"
+#endif
     "rsync\n"
     : : : "a2"
   );
@@ -341,16 +350,60 @@ static inline_function void xtensa_disable_all(void)
  * Name: xtensa_intclear
  ****************************************************************************/
 
-static inline_function void xtensa_intclear(uint32_t mask)
+static inline_function void xtensa_intclear(uint32_t intnum)
 {
-  __asm__ __volatile__
-  (
-    "wsr %0, INTCLEAR\n"
-    "rsync\n"
-    :
-    : "r"(mask)
-    :
-  );
+  DEBUGASSERT(intnum < XCHAL_NUM_INTERRUPTS);
+
+  if (intnum < 32)
+    {
+      __asm__ __volatile__
+      (
+        "wsr %0, INTCLEAR\n"
+        "rsync\n"
+        :
+        : "r"(1 << intnum)
+        :
+      );
+    }
+#if XCHAL_NUM_INTERRUPTS > 32
+  else if (intnum < 64)
+    {
+      __asm__ __volatile__
+      (
+        "wsr %0, INTCLEAR1\n"
+        "rsync\n"
+        :
+        : "r"(1 << (intnum - 32))
+        :
+      );
+    }
+#endif
+#if XCHAL_NUM_INTERRUPTS > 64
+  else if (intnum < 96)
+    {
+      __asm__ __volatile__
+      (
+        "wsr %0, INTCLEAR2\n"
+        "rsync\n"
+        :
+        : "r"(1 << (intnum - 64))
+        :
+      );
+    }
+#endif
+#if XCHAL_NUM_INTERRUPTS > 96
+  else if (intnum < 128)
+    {
+      __asm__ __volatile__
+      (
+        "wsr %0, INTCLEAR3\n"
+        "rsync\n"
+        :
+        : "r"(1 << (intnum - 96))
+        :
+      );
+    }
+#endif
 }
 
 #ifdef __cplusplus
diff --git a/arch/xtensa/src/common/CMakeLists.txt 
b/arch/xtensa/src/common/CMakeLists.txt
index a3c89b037c..6ff581120e 100644
--- a/arch/xtensa/src/common/CMakeLists.txt
+++ b/arch/xtensa/src/common/CMakeLists.txt
@@ -47,7 +47,7 @@ list(
   APPEND
   SRCS
   xtensa_context.S
-  xtensa_cpuint.S
+  xtensa_cpuint.c
   xtensa_panic.S
   xtensa_assert.c
   xtensa_cache.c
diff --git a/arch/xtensa/src/common/Make.defs b/arch/xtensa/src/common/Make.defs
index 3d5a58bcac..d0ba9e289f 100644
--- a/arch/xtensa/src/common/Make.defs
+++ b/arch/xtensa/src/common/Make.defs
@@ -29,10 +29,10 @@ HEAD_ASRC += xtensa_int_handlers.S xtensa_user_handler.S
 
 # Common Xtensa files (arch/xtensa/src/common)
 
-CMN_ASRCS  = xtensa_context.S xtensa_cpuint.S xtensa_panic.S
+CMN_ASRCS  = xtensa_context.S xtensa_panic.S
 
 CMN_CSRCS  = xtensa_assert.c xtensa_cache.c xtensa_cpenable.c
-CMN_CSRCS += xtensa_cpuinfo.c xtensa_createstack.c xtensa_exit.c
+CMN_CSRCS += xtensa_cpuinfo.c xtensa_cpuint.c xtensa_createstack.c 
xtensa_exit.c
 CMN_CSRCS += xtensa_getintstack.c xtensa_initialize.c xtensa_initialstate.c
 CMN_CSRCS += xtensa_irqdispatch.c xtensa_lowputs.c xtensa_mdelay.c
 CMN_CSRCS += xtensa_modifyreg8.c xtensa_modifyreg16.c xtensa_modifyreg32.c
diff --git a/arch/xtensa/src/common/xtensa.h b/arch/xtensa/src/common/xtensa.h
index 13deae4603..2a4c1eb95b 100644
--- a/arch/xtensa/src/common/xtensa.h
+++ b/arch/xtensa/src/common/xtensa.h
@@ -236,10 +236,10 @@ void xtensa_window_spill(void);
 
 /* IRQs */
 
-uint32_t *xtensa_int_decode(uint32_t cpuints, uint32_t *regs);
+uint32_t *xtensa_int_decode(uint32_t *cpuints, uint32_t *regs);
 uint32_t *xtensa_irq_dispatch(int irq, uint32_t *regs);
-uint32_t xtensa_enable_cpuint(uint32_t *shadow, uint32_t intmask);
-uint32_t xtensa_disable_cpuint(uint32_t *shadow, uint32_t intmask);
+void xtensa_enable_cpuint(uint32_t *shadow, uint32_t intnum);
+void xtensa_disable_cpuint(uint32_t *shadow, uint32_t intnum);
 void xtensa_panic(int xptcode, uint32_t *regs) noreturn_function;
 void xtensa_user_panic(int exccause, uint32_t *regs) noreturn_function;
 uint32_t *xtensa_user(int exccause, uint32_t *regs);
diff --git a/arch/xtensa/src/common/xtensa_cpuint.S 
b/arch/xtensa/src/common/xtensa_cpuint.S
deleted file mode 100644
index d60cbfb2bc..0000000000
--- a/arch/xtensa/src/common/xtensa_cpuint.S
+++ /dev/null
@@ -1,128 +0,0 @@
-/****************************************************************************
- * arch/xtensa/src/common/xtensa_cpuint.S
- *
- * SPDX-License-Identifier: MIT
- * SPDX-FileCopyrightText: 2016 Gregory Nutt. All rights reserved.
- * SPDX-FileCopyrightText: 2006-2015 Cadence Design Systems Inc.
- * SPDX-FileContributor: Gregory Nutt <gn...@nuttx.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- ****************************************************************************/
-
-       .file   "xtensa_cpuint.S"
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-#include <arch/chip/core-isa.h>
-
-#include <arch/xtensa/xtensa_abi.h>
-
-#if XCHAL_HAVE_INTERRUPTS
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: xtensa_enable_cpuint
- *
- * C Prototype:
- *   uint32_t xtensa_enable_cpuint(uint32_t *shadow, unsigned int intmask)
- *
- * Description:
- *   Enables a set of interrupts. Does not simply set INTENABLE directly,
- *   but operates on a shadow copy of the CPU INTENABLE register then
- *   writes that value to the hardware INTENABLE register.  Can be called
- *   from interrupt handlers.
- *
- *   NOTE: It is possible only to enable interrupts on the current CPU
- *   because there is an INTENABLE register implemented in each CPU.
- *
- ****************************************************************************/
-
-       .text
-       .global xtensa_enable_cpuint
-       .type   xtensa_enable_cpuint, @function
-       .align  4
-
-xtensa_enable_cpuint:
-       ENTRY(16)
-
-       movi    a4, 0
-       xsr             a4, INTENABLE           /* Disables all interrupts */
-       rsync
-
-       l32i    a4, a2, 0                         /* a4 = value of INTENABLE 
shadow */
-       or              a5, a4, a3                      /* a5 = shadow | mask */
-       s32i    a5, a2, 0                         /* shadow |= mask */
-
-       wsr             a5, INTENABLE           /* Set CPU INTENABLE to shadow 
*/
-       rsync
-       mov             a3, a4                          /* Return previous 
shadow content */
-       RET(16)
-
-       .size   xtensa_enable_cpuint, . - xtensa_enable_cpuint
-
-/****************************************************************************
- * Name: xtensa_disable_cpuint
- *
- * C Prototype:
- *   uint32_t xtensa_disable_cpuint(uint32_t *shadow, unsigned int intmask)
- *
- * Description:
- *   Disables a set of interrupts. Does not simply set INTENABLE directly,
- *   but operates on a shadow copy of the CPU INTENABLE register then
- *   writes that value to the hardware INTENABLE register.  Can be called
- *   from interrupt handlers.
- *
- *   NOTE: It is possible only to disable interrupts on the current CPU
- *   because there is an INTENABLE register implemented in each CPU.
- *
- ****************************************************************************/
-
-       .text
-       .global xtensa_disable_cpuint
-       .type   xtensa_disable_cpuint, @function
-       .align  4
-
-xtensa_disable_cpuint:
-       ENTRY(16)
-
-       movi    a4, 0
-       xsr             a4, INTENABLE           /* Disables all interrupts */
-       rsync
-
-       l32i    a4, a2, 0                         /* a4 = value of INTENABLE 
shadow */
-       or              a5, a4, a3                      /* a5 = shadow | mask */
-       xor             a5, a5, a3                      /* a5 = shadow & ~mask 
*/
-       s32i    a5, a2, 0                         /* shadow &= ~mask */
-
-       wsr             a5, INTENABLE           /* Set CPU INTENABLE to shadow 
*/
-       rsync
-       mov             a3, a4                            /* Return previous 
shadow content */
-       RET(16)
-
-       .size   xtensa_disable_cpuint, . - xtensa_disable_cpuint
-
-#endif /* XCHAL_HAVE_INTERRUPTS */
diff --git a/arch/xtensa/src/common/xtensa_cpuint.c 
b/arch/xtensa/src/common/xtensa_cpuint.c
new file mode 100644
index 0000000000..2bfd98eda1
--- /dev/null
+++ b/arch/xtensa/src/common/xtensa_cpuint.c
@@ -0,0 +1,183 @@
+/****************************************************************************
+ * arch/xtensa/src/common/xtensa_cpuint.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <assert.h>
+#include <sys/types.h>
+
+#include <arch/chip/core-isa.h>
+#include <arch/xtensa/xtensa_specregs.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: xtensa_enable_cpuint
+ *
+ * Description:
+ *   Enables an interrupts. Does not simply set INTENABLE directly,
+ *   but operates on a shadow copy of the CPU INTENABLE register then
+ *   writes that value to the hardware INTENABLE register.  Can be called
+ *   from interrupt handlers.
+ *
+ *   NOTE: It is possible only to enable interrupts on the current CPU
+ *   because there is an INTENABLE register implemented in each CPU.
+ *
+ ****************************************************************************/
+
+void xtensa_enable_cpuint(uint32_t *shadow, uint32_t intnum)
+{
+  DEBUGASSERT(intnum < XCHAL_NUM_INTERRUPTS);
+
+  if (intnum < 32)
+    {
+      shadow[0] |= (1 << intnum);
+      __asm__ __volatile__
+      (
+        "wsr %0, INTENABLE\n"
+        "rsync\n"
+        :
+        : "r"(shadow[0])
+        :
+      );
+    }
+#if XCHAL_NUM_INTERRUPTS > 32
+  else if (intnum < 64)
+    {
+      shadow[1] |= (1 << (intnum - 32));
+      __asm__ __volatile__
+      (
+        "wsr %0, INTENABLE1\n"
+        "rsync\n"
+        :
+        : "r"(shadow[1])
+        :
+      );
+    }
+#endif
+#if XCHAL_NUM_INTERRUPTS > 64
+  else if (intnum < 96)
+    {
+      shadow[2] |= (1 << (intnum - 64));
+      __asm__ __volatile__
+      (
+        "wsr %0, INTENABLE2\n"
+        "rsync\n"
+        :
+        : "r"(shadow[2])
+        :
+      );
+    }
+#endif
+#if XCHAL_NUM_INTERRUPTS > 96
+  else if (intnum < 128)
+    {
+      shadow[3] |= (1 << (intnum - 96));
+      __asm__ __volatile__
+      (
+        "wsr %0, INTENABLE3\n"
+        "rsync\n"
+        :
+        : "r"(shadow[3])
+        :
+      );
+    }
+#endif
+}
+
+/****************************************************************************
+ * Name: xtensa_disable_cpuint
+ *
+ * Description:
+ *   Disables an interrupts. Does not simply clear INTENABLE directly,
+ *   but operates on a shadow copy of the CPU INTENABLE register then
+ *   writes that value to the hardware INTENABLE register.  Can be called
+ *   from interrupt handlers.
+ *
+ *   NOTE: It is possible only to disable interrupts on the current CPU
+ *   because there is an INTENABLE register implemented in each CPU.
+ *
+ ****************************************************************************/
+
+void xtensa_disable_cpuint(uint32_t *shadow, uint32_t intnum)
+{
+  DEBUGASSERT(intnum < XCHAL_NUM_INTERRUPTS);
+
+  if (intnum < 32)
+    {
+      shadow[0] &= ~(1 << intnum);
+      __asm__ __volatile__
+      (
+        "wsr %0, INTENABLE\n"
+        "rsync\n"
+        :
+        : "r"(shadow[0])
+        :
+      );
+    }
+#if XCHAL_NUM_INTERRUPTS > 32
+  else if (intnum < 64)
+    {
+      shadow[1] &= ~(1 << (intnum - 32));
+      __asm__ __volatile__
+      (
+        "wsr %0, INTENABLE1\n"
+        "rsync\n"
+        :
+        : "r"(shadow[1])
+        :
+      );
+    }
+#endif
+#if XCHAL_NUM_INTERRUPTS > 64
+  else if (intnum < 96)
+    {
+      shadow[2] &= ~(1 << (intnum - 64));
+      __asm__ __volatile__
+      (
+        "wsr %0, INTENABLE2\n"
+        "rsync\n"
+        :
+        : "r"(shadow[2])
+        :
+      );
+    }
+#endif
+#if XCHAL_NUM_INTERRUPTS > 96
+  else if (intnum < 128)
+    {
+      shadow[3] &= ~(1 << (intnum - 96));
+      __asm__ __volatile__
+      (
+        "wsr %0, INTENABLE3\n"
+        "rsync\n"
+        :
+        : "r"(shadow[3])
+        :
+      );
+    }
+#endif
+}
diff --git a/arch/xtensa/src/common/xtensa_int_handlers.S 
b/arch/xtensa/src/common/xtensa_int_handlers.S
index 21c2c86523..3c4073b478 100644
--- a/arch/xtensa/src/common/xtensa_int_handlers.S
+++ b/arch/xtensa/src/common/xtensa_int_handlers.S
@@ -87,6 +87,68 @@ g_intstacktop:
  * Assembly Language Macros
  ****************************************************************************/
 
+       .macro get_int_mask tmp level mask
+
+       .ifeq \mask
+               .ifeq \level - 1
+               movi    \tmp, XCHAL_INTLEVEL1_MASK
+               .elseif (\level - 2) == 0
+               movi    \tmp, XCHAL_INTLEVEL2_MASK
+               .elseif (\level - 3) == 0
+               movi    \tmp, XCHAL_INTLEVEL3_MASK
+               .elseif (\level - 4) == 0
+               movi    \tmp, XCHAL_INTLEVEL4_MASK
+               .elseif (\level - 5) == 0
+               movi    \tmp, XCHAL_INTLEVEL5_MASK
+               .elseif (\level - 6) == 0
+               movi    \tmp, XCHAL_INTLEVEL6_MASK
+               .endif
+       .elseif (\mask - 1) == 0
+               .ifeq \level - 1
+               movi    \tmp, XCHAL_INTLEVEL1_MASK1
+               .elseif (\level - 2) == 0
+               movi    \tmp, XCHAL_INTLEVEL2_MASK1
+               .elseif (\level - 3) == 0
+               movi    \tmp, XCHAL_INTLEVEL3_MASK1
+               .elseif (\level - 4) == 0
+               movi    \tmp, XCHAL_INTLEVEL4_MASK1
+               .elseif (\level - 5) == 0
+               movi    \tmp, XCHAL_INTLEVEL5_MASK1
+               .elseif (\level - 6) == 0
+               movi    \tmp, XCHAL_INTLEVEL6_MASK1
+               .endif
+       .elseif (\mask - 2) == 0
+               .ifeq \level - 1
+               movi    \tmp, XCHAL_INTLEVEL1_MASK2
+               .elseif (\level - 2) == 0
+               movi    \tmp, XCHAL_INTLEVEL2_MASK2
+               .elseif (\level - 3) == 0
+               movi    \tmp, XCHAL_INTLEVEL3_MASK2
+               .elseif (\level - 4) == 0
+               movi    \tmp, XCHAL_INTLEVEL4_MASK2
+               .elseif (\level - 5) == 0
+               movi    \tmp, XCHAL_INTLEVEL5_MASK2
+               .elseif (\level - 6) == 0
+               movi    \tmp, XCHAL_INTLEVEL6_MASK2
+               .endif
+       .elseif (\mask - 3) == 0
+               .ifeq \level - 1
+               movi    \tmp, XCHAL_INTLEVEL1_MASK3
+               .elseif (\level - 2) == 0
+               movi    \tmp, XCHAL_INTLEVEL2_MASK3
+               .elseif (\level - 3) == 0
+               movi    \tmp, XCHAL_INTLEVEL3_MASK3
+               .elseif (\level - 4) == 0
+               movi    \tmp, XCHAL_INTLEVEL4_MASK3
+               .elseif (\level - 5) == 0
+               movi    \tmp, XCHAL_INTLEVEL5_MASK3
+               .elseif (\level - 6) == 0
+               movi    \tmp, XCHAL_INTLEVEL6_MASK3
+               .endif
+       .endif
+
+       .endm
+
 /****************************************************************************
  * Macro dispatch_c_isr level mask tmp
  *
@@ -102,7 +164,6 @@ g_intstacktop:
  *
  * Entry Conditions/Side Effects:
  *   level - interrupt level
- *   mask  - interrupt bitmask for this level
  *   a12   - register save area
  *
  * Exit Conditions:
@@ -111,7 +172,7 @@ g_intstacktop:
  *
  ****************************************************************************/
 
-       .macro  dispatch_c_isr  level mask tmp
+       .macro  dispatch_c_isr  level tmp
 
        /* If the interrupt stack is disabled, reserve xcpcontext to ensure
         * that signal processing can have a separate xcpcontext to handle
@@ -122,6 +183,15 @@ g_intstacktop:
        addi    sp, sp, -XCPTCONTEXT_SIZE
 #endif
 
+       /* Reserve the area to save INTERRUPT[1|2|3] registers:
+        *   [sp + 0]  = INTERRUPT
+        *   [sp + 4]  = INTERRUPT1
+        *   [sp + 8]  = INTERRUPT2
+        *   [sp + 12] = INTERRUPT3
+        */
+
+       addi    sp, sp, -(XCHAL_NUM_INTERRUPTS / 8)
+
        /* Set up PS for C, enable interrupts above this level and clear EXCM. 
*/
 
        ps_setup        \level \tmp
@@ -130,10 +200,37 @@ g_intstacktop:
 
        rsr    ARG1, INTENABLE
        rsr    a3, INTERRUPT
-       movi   a4, \mask
+       get_int_mask a4, \level, 0
        and    ARG1, ARG1, a3
        and    ARG1, ARG1, a4           /* Set of pending, enabled interrupts 
for this level */
+       s32i   ARG1, sp, 0
+
+#if XCHAL_NUM_INTERRUPTS <= 32
        beqz   ARG1, 1f                 /* Nothing to do */
+#else
+       rsr    ARG1, INTENABLE1
+       rsr    a3, INTERRUPT1
+       get_int_mask a4, \level, 1
+       and    ARG1, ARG1, a3
+       and    ARG1, ARG1, a4           /* Set of pending, enabled interrupts 
for this level */
+       s32i   ARG1, sp, 4
+#  if XCHAL_NUM_INTERRUPTS > 64
+       rsr    ARG1, INTENABLE2
+       rsr    a3, INTERRUPT2
+       get_int_mask a4, \level, 2
+       and    ARG1, ARG1, a3
+       and    ARG1, ARG1, a4           /* Set of pending, enabled interrupts 
for this level */
+       s32i   ARG1, sp, 8
+#    if XCHAL_NUM_INTERRUPTS > 96
+       rsr    ARG1, INTENABLE3
+       rsr    a3, INTERRUPT3
+       get_int_mask a4, \level, 3
+       and    ARG1, ARG1, a3
+       and    ARG1, ARG1, a4           /* Set of pending, enabled interrupts 
for this level */
+       s32i   ARG1, sp, 12
+#    endif
+#  endif
+#endif
 
        /* Link the pre-exception frame for debugging. At this point, a12 
points to the
         * allocated and filled exception stack frame (old value of SP in case 
of
@@ -142,6 +239,7 @@ g_intstacktop:
 
        exception_backtrace a12 \level
 
+       mov     ARG1, sp
                                                                    /* Argument 
1: Set of CPU interrupt to dispatch */
        mov     ARG2, a12                                       /* Argument 2: 
Top of stack = register save area */
        CALL    xtensa_int_decode
@@ -164,6 +262,10 @@ g_intstacktop:
 
        mov     a2, a12
 2:
+       /* Release the area saving INTERRUPT[1|2|3] registers. */
+
+       addi    sp, sp, XCHAL_NUM_INTERRUPTS / 8
+
 #if CONFIG_ARCH_INTERRUPTSTACK < 15
        addi    sp, sp, XCPTCONTEXT_SIZE
 #endif
@@ -219,7 +321,7 @@ _xtensa_level1_handler:
         * area in a2.
         */
 
-       dispatch_c_isr  1 XCHAL_INTLEVEL1_MASK a0
+       dispatch_c_isr  1 a0
 
        /* Set PS.EXCM to 1 */
 
@@ -304,7 +406,7 @@ _xtensa_level2_handler:
         * area in a2.
         */
 
-       dispatch_c_isr  2 XCHAL_INTLEVEL2_MASK a0
+       dispatch_c_isr  2 a0
 
        /* Restore registers in preparation to return from interrupt */
 
@@ -357,7 +459,7 @@ _xtensa_level3_handler:
         * area in a2.
         */
 
-       dispatch_c_isr  3 XCHAL_INTLEVEL3_MASK a0
+       dispatch_c_isr  3 a0
 
        /* Restore registers in preparation to return from interrupt */
 
@@ -410,7 +512,7 @@ _xtensa_level4_handler:
         * area in a2.
         */
 
-       dispatch_c_isr  4 XCHAL_INTLEVEL4_MASK a0
+       dispatch_c_isr  4 a0
 
        /* Restore registers in preparation to return from interrupt */
 
@@ -463,7 +565,7 @@ _xtensa_level5_handler:
         * area in a2.
         */
 
-       dispatch_c_isr  5 XCHAL_INTLEVEL5_MASK a0
+       dispatch_c_isr  5 a0
 
        /* Restore registers in preparation to return from interrupt */
 
@@ -516,7 +618,7 @@ _xtensa_level6_handler:
         * area in a2.
         */
 
-       dispatch_c_isr  6 XCHAL_INTLEVEL6_MASK a0
+       dispatch_c_isr  6 a0
 
        /* Restore registers in preparation to return from interrupt */
 
diff --git a/arch/xtensa/src/esp32/esp32_irq.c 
b/arch/xtensa/src/esp32/esp32_irq.c
index 748cecfd26..261bb2b64a 100644
--- a/arch/xtensa/src/esp32/esp32_irq.c
+++ b/arch/xtensa/src/esp32/esp32_irq.c
@@ -362,7 +362,7 @@ static int esp32_getcpuint(int cpu, uint32_t intmask)
 
   if (ret >= 0)
     {
-      xtensa_enable_cpuint(&g_intenable[cpu], 1ul << ret);
+      xtensa_enable_cpuint(&g_intenable[cpu], ret);
     }
 
   return ret;
@@ -538,16 +538,16 @@ void up_irqinitialize(void)
 
 #ifdef CONFIG_ESPRESSIF_WIFI
   g_cpu0_intmap[ESP32_CPUINT_MAC] = CPUINT_ASSIGN(ESP32_IRQ_MAC);
-  xtensa_enable_cpuint(&g_intenable[0], 1 << ESP32_CPUINT_MAC);
+  xtensa_enable_cpuint(&g_intenable[0], ESP32_CPUINT_MAC);
 #endif
 
 #ifdef CONFIG_ESPRESSIF_BLE
   g_cpu0_intmap[ESP32_PERIPH_BT_BB_NMI] = CPUINT_ASSIGN(ESP32_IRQ_BT_BB_NMI);
   g_cpu0_intmap[ESP32_PERIPH_RWBT_NMI]  = CPUINT_ASSIGN(ESP32_IRQ_RWBT_NMI);
   g_cpu0_intmap[ESP32_PERIPH_RWBLE_IRQ] = CPUINT_ASSIGN(ESP32_IRQ_RWBLE_IRQ);
-  xtensa_enable_cpuint(&g_intenable[0], 1 << ESP32_PERIPH_BT_BB_NMI);
-  xtensa_enable_cpuint(&g_intenable[0], 1 << ESP32_PERIPH_RWBT_NMI);
-  xtensa_enable_cpuint(&g_intenable[0], 1 << ESP32_PERIPH_RWBLE_IRQ);
+  xtensa_enable_cpuint(&g_intenable[0], ESP32_PERIPH_BT_BB_NMI);
+  xtensa_enable_cpuint(&g_intenable[0], ESP32_PERIPH_RWBT_NMI);
+  xtensa_enable_cpuint(&g_intenable[0], ESP32_PERIPH_RWBLE_IRQ);
 #endif
 
   /* Attach and enable internal interrupts */
@@ -620,7 +620,7 @@ void up_disable_irq(int irq)
         }
 #endif
 
-      xtensa_disable_cpuint(&g_intenable[cpu], 1ul << cpuint);
+      xtensa_disable_cpuint(&g_intenable[cpu], cpuint);
     }
   else
     {
@@ -676,7 +676,7 @@ void up_enable_irq(int irq)
 
       /* Enable the CPU interrupt now for internal CPU. */
 
-      xtensa_enable_cpuint(&g_intenable[cpu], (1ul << cpuint));
+      xtensa_enable_cpuint(&g_intenable[cpu], cpuint);
     }
   else
     {
@@ -1055,7 +1055,7 @@ int esp32_getcpuint_from_irq(int irq, int *cpu)
  *
  ****************************************************************************/
 
-uint32_t *xtensa_int_decode(uint32_t cpuints, uint32_t *regs)
+uint32_t *xtensa_int_decode(uint32_t *cpuints, uint32_t *regs)
 {
   uint8_t *intmap;
   uint32_t mask;
@@ -1084,15 +1084,15 @@ uint32_t *xtensa_int_decode(uint32_t cpuints, uint32_t 
*regs)
   /* Skip over zero bits, eight at a time */
 
   for (bit = 0, mask = 0xff;
-       bit < ESP32_NCPUINTS && (cpuints & mask) == 0;
+       bit < ESP32_NCPUINTS && (cpuints[0] & mask) == 0;
        bit += 8, mask <<= 8);
 
   /* Process each pending CPU interrupt */
 
-  for (; bit < ESP32_NCPUINTS && cpuints != 0; bit++)
+  for (; bit < ESP32_NCPUINTS && cpuints[0] != 0; bit++)
     {
       mask = 1 << bit;
-      if ((cpuints & mask) != 0)
+      if ((cpuints[0] & mask) != 0)
         {
           /* Extract the IRQ number from the mapping table */
 
@@ -1114,7 +1114,7 @@ uint32_t *xtensa_int_decode(uint32_t cpuints, uint32_t 
*regs)
 
           /* Clear software or edge-triggered interrupt */
 
-           xtensa_intclear(mask);
+           xtensa_intclear(bit);
 
           /* Dispatch the CPU interrupt.
            *
@@ -1128,7 +1128,7 @@ uint32_t *xtensa_int_decode(uint32_t cpuints, uint32_t 
*regs)
            * we can exit the look early.
            */
 
-          cpuints &= ~mask;
+          cpuints[0] &= ~mask;
         }
     }
 
@@ -1154,6 +1154,8 @@ uint32_t *xtensa_int_decode(uint32_t cpuints, uint32_t 
*regs)
 void esp32_irq_noniram_disable(void)
 {
   irqstate_t irqstate;
+  uint32_t mask;
+  int bit;
   int cpu;
   uint32_t oldint;
   uint32_t non_iram_ints;
@@ -1167,7 +1169,14 @@ void esp32_irq_noniram_disable(void)
   g_non_iram_int_disabled_flag[cpu] = true;
   oldint = g_intenable[cpu];
 
-  xtensa_disable_cpuint(&g_intenable[cpu], non_iram_ints);
+  for (bit = 0; bit < ESP32_NCPUINTS; bit++)
+    {
+      mask = 1 << bit;
+      if ((non_iram_ints & mask) != 0)
+        {
+          xtensa_disable_cpuint(&g_intenable[cpu], bit);
+        }
+    }
 
   g_non_iram_int_disabled[cpu] = oldint & non_iram_ints;
 
@@ -1191,6 +1200,8 @@ void esp32_irq_noniram_disable(void)
 void esp32_irq_noniram_enable(void)
 {
   irqstate_t irqstate;
+  uint32_t mask;
+  int bit;
   int cpu;
   uint32_t non_iram_ints;
 
@@ -1202,7 +1213,14 @@ void esp32_irq_noniram_enable(void)
 
   g_non_iram_int_disabled_flag[cpu] = false;
 
-  xtensa_enable_cpuint(&g_intenable[cpu], non_iram_ints);
+  for (bit = 0; bit < ESP32_NCPUINTS; bit++)
+    {
+      mask = 1 << bit;
+      if ((non_iram_ints & mask) != 0)
+        {
+          xtensa_enable_cpuint(&g_intenable[cpu], bit);
+        }
+    }
 
   leave_critical_section(irqstate);
 }
diff --git a/arch/xtensa/src/esp32s2/esp32s2_irq.c 
b/arch/xtensa/src/esp32s2/esp32s2_irq.c
index 92ef3aa149..dda4cb05c1 100644
--- a/arch/xtensa/src/esp32s2/esp32s2_irq.c
+++ b/arch/xtensa/src/esp32s2/esp32s2_irq.c
@@ -191,7 +191,7 @@ static int esp32s2_getcpuint(uint32_t intmask)
 
   if (ret >= 0)
     {
-      xtensa_enable_cpuint(&g_intenable, 1ul << ret);
+      xtensa_enable_cpuint(&g_intenable, ret);
     }
 
   return ret;
@@ -309,7 +309,7 @@ void up_irqinitialize(void)
 #ifdef CONFIG_ESPRESSIF_WIFI
   g_cpu_intmap[ESP32S2_CPUINT_MAC] = CPUINT_ASSIGN(ESP32S2_IRQ_MAC);
   g_cpu_intmap[ESP32S2_CPUINT_PWR] = CPUINT_ASSIGN(ESP32S2_IRQ_PWR);
-  xtensa_enable_cpuint(&g_intenable, 1 << ESP32S2_CPUINT_MAC);
+  xtensa_enable_cpuint(&g_intenable, ESP32S2_CPUINT_MAC);
 #endif
 
 #ifdef CONFIG_ESP32S2_GPIO_IRQ
@@ -360,7 +360,7 @@ void up_disable_irq(int irq)
        * the Interrupt Matrix.
        */
 
-      xtensa_disable_cpuint(&g_intenable, 1ul << cpuint);
+      xtensa_disable_cpuint(&g_intenable, cpuint);
     }
   else
     {
@@ -394,7 +394,7 @@ void up_enable_irq(int irq)
     {
       /* Enable the CPU interrupt now for internal CPU. */
 
-      xtensa_enable_cpuint(&g_intenable, (1ul << cpuint));
+      xtensa_enable_cpuint(&g_intenable, cpuint);
     }
   else
     {
@@ -597,7 +597,7 @@ void esp32s2_teardown_irq(int periphid, int cpuint)
  *
  ****************************************************************************/
 
-uint32_t *xtensa_int_decode(uint32_t cpuints, uint32_t *regs)
+uint32_t *xtensa_int_decode(uint32_t *cpuints, uint32_t *regs)
 {
   uint32_t mask;
   int bit;
@@ -609,15 +609,15 @@ uint32_t *xtensa_int_decode(uint32_t cpuints, uint32_t 
*regs)
   /* Skip over zero bits, eight at a time */
 
   for (bit = 0, mask = 0xff;
-       bit < ESP32S2_NCPUINTS && (cpuints & mask) == 0;
+       bit < ESP32S2_NCPUINTS && (cpuints[0] & mask) == 0;
        bit += 8, mask <<= 8);
 
   /* Process each pending CPU interrupt */
 
-  for (; bit < ESP32S2_NCPUINTS && cpuints != 0; bit++)
+  for (; bit < ESP32S2_NCPUINTS && cpuints[0] != 0; bit++)
     {
       mask = 1 << bit;
-      if ((cpuints & mask) != 0)
+      if ((cpuints[0] & mask) != 0)
         {
           /* Extract the IRQ number from the mapping table */
 
@@ -628,7 +628,7 @@ uint32_t *xtensa_int_decode(uint32_t cpuints, uint32_t 
*regs)
 
           /* Clear software or edge-triggered interrupt */
 
-           xtensa_intclear(mask);
+           xtensa_intclear(bit);
 
           /* Dispatch the CPU interrupt.
            *
@@ -642,7 +642,7 @@ uint32_t *xtensa_int_decode(uint32_t cpuints, uint32_t 
*regs)
            * we can exit the look early.
            */
 
-          cpuints &= ~mask;
+          cpuints[0] &= ~mask;
         }
     }
 
diff --git a/arch/xtensa/src/esp32s3/esp32s3_irq.c 
b/arch/xtensa/src/esp32s3/esp32s3_irq.c
index 5c75598b43..a5c00285e1 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_irq.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_irq.c
@@ -343,7 +343,7 @@ static int esp32s3_getcpuint(int cpu, uint32_t intmask)
 
   if (ret >= 0)
     {
-      xtensa_enable_cpuint(&g_intenable[cpu], 1ul << ret);
+      xtensa_enable_cpuint(&g_intenable[cpu], ret);
     }
 
   return ret;
@@ -499,7 +499,7 @@ void up_irqinitialize(void)
 #ifdef CONFIG_ESPRESSIF_WIFI
   g_cpu0_intmap[ESP32S3_CPUINT_MAC] = CPUINT_ASSIGN(ESP32S3_IRQ_MAC);
   g_cpu0_intmap[ESP32S3_CPUINT_PWR] = CPUINT_ASSIGN(ESP32S3_IRQ_PWR);
-  xtensa_enable_cpuint(&g_intenable[0], 1 << ESP32S3_CPUINT_MAC);
+  xtensa_enable_cpuint(&g_intenable[0], ESP32S3_CPUINT_MAC);
 #endif
 
 #ifdef CONFIG_SMP
@@ -570,7 +570,7 @@ void up_disable_irq(int irq)
         }
 #endif
 
-      xtensa_disable_cpuint(&g_intenable[cpu], 1ul << cpuint);
+      xtensa_disable_cpuint(&g_intenable[cpu], cpuint);
     }
   else
     {
@@ -615,7 +615,7 @@ void up_enable_irq(int irq)
 
       /* Enable the CPU interrupt now for internal CPU. */
 
-      xtensa_enable_cpuint(&g_intenable[cpu], (1ul << cpuint));
+      xtensa_enable_cpuint(&g_intenable[cpu], cpuint);
     }
   else
     {
@@ -986,7 +986,7 @@ int esp32s3_getcpuint_from_irq(int irq, int *cpu)
  *
  ****************************************************************************/
 
-uint32_t *xtensa_int_decode(uint32_t cpuints, uint32_t *regs)
+uint32_t *xtensa_int_decode(uint32_t *cpuints, uint32_t *regs)
 {
   uint8_t *intmap;
   uint32_t mask;
@@ -1014,15 +1014,15 @@ uint32_t *xtensa_int_decode(uint32_t cpuints, uint32_t 
*regs)
   /* Skip over zero bits, eight at a time */
 
   for (bit = 0, mask = 0xff;
-       bit < ESP32S3_NCPUINTS && (cpuints & mask) == 0;
+       bit < ESP32S3_NCPUINTS && (cpuints[0] & mask) == 0;
        bit += 8, mask <<= 8);
 
   /* Process each pending CPU interrupt */
 
-  for (; bit < ESP32S3_NCPUINTS && cpuints != 0; bit++)
+  for (; bit < ESP32S3_NCPUINTS && cpuints[0] != 0; bit++)
     {
       mask = 1 << bit;
-      if ((cpuints & mask) != 0)
+      if ((cpuints[0] & mask) != 0)
         {
           /* Extract the IRQ number from the mapping table */
 
@@ -1044,7 +1044,7 @@ uint32_t *xtensa_int_decode(uint32_t cpuints, uint32_t 
*regs)
 
           /* Clear software or edge-triggered interrupt */
 
-           xtensa_intclear(mask);
+           xtensa_intclear(bit);
 
           /* Dispatch the CPU interrupt.
            *
@@ -1058,7 +1058,7 @@ uint32_t *xtensa_int_decode(uint32_t cpuints, uint32_t 
*regs)
            * we can exit the look early.
            */
 
-          cpuints &= ~mask;
+          cpuints[0] &= ~mask;
         }
     }
 
@@ -1084,6 +1084,8 @@ uint32_t *xtensa_int_decode(uint32_t cpuints, uint32_t 
*regs)
 void esp32s3_irq_noniram_disable(void)
 {
   irqstate_t irqstate;
+  uint32_t mask;
+  int bit;
   int cpu;
   uint32_t oldint;
   uint32_t non_iram_ints;
@@ -1097,7 +1099,14 @@ void esp32s3_irq_noniram_disable(void)
   g_non_iram_int_disabled_flag[cpu] = true;
   oldint = g_intenable[cpu];
 
-  xtensa_disable_cpuint(&g_intenable[cpu], non_iram_ints);
+  for (bit = 0; bit < ESP32S3_NCPUINTS; bit++)
+    {
+      mask = 1 << bit;
+      if ((non_iram_ints & mask) != 0)
+        {
+          xtensa_disable_cpuint(&g_intenable[cpu], bit);
+        }
+    }
 
   g_non_iram_int_disabled[cpu] = oldint & non_iram_ints;
 
@@ -1121,6 +1130,8 @@ void esp32s3_irq_noniram_disable(void)
 void esp32s3_irq_noniram_enable(void)
 {
   irqstate_t irqstate;
+  uint32_t mask;
+  int bit;
   int cpu;
   uint32_t non_iram_ints;
 
@@ -1132,7 +1143,14 @@ void esp32s3_irq_noniram_enable(void)
 
   g_non_iram_int_disabled_flag[cpu] = false;
 
-  xtensa_enable_cpuint(&g_intenable[cpu], non_iram_ints);
+  for (bit = 0; bit < ESP32S3_NCPUINTS; bit++)
+    {
+      mask = 1 << bit;
+      if ((non_iram_ints & mask) != 0)
+        {
+          xtensa_enable_cpuint(&g_intenable[cpu], bit);
+        }
+    }
 
   leave_critical_section(irqstate);
 }

Reply via email to