// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD // // Licensed 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. #include #include #include #include "freertos/xtensa_context.h" #include "freertos/xtensa_rtos.h" #include "esp_private/panic_reason.h" #include "sdkconfig.h" #include "soc/soc.h" #include "soc/dport_reg.h" #include "soc/timer_group_reg.h" /* Interrupt , a high-priority interrupt, is used for several things: - IPC_ISR handler - Cache error panic handler - Interrupt watchdog panic handler */ #define L4_INTR_STACK_SIZE 12 #define L4_INTR_A2_OFFSET 0 #define L4_INTR_A3_OFFSET 4 #define L4_INTR_A4_OFFSET 8 .data _l4_intr_stack: .space L4_INTR_STACK_SIZE*portNUM_PROCESSORS /* This allocates stacks for each individual CPU. */ #if CONFIG_ESP32_ECO3_CACHE_LOCK_FIX && CONFIG_ESP_INT_WDT .global _l4_intr_livelock_counter .global _l4_intr_livelock_max .align 16 _l4_intr_livelock_counter: .word 0 _l4_intr_livelock_max: .word 0 _l4_intr_livelock_sync: .word 0, 0 _l4_intr_livelock_app: .word 0 _l4_intr_livelock_pro: .word 0 #endif .section .iram1,"ax" .global xt_highint4 .type xt_highint4,@function .align 4 xt_highint4: #ifndef CONFIG_FREERTOS_UNICORE /* See if we're here for the IPC_ISR interrupt */ rsr a0, INTERRUPT extui a0, a0, ETS_IPC_ISR_INUM, 1 bnez a0, esp_ipc_isr_handler #endif // not CONFIG_FREERTOS_UNICORE #if CONFIG_ESP32_ECO3_CACHE_LOCK_FIX && CONFIG_ESP_INT_WDT /* See if we're here for the tg1 watchdog interrupt */ rsr a0, INTERRUPT extui a0, a0, ETS_T1_WDT_INUM, 1 beqz a0, 1f wsr a5, depc /* use DEPC as temp storage */ movi a0, _l4_intr_livelock_counter l32i a0, a0, 0 movi a5, _l4_intr_livelock_max l32i a5, a5, 0 bltu a0, a5, .handle_livelock_int /* _l4_intr_livelock_counter < _l4_intr_livelock_max */ rsr a5, depc /* restore a5 */ #endif /* Allocate exception frame and save minimal context. */ 1: mov a0, sp addi sp, sp, -XT_STK_FRMSZ s32i a0, sp, XT_STK_A1 #if XCHAL_HAVE_WINDOWED s32e a0, sp, -12 /* for debug backtrace */ #endif rsr a0, PS /* save interruptee's PS */ s32i a0, sp, XT_STK_PS rsr a0, EPC_4 /* save interruptee's PC */ s32i a0, sp, XT_STK_PC #if XCHAL_HAVE_WINDOWED s32e a0, sp, -16 /* for debug backtrace */ #endif s32i a12, sp, XT_STK_A12 /* _xt_context_save requires A12- */ s32i a13, sp, XT_STK_A13 /* A13 to have already been saved */ call0 _xt_context_save /* Save vaddr into exception frame */ rsr a0, EXCVADDR s32i a0, sp, XT_STK_EXCVADDR /* Figure out reason, save into EXCCAUSE reg */ rsr a0, INTERRUPT extui a0, a0, ETS_MEMACCESS_ERR_INUM, 1 /* get cacheerr int bit */ beqz a0, 1f /* Kill this interrupt; we cannot reset it. */ rsr a0, INTENABLE movi a4, ~(1<