feat(esp_system): add CPU lockup debug support for esp32h4 and esp32s31

This commit is contained in:
Marius Vikhammer
2026-04-15 15:56:38 +08:00
parent 38e2cacc27
commit 8e2b416c38
38 changed files with 533 additions and 246 deletions

View File

@@ -0,0 +1,70 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <inttypes.h>
#include "sdkconfig.h"
#include "esp_log.h"
#include "esp_rom_sys.h"
#include "soc/soc_caps.h"
#if SOC_CPU_LOCKUP_DEBUG_SUPPORTED
#include "hal/assist_debug_ll.h"
#include "esp_rom_caps.h"
#endif
#include "bootloader_init.h"
ESP_LOG_ATTR_TAG(TAG, "boot");
#if SOC_CPU_LOCKUP_DEBUG_SUPPORTED && !ESP_ROM_PRINTS_LOCKUP_STATUS
static void lockup_info_dump(int cpu)
{
const char *cpu_name = cpu ? "APP" : "PRO";
ESP_LOGW(TAG, "%s CPU reset due to CPU lockup (exception inside exception handler).", cpu_name);
ESP_LOGW(TAG, "%s CPU trap chain:", cpu_name);
for (int i = 0; i < 2; i++) {
uint32_t cause = assist_debug_ll_lockup_get_cause(cpu, i);
uint32_t tval = assist_debug_ll_lockup_get_tval(cpu, i);
uint32_t iaddr = assist_debug_ll_lockup_get_iaddr(cpu, i);
uint32_t priv = assist_debug_ll_lockup_get_priv(cpu, i);
const char *label = i == 0 ? "latest" : "previous";
ESP_LOGW(TAG, " [%s trap] cause=0x%02"PRIx32" PCAddr=0x%08"PRIx32" tval=0x%08"PRIx32" priv=%"PRIu32,
label, cause, iaddr, tval, priv);
}
}
#endif
void bootloader_check_reset(void)
{
bool any_wdt_reset = false;
soc_reset_reason_t reset_reason;
reset_reason = esp_rom_get_reset_reason(0);
any_wdt_reset |= bootloader_check_if_wdt_reset(0, reset_reason);
#if SOC_CPU_LOCKUP_DEBUG_SUPPORTED && !ESP_ROM_PRINTS_LOCKUP_STATUS
if (reset_reason == RESET_REASON_CPU_LOCKUP) {
lockup_info_dump(0);
}
#endif
#if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
reset_reason = esp_rom_get_reset_reason(1);
any_wdt_reset |= bootloader_check_if_wdt_reset(1, reset_reason);
#if SOC_CPU_LOCKUP_DEBUG_SUPPORTED && !ESP_ROM_PRINTS_LOCKUP_STATUS
if (reset_reason == RESET_REASON_CPU_LOCKUP) {
lockup_info_dump(1);
}
#endif
#endif
if (any_wdt_reset) {
bootloader_dump_wdt_reset_info(0);
#if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
bootloader_dump_wdt_reset_info(1);
#endif
}
bootloader_enable_cpu_reset_info();
}

View File

