diff --git a/arch/xtensa/src/common/xtensa_nmi_handler.S b/arch/xtensa/src/common/xtensa_nmi_handler.S deleted file mode 100644 index bbf08cfe4ad..00000000000 --- a/arch/xtensa/src/common/xtensa_nmi_handler.S +++ /dev/null @@ -1,136 +0,0 @@ -/**************************************************************************** - * arch/xtensa/src/common/xtensa_nmi_handler.S - * - * Adapted from use in NuttX by: - * - * Copyright (C) 2016 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Derives from logic originally provided by Cadence Design Systems Inc. - * - * Copyright (c) 2006-2015 Cadence Design Systems Inc. - * - * 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_nmi_handler.S" - -/* NOTES on the use of 'call0' for long jumps instead of 'j': - * - * 1. This file should be assembled with the -mlongcalls option to xt-xcc. - * - * 2. The -mlongcalls compiler option causes 'call0 dest' to be expanded to - * a sequence 'l32r a0, dest' 'callx0 a0' which works regardless of the - * distance from the call to the destination. The linker then relaxes - * it back to 'call0 dest' if it determines that dest is within range. - * This allows more flexibility in locating code without the performance - * overhead of the 'l32r' literal data load in cases where the destination - * is in range of 'call0'. There is an additional benefit in that 'call0' - * has a longer range than 'j' due to the target being word-aligned, so - * the 'l32r' sequence is less likely needed. - * - * 3. The use of 'call0' with -mlongcalls requires that register a0 not be - * live at the time of the call, which is always the case for a function - * call but needs to be ensured if 'call0' is used as a jump in lieu of 'j'. - * - * 4. This use of 'call0' is independent of the C function call ABI. - */ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include - -#include "chip_macros.h" -#include "xtensa_abi.h" - -/**************************************************************************** - * Assembly Language Macros - ****************************************************************************/ - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * HIGH PRIORITY NMI LOW-LEVEL HANDLER - * - * High priority interrupts are by definition those with priorities greater - * than XCHAL_EXCM_LEVEL. This includes non-maskable (NMI). High priority - * interrupts cannot interact with the RTOS, that is they must save all regs - * they use and not call any RTOS function. - * - * A further restriction imposed by the Xtensa windowed architecture is that - * high priority interrupts must not modify the stack area even logically - * "above" the top of the interrupted stack (they need to provide their - * own stack or static save area). - * - * Cadence Design Systems recommends high priority interrupt handlers be - * coded in assembly and used for purposes requiring very short service - * times. - * - * The NMI vector goes at a predetermined location according to the Xtensa - * hardware configuration, which is ensured by its placement in a special - * section known to the Xtensa linker support package (LSP). It performs - * the minimum necessary before jumping to the NMI andler. - * - * Below is a template for the high priority NMI interrupt handler. - * A template and example can be found in the Cadence Design Systems tools - * documentation: "Microprocessor Programmer's Guide". - * - ****************************************************************************/ - -#if XCHAL_HAVE_NMI - .section HANDLER_SECTION, "ax" - .type _xtensa_nmi, @function - .align 4 - -_xtensa_nmi: - -#if 1 - /* For now, just panic */ - - mov a0, sp /* sp == a1 */ - addi sp, sp, -(4 * XCPTCONTEXT_SIZE) /* Allocate interrupt stack frame */ - s32i a0, sp, (4 * REG_A1) /* Save pre-interrupt SP */ - rsr a0, EPS_2 /* Save interruptee's PS */ - s32i a0, sp, (4 * REG_PS) - rsr a0, EPC_2 /* Save interruptee's PC */ - s32i a0, sp, (4 * REG_PC) - rsr a0, EXCSAVE_2 /* Save interruptee's a0 */ - s32i a0, sp, (4 * REG_A0) - - s32i a2, sp, (4 * REG_A2) - movi a2, XTENSA_NMI_EXCEPTION /* Address of state save on stack */ - call0 _xtensa_panic /* Does not return */ - -#else - /* Add high priority non-maskable interrupt (NMI) handler code here. */ - - rsr a0, EXCSAVE + XCHAL_NMILEVEL /* Restore a0 */ - rfi XCHAL_NMILEVEL - -#endif -#endif /* XCHAL_HAVE_NMI */ diff --git a/arch/xtensa/src/common/xtensa_panic.S b/arch/xtensa/src/common/xtensa_panic.S index 8b6608d7951..e24acc12fa4 100644 --- a/arch/xtensa/src/common/xtensa_panic.S +++ b/arch/xtensa/src/common/xtensa_panic.S @@ -64,7 +64,7 @@ #include /**************************************************************************** - * Assembly Language Marcros + * Public Functions ****************************************************************************/ /**************************************************************************** @@ -111,7 +111,7 @@ _xtensa_panic: /* Set up PS for C, reenable hi-pri interrupts, and clear EXCM. */ - mov a0, PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM | PS_WOE + movi a0, PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM | PS_WOE wsr a0, PS /* Call C panic handler: Arg1 (A2) = Exception code; Arg 2 (A3) = start diff --git a/arch/xtensa/src/common/xtensa_vectors.S b/arch/xtensa/src/common/xtensa_vectors.S index 9e9a1ab28eb..5f5c16248bd 100644 --- a/arch/xtensa/src/common/xtensa_vectors.S +++ b/arch/xtensa/src/common/xtensa_vectors.S @@ -48,15 +48,14 @@ ****************************************************************************/ /**************************************************************************** - * C Prototype: - * void _xtensa_levelN_vector(void) + * Name: _xtensa_level[n]_vector, n=2..6 * * Description: - * Xtensa interrupt vectors. Each vector goes at a predetermined location - * according to the Xtensa hardware configuration, which is ensured by its - * placement in a special section known to the NuttX linker script. The - * vector logic performs the minimum necessary operations before jumping - * to the handler. + * Xtensa medium/nigh priority interrupt vectors. Each vector goes at a + * predetermined location according to the Xtensa hardware configuration, + * which is ensured by its placement in a special section known to the + * NuttX linker script. The vector logic performs the minimum necessary + * operations before jumping to the handler. * ****************************************************************************/ @@ -154,15 +153,26 @@ _xtensa_level6_vector: #endif /**************************************************************************** - * C Prototype: - * void _xtensa_nmi_vector(void) + * Exception Vectors (except User, Co-processor and window exception + * vectors). + * + * Each vector goes at a predetermined location according to the Xtensa + * hardware configuration, which is ensured by its placement in a special + * section known to the Xtensa linker support package (LSP). It performs + * the minimum necessary before jumping to the handler in the .text section. + * + * The corresponding handler goes in the normal .text section. It sets up + * the appropriate stack frame, saves a few vector-specific registers and + * calls _xtensa_panic() to save the rest of the interrupted context + * and enter the NuttX panic handler + * + ****************************************************************************/ + +/**************************************************************************** + * Name: _xtensa_nmi_vector * * Description: - * Xtensa NMI vectors. This vector goes at a predetermined location - * according to the Xtensa hardware configuration, which is ensured by its - * placement in a special section known to the NuttX linker script. The - * vector logic performs the minimum necessary operations before jumping - * to the handler. + * NMI Exception * ****************************************************************************/ @@ -175,11 +185,141 @@ _xtensa_level6_vector: _xtensa_nmi_vector: - wsr a0, EXCSAVE + XCHAL_NMILEVEL /* Preserve a0 */ - call0 _xtensa_nmi /* Load interrupt handler */ +#if 1 + /* For now, just panic */ - /* Never returns here - call0 is used as a jump */ + wsr a0, EXCSAVE + XCHAL_NMILEVEL /* Preserve a0 */ + + mov a0, sp /* sp == a1 */ + addi sp, sp, -(4 * XCPTCONTEXT_SIZE) /* Allocate interrupt stack frame */ + s32i a0, sp, (4 * REG_A1) /* Save pre-interrupt SP */ + rsr a0, EPS + XCHAL_NMILEVEL /* Save interruptee's PS */ + s32i a0, sp, (4 * REG_PS) + rsr a0, EPC_2 /* Save interruptee's PC */ + s32i a0, sp, (4 * REG_PC) + rsr a0, EXCSAVE + XCHAL_NMILEVEL /* Save interruptee's a0 */ + s32i a0, sp, (4 * REG_A0) + + s32i a2, sp, (4 * REG_A2) + movi a2, XTENSA_NMI_EXCEPTION /* Address of state save on stack */ + call0 _xtensa_panic /* Does not return */ + +#else + /* Add high priority non-maskable interrupt (NMI) handler code here. */ + + rfi XCHAL_NMILEVEL + +#endif .size _xtensa_nmi_vector, . - _xtensa_nmi_vector .end literal_prefix + +/**************************************************************************** + * Name: _debug_exception_vector + * + * Description: + * Debug exception vector + * + ****************************************************************************/ + +#if XCHAL_HAVE_DEBUG + .begin literal_prefix .debug_exception_vector + .section .debug_exception_vector.text, "ax" + .global _debug_exception_vector + .align 4 + +_debug_exception_vector: + + mov a0, sp /* sp == a1 */ + addi sp, sp, -(4 * XCPTCONTEXT_SIZE) /* Allocate interrupt stack frame */ + s32i a0, sp, (4 * REG_A1) /* Save pre-interrupt SP */ + rsr a0, EPS + XCHAL_DEBUGLEVEL /* Save interruptee's PS */ + s32i a0, sp, (4 * REG_PS) + rsr a0, EPC + XCHAL_DEBUGLEVEL /* Save interruptee's PC */ + s32i a0, sp, (4 * REG_PC) + rsr a0, EXCSAVE + XCHAL_DEBUGLEVEL /* Save interruptee's a0 */ + s32i a0, sp, (4 * REG_A0) + + s32i a2, sp, (4 * REG_A2) + movi a2, XTENSA_DEBUG_EXCEPTION /* Address of state save on stack */ + call0 _xtensa_panic /* Does not return */ + + .end literal_prefix + +#endif /* XCHAL_HAVE_DEBUG */ + +/**************************************************************************** + * Name: _double_exception_vector + * + * Description: + * Double Exception Vector. Double exceptions are not a normal occurrence. + * They indicate a bug of some kind. + * + ****************************************************************************/ + +#ifdef XCHAL_DOUBLEEXC_VECTOR_VADDR + .begin literal_prefix .double_exception_vector + .section .double_exception_vector.text, "ax" + .global _double_exception_vector + .align 4 + +_double_exception_vector: + +#if XCHAL_HAVE_DEBUG + break 1, 4 /* Unhandled double exception */ +#endif + + mov a0, sp /* sp == a1 */ + addi sp, sp, -(4 * XCPTCONTEXT_SIZE) /* Allocate interrupt stack frame */ + s32i a0, sp, (4 * REG_A1) /* Save pre-interrupt SP */ + rsr a0, EPS_1 /* Save interruptee's PS -- REVISIT */ + s32i a0, sp, (4 * REG_PS) + rsr a0, DEPC /* Save interruptee's PC */ + s32i a0, sp, (4 * REG_PC) + rsr a0, EXCSAVE_1 /* Save interruptee's a0 -- REVISIT */ + s32i a0, sp, (4 * REG_A0) + + s32i a2, sp, (4 * REG_A2) + movi a2, XTENSA_DOUBLE_EXCEPTION /* Address of state save on stack */ + call0 _xtensa_panic /* Does not return */ + + .end literal_prefix + +#endif /* XCHAL_DOUBLEEXC_VECTOR_VADDR */ + +/**************************************************************************** + * Name: _kernel_exception_vector + * + * Description: + * Kernel Exception (including Level 1 Interrupt from kernel mode). + * + ****************************************************************************/ + + .begin literal_prefix .kernel_exception_vector + .section .kernel_exception_vector.text, "ax" + .global _kernel_exception_vector + .align 4 + +_kernel_exception_vector: + +#if XCHAL_HAVE_DEBUG + break 1, 0 /* Unhandled kernel exception */ +#endif + + mov a0, sp /* sp == a1 */ + addi sp, sp, -(4 * XCPTCONTEXT_SIZE) /* Allocate interrupt stack frame */ + s32i a0, sp, (4 * REG_A1) /* Save pre-interrupt SP */ + rsr a0, EPS_1 /* Save interruptee's PS */ + s32i a0, sp, (4 * REG_PS) + rsr a0, EPC_1 /* Save interruptee's PC */ + s32i a0, sp, (4 * REG_PC) + rsr a0, EXCSAVE_1 /* Save interruptee's a0 */ + s32i a0, sp, (4 * REG_A0) + + s32i a2, sp, (4 * REG_A2) + movi a2, XTENSA_KERNEL_EXCEPTION /* Address of state save on stack */ + call0 _xtensa_panic /* Does not return */ + + .end literal_prefix + #endif diff --git a/arch/xtensa/src/esp32/Make.defs b/arch/xtensa/src/esp32/Make.defs index b1fea99b585..3cb7c2b0c6e 100644 --- a/arch/xtensa/src/esp32/Make.defs +++ b/arch/xtensa/src/esp32/Make.defs @@ -41,7 +41,7 @@ HEAD_CSRC = esp32_start.c # Common XTENSA files (arch/xtensa/src/common) CMN_ASRCS = xtensa_context.S xtensa_coproc.S xtensa_cpuint.S -CMN_ASRCS += xtensa_int_handlers.S xtensa_nmi_handler.S xtensa_vectors.S +CMN_ASRCS += xtensa_int_handlers.S xtensa_panic.S xtensa_vectors.S CMN_CSRCS = xtensa_assert.c xtensa_blocktask.c xtensa_copystate.c CMN_CSRCS += xtensa_cpenable.c xtensa_createstack.c xtensa_exit.c xtensa_idle.c diff --git a/configs/esp32-core/scripts/esp32_common.ld b/configs/esp32-core/scripts/esp32_common.ld index 680c71a7844..606cc814d02 100644 --- a/configs/esp32-core/scripts/esp32_common.ld +++ b/configs/esp32-core/scripts/esp32_common.ld @@ -29,15 +29,15 @@ SECTIONS . = 0x240; KEEP(*(.xtensa_level5_vector.text)); . = 0x280; - KEEP(*(.DebugExceptionVector.text)); + KEEP(*(.debug_exception_vector.text)); . = 0x2c0; KEEP(*(.nmi_vector.text)); . = 0x300; - KEEP(*(.KernelExceptionVector.text)); + KEEP(*(.kernel_exception_vector.text)); . = 0x340; KEEP(*(.UserExceptionVector.text)); . = 0x3C0; - KEEP(*(.DoubleExceptionVector.text)); + KEEP(*(.double_exception_vector.text)); . = 0x400; *(.*Vector.literal)