From 75d23e84583da47832147b946f6bf5be5f6e1ae1 Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Wed, 11 Dec 2019 07:28:45 +0100 Subject: [PATCH] cpu/esp*: common exception handling --- cpu/esp32/exceptions.c | 221 ----------------------- cpu/{esp8266 => esp_common}/exceptions.c | 70 ++++--- 2 files changed, 48 insertions(+), 243 deletions(-) delete mode 100644 cpu/esp32/exceptions.c rename cpu/{esp8266 => esp_common}/exceptions.c (85%) diff --git a/cpu/esp32/exceptions.c b/cpu/esp32/exceptions.c deleted file mode 100644 index 693a473917..0000000000 --- a/cpu/esp32/exceptions.c +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (C) 2018 Gunar Schorcht - * - * This file is subject to the terms and conditions of the GNU Lesser - * General Public License v2.1. See the file LICENSE in the top level - * directory for more details. - */ - -/** - * @ingroup cpu_esp32 - * @{ - * - * @file - * @brief ESP32 exception handling - * - * @author Gunar Schorcht - * @} - */ - -#define ENABLE_DEBUG 0 -#include "debug.h" - -#include -#include -#include - -#include "esp_common.h" -#include "irq.h" -#include "log.h" -#include "periph/pm.h" -#include "ps.h" - -#include "esp/common_macros.h" -#include "esp/xtensa_ops.h" -#include "rom/ets_sys.h" -#include "rom/rtc.h" -#include "rom/uart.h" -#include "sdk_conf.h" -#include "xtensa/corebits.h" -#include "freertos/xtensa_api.h" - -#ifdef MODULE_ESP_GDBSTUB -#include "esp_gdbstub.h" -#endif - -#ifdef MODULE_ESP_IDF_HEAP -#include "heap/esp_heap_caps.h" -#endif - -extern void malloc_stats (void); -extern unsigned int get_free_heap_size (void); -extern uint8_t _eheap; /* end of heap (defined in esp32.common.ld) */ -extern uint8_t _sheap; /* start of heap (defined in esp32.common.ld) */ - -static const char* exception_names [] = -{ - "IllegalInstructionCause", /* 0 */ - "SyscallCause", /* 1 */ - "InstructionFetchErrorCause", /* 2 */ - "LoadStoreErrorCause", /* 3 */ - "Level1InterruptCause", /* 4 */ - "AllocaCause", /* 5 */ - "IntegerDivideByZeroCause", /* 6 */ - "", /* 7 - reserved */ - "PrivilegedCause", /* 8 */ - "LoadStoreAlignmentCause", /* 9 */ - "", /* 10 - reserved */ - "", /* 11 - reserved */ - "InstrPIFDataErrorCause", /* 12 */ - "LoadStorePIFDataErrorCause", /* 13 */ - "InstrPIFAddrErrorCause", /* 14 */ - "LoadStorePIFAddrErrorCause", /* 15 */ - "InstTLBMissCause", /* 16 */ - "InstTLBMultiHitCause", /* 17 */ - "InstFetchPrivilegeCause", /* 18 */ - "", /* 19 - reserved */ - "InstFetchProhibitedCause", /* 20 */ - "", /* 21 - reserved */ - "", /* 22 - reserved */ - "", /* 23 - reserved */ - "LoadStoreTLBMissCause", /* 24 */ - "LoadStoreTLBMultiHitCause", /* 25 */ - "LoadStorePrivilegeCause", /* 26 */ - "", /* 27 - reserved */ - "LoadProhibitedCause", /* 28 */ - "StoreProhibitedCause", /* 29 */ - "", /* 30 - reserved */ - "", /* 31 - reserved */ - "Coprocessor0Disabled", /* 32 */ - "Coprocessor1Disabled", /* 33 */ - "Coprocessor2Disabled", /* 34 */ - "Coprocessor3Disabled", /* 35 */ - "Coprocessor4Disabled", /* 36 */ - "Coprocessor5Disabled", /* 37 */ - "Coprocessor6Disabled", /* 38 */ - "Coprocessor7Disabled", /* 39 */ -}; - -const char *reg_names[] = { - "pc ", "ps ", - "a0 ", "a1 ", "a2 ", "a3 ", "a4 ", "a5 ", - "a6 ", "a7 ", "a8 ", "a9 ", "a10 ", "a11 ", - "a12 ", "a13 ", "a14 ", "A15 ", "SAR ", - "exccause", "excvaddr", "lbeg ", "lend ", "lcount " -}; - -void IRAM NORETURN exception_handler (XtExcFrame *frame) -{ - uint32_t excsave1; - uint32_t epc1; - uint32_t epc2; - uint32_t epc3; - uint32_t epc4; - RSR(excsave1, excsave1); - RSR(epc1, epc1); - RSR(epc2, epc2); - RSR(epc3, epc3); - RSR(epc4, epc4); - - #ifdef MODULE_ESP_GDBSTUB - esp_gdbstub_panic_handler(frame); - #endif - - ets_printf("EXCEPTION!! exccause=%d (%s) @%08x excvaddr=%08x\n\n", - frame->exccause, exception_names[frame->exccause], - excsave1, frame->excvaddr); - - #if defined(DEVELHELP) - #if defined(MODULE_PS) - ets_printf("processes:\n"); - ps(); - ets_printf("\n"); - #endif /* MODULE_PS */ - #ifdef MODULE_ESP_IDF_HEAP - heap_caps_print_heap_info(MALLOC_CAP_DEFAULT); - #else - ets_printf("\nheap: %u (free %u) byte\n", &_eheap - &_sheap, get_free_heap_size()); - #endif /* MODULE_ESP_IDF_HEAP */ - - ets_printf("\nregister set\n"); - ets_printf("pc : %08x\t", frame->pc); - ets_printf("ps : %08x\t", frame->ps); - ets_printf("exccause: %08x\t", frame->exccause); - ets_printf("excvaddr: %08x\n", frame->excvaddr); - ets_printf("epc1 : %08x\t", epc1); - ets_printf("epc2 : %08x\t", epc2); - ets_printf("epc3 : %08x\t", epc3); - ets_printf("epc4 : %08x\n", epc4); - ets_printf("a0 : %08x\t", frame->a0); - ets_printf("a1 : %08x\t", frame->a1); - ets_printf("a2 : %08x\t", frame->a2); - ets_printf("a3 : %08x\n", frame->a3); - ets_printf("a4 : %08x\t", frame->a4); - ets_printf("a5 : %08x\t", frame->a5); - ets_printf("a6 : %08x\t", frame->a6); - ets_printf("a7 : %08x\n", frame->a7); - ets_printf("a8 : %08x\t", frame->a8); - ets_printf("a9 : %08x\t", frame->a9); - ets_printf("a10 : %08x\t", frame->a10); - ets_printf("a11 : %08x\n", frame->a11); - ets_printf("a12 : %08x\t", frame->a12); - ets_printf("a13 : %08x\t", frame->a13); - ets_printf("a14 : %08x\t", frame->a14); - ets_printf("a15 : %08x\n", frame->a15); - ets_printf("lbeg : %08x\t", frame->lbeg); - ets_printf("lend : %08x\t", frame->lend); - ets_printf("lcount : %08x\n", frame->lcount); - #endif /* DEVELHELP */ - - /* restart */ - /* TODO: Improvement - Normally, we should try to restart the system. However, this - will not work after some exceptions, e.g., the LoadStoreErrorCause. - Therefore, we break the execution and wait for the WDT reset. Maybe - there is better way. If debugger is active, 'break 0,0' stops - execution in debugger. */ - __asm__ volatile ("break 0,0"); - - UNREACHABLE(); -} - -void init_exceptions (void) -{ - xt_set_exception_handler(EXCCAUSE_UNALIGNED, exception_handler); - xt_set_exception_handler(EXCCAUSE_ILLEGAL, exception_handler); - xt_set_exception_handler(EXCCAUSE_INSTR_ERROR, exception_handler); - xt_set_exception_handler(EXCCAUSE_LOAD_STORE_ERROR, exception_handler); - xt_set_exception_handler(EXCCAUSE_LOAD_PROHIBITED, exception_handler); - xt_set_exception_handler(EXCCAUSE_STORE_PROHIBITED, exception_handler); - xt_set_exception_handler(EXCCAUSE_PRIVILEGED, exception_handler); -} - -void IRAM NORETURN panic_arch(void) -{ - #if defined(DEVELHELP) - - #ifdef MODULE_ESP_IDF_HEAP - heap_caps_print_heap_info(MALLOC_CAP_DEFAULT); - #else - ets_printf("\nheap: %u (free %u) byte\n", &_eheap - &_sheap, get_free_heap_size()); - #endif /* MODULE_ESP_IDF_HEAP */ - - /* break in debugger or reboot after WDT */ - __asm__ volatile ("break 0,0"); - - #else /* DEVELHELP */ - - /* restart */ - software_reset(); - - #endif /* DEVELHELP */ - - UNREACHABLE(); -} - -void _panic_handler(uint32_t addr) -{ - ets_printf("#! _xt_panic called from 0x%08x: powering off\n", addr); - pm_off(); - while (1) { }; -} diff --git a/cpu/esp8266/exceptions.c b/cpu/esp_common/exceptions.c similarity index 85% rename from cpu/esp8266/exceptions.c rename to cpu/esp_common/exceptions.c index a81efb41fd..befe2677da 100644 --- a/cpu/esp8266/exceptions.c +++ b/cpu/esp_common/exceptions.c @@ -7,19 +7,16 @@ */ /** - * @ingroup cpu_esp8266 + * @ingroup cpu_esp_common * @{ * * @file - * @brief ESP8266 exception handling + * @brief ESP SoCs exception handling * * @author Gunar Schorcht * @} */ -#define ENABLE_DEBUG (0) -#include "debug.h" - #include #include #include @@ -31,10 +28,12 @@ #include "esp_common.h" #include "esp/common_macros.h" #include "esp/xtensa_ops.h" -#include "sdk/ets.h" #include "xtensa/corebits.h" #include "xtensa/xtensa_api.h" +#define ENABLE_DEBUG (0) +#include "debug.h" + extern void heap_stats(void); static const char* exception_names [] = @@ -85,17 +84,32 @@ void IRAM NORETURN exception_handler (XtExcFrame *frame) { uint32_t excsave1; uint32_t epc1; - uint32_t epc2; - uint32_t epc3; RSR(excsave1, excsave1); RSR(epc1, epc1); +#if XCHAL_NMILEVEL >= 2 + uint32_t epc2; RSR(epc2, epc2); +#endif +#if XCHAL_NMILEVEL >= 3 + uint32_t epc3; RSR(epc3, epc3); - -#ifdef MCU_ESP32 +#endif +#if XCHAL_NMILEVEL >= 4 uint32_t epc4; RSR(epc4, epc4); #endif +#if XCHAL_NMILEVEL >= 5 + uint32_t epc5; + RSR(epc5, epc5); +#endif +#if XCHAL_NMILEVEL >= 6 + uint32_t epc6; + RSR(epc6, epc6); +#endif +#if XCHAL_NMILEVEL >= 7 + uint32_t epc7; + RSR(epc7, epc7); +#endif ets_printf("EXCEPTION!! exccause=%d (%s) @%08x excvaddr=%08x\n", frame->exccause, exception_names[frame->exccause], @@ -117,13 +131,25 @@ void IRAM NORETURN exception_handler (XtExcFrame *frame) ets_printf("exccause: %08x\t", frame->exccause); ets_printf("excvaddr: %08x\n", frame->excvaddr); ets_printf("epc1 : %08x\t", epc1); +#if XCHAL_NMILEVEL >= 2 ets_printf("epc2 : %08x\t", epc2); +#endif +#if XCHAL_NMILEVEL >= 3 ets_printf("epc3 : %08x\t", epc3); -#ifdef MCU_ESP32 +#endif +#if XCHAL_NMILEVEL >= 4 ets_printf("epc4 : %08x\n", epc4); -#else /* MCU_ESP32 */ - ets_printf("epc3 : %08x\n", epc3); -#endif /* MCU_ESP32 */ +#endif +#if XCHAL_NMILEVEL >= 5 + ets_printf("epc5 : %08x\t", epc5); +#endif +#if XCHAL_NMILEVEL >= 6 + ets_printf("epc6 : %08x\t", epc6); +#endif +#if XCHAL_NMILEVEL >= 7 + ets_printf("epc7 : %08x\t", epc7); +#endif + ets_printf("\n"); ets_printf("a0 : %08x\t", frame->a0); ets_printf("a1 : %08x\t", frame->a1); ets_printf("a2 : %08x\t", frame->a2); @@ -154,9 +180,7 @@ void IRAM NORETURN exception_handler (XtExcFrame *frame) One option is to break the execution and wait for the WDT reset. Maybe there is better way. If debugger is active, 'break 0,0' stops the execution in debugger. */ - /* __asm__ volatile ("break 0,0"); */ - /* hard reset */ - __asm__ volatile (" call0 0x40000080 "); + __asm__ volatile ("break 0,0"); UNREACHABLE(); } @@ -174,12 +198,14 @@ void init_exceptions (void) void IRAM NORETURN panic_arch(void) { - #if defined(DEVELHELP) +#if defined(DEVELHELP) heap_stats(); - #endif - - /* hard reset */ - __asm__ volatile (" call0 0x40000080 "); + /* break in debugger or reboot after WDT */ + __asm__ volatile ("break 0,0"); +#else /* DEVELHELP */ + /* restart */ + pm_reboot(); +#endif /* DEVELHELP */ UNREACHABLE(); }