@@ -91,14 +91,14 @@ static inline esp_err_t bootloader_check_rated_cpu_clock(void)
}
#if SOC_RTC_WDT_SUPPORTED
static void wdt_reset_cpu0_info_enable(void)
void bootloader_enable_cpu_reset_info(void)
{
//We do not reset core1 info here because it didn't work before cpu1 was up. So we put it into call_start_cpu1.
DPORT_REG_SET_BIT(DPORT_PRO_CPU_RECORD_CTRL_REG, DPORT_PRO_CPU_PDEBUG_ENABLE | DPORT_PRO_CPU_RECORD_ENABLE);
DPORT_REG_CLR_BIT(DPORT_PRO_CPU_RECORD_CTRL_REG, DPORT_PRO_CPU_RECORD_ENABLE);
}
static void wdt_reset_info_dump(int cpu)
void bootloader_dump_wdt_reset_info(int cpu)
{
uint32_t inst = 0, pid = 0, stat = 0, data = 0, pc = 0,
lsstat = 0, lsaddr = 0, lsdata = 0, dstat = 0;
@@ -145,32 +145,23 @@ static void wdt_reset_info_dump(int cpu)
ESP_LOGD(TAG, "WDT rst info: %s CPU PDEBUGLS0DATA 0x%08"PRIx32, cpu_name, lsdata);
}
static void bootloader_check_wdt_reset(void)
bool bootloader_check_if_wdt_reset(int cpu, soc_reset_reason_t rst_reason)
{
int wdt_rst = 0;
soc_reset_reason_t rst_reas[2];
rst_reas[0] = esp_rom_get_reset_reason(0);
rst_reas[1] = esp_rom_get_reset_reason(1);
if (rst_reas[0] == RESET_REASON_CORE_RTC_WDT || rst_reas[0] == RESET_REASON_CORE_MWDT0 || rst_reas[0] == RESET_REASON_CORE_MWDT1 ||
rst_reas[0] == RESET_REASON_CPU0_MWDT0 || rst_reas[0] == RESET_REASON_CPU0_RTC_WDT) {
if (cpu == 0 && (rst_reason == RESET_REASON_CORE_RTC_WDT || rst_reason == RESET_REASON_CORE_MWDT0 ||
rst_reason == RESET_REASON_CORE_MWDT1 || rst_reason == RESET_REASON_CPU0_MWDT0 ||
rst_reason == RESET_REASON_CPU0_RTC_WDT)) {
ESP_LOGW(TAG, "PRO CPU has been reset by WDT");
wdt_rst = 1;
return true;
}
if (rst_reas[1] == RESET_REASON_CORE_RTC_WDT || rst_reas[1] == RESET_REASON_CORE_MWDT0 || rst_reas[1] == RESET_REASON_CORE_MWDT1 ||
rst_reas[1] == RESET_REASON_CPU1_MWDT1 || rst_reas[1] == RESET_REASON_CPU1_RTC_WDT) {
if (cpu == 1 && (rst_reason == RESET_REASON_CORE_RTC_WDT || rst_reason == RESET_REASON_CORE_MWDT0 ||
rst_reason == RESET_REASON_CORE_MWDT1 || rst_reason == RESET_REASON_CPU1_MWDT1 ||
rst_reason == RESET_REASON_CPU1_RTC_WDT)) {
ESP_LOGW(TAG, "APP CPU has been reset by WDT");
wdt_rst = 1;
return true;
}
if (wdt_rst) {
// if reset by WDT dump info from trace port
wdt_reset_info_dump(0);
#if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
wdt_reset_info_dump(1);
#endif
}
wdt_reset_cpu0_info_enable();
return false;
}
#endif // SOC_RTC_WDT_SUPPORTED
esp_err_t bootloader_init(void)
@@ -244,10 +235,8 @@ esp_err_t bootloader_init(void)
}
#endif // #if !CONFIG_APP_BUILD_TYPE_RAM
#if SOC_RTC_WDT_SUPPORTED
// check whether a WDT reset happened
bootloader_check_wdt_reset();
#endif
// check reset reason and dump diagnostic info
bootloader_check_reset();
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
// config WDT
bootloader_config_wdt();

View File

@@ -42,34 +42,29 @@
ESP_LOG_ATTR_TAG(TAG, "boot.esp32c2");
#if SOC_RTC_WDT_SUPPORTED
static void wdt_reset_cpu0_info_enable(void)
void bootloader_enable_cpu_reset_info(void)
{
REG_SET_BIT(SYSTEM_CPU_PERI_CLK_EN_REG, SYSTEM_CLK_EN_ASSIST_DEBUG);
REG_CLR_BIT(SYSTEM_CPU_PERI_RST_EN_REG, SYSTEM_RST_EN_ASSIST_DEBUG);
REG_WRITE(ASSIST_DEBUG_CORE_0_RCD_EN_REG, ASSIST_DEBUG_CORE_0_RCD_PDEBUGEN | ASSIST_DEBUG_CORE_0_RCD_RECORDEN);
}
static void wdt_reset_info_dump(int cpu)
void bootloader_dump_wdt_reset_info(int cpu)
{
(void) cpu;
// saved PC was already printed by the ROM bootloader.
// nothing to do here.
}
static void bootloader_check_wdt_reset(void)
bool bootloader_check_if_wdt_reset(int cpu, soc_reset_reason_t rst_reason)
{
int wdt_rst = 0;
soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0);
(void) cpu;
if (rst_reason == RESET_REASON_CORE_RTC_WDT || rst_reason == RESET_REASON_CORE_MWDT0 ||
rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_RTC_WDT) {
ESP_LOGW(TAG, "PRO CPU has been reset by WDT.");
wdt_rst = 1;
return true;
}
if (wdt_rst) {
// if reset by WDT dump info from trace port
wdt_reset_info_dump(0);
}
wdt_reset_cpu0_info_enable();
return false;
}
static void bootloader_super_wdt_auto_feed(void)
@@ -141,10 +136,8 @@ esp_err_t bootloader_init(void)
}
#endif // !CONFIG_APP_BUILD_TYPE_RAM
#if SOC_RTC_WDT_SUPPORTED
// check whether a WDT reset happened
bootloader_check_wdt_reset();
#endif
// check reset reason and dump diagnostic info
bootloader_check_reset();
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
// config WDT
bootloader_config_wdt();

View File

