You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ac...@apache.org on 2025/07/04 14:26:12 UTC
(nuttx) branch master updated: xtensa: support more than 32 cpu interrupts
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 <ch...@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 <ch...@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);
}