From 7d254eb3f0486b9c81d02f769080325336d996a0 Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Wed, 26 Oct 2016 12:23:01 +0800 Subject: [PATCH] Move panic handler and gdbstub into esp32 component, clean up wdt according to merge req suggestions --- components/esp32/Kconfig | 41 +++++++ components/esp32/cpu_start.c | 12 +-- components/{freertos => esp32}/gdbstub.c | 2 +- .../gdbstub.h => esp32/include/esp_gdbstub.h} | 2 +- components/esp32/include/esp_int_wdt.h | 20 +++- components/esp32/include/esp_panic.h | 2 +- components/esp32/include/esp_task_wdt.h | 20 +++- components/esp32/include/soc/rtc_cntl_reg.h | 2 + .../esp32/include/soc/timer_group_reg.h | 2 + components/esp32/int_wdt.c | 17 +-- components/esp32/panic.c | 22 ++-- components/esp32/task_wdt.c | 22 +--- components/freertos/Kconfig | 39 ------- components/freertos/port.c | 4 +- components/freertos/xtensa_vectors.S | 100 +++++++++--------- 15 files changed, 161 insertions(+), 146 deletions(-) rename components/{freertos => esp32}/gdbstub.c (99%) rename components/{freertos/gdbstub.h => esp32/include/esp_gdbstub.h} (93%) diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index 7fc5090f4e..9e141529be 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -81,8 +81,10 @@ config TRACEMEM_RESERVE_DRAM default 0x4000 if MEMMAP_TRACEMEM && !MEMMAP_TRACEMEM_TWOBANKS default 0x0 +# Not implemented and/or needs new silicon rev to work config MEMMAP_SPISRAM bool "Use external SPI SRAM chip as main memory" + depends on ESP32_NEEDS_NEW_SILICON_REV default "n" help The ESP32 can control an external SPI SRAM chip, adding the memory it contains to the @@ -153,6 +155,45 @@ config ULP_COPROC_RESERVE_MEM depends on !ULP_COPROC_ENABLED +choice ESP32_PANIC + prompt "Panic handler behaviour" + default FREERTOS_PANIC_PRINT_REBOOT + help + If FreeRTOS detects unexpected behaviour or an unhandled exception, the panic handler is + invoked. Configure the panic handlers action here. + +config ESP32_PANIC_PRINT_HALT + bool "Print registers and halt" + help + Outputs the relevant registers over the serial port and halt the + processor. Needs a manual reset to restart. + +config ESP32_PANIC_PRINT_REBOOT + bool "Print registers and reboot" + help + Outputs the relevant registers over the serial port and immediately + reset the processor. + +config ESP32_PANIC_SILENT_REBOOT + bool "Silent reboot" + help + Just resets the processor without outputting anything + +config ESP32_PANIC_GDBSTUB + bool "Invoke GDBStub" + help + Invoke gdbstub on the serial port, allowing for gdb to attach to it to do a postmortem + of the crash. +endchoice + +config ESP32_DEBUG_OCDAWARE + bool "Make exception and panic handlers JTAG/OCD aware" + default y + help + The FreeRTOS panic and unhandled exception handers can detect a JTAG OCD debugger and + instead of panicking, have the debugger stop on the offending instruction. + + config INT_WDT bool "Interrupt watchdog" default y diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index aecea66ef9..37205dcd9a 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -147,19 +147,19 @@ void start_cpu0_default(void) #endif esp_set_cpu_freq(); // set CPU frequency configured in menuconfig uart_div_modify(0, (APB_CLK_FREQ << 4) / 115200); - ets_setup_syscalls(); - do_global_ctors(); - esp_ipc_init(); - spi_flash_init(); #if CONFIG_BROWNOUT_DET esp_brownout_init(); #endif #if CONFIG_INT_WDT - int_wdt_init(); + esp_int_wdt_init(); #endif #if CONFIG_TASK_WDT - task_wdt_init(); + esp_task_wdt_init(); #endif + ets_setup_syscalls(); + do_global_ctors(); + esp_ipc_init(); + spi_flash_init(); xTaskCreatePinnedToCore(&main_task, "main", ESP_TASK_MAIN_STACK, NULL, diff --git a/components/freertos/gdbstub.c b/components/esp32/gdbstub.c similarity index 99% rename from components/freertos/gdbstub.c rename to components/esp32/gdbstub.c index 1a92299bdd..d75fced4cd 100644 --- a/components/freertos/gdbstub.c +++ b/components/esp32/gdbstub.c @@ -24,7 +24,7 @@ #include "soc/uart_reg.h" #include "soc/io_mux_reg.h" -#include "gdbstub.h" +#include "esp_gdbstub.h" //Length of buffer used to reserve GDB commands. Has to be at least able to fit the G command, which //implies a minimum size of about 320 bytes. diff --git a/components/freertos/gdbstub.h b/components/esp32/include/esp_gdbstub.h similarity index 93% rename from components/freertos/gdbstub.h rename to components/esp32/include/esp_gdbstub.h index 5e97213c92..bc26f2941a 100644 --- a/components/freertos/gdbstub.h +++ b/components/esp32/include/esp_gdbstub.h @@ -17,6 +17,6 @@ #include #include "freertos/xtensa_api.h" -void gdbstubPanicHandler(XtExcFrame *frame); +void esp_gdbstub_panic_handler(XtExcFrame *frame); #endif \ No newline at end of file diff --git a/components/esp32/include/esp_int_wdt.h b/components/esp32/include/esp_int_wdt.h index dc5bd0dda1..4387400396 100644 --- a/components/esp32/include/esp_int_wdt.h +++ b/components/esp32/include/esp_int_wdt.h @@ -23,15 +23,29 @@ extern "C" { * @{ */ +/* +This routine enables a watchdog to catch instances of processes disabling +interrupts for too long, or code within interrupt handlers taking too long. +It does this by setting up a watchdog which gets fed from the FreeRTOS +task switch interrupt. When this watchdog times out, initially it will call +a high-level interrupt routine that will panic FreeRTOS in order to allow +for forensic examination of the state of the CPU. When this interrupt +handler is not called and the watchdog times out a second time, it will +reset the SoC. + +This uses the TIMERG1 WDT. +*/ + + /** - * @brief Initialize the interrupt watchdog. This is called in the init code, no need to - * call it explicitly. + * @brief Initialize the interrupt watchdog. This is called in the init code if + * the interrupt watchdog is enabled in menuconfig. * * @param null * * @return null */ -void int_wdt_init(); +void esp_int_wdt_init(); /** diff --git a/components/esp32/include/esp_panic.h b/components/esp32/include/esp_panic.h index 89dee5b249..6aba6c5f48 100644 --- a/components/esp32/include/esp_panic.h +++ b/components/esp32/include/esp_panic.h @@ -14,7 +14,7 @@ #ifndef __ASSEMBLER__ -void setBreakpointIfJtag(void *fn); +void esp_set_breakpoint_if_jtag(void *fn); #endif diff --git a/components/esp32/include/esp_task_wdt.h b/components/esp32/include/esp_task_wdt.h index c050616af6..bbc4995674 100644 --- a/components/esp32/include/esp_task_wdt.h +++ b/components/esp32/include/esp_task_wdt.h @@ -28,15 +28,25 @@ extern "C" { * @{ */ +/* +This routine enables a more general-purpose task watchdog: tasks can individually +feed the watchdog and the watchdog will bark if one or more tasks haven't fed the +watchdog within the specified time. Optionally, the idle tasks can also configured +to feed the watchdog in a similar fashion, to detect CPU starvation. + +This uses the TIMERG0 WDT. +*/ + + /** - * @brief Initialize the task watchdog. This is called in the init code, no need to - * call it explicitly. + * @brief Initialize the task watchdog. This is called in the init code, if the + * task watchdog is enabled in menuconfig. * * @param null * * @return null */ -void task_wdt_init(); +void esp_task_wdt_init(); /** * @brief Feed the watchdog. After the first feeding session, the watchdog will expect the calling @@ -47,7 +57,7 @@ void task_wdt_init(); * @return null */ -void task_wdt_feed(); +void esp_task_wdt_feed(); /** @@ -57,7 +67,7 @@ void task_wdt_feed(); * * @return null */ -void task_wdt_delete(); +void esp_task_wdt_delete(); /** * @} diff --git a/components/esp32/include/soc/rtc_cntl_reg.h b/components/esp32/include/soc/rtc_cntl_reg.h index 47328611e0..24e0f1403c 100644 --- a/components/esp32/include/soc/rtc_cntl_reg.h +++ b/components/esp32/include/soc/rtc_cntl_reg.h @@ -14,6 +14,8 @@ #ifndef _SOC_RTC_CNTL_REG_H_ #define _SOC_RTC_CNTL_REG_H_ +#define WDT_WRITE_KEY 0x50D83AA1 + #include "soc.h" #define RTC_CNTL_OPTIONS0_REG (DR_REG_RTCCNTL_BASE + 0x0) diff --git a/components/esp32/include/soc/timer_group_reg.h b/components/esp32/include/soc/timer_group_reg.h index 96a5eb7905..0d67cab517 100644 --- a/components/esp32/include/soc/timer_group_reg.h +++ b/components/esp32/include/soc/timer_group_reg.h @@ -15,6 +15,8 @@ #define __TIMG_REG_H__ #include "soc.h" +#define WDT_WRITE_KEY 0x50D83AA1 + #define REG_TIMG_BASE(i) (DR_REG_TIMERGROUP0_BASE + i*0x1000) #define TIMG_T0CONFIG_REG(i) (REG_TIMG_BASE(i) + 0x0000) /* TIMG_T0_EN : R/W ;bitpos:[31] ;default: 1'h0 ; */ diff --git a/components/esp32/int_wdt.c b/components/esp32/int_wdt.c index 8c506bde1f..5f123ee368 100644 --- a/components/esp32/int_wdt.c +++ b/components/esp32/int_wdt.c @@ -13,18 +13,6 @@ // limitations under the License. -/* -This routine enables a watchdog to catch instances of processes disabling -interrupts for too long, or code within interrupt handlers taking too long. -It does this by setting up a watchdog which gets fed from the FreeRTOS -task switch interrupt. When this watchdog times out, initially it will call -a high-level interrupt routine that will panic FreeRTOS in order to allow -for forensic examination of the state of the CPU. When this interrupt -handler is not called and the watchdog times out a second time, it will -reset the SoC. - -This uses the TIMERG1 WDT. -*/ #include "sdkconfig.h" #include @@ -37,6 +25,7 @@ This uses the TIMERG1 WDT. #include "esp_err.h" #include "esp_intr.h" #include "soc/timer_group_struct.h" +#include "soc/timer_group_reg.h" #include "esp_int_wdt.h" @@ -45,9 +34,8 @@ This uses the TIMERG1 WDT. #define WDT_INT_NUM 24 -#define WDT_WRITE_KEY 0x50D83AA1 -void int_wdt_init() { +void esp_int_wdt_init() { TIMERG1.wdt_wprotect=WDT_WRITE_KEY; TIMERG1.wdt_config0.sys_reset_length=7; //3.2uS TIMERG1.wdt_config0.cpu_reset_length=7; //3.2uS @@ -73,6 +61,7 @@ void int_wdt_init() { } +//Take care: the tick hook can also be called before esp_int_wdt_init() is called. #if CONFIG_INT_WDT_CHECK_CPU1 //Not static; the ISR assembly checks this. bool int_wdt_app_cpu_ticked=false; diff --git a/components/esp32/panic.c b/components/esp32/panic.c index 0735e6b045..758d581d09 100644 --- a/components/esp32/panic.c +++ b/components/esp32/panic.c @@ -26,11 +26,10 @@ #include "soc/dport_reg.h" #include "soc/rtc_cntl_reg.h" #include "soc/timer_group_struct.h" +#include "soc/timer_group_reg.h" -#include "gdbstub.h" -#include "panic.h" - -#define WDT_WRITE_KEY 0x50D83AA1 +#include "esp_gdbstub.h" +#include "esp_panic.h" /* @@ -196,7 +195,13 @@ void xt_unhandled_exception(XtExcFrame *frame) { } -//Disables all but one WDT, and allows enough time on that WDT to do what we need to do. +/* +If watchdogs are enabled, the panic handler runs the risk of getting aborted pre-emptively because +an overzealous watchdog decides to reset it. On the other hand, if we disable all watchdogs, we run +the risk of somehow halting in the panic handler and not resetting. That is why this routine kills +all watchdogs except the timer group 0 watchdog, and it reconfigures that to reset the chip after +one second. +*/ static void reconfigureAllWdts() { TIMERG0.wdt_wprotect=WDT_WRITE_KEY; TIMERG0.wdt_feed=1; @@ -213,6 +218,9 @@ static void reconfigureAllWdts() { TIMERG1.wdt_wprotect=0; } +/* +This disables all the watchdogs for when we call the gdbstub. +*/ static void disableAllWdts() { TIMERG0.wdt_wprotect=WDT_WRITE_KEY; TIMERG0.wdt_config0.en=0; @@ -254,7 +262,7 @@ void commonErrorHandler(XtExcFrame *frame) { #if CONFIG_FREERTOS_PANIC_GDBSTUB disableAllWdts(); panicPutStr("Entering gdb stub now.\r\n"); - gdbstubPanicHandler(frame); + esp_gdbstub_panic_handler(frame); #elif CONFIG_FREERTOS_PANIC_PRINT_REBOOT || CONFIG_FREERTOS_PANIC_SILENT_REBOOT panicPutStr("Rebooting...\r\n"); for (x=0; x<100; x++) ets_delay_us(1000); @@ -267,7 +275,7 @@ void commonErrorHandler(XtExcFrame *frame) { } -void setBreakpointIfJtag(void *fn) { +void esp_set_breakpoint_if_jtag(void *fn) { if (!inOCDMode()) return; setFirstBreakpoint((uint32_t)fn); } diff --git a/components/esp32/task_wdt.c b/components/esp32/task_wdt.c index e6a4620882..24d3977b18 100644 --- a/components/esp32/task_wdt.c +++ b/components/esp32/task_wdt.c @@ -13,14 +13,6 @@ // limitations under the License. -/* -This routine enables a more general-purpose task watchdog: tasks can individually -feed the watchdog and the watchdog will bark if one or more tasks haven't fed the -watchdog within the specified time. Optionally, the idle tasks can also configured -to feed the watchdog in a similar fashion, to detect CPU starvation. - -This uses the TIMERG0 WDT. -*/ #include #include @@ -35,6 +27,7 @@ This uses the TIMERG0 WDT. #include "esp_intr.h" #include "esp_attr.h" #include "soc/timer_group_struct.h" +#include "soc/timer_group_reg.h" #include "esp_log.h" #include "esp_task_wdt.h" @@ -52,11 +45,6 @@ struct wdt_task_t { static wdt_task_t *wdt_task_list=NULL; -//We use this interrupt number on whatever task calls task_wdt_init. -#define WDT_INT_NUM 24 - -#define WDT_WRITE_KEY 0x50D83AA1 - static void IRAM_ATTR task_wdt_isr(void *arg) { wdt_task_t *wdttask; const char *cpu; @@ -87,7 +75,7 @@ static void IRAM_ATTR task_wdt_isr(void *arg) { } -void task_wdt_feed() { +void esp_task_wdt_feed() { wdt_task_t *wdttask=wdt_task_list; bool found_task=false, do_feed_wdt=true; TaskHandle_t handle=xTaskGetCurrentTaskHandle(); @@ -127,7 +115,7 @@ void task_wdt_feed() { } } -void task_wdt_delete() { +void esp_task_wdt_delete() { TaskHandle_t handle=xTaskGetCurrentTaskHandle(); wdt_task_t *wdttask=wdt_task_list; //Wdt task list can't be empty @@ -152,7 +140,7 @@ void task_wdt_delete() { } } -void task_wdt_init() { +void esp_task_wdt_init() { TIMERG0.wdt_wprotect=WDT_WRITE_KEY; TIMERG0.wdt_config0.sys_reset_length=7; //3.2uS TIMERG0.wdt_config0.cpu_reset_length=7; //3.2uS @@ -178,7 +166,7 @@ void vApplicationIdleHook(void) { #if !CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1 if (xPortGetCoreID()!=0) return; #endif - task_wdt_feed(); + esp_task_wdt_feed(); } #endif diff --git a/components/freertos/Kconfig b/components/freertos/Kconfig index 1a65e1eeb7..413c710d22 100644 --- a/components/freertos/Kconfig +++ b/components/freertos/Kconfig @@ -93,45 +93,6 @@ config FREERTOS_THREAD_LOCAL_STORAGE_POINTERS If using the WiFi stack, this value must be at least 1. -#This still needs to be implemented. -choice FREERTOS_PANIC - prompt "Panic handler behaviour" - default FREERTOS_PANIC_PRINT_REBOOT - help - If FreeRTOS detects unexpected behaviour or an unhandled exception, the panic handler is - invoked. Configure the panic handlers action here. - -config FREERTOS_PANIC_PRINT_HALT - bool "Print registers and halt" - help - Outputs the relevant registers over the serial port and halt the - processor. Needs a manual reset to restart. - -config FREERTOS_PANIC_PRINT_REBOOT - bool "Print registers and reboot" - help - Outputs the relevant registers over the serial port and immediately - reset the processor. - -config FREERTOS_PANIC_SILENT_REBOOT - bool "Silent reboot" - help - Just resets the processor without outputting anything - -config FREERTOS_PANIC_GDBSTUB - bool "Invoke GDBStub" - help - Invoke gdbstub on the serial port, allowing for gdb to attach to it to do a postmortem - of the crash. -endchoice - -config FREERTOS_DEBUG_OCDAWARE - bool "Make exception and panic handlers JTAG/OCD aware" - default y - help - The FreeRTOS panic and unhandled exception handers can detect a JTAG OCD debugger and - instead of panicking, have the debugger stop on the offending instruction. - choice FREERTOS_ASSERT prompt "FreeRTOS assertions" default FREERTOS_ASSERT_FAIL_ABORT diff --git a/components/freertos/port.c b/components/freertos/port.c index a982db7d42..834d787bea 100644 --- a/components/freertos/port.c +++ b/components/freertos/port.c @@ -101,7 +101,7 @@ #include "FreeRTOS.h" #include "task.h" -#include "panic.h" +#include "esp_panic.h" /* Defined in portasm.h */ extern void _frxt_tick_timer_init(void); @@ -375,7 +375,7 @@ portBASE_TYPE vPortCPUReleaseMutex(portMUX_TYPE *mux) { #if CONFIG_FREERTOS_BREAK_ON_SCHEDULER_START_JTAG void vPortFirstTaskHook(TaskFunction_t function) { - setBreakpointIfJtag(function); + esp_set_breakpoint_if_jtag(function); } #endif diff --git a/components/freertos/xtensa_vectors.S b/components/freertos/xtensa_vectors.S index fcf9af1cd1..94acbd896e 100644 --- a/components/freertos/xtensa_vectors.S +++ b/components/freertos/xtensa_vectors.S @@ -91,7 +91,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *******************************************************************************/ #include "xtensa_rtos.h" -#include "panic.h" +#include "esp_panic.h" #include "sdkconfig.h" /* Define for workaround: pin no-cpu-affinity tasks to a cpu when fpu is used. @@ -303,12 +303,12 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ .section .iram1,"ax" - .global panicHandler + .global panicHandler .global _xt_panic .type _xt_panic,@function .align 4 - .literal_position + .literal_position .align 4 _xt_panic: @@ -344,41 +344,41 @@ _xt_panic: movi a0, PS_INTLEVEL(7) | PS_UM | PS_WOE wsr a0, PS - //Call panic handler - mov a6,sp - call4 panicHandler + //Call panic handler + mov a6,sp + call4 panicHandler 1: j 1b /* loop infinitely */ - retw + retw - .align 4 + .align 4 //Call using call0. Prints the hex char in a2. Kills a3, a4, a5 panic_print_hex: - movi a3,0x60000000 - movi a4,8 + movi a3,0x60000000 + movi a4,8 panic_print_hex_loop: - l32i a5, a3, 0x1c - extui a5, a5, 16, 8 - bgei a5,64,panic_print_hex_loop + l32i a5, a3, 0x1c + extui a5, a5, 16, 8 + bgei a5,64,panic_print_hex_loop - srli a5,a2,28 - bgei a5,10,panic_print_hex_a - addi a5,a5,'0' - j panic_print_hex_ok + srli a5,a2,28 + bgei a5,10,panic_print_hex_a + addi a5,a5,'0' + j panic_print_hex_ok panic_print_hex_a: - addi a5,a5,'A'-10 + addi a5,a5,'A'-10 panic_print_hex_ok: - s32i a5,a3,0 - slli a2,a2,4 - - addi a4,a4,-1 - bnei a4,0,panic_print_hex_loop - movi a5,' ' - s32i a5,a3,0 + s32i a5,a3,0 + slli a2,a2,4 + + addi a4,a4,-1 + bnei a4,0,panic_print_hex_loop + movi a5,' ' + s32i a5,a3,0 - ret + ret @@ -463,8 +463,8 @@ _DebugExceptionVector: jx a3 #else wsr a0, EXCSAVE+XCHAL_DEBUGLEVEL /* save original a0 somewhere */ - movi a0,PANIC_RSN_DEBUGEXCEPTION - wsr a0,EXCCAUSE + movi a0,PANIC_RSN_DEBUGEXCEPTION + wsr a0,EXCCAUSE call0 _xt_panic /* does not return */ rfi XCHAL_DEBUGLEVEL /* make a0 point here not later */ #endif @@ -492,8 +492,8 @@ _DoubleExceptionVector: #if XCHAL_HAVE_DEBUG break 1, 4 /* unhandled double exception */ #endif - movi a0,PANIC_RSN_DOUBLEEXCEPTION - wsr a0,EXCCAUSE + movi a0,PANIC_RSN_DOUBLEEXCEPTION + wsr a0,EXCCAUSE call0 _xt_panic /* does not return */ rfde /* make a0 point here not later */ @@ -527,8 +527,8 @@ _xt_kernel_exc: #if XCHAL_HAVE_DEBUG break 1, 0 /* unhandled kernel exception */ #endif - movi a0,PANIC_RSN_KERNELEXCEPTION - wsr a0,EXCCAUSE + movi a0,PANIC_RSN_KERNELEXCEPTION + wsr a0,EXCCAUSE call0 _xt_panic /* does not return */ rfe /* make a0 point here not there */ @@ -916,11 +916,11 @@ _xt_coproc_exc: addi a2, a2, TASKTCB_XCOREID_OFFSET /* offset to xCoreID in tcb struct */ s32i a3, a2, 0 /* store current cpuid */ - /* Grab correct xt_coproc_owner_sa for this core */ - movi a2, XCHAL_CP_MAX << 2 - mull a2, a2, a3 + /* Grab correct xt_coproc_owner_sa for this core */ + movi a2, XCHAL_CP_MAX << 2 + mull a2, a2, a3 movi a3, _xt_coproc_owner_sa /* a3 = base of owner array */ - add a3, a3, a2 + add a3, a3, a2 extui a2, a0, 0, 16 /* coprocessor bitmask portion */ or a4, a4, a2 /* a4 = CPENABLE | (1 << n) */ @@ -1031,8 +1031,8 @@ _xt_coproc_exc: #if XCHAL_HAVE_DEBUG break 1, 1 /* unhandled user exception */ #endif - movi a0,PANIC_RSN_COPROCEXCEPTION - wsr a0,EXCCAUSE + movi a0,PANIC_RSN_COPROCEXCEPTION + wsr a0,EXCCAUSE call0 _xt_panic /* not in a thread (invalid) */ /* never returns */ @@ -1620,19 +1620,19 @@ _xt_highint4: /* On the ESP32, this level is used for the INT_WDT handler. If that triggers, the program is stuck with interrupts off and the CPU should panic. */ - rsr a0, EXCSAVE_4 - wsr a0, EXCSAVE_1 /* panic handler reads this register */ - /* Set EXCCAUSE to reflect cause of the wdt int trigger */ - movi a0,PANIC_RSN_INTWDT_CPU0 - wsr a0,EXCCAUSE + rsr a0, EXCSAVE_4 + wsr a0, EXCSAVE_1 /* panic handler reads this register */ + /* Set EXCCAUSE to reflect cause of the wdt int trigger */ + movi a0,PANIC_RSN_INTWDT_CPU0 + wsr a0,EXCCAUSE #if CONFIG_INT_WDT_CHECK_CPU1 - /* Check if the cause is the app cpu failing to tick.*/ - movi a0, int_wdt_app_cpu_ticked - l32i a0, a0, 0 - bnez a0, 1f - /* It is. Modify cause. */ - movi a0,PANIC_RSN_INTWDT_CPU1 - wsr a0,EXCCAUSE + /* Check if the cause is the app cpu failing to tick.*/ + movi a0, int_wdt_app_cpu_ticked + l32i a0, a0, 0 + bnez a0, 1f + /* It is. Modify cause. */ + movi a0,PANIC_RSN_INTWDT_CPU1 + wsr a0,EXCCAUSE 1: #endif call0 _xt_panic