@@ -47,34 +47,29 @@
ESP_LOG_ATTR_TAG(TAG, "boot.esp32c3");
#if SOC_RTC_WDT_SUPPORTED
static void wdt_reset_cpu0_info_enable(void)
void bootloader_enable_cpu_reset_info(void)
{
REG_SET_BIT(SYSTEM_CPU_PERI_CLK_EN_REG, SYSTEM_CLK_EN_ASSIST_DEBUG);
REG_CLR_BIT(SYSTEM_CPU_PERI_RST_EN_REG, SYSTEM_RST_EN_ASSIST_DEBUG);
REG_WRITE(ASSIST_DEBUG_CORE_0_RCD_EN_REG, ASSIST_DEBUG_CORE_0_RCD_PDEBUGEN | ASSIST_DEBUG_CORE_0_RCD_RECORDEN);
}
static void wdt_reset_info_dump(int cpu)
void bootloader_dump_wdt_reset_info(int cpu)
{
(void) cpu;
// saved PC was already printed by the ROM bootloader.
// nothing to do here.
}
static void bootloader_check_wdt_reset(void)
bool bootloader_check_if_wdt_reset(int cpu, soc_reset_reason_t rst_reason)
{
int wdt_rst = 0;
soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0);
(void) cpu;
if (rst_reason == RESET_REASON_CORE_RTC_WDT || rst_reason == RESET_REASON_CORE_MWDT0 || rst_reason == RESET_REASON_CORE_MWDT1 ||
rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_MWDT1 || rst_reason == RESET_REASON_CPU0_RTC_WDT) {
ESP_LOGW(TAG, "PRO CPU has been reset by WDT.");
wdt_rst = 1;
return true;
}
if (wdt_rst) {
// if reset by WDT dump info from trace port
wdt_reset_info_dump(0);
}
wdt_reset_cpu0_info_enable();
return false;
}
static void bootloader_super_wdt_auto_feed(void)
@@ -185,10 +180,8 @@ esp_err_t bootloader_init(void)
}
#endif //#if !CONFIG_APP_BUILD_TYPE_RAM
#if SOC_RTC_WDT_SUPPORTED
// check whether a WDT reset happened
bootloader_check_wdt_reset();
#endif
// check reset reason and dump diagnostic info
bootloader_check_reset();
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
// config WDT
bootloader_config_wdt();

View File

@@ -47,34 +47,29 @@
ESP_LOG_ATTR_TAG(TAG, "boot.esp32c5");
#if SOC_RTC_WDT_SUPPORTED
static void wdt_reset_cpu0_info_enable(void)
void bootloader_enable_cpu_reset_info(void)
{
REG_SET_BIT(PCR_ASSIST_CONF_REG, PCR_ASSIST_CLK_EN);
REG_CLR_BIT(PCR_ASSIST_CONF_REG, PCR_ASSIST_RST_EN);
REG_WRITE(ASSIST_DEBUG_CORE_0_RCD_EN_REG, ASSIST_DEBUG_CORE_0_RCD_PDEBUGEN | ASSIST_DEBUG_CORE_0_RCD_RECORDEN);
}
static void wdt_reset_info_dump(int cpu)
void bootloader_dump_wdt_reset_info(int cpu)
{
(void) cpu;
// saved PC was already printed by the ROM bootloader.
// nothing to do here.
}
static void bootloader_check_wdt_reset(void)
bool bootloader_check_if_wdt_reset(int cpu, soc_reset_reason_t rst_reason)
{
int wdt_rst = 0;
soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0);
(void) cpu;
if (rst_reason == RESET_REASON_CORE_RTC_WDT || rst_reason == RESET_REASON_CORE_MWDT0 || rst_reason == RESET_REASON_CORE_MWDT1 ||
rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_MWDT1 || rst_reason == RESET_REASON_CPU0_RTC_WDT) {
ESP_LOGW(TAG, "PRO CPU has been reset by WDT.");
wdt_rst = 1;
return true;
}
if (wdt_rst) {
// if reset by WDT dump info from trace port
wdt_reset_info_dump(0);
}
wdt_reset_cpu0_info_enable();
return false;
}
static void bootloader_super_wdt_auto_feed(void)
@@ -169,10 +164,8 @@ esp_err_t bootloader_init(void)
}
#endif // !CONFIG_APP_BUILD_TYPE_RAM
#if SOC_RTC_WDT_SUPPORTED
// check whether a WDT reset happened
bootloader_check_wdt_reset();
#endif
// check reset reason and dump diagnostic info
bootloader_check_reset();
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
// config WDT
bootloader_config_wdt();

View File

