1
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
60
61
64
65
66
70
71
72
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
104
105
106
107
108
109
110
111
112
113
114
115
120
121
122
123
124
125
126
132
133
134
135
136
137
141
142
143
144
145
146
147
148
149
180
181
182
183
184
185
186
191
192
193
194
195
196
197
205
206
207
208
209
214
215
216
217
218
219
220
221
222
223
227
228
237
238
239
240
241
242
243
244
245
246
247
248
249
250
257
258
/* ... */
#include <stdlib.h>
#include "esp_macros.h"
#include "esp_ipc_isr.h"
#include "esp_private/system_internal.h"
#include "esp_private/cache_utils.h"
#include "soc/soc_memory_layout.h"
#include "esp_cpu.h"
#include "soc/soc_caps.h"
#include "soc/rtc.h"
#include "hal/soc_hal.h"
#include "esp_private/cache_err_int.h"
#include "sdkconfig.h"
#include "esp_rom_sys.h"13 includes
#if CONFIG_ESP_SYSTEM_MEMPROT_FEATURE
#ifdef CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/memprot.h"
#else
#include "esp_memprot.h"
#endif/* ... */
#endif
#include "esp_private/panic_internal.h"
#include "esp_private/panic_reason.h"
#include "hal/wdt_types.h"
#include "hal/wdt_hal.h"
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
#include "esp_private/hw_stack_guard.h"
#endif
extern int _invalid_pc_placeholder;
extern void esp_panic_handler_reconfigure_wdts(uint32_t timeout_ms);
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};
/* ... */
/* ... */
static void print_state_for_core(const void *f, int core)
{
/* ... */
#if (CONFIG_IDF_TARGET_ARCH_XTENSA && defined(XCHAL_HAVE_WINDOWED)) || \
(CONFIG_IDF_TARGET_ARCH_RISCV && CONFIG_ESP_SYSTEM_USE_EH_FRAME)
if (!g_panic_abort) {
#else
if (true) {
#endif
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
for (int i = 0; i < SOC_CPU_CORES_NUM; i++) {
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 = esp_cpu_get_core_id();
info->exception = PANIC_EXCEPTION_FAULT;
info->details = NULL;
info->reason = "Unknown";
info->pseudo_excause = panic_soc_check_pseudo_cause(frame, info) | pseudo_excause;
if (info->pseudo_excause) {
panic_soc_fill_info(frame, info);
}{...} else {
panic_arch_fill_info(frame, info);
}{...}
info->state = print_state;
info->frame = frame;
}{ ... }
#if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
FORCE_INLINE_ATTR __attribute__((__noreturn__))
void busy_wait(void)
{
ESP_INFINITE_LOOP();
}{ ... }
/* ... */#endif
static void panic_handler(void *frame, bool pseudo_excause)
{
panic_info_t info = { 0 };
/* ... */
int core_id = esp_cpu_get_core_id();
g_exc_frames[core_id] = frame;
#if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
if (pseudo_excause) {
if (panic_get_cause(frame) == PANIC_RSN_INTWDT_CPU0 && core_id == 1) {
busy_wait();
}{...} else if (panic_get_cause(frame) == PANIC_RSN_INTWDT_CPU1 && core_id == 0) {
busy_wait();
}{...} else if (panic_get_cause(frame) == PANIC_RSN_CACHEERR) {
if (esp_cache_err_get_cpuid() == -1) {
if (core_id != 0) {
busy_wait();
}{...}
}{...} else if (core_id != esp_cache_err_get_cpuid()) {
g_exc_frames[core_id] = NULL;
busy_wait();
}{...}
}{...}
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
else if (panic_get_cause(frame) == ETS_ASSIST_DEBUG_INUM &&
esp_hw_stack_guard_get_fired_cpu() != core_id &&
esp_hw_stack_guard_get_fired_cpu() != ESP_HW_STACK_GUARD_NOT_FIRED) {
g_exc_frames[core_id] = NULL;
busy_wait();
}{...}
#endif/* ... */
}{...}
esp_panic_handler_reconfigure_wdts(1000);
esp_rom_delay_us(1);
for (uint32_t i = 0; i < SOC_CPU_CORES_NUM; i++) {
if (i != core_id) {
esp_cpu_stall(i);
}{...}
}{...}
#endif/* ... */
esp_ipc_isr_stall_abort();
if (esp_cpu_dbgr_is_attached()) {
#if __XTENSA__
if (!(esp_ptr_executable(esp_cpu_pc_to_addr(panic_get_address(frame))) && (panic_get_address(frame) & 0xC0000000U))) {
/* ... */
panic_set_address(frame, (uint32_t)&_invalid_pc_placeholder);
}{...}
#endif/* ... */
if (panic_get_cause(frame) == PANIC_RSN_INTWDT_CPU0
#if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
|| panic_get_cause(frame) == PANIC_RSN_INTWDT_CPU1
#endif
) {
wdt_hal_write_protect_disable(&wdt0_context);
wdt_hal_handle_intr(&wdt0_context);
wdt_hal_write_protect_enable(&wdt0_context);
}{...}
}{...}
frame_to_panic_info(frame, &info, pseudo_excause);
esp_panic_handler(&info);
}{ ... }
/* ... */
#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
static void IRAM_ATTR panic_enable_cache(void)
{
int core_id = esp_cpu_get_core_id();
if (!spi_flash_cache_enabled()) {
esp_ipc_isr_stall_abort();
spi_flash_enable_cache(core_id);
}{...}
}{ ... }
/* ... */#endif
void IRAM_ATTR panicHandler(void *frame)
{
#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
panic_enable_cache();
#endif
panic_handler(frame, true);
}{ ... }
void IRAM_ATTR xt_unhandled_exception(void *frame)
{
#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
panic_enable_cache();
#endif
panic_handler(frame, false);
}{ ... }
void __attribute__((noreturn)) panic_restart(void)
{
#ifdef CONFIG_IDF_TARGET_ESP32
if (esp_cache_err_get_cpuid() != -1) {
esp_restart_noos_dig();
}{...}
#endif/* ... */
esp_restart_noos();
}{ ... }