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