@@ -49,34 +49,29 @@
ESP_LOG_ATTR_TAG(TAG, "boot.esp32c6");
#if SOC_RTC_WDT_SUPPORTED
static void wdt_reset_cpu0_info_enable(void)
void bootloader_enable_cpu_reset_info(void)
{
REG_SET_BIT(PCR_ASSIST_CONF_REG, PCR_ASSIST_CLK_EN);
REG_CLR_BIT(PCR_ASSIST_CONF_REG, PCR_ASSIST_RST_EN);
REG_WRITE(ASSIST_DEBUG_CORE_0_RCD_EN_REG, ASSIST_DEBUG_CORE_0_RCD_PDEBUGEN | ASSIST_DEBUG_CORE_0_RCD_RECORDEN);
}
static void wdt_reset_info_dump(int cpu)
void bootloader_dump_wdt_reset_info(int cpu)
{
(void) cpu;
// saved PC was already printed by the ROM bootloader.
// nothing to do here.
}
static void bootloader_check_wdt_reset(void)
bool bootloader_check_if_wdt_reset(int cpu, soc_reset_reason_t rst_reason)
{
int wdt_rst = 0;
soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0);
(void) cpu;
if (rst_reason == RESET_REASON_CORE_RTC_WDT || rst_reason == RESET_REASON_CORE_MWDT0 || rst_reason == RESET_REASON_CORE_MWDT1 ||
rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_MWDT1 || rst_reason == RESET_REASON_CPU0_RTC_WDT) {
ESP_LOGW(TAG, "PRO CPU has been reset by WDT.");
wdt_rst = 1;
return true;
}
if (wdt_rst) {
// if reset by WDT dump info from trace port
wdt_reset_info_dump(0);
}
wdt_reset_cpu0_info_enable();
return false;
}
static void bootloader_super_wdt_auto_feed(void)
@@ -169,10 +164,8 @@ esp_err_t bootloader_init(void)
}
#endif // !CONFIG_APP_BUILD_TYPE_RAM
#if SOC_RTC_WDT_SUPPORTED
// check whether a WDT reset happened
bootloader_check_wdt_reset();
#endif
// check reset reason and dump diagnostic info
bootloader_check_reset();
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
// config WDT
bootloader_config_wdt();

View File

@@ -49,34 +49,29 @@
ESP_LOG_ATTR_TAG(TAG, "boot.esp32c61");
#if SOC_RTC_WDT_SUPPORTED
static void wdt_reset_cpu0_info_enable(void)
void bootloader_enable_cpu_reset_info(void)
{
REG_SET_BIT(PCR_ASSIST_CONF_REG, PCR_ASSIST_CLK_EN);
REG_CLR_BIT(PCR_ASSIST_CONF_REG, PCR_ASSIST_RST_EN);
REG_WRITE(ASSIST_DEBUG_CORE_0_RCD_EN_REG, ASSIST_DEBUG_CORE_0_RCD_PDEBUGEN | ASSIST_DEBUG_CORE_0_RCD_RECORDEN);
}
static void wdt_reset_info_dump(int cpu)
void bootloader_dump_wdt_reset_info(int cpu)
{
(void) cpu;
// saved PC was already printed by the ROM bootloader.
// nothing to do here.
}
static void bootloader_check_wdt_reset(void)
bool bootloader_check_if_wdt_reset(int cpu, soc_reset_reason_t rst_reason)
{
int wdt_rst = 0;
soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0);
(void) cpu;
if (rst_reason == RESET_REASON_CORE_RTC_WDT || rst_reason == RESET_REASON_CORE_MWDT0 || rst_reason == RESET_REASON_CORE_MWDT1 ||
rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_MWDT1 || rst_reason == RESET_REASON_CPU0_RTC_WDT) {
ESP_LOGW(TAG, "PRO CPU has been reset by WDT.");
wdt_rst = 1;
return true;
}
if (wdt_rst) {
// if reset by WDT dump info from trace port
wdt_reset_info_dump(0);
}
wdt_reset_cpu0_info_enable();
return false;
}
static void bootloader_super_wdt_auto_feed(void)
@@ -161,10 +156,8 @@ esp_err_t bootloader_init(void)
}
#endif // !CONFIG_APP_BUILD_TYPE_RAM
#if SOC_RTC_WDT_SUPPORTED
// check whether a WDT reset happened
bootloader_check_wdt_reset();
#endif
// check reset reason and dump diagnostic info
bootloader_check_reset();
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
// config WDT
bootloader_config_wdt();

View File

