From fdede8099b017600fa5f6af2fad01f26177798aa Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sun, 30 Oct 2016 10:57:57 -0600 Subject: [PATCH] Xtensa/ESP32: Add Level1 handler, panic handler, remove EXECHOOKS. --- arch/xtensa/include/esp32/irq.h | 13 + arch/xtensa/src/common/xtensa.h | 1 + arch/xtensa/src/common/xtensa_assert.c | 35 +++ arch/xtensa/src/common/xtensa_int_handlers.S | 243 ++++++++++++------- arch/xtensa/src/common/xtensa_nmi_handler.S | 31 ++- arch/xtensa/src/common/xtensa_panic.S | 129 ++++++++++ arch/xtensa/src/common/xtensa_vectors.S | 4 +- 7 files changed, 350 insertions(+), 106 deletions(-) create mode 100644 arch/xtensa/src/common/xtensa_panic.S diff --git a/arch/xtensa/include/esp32/irq.h b/arch/xtensa/include/esp32/irq.h index 590e6d28cb..a5f521f8b6 100644 --- a/arch/xtensa/include/esp32/irq.h +++ b/arch/xtensa/include/esp32/irq.h @@ -50,6 +50,19 @@ * Pre-processor Definitions ****************************************************************************/ +/* Exception Codes */ + +#define XTENSA_NMI_EXCEPTION 0 +#define XTENSA_DEBUG_EXCEPTION 1 +#define XTENSA_DOUBLE_EXCEPTION 2 +#define XTENSA_KERNEL_EXCEPTION 3 +#define XTENSA_COPROC_EXCEPTION 4 +#define XTENSA_LEVEL2_EXCEPTION 5 +#define XTENSA_LEVEL3_EXCEPTION 6 +#define XTENSA_LEVEL4_EXCEPTION 7 +#define XTENSA_LEVEL5_EXCEPTION 8 +#define XTENSA_LEVEL6_EXCEPTION 9 + /* Interrupt Matrix * * The Interrupt Matrix embedded in the ESP32 independently allocates diff --git a/arch/xtensa/src/common/xtensa.h b/arch/xtensa/src/common/xtensa.h index d6af111d04..2dce849d85 100644 --- a/arch/xtensa/src/common/xtensa.h +++ b/arch/xtensa/src/common/xtensa.h @@ -249,6 +249,7 @@ uint32_t *xtensa_int_decode(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_panic(int xptcode, uint32_t *regs) noreturn_function; /* Software interrupt handler */ diff --git a/arch/xtensa/src/common/xtensa_assert.c b/arch/xtensa/src/common/xtensa_assert.c index 98c5562d92..41adf94a48 100644 --- a/arch/xtensa/src/common/xtensa_assert.c +++ b/arch/xtensa/src/common/xtensa_assert.c @@ -158,3 +158,38 @@ void up_assert(const uint8_t *filename, int lineno) xtensa_assert(EXIT_FAILURE); } + +/**************************************************************************** + * Name: xtensa_panic + ****************************************************************************/ + +void xtensa_panic(int xptcode, uint32_t *regs) +{ +#if CONFIG_TASK_NAME_SIZE > 0 && defined(CONFIG_DEBUG_ALERT) + struct tcb_s *rtcb = this_task(); +#endif + + /* We get here when a un-dispatch-able, irrecoverable excpetion occurs */ + + board_autoled_on(LED_ASSERTION); + +#if CONFIG_TASK_NAME_SIZE > 0 + _alert("Unhandled Exception %d task: %s\n", xptcode, rtcb->name); +#else + _alert("Unhandled Exception %d\n", xptcode); +#endif + + xtensa_dumpstate(); + +#ifdef CONFIG_ARCH_USBDUMP + /* Dump USB trace data */ + + (void)usbtrace_enumerate(assert_tracecallback, NULL); +#endif + +#ifdef CONFIG_BOARD_CRASHDUMP + board_crashdump(up_getsp(), this_task(), filename, lineno); +#endif + + xtensa_assert(EXIT_FAILURE); +} diff --git a/arch/xtensa/src/common/xtensa_int_handlers.S b/arch/xtensa/src/common/xtensa_int_handlers.S index f5fda35b57..db358ff734 100644 --- a/arch/xtensa/src/common/xtensa_int_handlers.S +++ b/arch/xtensa/src/common/xtensa_int_handlers.S @@ -127,25 +127,6 @@ and a2, a2, a4 beqz a2, 5f /* Nothing to do */ -#ifdef XT_INTEXC_HOOKS - /* Call interrupt hook if present to (pre)handle interrupts. */ - - movi a4, _xt_intexc_hooks - l32i a4, a4, \level << 2 - beqz a4, 2f - -#ifdef __XTENSA_CALL0_ABI__ - callx0 a4 - beqz a2, 5f -#else - mov a6, a2 - callx4 a4 - beqz a6, 5f - mov a2, a6 -#endif -2: -#endif - /* If multiple bits are set then MSB has highest priority. */ extract_msb a4, a2 /* a4 = MSB of a2, a2 trashed */ @@ -259,10 +240,63 @@ ****************************************************************************/ /**************************************************************************** - * LOW PRIORITY (LEVEL 1) LOW LEVEL HANDLER. + * LEVEL 1 INTERRUPT HANDLER ****************************************************************************/ +/* The level1 interrupt vector is invoked via the User exception vector. */ -#warning REVISIT level 1 interrupt handlers + .section HANDLER_SECTION, "ax" + .type _xtensa_level1_handler, @function + .align 4 + +_xtensa_level1_handler: + + 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, PS /* 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) + + /* Save rest of interrupt context. */ + + s32i a2, sp, (4 * REG_A2) + mov a2, sp /* Address of state save on stack */ + call0 _xtensa_context_save /* Save full register state */ + + /* Set up PS for C, enable interrupts above this level and clear EXCM. */ + + ps_setup 1 a0 + + /* Decode and dispatch the interrupt. In the event of an interrupt + * level context dispatch_c_isr() will switch stacks to the new task's + * context save area. + */ + + dispatch_c_isr 1 XCHAL_INTLEVEL1_MASK + + /* Restore registers in preparation to return from interrupt */ + + call0 _xtensa_context_restore + + /* Restore only level-specific regs (the rest were already restored) */ + + l32i a0, sp, (4 * REG_PS) /* Retrieve interruptee's PS */ + wsr a0, EPS_1 + l32i a0, sp, (4 * REG_PC) /* Retrieve interruptee's PC */ + wsr a0, EPC_1 + l32i a0, sp, (4 * REG_A0) /* Retrieve interruptee's A0 */ + l32i a2, sp, (4 * REG_A2) /* Retrieve interruptee's A2 */ + l32i sp, sp, (4 * REG_A1) /* Remove interrupt stack frame */ + rsync /* Ensure EPS and EPC written */ + + /* Return from interrupt. RFI restores the PS from EPS_1 and jumps to + * the address in EPC_1. + */ + + rfi 1 /**************************************************************************** * MEDIUM PRIORITY (LEVEL 2+) INTERRUPT LOW LEVEL HANDLERS. @@ -310,7 +344,7 @@ _xtensa_level2_handler: /* Save rest of interrupt context. */ s32i a2, sp, (4 * REG_A2) - movi a2, sp /* Address of state save on stack */ + mov a2, sp /* Address of state save on stack */ call0 _xtensa_context_save /* Save full register state */ /* Set up PS for C, enable interrupts above this level and clear EXCM. */ @@ -367,7 +401,7 @@ _xtensa_level3_handler: /* Save rest of interrupt context. */ s32i a2, sp, (4 * REG_A2) - movi a2, sp /* Address of state save on stack */ + mov a2, sp /* Address of state save on stack */ call0 _xtensa_context_save /* Save full register state */ /* Set up PS for C, enable interrupts above this level and clear EXCM. */ @@ -424,7 +458,7 @@ _xtensa_level4_handler: /* Save rest of interrupt context. */ s32i a2, sp, (4 * REG_A2) - movi a2, sp /* Address of state save on stack */ + mov a2, sp /* Address of state save on stack */ call0 _xtensa_context_save /* Save full register state */ /* Set up PS for C, enable interrupts above this level and clear EXCM. */ @@ -481,7 +515,7 @@ _xtensa_level5_handler: /* Save rest of interrupt context. */ s32i a2, sp, (4 * REG_A2) - movi a2, sp /* Address of state save on stack */ + mov a2, sp /* Address of state save on stack */ call0 _xtensa_context_save /* Save full register state */ /* Set up PS for C, enable interrupts above this level and clear EXCM. */ @@ -538,7 +572,7 @@ _xtensa_level6_handler: /* Save rest of interrupt context. */ s32i a2, sp, (4 * REG_A2) - movi a2, sp /* Address of state save on stack */ + mov a2, sp /* Address of state save on stack */ call0 _xtensa_context_save /* Save full register state */ /* Set up PS for C, enable interrupts above this level and clear EXCM. */ @@ -618,29 +652,30 @@ _xtensa_level6_handler: _xtensa_level2_handler: -#ifdef XT_INTEXC_HOOKS - /* Call interrupt hook if present to (pre)handle interrupts. */ +#if 1 + /* For now, just panic */ - movi a0, _xt_intexc_hooks - l32i a0, a0, 2 << 2 - beqz a0, 1f + 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) -.Ln_xtensa_level2_handler_call_hook: + s32i a2, sp, (4 * REG_A2) + movi a2, XTENSA_LEVEL2_EXCEPTION /* Address of state save on stack */ + call0 _xtensa_panic /* Does not return */ - callx0 a0 /* Must NOT disturb stack! */ - -1: -#endif - - /* USER_EDIT: - * ADD HIGH PRIORITY LEVEL 2 INTERRUPT HANDLER CODE HERE. - */ - - .align 4 +#else + /* Add high priority level 2 interrupt handler code here. */ rsr a0, EXCSAVE_2 /* Restore a0 */ rfi 2 +#endif #endif /* XCHAL_INT_NLEVELS >=2 && XCHAL_EXCM_LEVEL < 2 && XCHAL_DEBUGLEVEL !=2 */ #if XCHAL_INT_NLEVELS >=3 && XCHAL_EXCM_LEVEL < 3 && XCHAL_DEBUGLEVEL !=3 @@ -650,28 +685,32 @@ _xtensa_level2_handler: _xtensa_level3_handler: -#ifdef XT_INTEXC_HOOKS - /* Call interrupt hook if present to (pre)handle interrupts. */ +#if 1 + /* For now, just panic */ - movi a0, _xt_intexc_hooks - l32i a0, a0, 3 << 2 - beqz a0, 1f + 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_3 /* Save interruptee's PS */ + s32i a0, sp, (4 * REG_PS) + rsr a0, EPC_3 /* Save interruptee's PC */ + s32i a0, sp, (4 * REG_PC) + rsr a0, EXCSAVE_3 /* Save interruptee's a0 */ + s32i a0, sp, (4 * REG_A0) -.Ln_xtensa_level3_handler_call_hook: + s32i a2, sp, (4 * REG_A2) + movi a2, XTENSA_LEVEL3_EXCEPTION /* Address of state save on stack */ + call0 _xtensa_panic /* Does not return */ - callx0 a0 /* Must NOT disturb stack! */ -1: -#endif +#else + wsr a0, EXCSAVE_3 /* Save a0 */ - /* USER_EDIT: - * ADD HIGH PRIORITY LEVEL 3 INTERRUPT HANDLER CODE HERE. - */ - - .align 4 + /* Add high priority level 2 interrupt handler code here. */ rsr a0, EXCSAVE_3 /* Restore a0 */ rfi 3 +#endif #endif /* XCHAL_INT_NLEVELS >=3 && XCHAL_EXCM_LEVEL < 3 && XCHAL_DEBUGLEVEL !=3 */ #if XCHAL_INT_NLEVELS >=4 && XCHAL_EXCM_LEVEL < 4 && XCHAL_DEBUGLEVEL !=4 @@ -681,28 +720,32 @@ _xtensa_level3_handler: _xtensa_level4_handler: -#ifdef XT_INTEXC_HOOKS - /* Call interrupt hook if present to (pre)handle interrupts. */ +#if 1 + /* For now, just panic */ - movi a0, _xt_intexc_hooks - l32i a0, a0, 4 << 2 - beqz a0, 1f + 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_4 /* Save interruptee's PS */ + s32i a0, sp, (4 * REG_PS) + rsr a0, EPC_4 /* Save interruptee's PC */ + s32i a0, sp, (4 * REG_PC) + rsr a0, EXCSAVE_4 /* Save interruptee's a0 */ + s32i a0, sp, (4 * REG_A0) -.Ln_xtensa_level4_handler_call_hook: + s32i a2, sp, (4 * REG_A2) + movi a2, XTENSA_LEVEL4_EXCEPTION /* Address of state save on stack */ + call0 _xtensa_panic /* Does not return */ - callx0 a0 /* Must NOT disturb stack! */ -1: -#endif +#else + wsr a0, EXCSAVE_4 /* Save a0 */ - /* USER_EDIT: - * ADD HIGH PRIORITY LEVEL 4 INTERRUPT HANDLER CODE HERE. - */ - - .align 4 + /* Add high priority level 2 interrupt handler code here. */ rsr a0, EXCSAVE_4 /* Restore a0 */ rfi 4 +#endif #endif /* XCHAL_INT_NLEVELS >=4 && XCHAL_EXCM_LEVEL < 4 && XCHAL_DEBUGLEVEL !=4 */ #if XCHAL_INT_NLEVELS >=5 && XCHAL_EXCM_LEVEL < 5 && XCHAL_DEBUGLEVEL !=5 @@ -712,26 +755,32 @@ _xtensa_level4_handler: _xtensa_level5_handler: -#ifdef XT_INTEXC_HOOKS - /* Call interrupt hook if present to (pre)handle interrupts. */ +#if 1 + /* For now, just panic */ - movi a0, _xt_intexc_hooks - l32i a0, a0, 5 << 2 - beqz a0, 1f + 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_5 /* Save interruptee's PS */ + s32i a0, sp, (4 * REG_PS) + rsr a0, EPC_5 /* Save interruptee's PC */ + s32i a0, sp, (4 * REG_PC) + rsr a0, EXCSAVE_5 /* Save interruptee's a0 */ + s32i a0, sp, (4 * REG_A0) -.Ln_xtensa_level5_handler_call_hook: + s32i a2, sp, (4 * REG_A2) + movi a2, XTENSA_LEVEL5_EXCEPTION /* Address of state save on stack */ + call0 _xtensa_panic /* Does not return */ - callx0 a0 /* Must NOT disturb stack! */ -1: -#endif +#else + wsr a0, EXCSAVE_5 /* Save a0 */ - /* USER_EDIT: - * ADD HIGH PRIORITY LEVEL 5 INTERRUPT HANDLER CODE HERE. - */ + /* Add high priority level 2 interrupt handler code here. */ rsr a0, EXCSAVE_5 /* Restore a0 */ rfi 5 +#endif #endif /* XCHAL_INT_NLEVELS >=5 && XCHAL_EXCM_LEVEL < 5 && XCHAL_DEBUGLEVEL !=5 */ #if XCHAL_INT_NLEVELS >=6 && XCHAL_EXCM_LEVEL < 6 && XCHAL_DEBUGLEVEL !=6 @@ -741,24 +790,30 @@ _xtensa_level5_handler: _xtensa_level6_handler: -#ifdef XT_INTEXC_HOOKS - /* Call interrupt hook if present to (pre)handle interrupts. */ +#if 1 + /* For now, just panic */ - movi a0, _xt_intexc_hooks - l32i a0, a0, 6 << 2 - beqz a0, 1f + 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_6 /* Save interruptee's PS */ + s32i a0, sp, (4 * REG_PS) + rsr a0, EPC_6 /* Save interruptee's PC */ + s32i a0, sp, (4 * REG_PC) + rsr a0, EXCSAVE_6 /* Save interruptee's a0 */ + s32i a0, sp, (4 * REG_A0) -.Ln_xtensa_level6_handler_call_hook: + s32i a2, sp, (4 * REG_A2) + movi a2, XTENSA_LEVEL6_EXCEPTION /* Address of state save on stack */ + call0 _xtensa_panic /* Does not return */ - callx0 a0 /* Must NOT disturb stack! */ -1: -#endif +#else + wsr a0, EXCSAVE_6 /* Save a0 */ - /* USER_EDIT: - * ADD HIGH PRIORITY LEVEL 6 INTERRUPT HANDLER CODE HERE. - */ + /* Add high priority level 2 interrupt handler code here. */ rsr a0, EXCSAVE_6 /* Restore a0 */ rfi 6 +#endif #endif /* XCHAL_INT_NLEVELS >=6 && XCHAL_EXCM_LEVEL < 6 && XCHAL_DEBUGLEVEL !=6 */ diff --git a/arch/xtensa/src/common/xtensa_nmi_handler.S b/arch/xtensa/src/common/xtensa_nmi_handler.S index 67510aa41c..bbf08cfe4a 100644 --- a/arch/xtensa/src/common/xtensa_nmi_handler.S +++ b/arch/xtensa/src/common/xtensa_nmi_handler.S @@ -59,6 +59,7 @@ #include +#include #include #include @@ -103,23 +104,33 @@ #if XCHAL_HAVE_NMI .section HANDLER_SECTION, "ax" - .type _xt_nmi, @function + .type _xtensa_nmi, @function .align 4 -_xt_nmi: -#ifdef XT_INTEXC_HOOKS - /* Call interrupt hook if present to (pre)handle interrupts. */ +_xtensa_nmi: - movi a0, _xt_intexc_hooks - l32i a0, a0, XCHAL_NMILEVEL << 2 - beqz a0, 1f - callx0 a0 /* Must NOT disturb stack! */ -1: -#endif +#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 new file mode 100644 index 0000000000..8b6608d795 --- /dev/null +++ b/arch/xtensa/src/common/xtensa_panic.S @@ -0,0 +1,129 @@ +/**************************************************************************** + * arch/xtensa/src/common/xtensa_panic.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_panic.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 + +/**************************************************************************** + * Assembly Language Marcros + ****************************************************************************/ + +/**************************************************************************** + * Name: _xtensa_panic + * + * Description: + * Should be reached by call0 (preferable) or jump only. If call0, a0 says + * where from. If on simulator, display panic message and abort, else loop + * indefinitely. + * + * Entry Conditions: + * - A1 = Stack frame already allocated. SP points to beginning of the + * register frame. + * - A0, A1, A2, PC and PS = Already saved in the stack frame + * - A2 = Exception code + * + * Exit conditions: + * Does not return. + * + ****************************************************************************/ + + .section HANDLER_SECTION, "ax" + .global _xtensa_panic + .type _xtensa_panic, @function + + .align 4 + .literal_position + .align 4 + +_xtensa_panic: + /* Save rest of interrupt context (A2=address of state save area on + * stack. + */ + + mov a2, sp /* Address of state save on stack */ + call0 _xtensa_context_save /* Save full register state */ + + /* Save exc cause and vaddr into exception frame */ + + rsr a0, EXCCAUSE + s32i a0, sp, (4 * REG_EXCCAUSE) + rsr a0, EXCVADDR + s32i a0, sp, (4 * REG_EXCVADDR) + + /* Set up PS for C, reenable hi-pri interrupts, and clear EXCM. */ + + mov 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 + * of the register save area. + */ + + mov a3, sp +#ifdef __XTENSA_CALL0_ABI__ + call0 xtensa_panic /* Call xtensa_panic. Should not return */ +#else + call4 xtensa_panic /* Call xtensa_panic. Should not return */ +#endif + +1: j 1b /* loop infinitely */ + retw diff --git a/arch/xtensa/src/common/xtensa_vectors.S b/arch/xtensa/src/common/xtensa_vectors.S index 6f84444aeb..9e9a1ab28e 100644 --- a/arch/xtensa/src/common/xtensa_vectors.S +++ b/arch/xtensa/src/common/xtensa_vectors.S @@ -175,8 +175,8 @@ _xtensa_level6_vector: _xtensa_nmi_vector: - wsr a0, EXCSAVE + XCHAL_NMILEVEL _ /* preserve a0 */ - call0 _xt_nmi /* load interrupt handler */ + wsr a0, EXCSAVE + XCHAL_NMILEVEL /* Preserve a0 */ + call0 _xtensa_nmi /* Load interrupt handler */ /* Never returns here - call0 is used as a jump */