diff --git a/components/esp_system/component.mk b/components/esp_system/component.mk index caa3400967..d78bcef737 100644 --- a/components/esp_system/component.mk +++ b/components/esp_system/component.mk @@ -5,7 +5,7 @@ COMPONENT_ADD_INCLUDEDIRS := include COMPONENT_PRIV_INCLUDEDIRS := private_include port/include COMPONENT_ADD_LDFRAGMENTS += linker.lf --include $(COMPONENT_PATH)/port/$(SOC_NAME)/component.mk +include $(COMPONENT_PATH)/port/soc/$(SOC_NAME)/component.mk # disable stack protection in files which are involved in initialization of that feature startup.o: CFLAGS := $(filter-out -fstack-protector%, $(CFLAGS)) diff --git a/components/esp_system/include/esp_private/panic_internal.h b/components/esp_system/include/esp_private/panic_internal.h index 583d3eba74..d43a705aba 100644 --- a/components/esp_system/include/esp_private/panic_internal.h +++ b/components/esp_system/include/esp_private/panic_internal.h @@ -16,14 +16,20 @@ #include #include + +#include "soc/soc_caps.h" + #include "sdkconfig.h" + #ifdef __cplusplus extern "C" { #endif extern bool g_panic_abort; +extern void *g_exc_frames[SOC_CPU_CORES_NUM]; + // Function to print longer amounts of information such as the details // and backtrace field of panic_info_t. These functions should limit themselves // to printing to the console and should do other more involved processing, @@ -72,6 +78,20 @@ void panic_print_hex(int h); void __attribute__((noreturn)) panic_abort(const char *details); +void panic_arch_fill_info(void *frame, panic_info_t *info); + +void panic_soc_fill_info(void *frame, panic_info_t *info); + +void panic_print_registers(const void *frame, int core); + +void panic_print_backtrace(const void *frame, int core); + +uint32_t panic_get_address(const void* frame); + +void panic_set_address(void *frame, uint32_t addr); + +uint32_t panic_get_cause(const void* frame); + #ifdef __cplusplus } #endif diff --git a/components/esp_system/linker.lf b/components/esp_system/linker.lf index 412b10d192..17ab599c35 100644 --- a/components/esp_system/linker.lf +++ b/components/esp_system/linker.lf @@ -3,6 +3,7 @@ archive: libesp_system.a entries: panic (noflash) panic_handler (noflash) + panic_arch (noflash) reset_reason (noflash) system_api:esp_system_abort (noflash) startup:do_core_init (default) diff --git a/components/esp_system/panic.c b/components/esp_system/panic.c index 4085be6bcb..518a75e4c7 100644 --- a/components/esp_system/panic.c +++ b/components/esp_system/panic.c @@ -46,11 +46,26 @@ #include "sdkconfig.h" +#if CONFIG_ESP_SYSTEM_PANIC_GDBSTUB +#include "esp_private/gdbstub.h" +#endif + +#if CONFIG_ESP32_ENABLE_COREDUMP +#include "esp_core_dump.h" +#endif + +#if CONFIG_APPTRACE_ENABLE +#include "esp_app_trace.h" +#if CONFIG_SYSVIEW_ENABLE +#include "SEGGER_RTT.h" +#endif + #if CONFIG_APPTRACE_ONPANIC_HOST_FLUSH_TMO == -1 #define APPTRACE_ONPANIC_HOST_FLUSH_TMO ESP_APPTRACE_TMO_INFINITE #else #define APPTRACE_ONPANIC_HOST_FLUSH_TMO (1000*CONFIG_APPTRACE_ONPANIC_HOST_FLUSH_TMO) #endif +#endif // CONFIG_APPTRACE_ENABLE #if CONFIG_ESP_SYSTEM_PANIC_GDBSTUB #include "esp_private/gdbstub.h" diff --git a/components/esp_system/port/CMakeLists.txt b/components/esp_system/port/CMakeLists.txt index c53c2aeaa8..628c79f007 100644 --- a/components/esp_system/port/CMakeLists.txt +++ b/components/esp_system/port/CMakeLists.txt @@ -1,10 +1,9 @@ target_include_directories(${COMPONENT_LIB} PRIVATE include) -set(srcs "cpu_start.c") - +set(srcs "cpu_start.c" "panic_handler.c") add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" ${srcs}) target_sources(${COMPONENT_LIB} PRIVATE ${srcs}) idf_build_get_property(target IDF_TARGET) -add_subdirectory(${target}) +add_subdirectory(soc/${target}) diff --git a/components/esp_system/port/arch/riscv/panic_arch.c b/components/esp_system/port/arch/riscv/panic_arch.c new file mode 100644 index 0000000000..ded4a7ee6f --- /dev/null +++ b/components/esp_system/port/arch/riscv/panic_arch.c @@ -0,0 +1,127 @@ + +// Copyright 2020 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 "esp_private/panic_internal.h" +#include "riscv/rvruntime-frames.h" + +extern void esp_panic_handler(panic_info_t *); + +void panic_print_registers(const void *f, int core) +{ + uint32_t *regs = (uint32_t *)f; + + // only print ABI name + const char *desc[] = { + "MEPC ", "RA ", "SP ", "GP ", "TP ", "T0 ", "T1 ", "T2 ", + "S0/FP ", "S1 ", "A0 ", "A1 ", "A2 ", "A3 ", "A4 ", "A5 ", + "A6 ", "A7 ", "S2 ", "S3 ", "S4 ", "S5 ", "S6 ", "S7 ", + "S8 ", "S9 ", "S10 ", "S11 ", "T3 ", "T4 ", "T5 ", "T6 ", + "MSTATUS ", "MTVEC ", "MCAUSE ", "MTVAL ", "MHARTID " + }; + + panic_print_str("Core "); + panic_print_dec(((RvExcFrame *)f)->mhartid); + panic_print_str(" register dump:"); + + for (int x = 0; x < sizeof(desc) / sizeof(desc[0]); x += 4) { + panic_print_str("\r\n"); + for (int y = 0; y < 4 && x + y < sizeof(desc) / sizeof(desc[0]); y++) { + if (desc[x + y][0] != 0) { + panic_print_str(desc[x + y]); + panic_print_str(": 0x"); + panic_print_hex(regs[x + y]); + panic_print_str(" "); + } + } + } +} + +void panic_soc_fill_info(void *f, panic_info_t *info) +{ + // TODO ESP32-C3 IDF-2386 / support soc panic + return; +} + +void panic_arch_fill_info(void *frame, panic_info_t *info) +{ + RvExcFrame *regs = (RvExcFrame *) frame; + info->core = 0; + info->exception = PANIC_EXCEPTION_FAULT; + + //Please keep in sync with PANIC_RSN_* defines + static const char *reason[] = { + "Instruction address misaligned", + "Instruction access fault", + "Illegal instruction", + "Breakpoint", + "Load address misaligned", + "Load access fault", + "Store address misaligned", + "Store access fault", + "Environment call from U-mode", + "Environment call from S-mode", + NULL, + "Environment call from M-mode", + "Instruction page fault", + "Load page fault", + NULL, + "Store page fault", + }; + + if (regs->mcause < (sizeof(reason) / sizeof(reason[0]))) { + if (reason[regs->mcause] != NULL) { + info->reason = (reason[regs->mcause]); + } + } + + info->description = "Exception was unhandled."; + + info->addr = (void *) regs->mepc; + info->frame = ®s; +} + +void panic_print_backtrace(const void *frame, int core) +{ + // Basic backtrace + panic_print_str("\r\nStack memory:\n"); + uint32_t sp = (uint32_t)((RvExcFrame *)frame)->sp; + const int per_line = 8; + for (int x = 0; x < 1024; x += per_line * sizeof(uint32_t)) { + uint32_t *spp = (uint32_t *)(sp + x); + panic_print_hex(sp + x); + panic_print_str(": "); + for (int y = 0; y < per_line; y++) { + panic_print_str("0x"); + panic_print_hex(spp[y]); + panic_print_char(y == per_line - 1 ? '\n' : ' '); + } + } +} + +uint32_t panic_get_address(const void *f) +{ + return ((RvExcFrame *)f)->mepc; +} + +uint32_t panic_get_cause(const void *f) +{ + return ((RvExcFrame *)f)->mcause; +} + +void panic_set_address(void *f, uint32_t addr) +{ + ((RvExcFrame *)f)->mepc = addr; +} diff --git a/components/esp_system/port/arch/xtensa/panic_handler.c b/components/esp_system/port/arch/xtensa/panic_arch.c similarity index 62% rename from components/esp_system/port/arch/xtensa/panic_handler.c rename to components/esp_system/port/arch/xtensa/panic_arch.c index 76975d8c55..752b46fa9e 100644 --- a/components/esp_system/port/arch/xtensa/panic_handler.c +++ b/components/esp_system/port/arch/xtensa/panic_arch.c @@ -11,185 +11,38 @@ // 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 "freertos/xtensa_context.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "esp_spi_flash.h" - -#include "esp_private/panic_reason.h" -#include "esp_private/system_internal.h" #include "esp_debug_helpers.h" -#include "soc/soc_memory_layout.h" -#include "soc/cpu.h" -#include "soc/soc_caps.h" -#include "soc/rtc.h" - -#include "hal/soc_hal.h" -#include "hal/cpu_hal.h" -#include "hal/wdt_types.h" -#include "hal/wdt_hal.h" - +#include "esp_private/panic_internal.h" +#include "esp_private/panic_reason.h" +#include "soc/soc.h" #include "sdkconfig.h" #if CONFIG_IDF_TARGET_ESP32 #include "esp32/cache_err_int.h" -#include "esp32/dport_access.h" -#include "esp32/rom/uart.h" -#elif CONFIG_IDF_TARGET_ESP32S2 -#include "esp32s2/cache_err_int.h" -#include "esp32s2/rom/uart.h" -#include "esp32s2/memprot.h" +#else #include "soc/extmem_reg.h" #include "soc/cache_memory.h" #include "soc/rtc_cntl_reg.h" +#if CONFIG_IDF_TARGET_ESP32S2 +#include "esp32s2/cache_err_int.h" +#include "esp32s2/memprot.h" #elif CONFIG_IDF_TARGET_ESP32S3 #include "esp32s3/cache_err_int.h" -#include "esp32s3/rom/uart.h" #include "esp32s3/memprot.h" -#include "soc/extmem_reg.h" -#include "soc/cache_memory.h" -#include "soc/rtc_cntl_reg.h" #endif +#endif // CONFIG_IDF_TARGET_ESP32 -#include "esp_private/panic_internal.h" - -extern int _invalid_pc_placeholder; - -extern void esp_panic_handler(panic_info_t*); - -static wdt_hal_context_t wdt0_context = {.inst = WDT_MWDT0, .mwdt_dev = &TIMERG0}; - -static XtExcFrame *xt_exc_frames[SOC_CPU_CORES_NUM] = {NULL}; - -/* - Panic handlers; these get called when an unhandled exception occurs or the assembly-level - task switching / interrupt code runs into an unrecoverable error. The default task stack - overflow handler and abort handler are also in here. -*/ - -/* - Note: The linker script will put everything in this file in IRAM/DRAM, so it also works with flash cache disabled. -*/ -static void print_illegal_instruction_details(const void *f) -{ - XtExcFrame *frame = (XtExcFrame *) f; - /* Print out memory around the instruction word */ - uint32_t epc = frame->pc; - epc = (epc & ~0x3) - 4; - - /* check that the address was sane */ - if (epc < SOC_IROM_MASK_LOW || epc >= SOC_IROM_HIGH) { - return; - } - volatile uint32_t *pepc = (uint32_t *)epc; - - panic_print_str("Memory dump at 0x"); - panic_print_hex(epc); - panic_print_str(": "); - - panic_print_hex(*pepc); - panic_print_str(" "); - panic_print_hex(*(pepc + 1)); - panic_print_str(" "); - panic_print_hex(*(pepc + 2)); -} - -static void print_debug_exception_details(const void *f) -{ - int debug_rsn; - asm("rsr.debugcause %0":"=r"(debug_rsn)); - panic_print_str("Debug exception reason: "); - if (debug_rsn & XCHAL_DEBUGCAUSE_ICOUNT_MASK) { - panic_print_str("SingleStep "); - } - if (debug_rsn & XCHAL_DEBUGCAUSE_IBREAK_MASK) { - panic_print_str("HwBreakpoint "); - } - if (debug_rsn & XCHAL_DEBUGCAUSE_DBREAK_MASK) { - //Unlike what the ISA manual says, this core seemingly distinguishes from a DBREAK - //reason caused by watchdog 0 and one caused by watchdog 1 by setting bit 8 of the - //debugcause if the cause is watchpoint 1 and clearing it if it's watchpoint 0. - if (debug_rsn & (1 << 8)) { -#if CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK - int core = 0; - -#if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE - if (f == xt_exc_frames[1]) { - core = 1; - } -#endif - - const char *name = pcTaskGetTaskName(xTaskGetCurrentTaskHandleForCPU(core)); - panic_print_str("Stack canary watchpoint triggered ("); - panic_print_str(name); - panic_print_str(") "); -#else - panic_print_str("Watchpoint 1 triggered "); -#endif - } else { - panic_print_str("Watchpoint 0 triggered "); - } - } - if (debug_rsn & XCHAL_DEBUGCAUSE_BREAK_MASK) { - panic_print_str("BREAK instr "); - } - if (debug_rsn & XCHAL_DEBUGCAUSE_BREAKN_MASK) { - panic_print_str("BREAKN instr "); - } - if (debug_rsn & XCHAL_DEBUGCAUSE_DEBUGINT_MASK) { - panic_print_str("DebugIntr "); - } -} - -static void print_backtrace_entry(uint32_t pc, uint32_t sp) -{ - panic_print_str("0x"); - panic_print_hex(pc); - panic_print_str(":0x"); - panic_print_hex(sp); -} - -static void print_backtrace(const void *f, int core) -{ - XtExcFrame *frame = (XtExcFrame *) f; - int depth = 100; - //Initialize stk_frame with first frame of stack - esp_backtrace_frame_t stk_frame = {.pc = frame->pc, .sp = frame->a1, .next_pc = frame->a0}; - panic_print_str("\r\nBacktrace:"); - print_backtrace_entry(esp_cpu_process_stack_pc(stk_frame.pc), stk_frame.sp); - - //Check if first frame is valid - bool corrupted = !(esp_stack_ptr_is_sane(stk_frame.sp) && - (esp_ptr_executable((void *)esp_cpu_process_stack_pc(stk_frame.pc)) || - /* Ignore the first corrupted PC in case of InstrFetchProhibited */ - frame->exccause == EXCCAUSE_INSTR_PROHIBITED)); - - uint32_t i = ((depth <= 0) ? INT32_MAX : depth) - 1; //Account for stack frame that's already printed - while (i-- > 0 && stk_frame.next_pc != 0 && !corrupted) { - if (!esp_backtrace_get_next_frame(&stk_frame)) { //Get next stack frame - corrupted = true; - } - panic_print_str(" "); - print_backtrace_entry(esp_cpu_process_stack_pc(stk_frame.pc), stk_frame.sp); - } - - //Print backtrace termination marker - if (corrupted) { - panic_print_str(" |<-CORRUPTED"); - } else if (stk_frame.next_pc != 0) { //Backtrace continues - panic_print_str(" |<-CONTINUES"); - } -} - -static void print_registers(const void *f, int core) +void panic_print_registers(const void *f, int core) { XtExcFrame *frame = (XtExcFrame *) f; int *regs = (int *)frame; + const char *sdesc[] = { "PC ", "PS ", "A0 ", "A1 ", "A2 ", "A3 ", "A4 ", "A5 ", "A6 ", "A7 ", "A8 ", "A9 ", "A10 ", "A11 ", "A12 ", "A13 ", @@ -248,37 +101,76 @@ static void print_registers(const void *f, int core) } } -static void print_state_for_core(const void *f, int core) +static void print_illegal_instruction_details(const void *f) { - if (!g_panic_abort) { - print_registers(f, core); - panic_print_str("\r\n"); + XtExcFrame *frame = (XtExcFrame *) f; + /* Print out memory around the instruction word */ + uint32_t epc = frame->pc; + epc = (epc & ~0x3) - 4; + + /* check that the address was sane */ + if (epc < SOC_IROM_MASK_LOW || epc >= SOC_IROM_HIGH) { + return; } - print_backtrace(f, core); + volatile uint32_t *pepc = (uint32_t *)epc; + + panic_print_str("Memory dump at 0x"); + panic_print_hex(epc); + panic_print_str(": "); + + panic_print_hex(*pepc); + panic_print_str(" "); + panic_print_hex(*(pepc + 1)); + panic_print_str(" "); + panic_print_hex(*(pepc + 2)); } -static void print_state(const void *f) + +static void print_debug_exception_details(const void *f) { + int debug_rsn; + asm("rsr.debugcause %0":"=r"(debug_rsn)); + panic_print_str("Debug exception reason: "); + if (debug_rsn & XCHAL_DEBUGCAUSE_ICOUNT_MASK) { + panic_print_str("SingleStep "); + } + if (debug_rsn & XCHAL_DEBUGCAUSE_IBREAK_MASK) { + panic_print_str("HwBreakpoint "); + } + if (debug_rsn & XCHAL_DEBUGCAUSE_DBREAK_MASK) { + //Unlike what the ISA manual says, this core seemingly distinguishes from a DBREAK + //reason caused by watchdog 0 and one caused by watchdog 1 by setting bit 8 of the + //debugcause if the cause is watchpoint 1 and clearing it if it's watchpoint 0. + if (debug_rsn & (1 << 8)) { +#if CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK + int core = 0; + #if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE - int err_core = f == xt_exc_frames[0] ? 0 : 1; -#else - int err_core = 0; + if (f == g_exc_frames[1]) { + core = 1; + } #endif - print_state_for_core(f, err_core); - - panic_print_str("\r\n"); - -#if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE - // If there are other frame info, print them as well - for (int i = 0; i < SOC_CPU_CORES_NUM; i++) { - // `f` is the frame for the offending core, see note above. - if (err_core != i && xt_exc_frames[i] != NULL) { - print_state_for_core(xt_exc_frames[i], i); - panic_print_str("\r\n"); + const char *name = pcTaskGetTaskName(xTaskGetCurrentTaskHandleForCPU(core)); + panic_print_str("Stack canary watchpoint triggered ("); + panic_print_str(name); + panic_print_str(") "); +#else + panic_print_str("Watchpoint 1 triggered "); +#endif + } else { + panic_print_str("Watchpoint 0 triggered "); } } -#endif + if (debug_rsn & XCHAL_DEBUGCAUSE_BREAK_MASK) { + panic_print_str("BREAK instr "); + } + if (debug_rsn & XCHAL_DEBUGCAUSE_BREAKN_MASK) { + panic_print_str("BREAKN instr "); + } + if (debug_rsn & XCHAL_DEBUGCAUSE_DEBUGINT_MASK) { + panic_print_str("DebugIntr "); + } } #if CONFIG_IDF_TARGET_ESP32S2 @@ -460,194 +352,146 @@ static inline void print_memprot_err_details(const void *f) } #endif -static void frame_to_panic_info(XtExcFrame *frame, panic_info_t *info, bool pseudo_excause) + +void panic_arch_fill_info(void *f, panic_info_t *info) { - info->core = cpu_hal_get_core_id(); - info->exception = PANIC_EXCEPTION_FAULT; - info->details = NULL; + XtExcFrame *frame = (XtExcFrame*) f; + static const char *reason[] = { + "IllegalInstruction", "Syscall", "InstructionFetchError", "LoadStoreError", + "Level1Interrupt", "Alloca", "IntegerDivideByZero", "PCValue", + "Privileged", "LoadStoreAlignment", "res", "res", + "InstrPDAddrError", "LoadStorePIFDataError", "InstrPIFAddrError", "LoadStorePIFAddrError", + "InstTLBMiss", "InstTLBMultiHit", "InstFetchPrivilege", "res", + "InstrFetchProhibited", "res", "res", "res", + "LoadStoreTLBMiss", "LoadStoreTLBMultihit", "LoadStorePrivilege", "res", + "LoadProhibited", "StoreProhibited", "res", "res", + "Cp0Dis", "Cp1Dis", "Cp2Dis", "Cp3Dis", + "Cp4Dis", "Cp5Dis", "Cp6Dis", "Cp7Dis" + }; - info->pseudo_excause = pseudo_excause; - if (pseudo_excause) { - if (frame->exccause == PANIC_RSN_INTWDT_CPU0) { - info->core = 0; - info->exception = PANIC_EXCEPTION_IWDT; - } else if (frame->exccause == PANIC_RSN_INTWDT_CPU1) { - info->core = 1; - info->exception = PANIC_EXCEPTION_IWDT; - } else if (frame->exccause == PANIC_RSN_CACHEERR) { - info->core = esp_cache_err_get_cpuid(); - } else {} - - //Please keep in sync with PANIC_RSN_* defines - static const char *pseudo_reason[] = { - "Unknown reason", - "Unhandled debug exception", - "Double exception", - "Unhandled kernel exception", - "Coprocessor exception", - "Interrupt wdt timeout on CPU0", - "Interrupt wdt timeout on CPU1", -#if CONFIG_IDF_TARGET_ESP32 - "Cache disabled but cached memory region accessed", -#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 - "Cache exception", -#endif - }; - - info->reason = pseudo_reason[0]; - info->description = NULL; - - if (frame->exccause <= PANIC_RSN_MAX) { - info->reason = pseudo_reason[frame->exccause]; - } - - if (frame->exccause == PANIC_RSN_DEBUGEXCEPTION) { - info->details = print_debug_exception_details; - info->exception = PANIC_EXCEPTION_DEBUG; - } - -#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 - if (frame->exccause == PANIC_RSN_CACHEERR) { - if ( esp_memprot_get_active_intr_memtype() != MEMPROT_NONE ) { - info->details = print_memprot_err_details; - info->reason = "Memory protection fault"; - } else { - info->details = print_cache_err_details; - } - } -#endif + if (frame->exccause < (sizeof(reason) / sizeof(char *))) { + info->reason = (reason[frame->exccause]); } else { - static const char *reason[] = { - "IllegalInstruction", "Syscall", "InstructionFetchError", "LoadStoreError", - "Level1Interrupt", "Alloca", "IntegerDivideByZero", "PCValue", - "Privileged", "LoadStoreAlignment", "res", "res", - "InstrPDAddrError", "LoadStorePIFDataError", "InstrPIFAddrError", "LoadStorePIFAddrError", - "InstTLBMiss", "InstTLBMultiHit", "InstFetchPrivilege", "res", - "InstrFetchProhibited", "res", "res", "res", - "LoadStoreTLBMiss", "LoadStoreTLBMultihit", "LoadStorePrivilege", "res", - "LoadProhibited", "StoreProhibited", "res", "res", - "Cp0Dis", "Cp1Dis", "Cp2Dis", "Cp3Dis", - "Cp4Dis", "Cp5Dis", "Cp6Dis", "Cp7Dis" - }; - - if (frame->exccause < (sizeof(reason) / sizeof(char *))) { - info->reason = (reason[frame->exccause]); - } else { - info->reason = "Unknown"; - } - - info->description = "Exception was unhandled."; - - if (frame->exccause == EXCCAUSE_ILLEGAL) { - info->details = print_illegal_instruction_details; - } + info->reason = "Unknown"; + } + + info->description = "Exception was unhandled."; + + if (frame->exccause == EXCCAUSE_ILLEGAL) { + info->details = print_illegal_instruction_details; } - info->state = print_state; info->addr = ((void *) ((XtExcFrame *) frame)->pc); - info->frame = frame; } -static void panic_handler(XtExcFrame *frame, bool pseudo_excause) +void panic_soc_fill_info(void *f, panic_info_t *info) { - /* - * Setup environment and perform necessary architecture/chip specific - * steps here prior to the system panic handler. - * */ - int core_id = cpu_hal_get_core_id(); - - // If multiple cores arrive at panic handler, save frames for all of them - xt_exc_frames[core_id] = frame; - -#if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE - // These are cases where both CPUs both go into panic handler. The following code ensures - // only one core proceeds to the system panic handler. - if (pseudo_excause) { -#define BUSY_WAIT_IF_TRUE(b) { if (b) while(1); } - // For WDT expiry, pause the non-offending core - offending core handles panic - BUSY_WAIT_IF_TRUE(frame->exccause == PANIC_RSN_INTWDT_CPU0 && core_id == 1); - BUSY_WAIT_IF_TRUE(frame->exccause == PANIC_RSN_INTWDT_CPU1 && core_id == 0); - - // For cache error, pause the non-offending core - offending core handles panic - if (frame->exccause == PANIC_RSN_CACHEERR && core_id != esp_cache_err_get_cpuid()) { - // Only print the backtrace for the offending core in case of the cache error - xt_exc_frames[core_id] = NULL; - while (1) { - ; - } - } - } - - esp_rom_delay_us(1); - SOC_HAL_STALL_OTHER_CORES(); -#endif + // [refactor-todo] this should be in the common port panic_handler.c, once + // these special exceptions are supported in there. + XtExcFrame *frame = (XtExcFrame*) f; + if (frame->exccause == PANIC_RSN_INTWDT_CPU0) { + info->core = 0; + info->exception = PANIC_EXCEPTION_IWDT; + } else if (frame->exccause == PANIC_RSN_INTWDT_CPU1) { + info->core = 1; + info->exception = PANIC_EXCEPTION_IWDT; + } else if (frame->exccause == PANIC_RSN_CACHEERR) { + info->core = esp_cache_err_get_cpuid(); + } else {} + //Please keep in sync with PANIC_RSN_* defines + static const char *pseudo_reason[] = { + "Unknown reason", + "Unhandled debug exception", + "Double exception", + "Unhandled kernel exception", + "Coprocessor exception", + "Interrupt wdt timeout on CPU0", + "Interrupt wdt timeout on CPU1", #if CONFIG_IDF_TARGET_ESP32 - esp_dport_access_int_abort(); + "Cache disabled but cached memory region accessed", +#elif CONFIG_IDF_TARGET_ESP32S2 + "Cache exception", #endif + }; -#if !CONFIG_ESP_PANIC_HANDLER_IRAM - // Re-enable CPU cache for current CPU if it was disabled - if (!spi_flash_cache_enabled()) { - spi_flash_enable_cache(core_id); - panic_print_str("Re-enable cpu cache.\r\n"); - } -#endif + info->reason = pseudo_reason[0]; + info->description = NULL; - if (esp_cpu_in_ocd_debug_mode()) { - if (!(esp_ptr_executable(cpu_ll_pc_to_ptr(frame->pc)) && (frame->pc & 0xC0000000U))) { - /* Xtensa ABI sets the 2 MSBs of the PC according to the windowed call size - * Incase the PC is invalid, GDB will fail to translate addresses to function names - * Hence replacing the PC to a placeholder address in case of invalid PC - */ - frame->pc = (uint32_t)&_invalid_pc_placeholder; - } - if (frame->exccause == PANIC_RSN_INTWDT_CPU0 || - frame->exccause == PANIC_RSN_INTWDT_CPU1) { - wdt_hal_write_protect_disable(&wdt0_context); - wdt_hal_handle_intr(&wdt0_context); - wdt_hal_write_protect_enable(&wdt0_context); - } + if (frame->exccause <= PANIC_RSN_MAX) { + info->reason = pseudo_reason[frame->exccause]; } - // Convert architecture exception frame into abstracted panic info - panic_info_t info; - frame_to_panic_info(frame, &info, pseudo_excause); - - // Call the system panic handler - esp_panic_handler(&info); -} - -void panicHandler(XtExcFrame *frame) -{ - // This panic handler gets called for when the double exception vector, - // kernel exception vector gets used; as well as handling interrupt-based - // faults cache error, wdt expiry. EXCAUSE register gets written with - // one of PANIC_RSN_* values. - panic_handler(frame, true); -} - -void xt_unhandled_exception(XtExcFrame *frame) -{ - panic_handler(frame, false); -} - -void __attribute__((noreturn)) panic_restart(void) -{ - bool digital_reset_needed = false; -#ifdef CONFIG_IDF_TARGET_ESP32 - // On the ESP32, cache error status can only be cleared by system reset - if (esp_cache_err_get_cpuid() != -1) { - digital_reset_needed = true; + if (frame->exccause == PANIC_RSN_DEBUGEXCEPTION) { + info->details = print_debug_exception_details; + info->exception = PANIC_EXCEPTION_DEBUG; } -#endif + #if CONFIG_IDF_TARGET_ESP32S2 - if (esp_memprot_is_intr_ena_any() || esp_memprot_is_locked_any()) { - digital_reset_needed = true; + if (frame->exccause == PANIC_RSN_CACHEERR) { + if ( esp_memprot_is_intr_ena_any() ) { + info->details = print_memprot_err_details; + info->reason = "Memory protection fault"; + } else { + info->details = print_cache_err_details; + } } #endif - if (digital_reset_needed) { - esp_restart_noos_dig(); - } - esp_restart_noos(); +} + +static void print_backtrace_entry(uint32_t pc, uint32_t sp) +{ + panic_print_str("0x"); + panic_print_hex(pc); + panic_print_str(":0x"); + panic_print_hex(sp); +} + +uint32_t panic_get_address(const void* f) +{ + return ((XtExcFrame*)f)->pc; +} + +uint32_t panic_get_cause(const void* f) +{ + return ((XtExcFrame*)f)->exccause; +} + +void panic_set_address(void *f, uint32_t addr) +{ + ((XtExcFrame*)f)->pc = addr; +} + +void panic_print_backtrace(const void *f, int core) +{ + // [refactor-todo] once debug helpers have support for both xtensa and riscv, move to + // common panic_handler.c + XtExcFrame *frame = (XtExcFrame *) f; + int depth = 100; + //Initialize stk_frame with first frame of stack + esp_backtrace_frame_t stk_frame = {.pc = frame->pc, .sp = frame->a1, .next_pc = frame->a0}; + panic_print_str("\r\nBacktrace:"); + print_backtrace_entry(esp_cpu_process_stack_pc(stk_frame.pc), stk_frame.sp); + + //Check if first frame is valid + bool corrupted = !(esp_stack_ptr_is_sane(stk_frame.sp) && + (esp_ptr_executable((void *)esp_cpu_process_stack_pc(stk_frame.pc)) || + /* Ignore the first corrupted PC in case of InstrFetchProhibited */ + frame->exccause == EXCCAUSE_INSTR_PROHIBITED)); + + uint32_t i = ((depth <= 0) ? INT32_MAX : depth) - 1; //Account for stack frame that's already printed + while (i-- > 0 && stk_frame.next_pc != 0 && !corrupted) { + if (!esp_backtrace_get_next_frame(&stk_frame)) { //Get next stack frame + corrupted = true; + } + panic_print_str(" "); + print_backtrace_entry(esp_cpu_process_stack_pc(stk_frame.pc), stk_frame.sp); + } + + //Print backtrace termination marker + if (corrupted) { + panic_print_str(" |<-CORRUPTED"); + } else if (stk_frame.next_pc != 0) { //Backtrace continues + panic_print_str(" |<-CONTINUES"); + } } diff --git a/components/esp_system/port/esp32/component.mk b/components/esp_system/port/esp32/component.mk deleted file mode 100644 index 88dd942940..0000000000 --- a/components/esp_system/port/esp32/component.mk +++ /dev/null @@ -1,2 +0,0 @@ -COMPONENT_SRCDIRS += port port/esp32 port/arch/xtensa -COMPONENT_OBJEXCLUDE += port/async_memcpy_impl_gdma.o diff --git a/components/esp_system/port/panic_handler.c b/components/esp_system/port/panic_handler.c new file mode 100644 index 0000000000..aff036f489 --- /dev/null +++ b/components/esp_system/port/panic_handler.c @@ -0,0 +1,220 @@ +// Copyright 2015-2016 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 "esp_spi_flash.h" + +#include "esp_private/system_internal.h" + +#include "soc/soc_memory_layout.h" +#include "soc/cpu.h" +#include "soc/soc_caps.h" +#include "soc/rtc.h" + +#include "hal/soc_hal.h" +#include "hal/cpu_hal.h" + +#include "sdkconfig.h" +#include "esp_rom_sys.h" + +#if CONFIG_IDF_TARGET_ESP32 +#include "esp32/dport_access.h" +#include "esp32/cache_err_int.h" +#elif CONFIG_IDF_TARGET_ESP32S2 +#include "esp32s2/memprot.h" +#include "esp32s2/cache_err_int.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/memprot.h" +#include "esp32s3/cache_err_int.h" +#endif + +#include "esp_private/panic_internal.h" +#include "esp_private/panic_reason.h" + +#include "hal/wdt_types.h" +#include "hal/wdt_hal.h" + +extern int _invalid_pc_placeholder; + +extern void esp_panic_handler(panic_info_t*); + +static wdt_hal_context_t wdt0_context = {.inst = WDT_MWDT0, .mwdt_dev = &TIMERG0}; + +void *g_exc_frames[SOC_CPU_CORES_NUM] = {NULL}; + +/* + Panic handlers; these get called when an unhandled exception occurs or the assembly-level + task switching / interrupt code runs into an unrecoverable error. The default task stack + overflow handler and abort handler are also in here. +*/ + +/* + Note: The linker script will put everything in this file in IRAM/DRAM, so it also works with flash cache disabled. +*/ +static void print_state_for_core(const void *f, int core) +{ + if (!g_panic_abort) { + panic_print_registers(f, core); + panic_print_str("\r\n"); + } + panic_print_backtrace(f, core); +} + +static void print_state(const void *f) +{ +#if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE + int err_core = f == g_exc_frames[0] ? 0 : 1; +#else + int err_core = 0; +#endif + + print_state_for_core(f, err_core); + + panic_print_str("\r\n"); + +#if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE + // If there are other frame info, print them as well + for (int i = 0; i < SOC_CPU_CORES_NUM; i++) { + // `f` is the frame for the offending core, see note above. + if (err_core != i && g_exc_frames[i] != NULL) { + print_state_for_core(g_exc_frames[i], i); + panic_print_str("\r\n"); + } + } +#endif +} + +static void frame_to_panic_info(void *frame, panic_info_t *info, bool pseudo_excause) +{ + info->core = cpu_hal_get_core_id(); + info->exception = PANIC_EXCEPTION_FAULT; + info->details = NULL; + info->reason = "Unknown"; + info->pseudo_excause = pseudo_excause; + + if (pseudo_excause) { + panic_soc_fill_info(frame, info); + } else { + panic_arch_fill_info(frame, info); + } + + info->state = print_state; + info->frame = frame; +} + +static void panic_handler(void *frame, bool pseudo_excause) +{ + /* + * Setup environment and perform necessary architecture/chip specific + * steps here prior to the system panic handler. + * */ + int core_id = cpu_hal_get_core_id(); + + // If multiple cores arrive at panic handler, save frames for all of them + g_exc_frames[core_id] = frame; + +#if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE + // These are cases where both CPUs both go into panic handler. The following code ensures + // only one core proceeds to the system panic handler. + if (pseudo_excause) { +#define BUSY_WAIT_IF_TRUE(b) { if (b) while(1); } + // For WDT expiry, pause the non-offending core - offending core handles panic + BUSY_WAIT_IF_TRUE(panic_get_cause(frame) == PANIC_RSN_INTWDT_CPU0 && core_id == 1); + BUSY_WAIT_IF_TRUE(panic_get_cause(frame) == PANIC_RSN_INTWDT_CPU1 && core_id == 0); + + // For cache error, pause the non-offending core - offending core handles panic + if (panic_get_cause(frame) == PANIC_RSN_CACHEERR && core_id != esp_cache_err_get_cpuid()) { + // Only print the backtrace for the offending core in case of the cache error + g_exc_frames[core_id] = NULL; + while (1) { + ; + } + } + } + + esp_rom_delay_us(1); + SOC_HAL_STALL_OTHER_CORES(); +#endif + +#if CONFIG_IDF_TARGET_ESP32 + esp_dport_access_int_abort(); +#endif + +#if !CONFIG_ESP_PANIC_HANDLER_IRAM + // Re-enable CPU cache for current CPU if it was disabled + if (!spi_flash_cache_enabled()) { + spi_flash_enable_cache(core_id); + panic_print_str("Re-enable cpu cache.\r\n"); + } +#endif + + if (esp_cpu_in_ocd_debug_mode()) { +#if __XTENSA__ + if (!(esp_ptr_executable(cpu_ll_pc_to_ptr(panic_get_address(frame))) && (panic_get_address(frame) & 0xC0000000U))) { + /* Xtensa ABI sets the 2 MSBs of the PC according to the windowed call size + * Incase the PC is invalid, GDB will fail to translate addresses to function names + * Hence replacing the PC to a placeholder address in case of invalid PC + */ + panic_set_address(frame, (uint32_t)&_invalid_pc_placeholder); + } +#endif + if (panic_get_cause(frame) == PANIC_RSN_INTWDT_CPU0 || + panic_get_cause(frame) == PANIC_RSN_INTWDT_CPU1) { + wdt_hal_write_protect_disable(&wdt0_context); + wdt_hal_handle_intr(&wdt0_context); + wdt_hal_write_protect_enable(&wdt0_context); + } + } + + // Convert architecture exception frame into abstracted panic info + panic_info_t info; + frame_to_panic_info(frame, &info, pseudo_excause); + + // Call the system panic handler + esp_panic_handler(&info); +} + +void panicHandler(void *frame) +{ + // This panic handler gets called for when the double exception vector, + // kernel exception vector gets used; as well as handling interrupt-based + // faults cache error, wdt expiry. EXCAUSE register gets written with + // one of PANIC_RSN_* values. + panic_handler(frame, true); +} + +void xt_unhandled_exception(void *frame) +{ + panic_handler(frame, false); +} + +void __attribute__((noreturn)) panic_restart(void) +{ + bool digital_reset_needed = false; +#ifdef CONFIG_IDF_TARGET_ESP32 + // On the ESP32, cache error status can only be cleared by system reset + if (esp_cache_err_get_cpuid() != -1) { + digital_reset_needed = true; + } +#endif +#if CONFIG_IDF_TARGET_ESP32S2 + if (esp_memprot_is_intr_ena_any() || esp_memprot_is_locked_any()) { + digital_reset_needed = true; + } +#endif + if (digital_reset_needed) { + esp_restart_noos_dig(); + } + esp_restart_noos(); +} diff --git a/components/esp_system/port/esp32/CMakeLists.txt b/components/esp_system/port/soc/esp32/CMakeLists.txt similarity index 84% rename from components/esp_system/port/esp32/CMakeLists.txt rename to components/esp_system/port/soc/esp32/CMakeLists.txt index f1ddfe3d05..388edd5a6e 100644 --- a/components/esp_system/port/esp32/CMakeLists.txt +++ b/components/esp_system/port/soc/esp32/CMakeLists.txt @@ -1,8 +1,8 @@ set(srcs "dport_panic_highint_hdl.S" "clk.c" "reset_reason.c" - "../arch/xtensa/panic_handler.c" - "../arch/xtensa/panic_handler_asm.S" + "../../arch/xtensa/panic_arch.c" + "../../arch/xtensa/panic_handler_asm.S" ) add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" ${srcs}) diff --git a/components/esp_system/port/esp32/clk.c b/components/esp_system/port/soc/esp32/clk.c similarity index 98% rename from components/esp_system/port/esp32/clk.c rename to components/esp_system/port/soc/esp32/clk.c index 853fa41493..e47453bfb0 100644 --- a/components/esp_system/port/esp32/clk.c +++ b/components/esp_system/port/soc/esp32/clk.c @@ -177,7 +177,8 @@ static void select_rtc_slow_clk(slow_clk_sel_t slow_clk) wdt_hal_write_protect_enable(&rtc_wdt_ctx); #endif - rtc_cpu_freq_config_t old_config, new_config; + rtc_cpu_freq_config_t old_config; + rtc_cpu_freq_config_t new_config; rtc_clk_cpu_freq_get_config(&old_config); const uint32_t old_freq_mhz = old_config.freq_mhz; const uint32_t new_freq_mhz = CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ; @@ -205,7 +206,9 @@ static void select_rtc_slow_clk(slow_clk_sel_t slow_clk) */ __attribute__((weak)) void esp_perip_clk_init(void) { - uint32_t common_perip_clk, hwcrypto_perip_clk, wifi_bt_sdio_clk = 0; + uint32_t common_perip_clk; + uint32_t hwcrypto_perip_clk; + uint32_t wifi_bt_sdio_clk; #if CONFIG_FREERTOS_UNICORE RESET_REASON rst_reas[1]; diff --git a/components/esp_system/port/soc/esp32/component.mk b/components/esp_system/port/soc/esp32/component.mk new file mode 100644 index 0000000000..02c670c81a --- /dev/null +++ b/components/esp_system/port/soc/esp32/component.mk @@ -0,0 +1,2 @@ +COMPONENT_SRCDIRS += port port/soc/esp32 port/arch/xtensa +COMPONENT_OBJEXCLUDE += port/async_memcpy_impl_gdma.o diff --git a/components/esp_system/port/esp32/dport_panic_highint_hdl.S b/components/esp_system/port/soc/esp32/dport_panic_highint_hdl.S similarity index 100% rename from components/esp_system/port/esp32/dport_panic_highint_hdl.S rename to components/esp_system/port/soc/esp32/dport_panic_highint_hdl.S diff --git a/components/esp_system/port/esp32/intr.c b/components/esp_system/port/soc/esp32/intr.c similarity index 100% rename from components/esp_system/port/esp32/intr.c rename to components/esp_system/port/soc/esp32/intr.c diff --git a/components/esp_system/port/esp32/reset_reason.c b/components/esp_system/port/soc/esp32/reset_reason.c similarity index 100% rename from components/esp_system/port/esp32/reset_reason.c rename to components/esp_system/port/soc/esp32/reset_reason.c diff --git a/components/esp_system/port/esp32s2/CMakeLists.txt b/components/esp_system/port/soc/esp32s2/CMakeLists.txt similarity index 87% rename from components/esp_system/port/esp32s2/CMakeLists.txt rename to components/esp_system/port/soc/esp32s2/CMakeLists.txt index ee8643a087..443c34c8c0 100644 --- a/components/esp_system/port/esp32s2/CMakeLists.txt +++ b/components/esp_system/port/soc/esp32s2/CMakeLists.txt @@ -2,8 +2,8 @@ set(srcs "async_memcpy_impl_cp_dma.c" "dport_panic_highint_hdl.S" "clk.c" "reset_reason.c" - "../arch/xtensa/panic_handler.c" - "../arch/xtensa/panic_handler_asm.S" + "../../arch/xtensa/panic_arch.c" + "../../arch/xtensa/panic_handler_asm.S" ) add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" ${srcs}) diff --git a/components/esp_system/port/esp32s2/async_memcpy_impl_cp_dma.c b/components/esp_system/port/soc/esp32s2/async_memcpy_impl_cp_dma.c similarity index 100% rename from components/esp_system/port/esp32s2/async_memcpy_impl_cp_dma.c rename to components/esp_system/port/soc/esp32s2/async_memcpy_impl_cp_dma.c diff --git a/components/esp_system/port/esp32s2/clk.c b/components/esp_system/port/soc/esp32s2/clk.c similarity index 100% rename from components/esp_system/port/esp32s2/clk.c rename to components/esp_system/port/soc/esp32s2/clk.c diff --git a/components/esp_system/port/esp32s2/dport_panic_highint_hdl.S b/components/esp_system/port/soc/esp32s2/dport_panic_highint_hdl.S similarity index 100% rename from components/esp_system/port/esp32s2/dport_panic_highint_hdl.S rename to components/esp_system/port/soc/esp32s2/dport_panic_highint_hdl.S diff --git a/components/esp_system/port/esp32s2/reset_reason.c b/components/esp_system/port/soc/esp32s2/reset_reason.c similarity index 100% rename from components/esp_system/port/esp32s2/reset_reason.c rename to components/esp_system/port/soc/esp32s2/reset_reason.c diff --git a/components/esp_system/port/esp32s2/usb_console.c b/components/esp_system/port/soc/esp32s2/usb_console.c similarity index 100% rename from components/esp_system/port/esp32s2/usb_console.c rename to components/esp_system/port/soc/esp32s2/usb_console.c diff --git a/components/esp_system/port/esp32s3/CMakeLists.txt b/components/esp_system/port/soc/esp32s3/CMakeLists.txt similarity index 78% rename from components/esp_system/port/esp32s3/CMakeLists.txt rename to components/esp_system/port/soc/esp32s3/CMakeLists.txt index 6bfc1d5a86..d35152b1d3 100644 --- a/components/esp_system/port/esp32s3/CMakeLists.txt +++ b/components/esp_system/port/soc/esp32s3/CMakeLists.txt @@ -1,9 +1,9 @@ set(srcs "dport_panic_highint_hdl.S" "clk.c" "reset_reason.c" - "../async_memcpy_impl_gdma.c" - "../arch/xtensa/panic_handler.c" - "../arch/xtensa/panic_handler_asm.S" + "../../async_memcpy_impl_gdma.c" + "../../arch/xtensa/panic_arch.c" + "../../arch/xtensa/panic_handler_asm.S" ) add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" ${srcs}) diff --git a/components/esp_system/port/esp32s3/clk.c b/components/esp_system/port/soc/esp32s3/clk.c similarity index 100% rename from components/esp_system/port/esp32s3/clk.c rename to components/esp_system/port/soc/esp32s3/clk.c diff --git a/components/esp_system/port/esp32s3/dport_panic_highint_hdl.S b/components/esp_system/port/soc/esp32s3/dport_panic_highint_hdl.S similarity index 100% rename from components/esp_system/port/esp32s3/dport_panic_highint_hdl.S rename to components/esp_system/port/soc/esp32s3/dport_panic_highint_hdl.S diff --git a/components/esp_system/port/esp32s3/reset_reason.c b/components/esp_system/port/soc/esp32s3/reset_reason.c similarity index 100% rename from components/esp_system/port/esp32s3/reset_reason.c rename to components/esp_system/port/soc/esp32s3/reset_reason.c diff --git a/components/riscv/include/esp_private/panic_reason.h b/components/riscv/include/esp_private/panic_reason.h new file mode 100644 index 0000000000..a91e6b3396 --- /dev/null +++ b/components/riscv/include/esp_private/panic_reason.h @@ -0,0 +1,20 @@ +// Copyright 2020 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. +#pragma once + +#define PANIC_RSN_NONE 0 +#define PANIC_RSN_INTWDT_CPU0 1 +#define PANIC_RSN_INTWDT_CPU1 2 +#define PANIC_RSN_CACHEERR 3 +#define PANIC_RSN_MAX 3 diff --git a/components/riscv/include/riscv/rvruntime-frames.h b/components/riscv/include/riscv/rvruntime-frames.h index b4e4c141b5..1ef8934f14 100644 --- a/components/riscv/include/riscv/rvruntime-frames.h +++ b/components/riscv/include/riscv/rvruntime-frames.h @@ -1,8 +1,22 @@ +// Copyright 2015-2020 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. + #ifndef __RVRUNTIME_FRAMES_H__ #define __RVRUNTIME_FRAMES_H__ /* Align a value up to nearest n-byte boundary, where n is a power of 2. */ -#define ALIGNUP(n, val) (((val) + (n)-1) & -(n)) +#define ALIGNUP(n, val) (((val) + (n) - 1) & -(n)) #ifdef STRUCT_BEGIN #undef STRUCT_BEGIN @@ -12,19 +26,15 @@ #endif #if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__) - #define STRUCT_BEGIN .pushsection .text; .struct 0 #define STRUCT_FIELD(ctype,size,asname,name) asname: .space size #define STRUCT_AFIELD(ctype,size,asname,name,n) asname: .space (size)*(n) #define STRUCT_END(sname) sname##Size:; .popsection - #else - #define STRUCT_BEGIN typedef struct { #define STRUCT_FIELD(ctype,size,asname,name) ctype name; #define STRUCT_AFIELD(ctype,size,asname,name,n) ctype name[n]; #define STRUCT_END(sname) } sname; - #endif /* @@ -33,63 +43,54 @@ ------------------------------------------------------------------------------- */ STRUCT_BEGIN -STRUCT_FIELD (long, 4, RV_STK_MEPC, mepc) /* Machine Exception Program Counter */ -STRUCT_FIELD (long, 4, RV_STK_RA, ra) /* Return address */ -STRUCT_FIELD (long, 4, RV_STK_SP, sp) /* Stack pointer */ -STRUCT_FIELD (long, 4, RV_STK_GP, gp) /* Global pointer */ -STRUCT_FIELD (long, 4, RV_STK_TP, tp) /* Thread pointer */ -STRUCT_FIELD (long, 4, RV_STK_T0, t0) /* Temporary/alternate link register */ -STRUCT_FIELD (long, 4, RV_STK_T1, t1) /* t1-2: Temporaries */ -STRUCT_FIELD (long, 4, RV_STK_T2, t2) -STRUCT_FIELD (long, 4, RV_STK_S0, s0) /* Saved register/frame pointer */ -STRUCT_FIELD (long, 4, RV_STK_S1, s1) /* Saved register */ -STRUCT_FIELD (long, 4, RV_STK_A0, a0) /* a0-1: Function arguments/return address */ -STRUCT_FIELD (long, 4, RV_STK_A1, a1) -STRUCT_FIELD (long, 4, RV_STK_A2, a2) /* a2-7: Function arguments */ -STRUCT_FIELD (long, 4, RV_STK_A3, a3) -STRUCT_FIELD (long, 4, RV_STK_A4, a4) -STRUCT_FIELD (long, 4, RV_STK_A5, a5) -STRUCT_FIELD (long, 4, RV_STK_A6, a6) -STRUCT_FIELD (long, 4, RV_STK_A7, a7) -STRUCT_FIELD (long, 4, RV_STK_S2, s2) /* s2-11: Saved registers */ -STRUCT_FIELD (long, 4, RV_STK_S3, s3) -STRUCT_FIELD (long, 4, RV_STK_S4, s4) -STRUCT_FIELD (long, 4, RV_STK_S5, s5) -STRUCT_FIELD (long, 4, RV_STK_S6, s6) -STRUCT_FIELD (long, 4, RV_STK_S7, s7) -STRUCT_FIELD (long, 4, RV_STK_S8, s8) -STRUCT_FIELD (long, 4, RV_STK_S9, s9) -STRUCT_FIELD (long, 4, RV_STK_S10, s10) -STRUCT_FIELD (long, 4, RV_STK_S11, s11) -STRUCT_FIELD (long, 4, RV_STK_T3, t3) /* t3-6: Temporaries */ -STRUCT_FIELD (long, 4, RV_STK_T4, t4) -STRUCT_FIELD (long, 4, RV_STK_T5, t5) -STRUCT_FIELD (long, 4, RV_STK_T6, t6) -STRUCT_FIELD (long, 4, RV_STK_MSTATUS, mstatus) /* Machine Status */ -STRUCT_FIELD (long, 4, RV_STK_MTVEC, mtvec) /* Machine Trap-Vector Base Address */ -STRUCT_FIELD (long, 4, RV_STK_MCAUSE, mcause) /* Machine Trap Cause */ -STRUCT_FIELD (long, 4, RV_STK_PCCRS, pccrs) /* Performance Counter Counter Registers */ -STRUCT_FIELD (long, 4, RV_STK_PCER, pcer) /* Performance Counter Enable */ -STRUCT_FIELD (long, 4, RV_STK_PCMR, pcmr) /* Performance Counter Mode */ -STRUCT_FIELD (long, 4, RV_STK_HWLP, hwlp) /* Hardware Loop Registers */ -STRUCT_FIELD (long, 4, RV_STK_PRIVLV, privlv) /* Privilege Level */ -STRUCT_FIELD (long, 4, RV_STK_UHARTID, uhartid) /* Hardware Thread ID */ -STRUCT_FIELD (long, 4, RV_STK_MHARTID, mhartid) /* Hardware Thread ID */ -STRUCT_FIELD (long, 4, RV_STK_DCSR, dcsr) /* Debug Control and Status */ -STRUCT_FIELD (long, 4, RV_STK_DPC, dpc) /* Debug PC */ -STRUCT_FIELD (long, 4, RV_STK_INTC_THRESH, intc_thresh) -STRUCT_FIELD (long, 4, RV_STK_RESERVED0, reserved0) +STRUCT_FIELD (long, 4, RV_STK_MEPC, mepc) /* Machine Exception Program Counter */ +STRUCT_FIELD (long, 4, RV_STK_RA, ra) /* Return address */ +STRUCT_FIELD (long, 4, RV_STK_SP, sp) /* Stack pointer */ +STRUCT_FIELD (long, 4, RV_STK_GP, gp) /* Global pointer */ +STRUCT_FIELD (long, 4, RV_STK_TP, tp) /* Thread pointer */ +STRUCT_FIELD (long, 4, RV_STK_T0, t0) /* Temporary/alternate link register */ +STRUCT_FIELD (long, 4, RV_STK_T1, t1) /* t1-2: Temporaries */ +STRUCT_FIELD (long, 4, RV_STK_T2, t2) +STRUCT_FIELD (long, 4, RV_STK_S0, s0) /* Saved register/frame pointer */ +STRUCT_FIELD (long, 4, RV_STK_S1, s1) /* Saved register */ +STRUCT_FIELD (long, 4, RV_STK_A0, a0) /* a0-1: Function arguments/return address */ +STRUCT_FIELD (long, 4, RV_STK_A1, a1) +STRUCT_FIELD (long, 4, RV_STK_A2, a2) /* a2-7: Function arguments */ +STRUCT_FIELD (long, 4, RV_STK_A3, a3) +STRUCT_FIELD (long, 4, RV_STK_A4, a4) +STRUCT_FIELD (long, 4, RV_STK_A5, a5) +STRUCT_FIELD (long, 4, RV_STK_A6, a6) +STRUCT_FIELD (long, 4, RV_STK_A7, a7) +STRUCT_FIELD (long, 4, RV_STK_S2, s2) /* s2-11: Saved registers */ +STRUCT_FIELD (long, 4, RV_STK_S3, s3) +STRUCT_FIELD (long, 4, RV_STK_S4, s4) +STRUCT_FIELD (long, 4, RV_STK_S5, s5) +STRUCT_FIELD (long, 4, RV_STK_S6, s6) +STRUCT_FIELD (long, 4, RV_STK_S7, s7) +STRUCT_FIELD (long, 4, RV_STK_S8, s8) +STRUCT_FIELD (long, 4, RV_STK_S9, s9) +STRUCT_FIELD (long, 4, RV_STK_S10, s10) +STRUCT_FIELD (long, 4, RV_STK_S11, s11) +STRUCT_FIELD (long, 4, RV_STK_T3, t3) /* t3-6: Temporaries */ +STRUCT_FIELD (long, 4, RV_STK_T4, t4) +STRUCT_FIELD (long, 4, RV_STK_T5, t5) +STRUCT_FIELD (long, 4, RV_STK_T6, t6) +STRUCT_FIELD (long, 4, RV_STK_MSTATUS, mstatus) /* Machine Status */ +STRUCT_FIELD (long, 4, RV_STK_MTVEC, mtvec) /* Machine Trap-Vector Base Address */ +STRUCT_FIELD (long, 4, RV_STK_MCAUSE, mcause) /* Machine Trap Cause */ +STRUCT_FIELD (long, 4, RV_STK_MTVAL, mtval) /* Machine Trap Value */ +STRUCT_FIELD (long, 4, RV_STK_MHARTID, mhartid) /* Hardware Thread ID in machine mode */ STRUCT_END(RvExcFrame) #if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__) -# define RV_STK_SZ1 RvExcFrameSize +#define RV_STK_SZ1 RvExcFrameSize #else -# define RV_STK_SZ1 sizeof(RvExcFrame) +#define RV_STK_SZ1 sizeof(RvExcFrame) #endif /* - * This is the frame size. + * Exception stack frame size, after align up to 16 bytes boundary */ -#define RV_STK_FRMSZ (ALIGNUP(0x10, RV_STK_SZ1)) +#define RV_STK_FRMSZ (ALIGNUP(0x10, RV_STK_SZ1)) #endif /* #ifndef __RVRUNTIME_FRAMES_H__ */ diff --git a/components/riscv/vectors.S b/components/riscv/vectors.S index 4348cb1047..203c5adabe 100644 --- a/components/riscv/vectors.S +++ b/components/riscv/vectors.S @@ -13,101 +13,85 @@ // limitations under the License. #include "soc/soc.h" #include "soc/interrupt_reg.h" +#include "riscv/rvruntime-frames.h" .equ SAVE_REGS, 32 .equ CONTEXT_SIZE, (SAVE_REGS * 4) - .equ PANIC_REGS, 38 - .equ PANIC_REGS_SIZE, (PANIC_REGS * 4) - -.altmacro - -.macro lwsp a, b - lw \a, ((\b)*4)(sp) -.endm - -.macro swsp a, b - sw \a, ((\b)*4)(sp) -.endm - .macro save_regs - addi sp, sp, -CONTEXT_SIZE - swsp ra, 1 - swsp a0, 2 - swsp a1, 3 - swsp a2, 4 - swsp a3, 5 - swsp a4, 6 - swsp a5, 7 - swsp a6, 8 - swsp a7, 9 - swsp t0, 10 - swsp t1, 11 - swsp t2, 12 - swsp t3, 13 - swsp t4, 14 - swsp t5, 15 - swsp t6, 16 - //swsp sp, 17 - //swsp gp, 18 - swsp tp, 19 - swsp s0, 20 - swsp s1, 21 - swsp s2, 22 - swsp s3, 23 - swsp s4, 24 - swsp s5, 25 - swsp s6, 26 - swsp s7, 27 - swsp s8, 28 - swsp s9, 29 - swsp s10, 30 - swsp s11, 31 + addi sp, sp, -CONTEXT_SIZE + sw ra, RV_STK_RA(sp) + sw tp, RV_STK_TP(sp) + sw t0, RV_STK_T0(sp) + sw t1, RV_STK_T1(sp) + sw t2, RV_STK_T2(sp) + sw s0, RV_STK_S0(sp) + sw s1, RV_STK_S1(sp) + sw a0, RV_STK_A0(sp) + sw a1, RV_STK_A1(sp) + sw a2, RV_STK_A2(sp) + sw a3, RV_STK_A3(sp) + sw a4, RV_STK_A4(sp) + sw a5, RV_STK_A5(sp) + sw a6, RV_STK_A6(sp) + sw a7, RV_STK_A7(sp) + sw s2, RV_STK_S2(sp) + sw s3, RV_STK_S3(sp) + sw s4, RV_STK_S4(sp) + sw s5, RV_STK_S5(sp) + sw s6, RV_STK_S6(sp) + sw s7, RV_STK_S7(sp) + sw s8, RV_STK_S8(sp) + sw s9, RV_STK_S9(sp) + sw s10, RV_STK_S10(sp) + sw s11, RV_STK_S11(sp) + sw t3, RV_STK_T3(sp) + sw t4, RV_STK_T4(sp) + sw t5, RV_STK_T5(sp) + sw t6, RV_STK_T6(sp) .endm .macro save_mepc - csrr t0, mepc - swsp t0, 0 + csrr t0, mepc + sw t0, RV_STK_MEPC(sp) .endm .macro restore_regs - lwsp ra, 1 - lwsp a0, 2 - lwsp a1, 3 - lwsp a2, 4 - lwsp a3, 5 - lwsp a4, 6 - lwsp a5, 7 - lwsp a6, 8 - lwsp a7, 9 - lwsp t0, 10 - lwsp t1, 11 - lwsp t2, 12 - lwsp t3, 13 - lwsp t4, 14 - lwsp t5, 15 - lwsp t6, 16 - //lwsp sp, 17 - //lwsp gp, 18 - lwsp tp, 19 - lwsp s0, 20 - lwsp s1, 21 - lwsp s2, 22 - lwsp s3, 23 - lwsp s4, 24 - lwsp s5, 25 - lwsp s6, 26 - lwsp s7, 27 - lwsp s8, 28 - lwsp s9, 29 - lwsp s10, 30 - lwsp s11, 31 + lw ra, RV_STK_RA(sp) + lw tp, RV_STK_TP(sp) + lw t0, RV_STK_T0(sp) + lw t1, RV_STK_T1(sp) + lw t2, RV_STK_T2(sp) + lw s0, RV_STK_S0(sp) + lw s1, RV_STK_S1(sp) + lw a0, RV_STK_A0(sp) + lw a1, RV_STK_A1(sp) + lw a2, RV_STK_A2(sp) + lw a3, RV_STK_A3(sp) + lw a4, RV_STK_A4(sp) + lw a5, RV_STK_A5(sp) + lw a6, RV_STK_A6(sp) + lw a7, RV_STK_A7(sp) + lw s2, RV_STK_S2(sp) + lw s3, RV_STK_S3(sp) + lw s4, RV_STK_S4(sp) + lw s5, RV_STK_S5(sp) + lw s6, RV_STK_S6(sp) + lw s7, RV_STK_S7(sp) + lw s8, RV_STK_S8(sp) + lw s9, RV_STK_S9(sp) + lw s10, RV_STK_S10(sp) + lw s11, RV_STK_S11(sp) + lw t3, RV_STK_T3(sp) + lw t4, RV_STK_T4(sp) + lw t5, RV_STK_T5(sp) + lw t6, RV_STK_T6(sp) addi sp, sp, CONTEXT_SIZE .endm .macro restore_mepc - lwsp t0, 0 + lw t0, RV_STK_MEPC(sp) csrw mepc, t0 .endm @@ -143,61 +127,61 @@ _vector_table: .size _vector_table, .-_vector_table /* Exception handler.*/ - .global panicHandler + .global xt_unhandled_exception .type _panic_handler, @function _panic_handler: - addi sp, sp, -PANIC_REGS_SIZE - swsp x0, 0 - swsp x1, 1 - /* x2 is sp - it will be placed on stack later (after we can use the other registers for computation) */ - swsp x3, 3 - swsp x4, 4 - swsp x5, 5 - swsp x6, 6 - swsp x7, 7 - swsp x8, 8 - swsp x9, 9 - swsp x10, 10 - swsp x11, 11 - swsp x12, 12 - swsp x13, 13 - swsp x14, 14 - swsp x15, 15 - swsp x16, 16 - swsp x17, 17 - swsp x18, 18 - swsp x19, 19 - swsp x20, 20 - swsp x21, 21 - swsp x22, 22 - swsp x23, 23 - swsp x24, 24 - swsp x25, 25 - swsp x26, 26 - swsp x27, 27 - swsp x28, 28 - swsp x29, 29 - swsp x30, 30 - swsp x31, 31 - /* "Undo" the modification already done to the sp (x2) by the panic handler */ - addi a1, x2, PANIC_REGS_SIZE - swsp a1, 2 - csrr a1, mcause - swsp a1, 32 - csrr a1, mepc - swsp a1, 33 - csrr a1, mhartid - swsp a1, 34 - csrr a1, mstatus - swsp a1, 35 - csrr a1, mtval - swsp a1, 36 - csrr a1, mtvec - swsp a1, 37 + addi sp, sp, -RV_STK_FRMSZ /* allocate space on stack to store necessary registers */ + /* save general registers */ + sw ra, RV_STK_RA(sp) + sw gp, RV_STK_GP(sp) + sw tp, RV_STK_TP(sp) + sw t0, RV_STK_T0(sp) + sw t1, RV_STK_T1(sp) + sw t2, RV_STK_T2(sp) + sw s0, RV_STK_S0(sp) + sw s1, RV_STK_S1(sp) + sw a0, RV_STK_A0(sp) + sw a1, RV_STK_A1(sp) + sw a2, RV_STK_A2(sp) + sw a3, RV_STK_A3(sp) + sw a4, RV_STK_A4(sp) + sw a5, RV_STK_A5(sp) + sw a6, RV_STK_A6(sp) + sw a7, RV_STK_A7(sp) + sw s2, RV_STK_S2(sp) + sw s3, RV_STK_S3(sp) + sw s4, RV_STK_S4(sp) + sw s5, RV_STK_S5(sp) + sw s6, RV_STK_S6(sp) + sw s7, RV_STK_S7(sp) + sw s8, RV_STK_S8(sp) + sw s9, RV_STK_S9(sp) + sw s10, RV_STK_S10(sp) + sw s11, RV_STK_S11(sp) + sw t3, RV_STK_T3(sp) + sw t4, RV_STK_T4(sp) + sw t5, RV_STK_T5(sp) + sw t6, RV_STK_T6(sp) + addi t0, sp, RV_STK_FRMSZ /* restore sp with the value when trap happened */ + sw t0, RV_STK_SP(sp) + csrr t0, mepc + sw t0, RV_STK_MEPC(sp) + csrr t0, mstatus + sw t0, RV_STK_MSTATUS(sp) + csrr t0, mtvec + sw t0, RV_STK_MTVEC(sp) + csrr t0, mcause + sw t0, RV_STK_MCAUSE(sp) + csrr t0, mtval + sw t0, RV_STK_MTVAL(sp) + csrr t0, mhartid + sw t0, RV_STK_MHARTID(sp) + + /* call xt_unhandled_exception(sp,cause) */ mv a0, sp csrr a1, mcause - jal zero, panicHandler - /* panicHandler never returns */ + jal zero, xt_unhandled_exception + /* panicHandler never returns */ .size _panic_handler, .-_panic_handler /* This is the interrupt handler. @@ -215,16 +199,15 @@ _interrupt_handler: /* scheduler not enabled, jump directly to ISR handler */ lw t0, uxSchedulerRunning - beq t0,zero,already_on_handler + beq t0, zero, already_on_handler /* increments the ISR nesting count */ - /* This will work properly when we have nested interrupts */ la t0, uxInterruptNesting lw t1, 0x0(t0) addi t2,t1,1 sw t2, 0x0(t0) - /* If reached here from another low-prio ISR, skip stack pushing to TCB */ + /* If reached here from another low priority ISR, skip stack pushing to TCB */ bne t1,zero, already_on_handler /* Otherwise, save current sp, and use the isr stack from here */ @@ -242,7 +225,7 @@ already_on_handler: lw s3, 0(t0) /* Increase interrupt threshold level */ - la t2, 0x7fffffff + li t2, 0x7fffffff and t1, s1, t2 /* t1 = mcause & mask */ slli t1, t1, 2 /* t1 = mcause * 4 */ la t2, INTC_INT_PRIO_REG(0) @@ -252,14 +235,14 @@ already_on_handler: sw t2, 0(t0) /* INTERRUPT_CORE0_CPU_INT_THRESH_REG = t2 */ fence - la t0, 0x8 + li t0, 0x8 csrrs t0, mstatus, t0 /* call the C dispatcher */ mv a0, sp /* argument 1, stack pointer */ csrr a1, mcause /* argument 2, interrupt number */ /* mask off the interrupt flag of mcause */ - la t0, 0x7fffffff + li t0, 0x7fffffff and a1, a1, t0 jal _global_interrupt_handler @@ -281,7 +264,7 @@ already_on_handler: la t0, uxInterruptNesting lw t1, 0x0(t0) - /* Already zero, protect againts underflow */ + /* Already zero, protect against underflow */ beq t1, zero, isr_skip_decrement addi t1,t1, -1 sw t1, 0x0(t0) @@ -290,7 +273,7 @@ isr_skip_decrement: /* may still have interrupts pending, skip section below and exit */ bne t1,zero,isr_exit - /* handlered all the ISRs and scheduled the next task, take its stack */ + /* handled all the ISRs and scheduled the next task, take its stack */ /* load on sp, then exit. */ lw sp, pxCurrentTCB lw sp, 0x0(sp) diff --git a/docs/en/api-guides/hlinterrupts.rst b/docs/en/api-guides/hlinterrupts.rst index 4d6b4a9d60..c5e28cb119 100644 --- a/docs/en/api-guides/hlinterrupts.rst +++ b/docs/en/api-guides/hlinterrupts.rst @@ -31,7 +31,7 @@ Using these symbols is done by creating an assembly file (suffix .S) and definin rsr a0, EXCSAVE_5 rfi 5 -For a real-life example, see the :component_file:`esp_system/port/{IDF_TARGET_PATH_NAME}/dport_panic_highint_hdl.S` file; the panic handler interrupt is implemented there. +For a real-life example, see the :component_file:`esp_system/port/soc/{IDF_TARGET_PATH_NAME}/dport_panic_highint_hdl.S` file; the panic handler interrupt is implemented there. Notes diff --git a/tools/test_idf_size/app.map b/tools/test_idf_size/app.map index a8bdc4d976..0dae32b208 100644 --- a/tools/test_idf_size/app.map +++ b/tools/test_idf_size/app.map @@ -17299,7 +17299,7 @@ END GROUP .literal.commonErrorHandler 0x0000000040080b80 0x4 /home/user/esp/esp-idf/tools/unit-test-app/build/esp32/libesp32.a(panic.o) 0x28 (size before relaxing) - .literal.panicHandler + .literal.panic_handle_pseudo_exception 0x0000000040080b84 0x38 /home/user/esp/esp-idf/tools/unit-test-app/build/esp32/libesp32.a(panic.o) 0xc0 (size before relaxing) .literal.xt_unhandled_exception @@ -18250,10 +18250,10 @@ END GROUP 0x0000000040087c34 0x44 /home/user/esp/esp-idf/tools/unit-test-app/build/esp32/libesp32.a(panic.o) 0x56 (size before relaxing) *fill* 0x0000000040087c78 0x0 - .text.panicHandler + .text.panic_handle_pseudo_exception 0x0000000040087c78 0x1a0 /home/user/esp/esp-idf/tools/unit-test-app/build/esp32/libesp32.a(panic.o) 0x1cc (size before relaxing) - 0x0000000040087c78 panicHandler + 0x0000000040087c78 panic_handle_pseudo_exception .text.xt_unhandled_exception 0x0000000040087e18 0x77 /home/user/esp/esp-idf/tools/unit-test-app/build/esp32/libesp32.a(panic.o) 0xa1 (size before relaxing) diff --git a/tools/test_idf_size/app2.map b/tools/test_idf_size/app2.map index ca6114cefe..51dd2ad2a8 100644 --- a/tools/test_idf_size/app2.map +++ b/tools/test_idf_size/app2.map @@ -8909,7 +8909,7 @@ LOAD /home/xy/.espressif/tools/xtensa-esp32-elf/esp-2019r2-8.2.0/xtensa-esp32-el .literal.vApplicationStackOverflowHook 0x0000000040080bb8 0x8 esp-idf/esp32/libesp32.a(panic.c.obj) 0x18 (size before relaxing) - .literal.panicHandler + .literal.panic_handle_pseudo_exception 0x0000000040080bc0 0x34 esp-idf/esp32/libesp32.a(panic.c.obj) 0xa8 (size before relaxing) .literal.xt_unhandled_exception @@ -10153,10 +10153,10 @@ LOAD /home/xy/.espressif/tools/xtensa-esp32-elf/esp-2019r2-8.2.0/xtensa-esp32-el 0x23 (size before relaxing) 0x0000000040086bd0 vApplicationStackOverflowHook *fill* 0x0000000040086be7 0x1 - .text.panicHandler + .text.panic_handle_pseudo_exception 0x0000000040086be8 0x165 esp-idf/esp32/libesp32.a(panic.c.obj) 0x19c (size before relaxing) - 0x0000000040086be8 panicHandler + 0x0000000040086be8 panic_handle_pseudo_exception *fill* 0x0000000040086d4d 0x3 .text.xt_unhandled_exception 0x0000000040086d50 0x88 esp-idf/esp32/libesp32.a(panic.c.obj) @@ -10939,7 +10939,7 @@ LOAD /home/xy/.espressif/tools/xtensa-esp32-elf/esp-2019r2-8.2.0/xtensa-esp32-el .rodata.vApplicationStackOverflowHook.str1.4 0x000000003ffb1cbc 0x3e esp-idf/esp32/libesp32.a(panic.c.obj) *fill* 0x000000003ffb1cfa 0x2 - .rodata.panicHandler.str1.4 + .rodata.panic_handle_pseudo_exception.str1.4 0x000000003ffb1cfc 0x1a9 esp-idf/esp32/libesp32.a(panic.c.obj) *fill* 0x000000003ffb1ea5 0x3 .rodata.xt_unhandled_exception.str1.4 @@ -17060,7 +17060,7 @@ newlib_include_locks_impl esp-idf/newlib/libnewlib.a(loc newlib_include_pthread_impl esp-idf/newlib/libnewlib.a(pthread.c.obj) newlib_include_syscalls_impl esp-idf/newlib/libnewlib.a(syscalls.c.obj) opendir esp-idf/vfs/libvfs.a(vfs.c.obj) -panicHandler esp-idf/esp32/libesp32.a(panic.c.obj) +panic_handle_pseudo_exception esp-idf/esp32/libesp32.a(panic.c.obj) esp-idf/freertos/libfreertos.a(xtensa_vectors.S.obj) esp-idf/esp32/libesp32.a(dport_panic_highint_hdl.S.obj) pcTaskGetTaskName esp-idf/freertos/libfreertos.a(tasks.c.obj) diff --git a/tools/test_idf_size/app_esp32s2.map b/tools/test_idf_size/app_esp32s2.map index c805a8f1e0..e459ef3e6c 100644 --- a/tools/test_idf_size/app_esp32s2.map +++ b/tools/test_idf_size/app_esp32s2.map @@ -7678,7 +7678,7 @@ LOAD /home/xy/.espressif/tools/xtensa-esp32s2-elf/esp-2019r2-8.2.0/xtensa-esp32s .literal.vApplicationStackOverflowHook 0x0000000040024a4c 0x8 esp-idf/esp32s2/libesp32s2.a(panic.c.obj) 0x18 (size before relaxing) - .literal.panicHandler + .literal.panic_handle_pseudo_exception 0x0000000040024a54 0x9c esp-idf/esp32s2/libesp32s2.a(panic.c.obj) 0x1a8 (size before relaxing) .literal.xt_unhandled_exception @@ -8819,10 +8819,10 @@ LOAD /home/xy/.espressif/tools/xtensa-esp32s2-elf/esp-2019r2-8.2.0/xtensa-esp32s 0x23 (size before relaxing) 0x0000000040029b88 vApplicationStackOverflowHook *fill* 0x0000000040029b9f 0x1 - .text.panicHandler + .text.panic_handle_pseudo_exception 0x0000000040029ba0 0x31d esp-idf/esp32s2/libesp32s2.a(panic.c.obj) 0x3a0 (size before relaxing) - 0x0000000040029ba0 panicHandler + 0x0000000040029ba0 panic_handle_pseudo_exception *fill* 0x0000000040029ebd 0x3 .text.xt_unhandled_exception 0x0000000040029ec0 0x7d esp-idf/esp32s2/libesp32s2.a(panic.c.obj) @@ -9570,7 +9570,7 @@ LOAD /home/xy/.espressif/tools/xtensa-esp32s2-elf/esp-2019r2-8.2.0/xtensa-esp32s .rodata.vApplicationStackOverflowHook.str1.4 0x000000003ffbd8f4 0x3e esp-idf/esp32s2/libesp32s2.a(panic.c.obj) *fill* 0x000000003ffbd932 0x2 - .rodata.panicHandler.str1.4 + .rodata.panic_handle_pseudo_exception.str1.4 0x000000003ffbd934 0x418 esp-idf/esp32s2/libesp32s2.a(panic.c.obj) .rodata.xt_unhandled_exception.str1.4 0x000000003ffbdd4c 0x4d esp-idf/esp32s2/libesp32s2.a(panic.c.obj) @@ -15047,7 +15047,7 @@ newlib_include_locks_impl esp-idf/newlib/libnewlib.a(loc newlib_include_pthread_impl esp-idf/newlib/libnewlib.a(pthread.c.obj) newlib_include_syscalls_impl esp-idf/newlib/libnewlib.a(syscalls.c.obj) opendir esp-idf/vfs/libvfs.a(vfs.c.obj) -panicHandler esp-idf/esp32s2/libesp32s2.a(panic.c.obj) +panic_handle_pseudo_exception esp-idf/esp32s2/libesp32s2.a(panic.c.obj) esp-idf/freertos/libfreertos.a(xtensa_vectors.S.obj) esp-idf/esp32s2/libesp32s2.a(dport_panic_highint_hdl.S.obj) pcTaskGetTaskName esp-idf/freertos/libfreertos.a(tasks.c.obj)