@@ -48,34 +48,29 @@
ESP_LOG_ATTR_TAG(TAG, "boot.esp32h2");
#if SOC_RTC_WDT_SUPPORTED
static void wdt_reset_cpu0_info_enable(void)
void bootloader_enable_cpu_reset_info(void)
{
REG_SET_BIT(PCR_ASSIST_CONF_REG, PCR_ASSIST_CLK_EN);
REG_CLR_BIT(PCR_ASSIST_CONF_REG, PCR_ASSIST_RST_EN);
REG_WRITE(ASSIST_DEBUG_CORE_0_RCD_EN_REG, ASSIST_DEBUG_CORE_0_RCD_PDEBUGEN | ASSIST_DEBUG_CORE_0_RCD_RECORDEN);
}
static void wdt_reset_info_dump(int cpu)
void bootloader_dump_wdt_reset_info(int cpu)
{
(void) cpu;
// saved PC was already printed by the ROM bootloader.
// nothing to do here.
}
static void bootloader_check_wdt_reset(void)
bool bootloader_check_if_wdt_reset(int cpu, soc_reset_reason_t rst_reason)
{
int wdt_rst = 0;
soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0);
(void) cpu;
if (rst_reason == RESET_REASON_CORE_RTC_WDT || rst_reason == RESET_REASON_CORE_MWDT0 || rst_reason == RESET_REASON_CORE_MWDT1 ||
rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_MWDT1 || rst_reason == RESET_REASON_CPU0_RTC_WDT) {
ESP_EARLY_LOGW(TAG, "PRO CPU has been reset by WDT.");
wdt_rst = 1;
return true;
}
if (wdt_rst) {
// if reset by WDT dump info from trace port
wdt_reset_info_dump(0);
}
wdt_reset_cpu0_info_enable();
return false;
}
static void bootloader_super_wdt_auto_feed(void)
@@ -166,10 +161,8 @@ esp_err_t bootloader_init(void)
}
#endif // !CONFIG_APP_BUILD_TYPE_RAM
// check whether a WDT reset happened
#if SOC_RTC_WDT_SUPPORTED
bootloader_check_wdt_reset();
#endif
// check reset reason and dump diagnostic info
bootloader_check_reset();
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
// config WDT
bootloader_config_wdt();

View File

@@ -48,34 +48,29 @@
ESP_LOG_ATTR_TAG(TAG, "boot.esp32h21");
#if SOC_RTC_WDT_SUPPORTED
static void wdt_reset_cpu0_info_enable(void)
void bootloader_enable_cpu_reset_info(void)
{
REG_SET_BIT(PCR_ASSIST_CONF_REG, PCR_ASSIST_CLK_EN);
REG_CLR_BIT(PCR_ASSIST_CONF_REG, PCR_ASSIST_RST_EN);
REG_WRITE(ASSIST_DEBUG_CORE_0_RCD_EN_REG, ASSIST_DEBUG_CORE_0_RCD_PDEBUGEN | ASSIST_DEBUG_CORE_0_RCD_RECORDEN);
}
static void wdt_reset_info_dump(int cpu)
void bootloader_dump_wdt_reset_info(int cpu)
{
(void) cpu;
// saved PC was already printed by the ROM bootloader.
// nothing to do here.
}
static void bootloader_check_wdt_reset(void)
bool bootloader_check_if_wdt_reset(int cpu, soc_reset_reason_t rst_reason)
{
int wdt_rst = 0;
soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0);
(void) cpu;
if (rst_reason == RESET_REASON_CORE_RTC_WDT || rst_reason == RESET_REASON_CORE_MWDT0 || rst_reason == RESET_REASON_CORE_MWDT1 ||
rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_MWDT1 || rst_reason == RESET_REASON_CPU0_RTC_WDT) {
ESP_EARLY_LOGW(TAG, "PRO CPU has been reset by WDT.");
wdt_rst = 1;
return true;
}
if (wdt_rst) {
// if reset by WDT dump info from trace port
wdt_reset_info_dump(0);
}
wdt_reset_cpu0_info_enable();
return false;
}
static void bootloader_super_wdt_auto_feed(void)
@@ -163,10 +158,8 @@ esp_err_t bootloader_init(void)
}
#endif // !CONFIG_APP_BUILD_TYPE_RAM
#if SOC_RTC_WDT_SUPPORTED
// check whether a WDT reset happened
bootloader_check_wdt_reset();
#endif
// check reset reason and dump diagnostic info
bootloader_check_reset();
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
// config WDT
bootloader_config_wdt();

View File

@@ -44,43 +44,54 @@
ESP_LOG_ATTR_TAG(TAG, "boot.esp32h4");
#if SOC_RTC_WDT_SUPPORTED
static void wdt_reset_cpu0_info_enable(void)
#if SOC_RTC_WDT_SUPPORTED || SOC_CPU_LOCKUP_DEBUG_SUPPORTED
void bootloader_enable_cpu_reset_info(void)
{
assist_debug_ll_enable_bus_clock(0, true);
assist_debug_ll_enable_pc_recording(0, true);
assist_debug_ll_lockup_monitor_enable(0, true);
assist_debug_ll_lockup_reset_enable(0);
#if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
assist_debug_ll_enable_bus_clock(1, true);
assist_debug_ll_enable_pc_recording(1, true);
assist_debug_ll_lockup_monitor_enable(1, true);
assist_debug_ll_lockup_reset_enable(1);
#endif
}
static void wdt_reset_info_dump(int cpu)
void bootloader_dump_wdt_reset_info(int cpu)
{
(void) cpu;
// saved PC was already printed by the ROM bootloader.
// nothing to do here.
}
static void bootloader_check_wdt_reset(void)
bool bootloader_check_if_wdt_reset(int cpu, soc_reset_reason_t reset_reason)
{
int wdt_rst = 0;
soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0);
if (rst_reason == RESET_REASON_CORE_RTC_WDT || rst_reason == RESET_REASON_CORE_MWDT0 || rst_reason == RESET_REASON_CORE_MWDT1 ||
rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_MWDT1 || rst_reason == RESET_REASON_CPU0_RTC_WDT) {
if (cpu == 0 && (reset_reason == RESET_REASON_CORE_RTC_WDT || reset_reason == RESET_REASON_CORE_MWDT0 ||
reset_reason == RESET_REASON_CORE_MWDT1 || reset_reason == RESET_REASON_CPU0_MWDT0 ||
reset_reason == RESET_REASON_CPU0_MWDT1 || reset_reason == RESET_REASON_CPU0_RTC_WDT)) {
ESP_LOGW(TAG, "PRO CPU has been reset by WDT.");
wdt_rst = 1;
return true;
}
if (wdt_rst) {
// if reset by WDT dump info from trace port
wdt_reset_info_dump(0);
if (cpu == 1 && (reset_reason == RESET_REASON_CORE_RTC_WDT || reset_reason == RESET_REASON_CORE_MWDT0 ||
reset_reason == RESET_REASON_CORE_MWDT1 || reset_reason == RESET_REASON_CPU0_MWDT0 ||
reset_reason == RESET_REASON_CPU0_MWDT1 || reset_reason == RESET_REASON_CPU0_RTC_WDT)) {
ESP_LOGW(TAG, "APP CPU has been reset by WDT.");
return true;
}
wdt_reset_cpu0_info_enable();
return false;
}
#if SOC_RTC_WDT_SUPPORTED
static void bootloader_super_wdt_auto_feed(void)
{
REG_WRITE(LP_WDT_SWD_WPROTECT_REG, LP_WDT_SWD_WKEY_VALUE);
REG_SET_BIT(LP_WDT_SWD_CONFIG_REG, LP_WDT_SWD_AUTO_FEED_EN);
REG_WRITE(LP_WDT_SWD_WPROTECT_REG, 0);
}
#endif // SOC_RTC_WDT_SUPPORTED
#endif
#endif // SOC_RTC_WDT_SUPPORTED || SOC_CPU_LOCKUP_DEBUG_SUPPORTED
static inline void bootloader_hardware_init(void)
{
@@ -178,10 +189,8 @@ esp_err_t bootloader_init(void)
#endif // !CONFIG_APP_BUILD_TYPE_RAM
bootloader_config_dcache();
bootloader_config_icache1();
#if SOC_RTC_WDT_SUPPORTED
// check whether a WDT reset happened
bootloader_check_wdt_reset();
#endif
// check reset reason and dump diagnostic info
bootloader_check_reset();
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
// config WDT
bootloader_config_wdt();

View File

@@ -55,36 +55,28 @@
ESP_LOG_ATTR_TAG(TAG, "boot.esp32p4");
#if SOC_RTC_WDT_SUPPORTED
static void wdt_reset_cpu0_info_enable(void)
void bootloader_enable_cpu_reset_info(void)
{
_assist_debug_ll_enable_bus_clock(0, true);
assist_debug_ll_enable_pc_recording(0, true);
}
static void wdt_reset_info_dump(int cpu)
void bootloader_dump_wdt_reset_info(int cpu)
{
(void) cpu;
// saved PC was already printed by the ROM bootloader.
// nothing to do here.
}
static void bootloader_check_wdt_reset(void)
bool bootloader_check_if_wdt_reset(int cpu, soc_reset_reason_t rst_reason)
{
int wdt_rst = 0;
soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0);
if (rst_reason == RESET_REASON_CPU_MWDT || rst_reason == RESET_REASON_CPU_RWDT || rst_reason == RESET_REASON_CORE_MWDT ||
rst_reason == RESET_REASON_CORE_RWDT || rst_reason == RESET_REASON_SYS_RWDT) {
if (cpu == 0 && (rst_reason == RESET_REASON_CPU_MWDT || rst_reason == RESET_REASON_CPU_RWDT ||
rst_reason == RESET_REASON_CORE_MWDT || rst_reason == RESET_REASON_CORE_RWDT ||
rst_reason == RESET_REASON_SYS_RWDT)) {
ESP_LOGW(TAG, "CPU has been reset by WDT.");
wdt_rst = 1;
return true;
}
if (wdt_rst) {
// if reset by WDT dump info from trace port
wdt_reset_info_dump(0);
#if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
wdt_reset_info_dump(1);
#endif
}
wdt_reset_cpu0_info_enable();
return false;
}
static void bootloader_super_wdt_auto_feed(void)
@@ -187,10 +179,8 @@ esp_err_t bootloader_init(void)
}
#endif // !CONFIG_APP_BUILD_TYPE_RAM
#if SOC_RTC_WDT_SUPPORTED
// check whether a WDT reset happened
bootloader_check_wdt_reset();
#endif
// check reset reason and dump diagnostic info
bootloader_check_reset();
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
// config WDT
bootloader_config_wdt();

View File

@@ -42,7 +42,7 @@
ESP_LOG_ATTR_TAG(TAG, "boot.esp32s2");
#if SOC_RTC_WDT_SUPPORTED
static void wdt_reset_cpu0_info_enable(void)
void bootloader_enable_cpu_reset_info(void)
{
DPORT_REG_SET_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_ASSIST_DEBUG);
DPORT_REG_CLR_BIT(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_ASSIST_DEBUG);
@@ -50,7 +50,7 @@ static void wdt_reset_cpu0_info_enable(void)
REG_WRITE(ASSIST_DEBUG_PRO_RCD_RECORDING, 1);
}
static void wdt_reset_info_dump(int cpu)
void bootloader_dump_wdt_reset_info(int cpu)
{
uint32_t inst = 0, pid = 0, stat = 0, data = 0, pc = 0,
lsstat = 0, lsaddr = 0, lsdata = 0, dstat = 0;
@@ -83,20 +83,15 @@ static void wdt_reset_info_dump(int cpu)
ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGLS0DATA 0x%08"PRIx32, cpu_name, lsdata);
}
static void bootloader_check_wdt_reset(void)
bool bootloader_check_if_wdt_reset(int cpu, soc_reset_reason_t rst_reason)
{
int wdt_rst = 0;
soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0);
(void) cpu;
if (rst_reason == RESET_REASON_CORE_RTC_WDT || rst_reason == RESET_REASON_CORE_MWDT0 || rst_reason == RESET_REASON_CORE_MWDT1 ||
rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_MWDT1 || rst_reason == RESET_REASON_CPU0_RTC_WDT) {
ESP_LOGW(TAG, "PRO CPU has been reset by WDT.");
wdt_rst = 1;
return true;
}
if (wdt_rst) {
// if reset by WDT dump info from trace port
wdt_reset_info_dump(0);
}
wdt_reset_cpu0_info_enable();
return false;
}
static void bootloader_super_wdt_auto_feed(void)
@@ -169,10 +164,8 @@ esp_err_t bootloader_init(void)
}
#endif // !CONFIG_APP_BUILD_TYPE_RAM
#if SOC_RTC_WDT_SUPPORTED
// check whether a WDT reset happened
bootloader_check_wdt_reset();
#endif
// check reset reason and dump diagnostic info
bootloader_check_reset();
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
// config WDT
bootloader_config_wdt();

View File

@@ -48,7 +48,7 @@
ESP_LOG_ATTR_TAG(TAG, "boot.esp32s3");
#if SOC_RTC_WDT_SUPPORTED
static void wdt_reset_cpu0_info_enable(void)
void bootloader_enable_cpu_reset_info(void)
{
REG_SET_BIT(SYSTEM_CPU_PERI_CLK_EN_REG, SYSTEM_CLK_EN_ASSIST_DEBUG);
REG_CLR_BIT(SYSTEM_CPU_PERI_RST_EN_REG, SYSTEM_RST_EN_ASSIST_DEBUG);
@@ -56,7 +56,7 @@ static void wdt_reset_cpu0_info_enable(void)
REG_WRITE(ASSIST_DEBUG_CORE_0_RCD_RECORDING_REG, 1);
}
static void wdt_reset_info_dump(int cpu)
void bootloader_dump_wdt_reset_info(int cpu)
{
uint32_t inst = 0, pid = 0, stat = 0, data = 0, pc = 0,
lsstat = 0, lsaddr = 0, lsdata = 0, dstat = 0;
@@ -98,31 +98,21 @@ static void wdt_reset_info_dump(int cpu)
ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGLS0DATA 0x%08"PRIx32, cpu_name, lsdata);
}
static void bootloader_check_wdt_reset(void)
bool bootloader_check_if_wdt_reset(int cpu, soc_reset_reason_t rst_reason)
{
int wdt_rst = 0;
soc_reset_reason_t rst_reas[2];
rst_reas[0] = esp_rom_get_reset_reason(0);
rst_reas[1] = esp_rom_get_reset_reason(1);
if (rst_reas[0] == RESET_REASON_CORE_RTC_WDT || rst_reas[0] == RESET_REASON_CORE_MWDT0 || rst_reas[0] == RESET_REASON_CORE_MWDT1 ||
rst_reas[0] == RESET_REASON_CPU0_MWDT0 || rst_reas[0] == RESET_REASON_CPU0_RTC_WDT) {
if (cpu == 0 && (rst_reason == RESET_REASON_CORE_RTC_WDT || rst_reason == RESET_REASON_CORE_MWDT0 ||
rst_reason == RESET_REASON_CORE_MWDT1 || rst_reason == RESET_REASON_CPU0_MWDT0 ||
rst_reason == RESET_REASON_CPU0_RTC_WDT)) {
ESP_LOGW(TAG, "PRO CPU has been reset by WDT.");
wdt_rst = 1;
return true;
}
if (rst_reas[1] == RESET_REASON_CORE_RTC_WDT || rst_reas[1] == RESET_REASON_CORE_MWDT0 || rst_reas[1] == RESET_REASON_CORE_MWDT1 ||
rst_reas[1] == RESET_REASON_CPU1_MWDT1 || rst_reas[1] == RESET_REASON_CPU1_RTC_WDT) {
if (cpu == 1 && (rst_reason == RESET_REASON_CORE_RTC_WDT || rst_reason == RESET_REASON_CORE_MWDT0 ||
rst_reason == RESET_REASON_CORE_MWDT1 || rst_reason == RESET_REASON_CPU1_MWDT1 ||
rst_reason == RESET_REASON_CPU1_RTC_WDT)) {
ESP_LOGW(TAG, "APP CPU has been reset by WDT.");
wdt_rst = 1;
return true;
}
if (wdt_rst) {
// if reset by WDT dump info from trace port
wdt_reset_info_dump(0);
#if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
wdt_reset_info_dump(1);
#endif
}
wdt_reset_cpu0_info_enable();
return false;
}
static void bootloader_super_wdt_auto_feed(void)
@@ -208,10 +198,8 @@ esp_err_t bootloader_init(void)
}
#endif // !CONFIG_APP_BUILD_TYPE_RAM
#if SOC_RTC_WDT_SUPPORTED
// check whether a WDT reset happened
bootloader_check_wdt_reset();
#endif
// check reset reason and dump diagnostic info
bootloader_check_reset();
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
// config WDT
bootloader_config_wdt();

View File

@@ -26,6 +26,9 @@
#include "soc/pmu_reg.h"
#include "hal/regi2c_ctrl_ll.h"
#include "hal/modem_lpcon_ll.h"
#include "soc/reset_reasons.h"
#include "hal/assist_debug_ll.h"
#include "esp_rom_sys.h"
ESP_LOG_ATTR_TAG(TAG, "boot.esp32s31");
@@ -44,6 +47,44 @@ static inline void bootloader_hardware_init(void)
#endif
}
void bootloader_enable_cpu_reset_info(void)
{
assist_debug_ll_enable_bus_clock(0, true);
assist_debug_ll_enable_pc_recording(0, true);
assist_debug_ll_lockup_monitor_enable(0, true);
assist_debug_ll_lockup_reset_enable(0);
#if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
assist_debug_ll_enable_bus_clock(1, true);
assist_debug_ll_enable_pc_recording(1, true);
assist_debug_ll_lockup_monitor_enable(1, true);
assist_debug_ll_lockup_reset_enable(1);
#endif
}
void bootloader_dump_wdt_reset_info(int cpu)
{
(void) cpu;
// saved PC was already printed by the ROM bootloader.
// nothing to do here.
}
bool bootloader_check_if_wdt_reset(int cpu, soc_reset_reason_t reset_reason)
{
if (cpu == 0 && (reset_reason == RESET_REASON_CORE_MWDT0 || reset_reason == RESET_REASON_CORE_MWDT1 ||
reset_reason == RESET_REASON_CORE_RWDT || reset_reason == RESET_REASON_CPU_MWDT ||
reset_reason == RESET_REASON_CPU_RWDT || reset_reason == RESET_REASON_SYS_RWDT)) {
ESP_LOGW(TAG, "PRO CPU has been reset by WDT.");
return true;
}
if (cpu == 1 && (reset_reason == RESET_REASON_CORE_MWDT0 || reset_reason == RESET_REASON_CORE_MWDT1 ||
reset_reason == RESET_REASON_CORE_RWDT || reset_reason == RESET_REASON_CPU_MWDT ||
reset_reason == RESET_REASON_CPU_RWDT || reset_reason == RESET_REASON_SYS_RWDT)) {
ESP_LOGW(TAG, "APP CPU has been reset by WDT.");
return true;
}
return false;
}
#if SOC_RTC_WDT_SUPPORTED
static void bootloader_super_wdt_auto_feed(void)
{
@@ -112,10 +153,8 @@ esp_err_t bootloader_init(void)
}
#endif // !CONFIG_APP_BUILD_TYPE_RAM
#if SOC_RTC_WDT_SUPPORTED
// check whether a WDT reset happened
// bootloader_check_wdt_reset(); // TODO: IDF-14678
#endif
// check reset reason and dump diagnostic info
bootloader_check_reset();
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
// config WDT
bootloader_config_wdt();