mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
feat(esp_system): add CPU lockup debug support for esp32h4 and esp32s31
This commit is contained in:
@@ -84,6 +84,7 @@ if(BOOTLOADER_BUILD OR CONFIG_APP_BUILD_TYPE_RAM)
|
|||||||
list(APPEND priv_requires esp_hal_wdt esp_hal_gpio esp_hal_uart esp_hal_ana_conv esp_hal_rtc_timer
|
list(APPEND priv_requires esp_hal_wdt esp_hal_gpio esp_hal_uart esp_hal_ana_conv esp_hal_rtc_timer
|
||||||
esp_hal_clock esp_hal_security)
|
esp_hal_clock esp_hal_security)
|
||||||
list(APPEND srcs
|
list(APPEND srcs
|
||||||
|
"src/bootloader_reset_common.c"
|
||||||
"src/bootloader_init.c"
|
"src/bootloader_init.c"
|
||||||
"src/bootloader_clock_loader.c"
|
"src/bootloader_clock_loader.c"
|
||||||
"src/bootloader_console.c"
|
"src/bootloader_console.c"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2018-2025 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2018-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
#include "esp_image_format.h"
|
#include "esp_image_format.h"
|
||||||
|
#include "soc/reset_reasons.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -37,6 +38,10 @@ extern esp_image_header_t bootloader_image_hdr;
|
|||||||
esp_err_t bootloader_read_bootloader_header(void);
|
esp_err_t bootloader_read_bootloader_header(void);
|
||||||
esp_err_t bootloader_check_bootloader_validity(void);
|
esp_err_t bootloader_check_bootloader_validity(void);
|
||||||
void bootloader_clear_bss_section(void);
|
void bootloader_clear_bss_section(void);
|
||||||
|
bool bootloader_check_if_wdt_reset(int cpu, soc_reset_reason_t reset_reason);
|
||||||
|
void bootloader_dump_wdt_reset_info(int cpu);
|
||||||
|
void bootloader_enable_cpu_reset_info(void);
|
||||||
|
void bootloader_check_reset(void);
|
||||||
void bootloader_config_wdt(void);
|
void bootloader_config_wdt(void);
|
||||||
void bootloader_enable_random(void);
|
void bootloader_enable_random(void);
|
||||||
void bootloader_print_banner(void);
|
void bootloader_print_banner(void);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
@@ -91,14 +91,14 @@ static inline esp_err_t bootloader_check_rated_cpu_clock(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED
|
#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.
|
//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_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);
|
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,
|
uint32_t inst = 0, pid = 0, stat = 0, data = 0, pc = 0,
|
||||||
lsstat = 0, lsaddr = 0, lsdata = 0, dstat = 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);
|
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;
|
if (cpu == 0 && (rst_reason == RESET_REASON_CORE_RTC_WDT || rst_reason == RESET_REASON_CORE_MWDT0 ||
|
||||||
soc_reset_reason_t rst_reas[2];
|
rst_reason == RESET_REASON_CORE_MWDT1 || rst_reason == RESET_REASON_CPU0_MWDT0 ||
|
||||||
|
rst_reason == RESET_REASON_CPU0_RTC_WDT)) {
|
||||||
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) {
|
|
||||||
ESP_LOGW(TAG, "PRO CPU has been reset by 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 ||
|
if (cpu == 1 && (rst_reason == RESET_REASON_CORE_RTC_WDT || rst_reason == RESET_REASON_CORE_MWDT0 ||
|
||||||
rst_reas[1] == RESET_REASON_CPU1_MWDT1 || rst_reas[1] == RESET_REASON_CPU1_RTC_WDT) {
|
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");
|
ESP_LOGW(TAG, "APP CPU has been reset by WDT");
|
||||||
wdt_rst = 1;
|
return true;
|
||||||
}
|
}
|
||||||
if (wdt_rst) {
|
return false;
|
||||||
// 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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // SOC_RTC_WDT_SUPPORTED
|
#endif // SOC_RTC_WDT_SUPPORTED
|
||||||
|
|
||||||
esp_err_t bootloader_init(void)
|
esp_err_t bootloader_init(void)
|
||||||
@@ -244,10 +235,8 @@ esp_err_t bootloader_init(void)
|
|||||||
}
|
}
|
||||||
#endif // #if !CONFIG_APP_BUILD_TYPE_RAM
|
#endif // #if !CONFIG_APP_BUILD_TYPE_RAM
|
||||||
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED
|
// check reset reason and dump diagnostic info
|
||||||
// check whether a WDT reset happened
|
bootloader_check_reset();
|
||||||
bootloader_check_wdt_reset();
|
|
||||||
#endif
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
|
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
|
||||||
// config WDT
|
// config WDT
|
||||||
bootloader_config_wdt();
|
bootloader_config_wdt();
|
||||||
|
|||||||
@@ -42,34 +42,29 @@
|
|||||||
ESP_LOG_ATTR_TAG(TAG, "boot.esp32c2");
|
ESP_LOG_ATTR_TAG(TAG, "boot.esp32c2");
|
||||||
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED
|
#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_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_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);
|
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;
|
(void) cpu;
|
||||||
// saved PC was already printed by the ROM bootloader.
|
// saved PC was already printed by the ROM bootloader.
|
||||||
// nothing to do here.
|
// 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;
|
(void) cpu;
|
||||||
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 ||
|
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) {
|
rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_RTC_WDT) {
|
||||||
ESP_LOGW(TAG, "PRO CPU has been reset by WDT.");
|
ESP_LOGW(TAG, "PRO CPU has been reset by WDT.");
|
||||||
wdt_rst = 1;
|
return true;
|
||||||
}
|
}
|
||||||
if (wdt_rst) {
|
return false;
|
||||||
// if reset by WDT dump info from trace port
|
|
||||||
wdt_reset_info_dump(0);
|
|
||||||
}
|
|
||||||
wdt_reset_cpu0_info_enable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bootloader_super_wdt_auto_feed(void)
|
static void bootloader_super_wdt_auto_feed(void)
|
||||||
@@ -141,10 +136,8 @@ esp_err_t bootloader_init(void)
|
|||||||
}
|
}
|
||||||
#endif // !CONFIG_APP_BUILD_TYPE_RAM
|
#endif // !CONFIG_APP_BUILD_TYPE_RAM
|
||||||
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED
|
// check reset reason and dump diagnostic info
|
||||||
// check whether a WDT reset happened
|
bootloader_check_reset();
|
||||||
bootloader_check_wdt_reset();
|
|
||||||
#endif
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
|
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
|
||||||
// config WDT
|
// config WDT
|
||||||
bootloader_config_wdt();
|
bootloader_config_wdt();
|
||||||
|
|||||||
@@ -47,34 +47,29 @@
|
|||||||
ESP_LOG_ATTR_TAG(TAG, "boot.esp32c3");
|
ESP_LOG_ATTR_TAG(TAG, "boot.esp32c3");
|
||||||
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED
|
#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_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_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);
|
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;
|
(void) cpu;
|
||||||
// saved PC was already printed by the ROM bootloader.
|
// saved PC was already printed by the ROM bootloader.
|
||||||
// nothing to do here.
|
// 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;
|
(void) cpu;
|
||||||
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 ||
|
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) {
|
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.");
|
ESP_LOGW(TAG, "PRO CPU has been reset by WDT.");
|
||||||
wdt_rst = 1;
|
return true;
|
||||||
}
|
}
|
||||||
if (wdt_rst) {
|
return false;
|
||||||
// if reset by WDT dump info from trace port
|
|
||||||
wdt_reset_info_dump(0);
|
|
||||||
}
|
|
||||||
wdt_reset_cpu0_info_enable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bootloader_super_wdt_auto_feed(void)
|
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
|
#endif //#if !CONFIG_APP_BUILD_TYPE_RAM
|
||||||
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED
|
// check reset reason and dump diagnostic info
|
||||||
// check whether a WDT reset happened
|
bootloader_check_reset();
|
||||||
bootloader_check_wdt_reset();
|
|
||||||
#endif
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
|
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
|
||||||
// config WDT
|
// config WDT
|
||||||
bootloader_config_wdt();
|
bootloader_config_wdt();
|
||||||
|
|||||||
@@ -47,34 +47,29 @@
|
|||||||
ESP_LOG_ATTR_TAG(TAG, "boot.esp32c5");
|
ESP_LOG_ATTR_TAG(TAG, "boot.esp32c5");
|
||||||
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED
|
#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_SET_BIT(PCR_ASSIST_CONF_REG, PCR_ASSIST_CLK_EN);
|
||||||
REG_CLR_BIT(PCR_ASSIST_CONF_REG, PCR_ASSIST_RST_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);
|
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;
|
(void) cpu;
|
||||||
// saved PC was already printed by the ROM bootloader.
|
// saved PC was already printed by the ROM bootloader.
|
||||||
// nothing to do here.
|
// 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;
|
(void) cpu;
|
||||||
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 ||
|
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) {
|
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.");
|
ESP_LOGW(TAG, "PRO CPU has been reset by WDT.");
|
||||||
wdt_rst = 1;
|
return true;
|
||||||
}
|
}
|
||||||
if (wdt_rst) {
|
return false;
|
||||||
// if reset by WDT dump info from trace port
|
|
||||||
wdt_reset_info_dump(0);
|
|
||||||
}
|
|
||||||
wdt_reset_cpu0_info_enable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bootloader_super_wdt_auto_feed(void)
|
static void bootloader_super_wdt_auto_feed(void)
|
||||||
@@ -169,10 +164,8 @@ esp_err_t bootloader_init(void)
|
|||||||
}
|
}
|
||||||
#endif // !CONFIG_APP_BUILD_TYPE_RAM
|
#endif // !CONFIG_APP_BUILD_TYPE_RAM
|
||||||
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED
|
// check reset reason and dump diagnostic info
|
||||||
// check whether a WDT reset happened
|
bootloader_check_reset();
|
||||||
bootloader_check_wdt_reset();
|
|
||||||
#endif
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
|
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
|
||||||
// config WDT
|
// config WDT
|
||||||
bootloader_config_wdt();
|
bootloader_config_wdt();
|
||||||
|
|||||||
@@ -49,34 +49,29 @@
|
|||||||
ESP_LOG_ATTR_TAG(TAG, "boot.esp32c6");
|
ESP_LOG_ATTR_TAG(TAG, "boot.esp32c6");
|
||||||
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED
|
#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_SET_BIT(PCR_ASSIST_CONF_REG, PCR_ASSIST_CLK_EN);
|
||||||
REG_CLR_BIT(PCR_ASSIST_CONF_REG, PCR_ASSIST_RST_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);
|
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;
|
(void) cpu;
|
||||||
// saved PC was already printed by the ROM bootloader.
|
// saved PC was already printed by the ROM bootloader.
|
||||||
// nothing to do here.
|
// 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;
|
(void) cpu;
|
||||||
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 ||
|
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) {
|
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.");
|
ESP_LOGW(TAG, "PRO CPU has been reset by WDT.");
|
||||||
wdt_rst = 1;
|
return true;
|
||||||
}
|
}
|
||||||
if (wdt_rst) {
|
return false;
|
||||||
// if reset by WDT dump info from trace port
|
|
||||||
wdt_reset_info_dump(0);
|
|
||||||
}
|
|
||||||
wdt_reset_cpu0_info_enable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bootloader_super_wdt_auto_feed(void)
|
static void bootloader_super_wdt_auto_feed(void)
|
||||||
@@ -169,10 +164,8 @@ esp_err_t bootloader_init(void)
|
|||||||
}
|
}
|
||||||
#endif // !CONFIG_APP_BUILD_TYPE_RAM
|
#endif // !CONFIG_APP_BUILD_TYPE_RAM
|
||||||
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED
|
// check reset reason and dump diagnostic info
|
||||||
// check whether a WDT reset happened
|
bootloader_check_reset();
|
||||||
bootloader_check_wdt_reset();
|
|
||||||
#endif
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
|
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
|
||||||
// config WDT
|
// config WDT
|
||||||
bootloader_config_wdt();
|
bootloader_config_wdt();
|
||||||
|
|||||||
@@ -49,34 +49,29 @@
|
|||||||
ESP_LOG_ATTR_TAG(TAG, "boot.esp32c61");
|
ESP_LOG_ATTR_TAG(TAG, "boot.esp32c61");
|
||||||
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED
|
#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_SET_BIT(PCR_ASSIST_CONF_REG, PCR_ASSIST_CLK_EN);
|
||||||
REG_CLR_BIT(PCR_ASSIST_CONF_REG, PCR_ASSIST_RST_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);
|
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;
|
(void) cpu;
|
||||||
// saved PC was already printed by the ROM bootloader.
|
// saved PC was already printed by the ROM bootloader.
|
||||||
// nothing to do here.
|
// 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;
|
(void) cpu;
|
||||||
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 ||
|
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) {
|
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.");
|
ESP_LOGW(TAG, "PRO CPU has been reset by WDT.");
|
||||||
wdt_rst = 1;
|
return true;
|
||||||
}
|
}
|
||||||
if (wdt_rst) {
|
return false;
|
||||||
// if reset by WDT dump info from trace port
|
|
||||||
wdt_reset_info_dump(0);
|
|
||||||
}
|
|
||||||
wdt_reset_cpu0_info_enable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bootloader_super_wdt_auto_feed(void)
|
static void bootloader_super_wdt_auto_feed(void)
|
||||||
@@ -161,10 +156,8 @@ esp_err_t bootloader_init(void)
|
|||||||
}
|
}
|
||||||
#endif // !CONFIG_APP_BUILD_TYPE_RAM
|
#endif // !CONFIG_APP_BUILD_TYPE_RAM
|
||||||
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED
|
// check reset reason and dump diagnostic info
|
||||||
// check whether a WDT reset happened
|
bootloader_check_reset();
|
||||||
bootloader_check_wdt_reset();
|
|
||||||
#endif
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
|
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
|
||||||
// config WDT
|
// config WDT
|
||||||
bootloader_config_wdt();
|
bootloader_config_wdt();
|
||||||
|
|||||||
@@ -48,34 +48,29 @@
|
|||||||
ESP_LOG_ATTR_TAG(TAG, "boot.esp32h2");
|
ESP_LOG_ATTR_TAG(TAG, "boot.esp32h2");
|
||||||
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED
|
#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_SET_BIT(PCR_ASSIST_CONF_REG, PCR_ASSIST_CLK_EN);
|
||||||
REG_CLR_BIT(PCR_ASSIST_CONF_REG, PCR_ASSIST_RST_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);
|
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;
|
(void) cpu;
|
||||||
// saved PC was already printed by the ROM bootloader.
|
// saved PC was already printed by the ROM bootloader.
|
||||||
// nothing to do here.
|
// 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;
|
(void) cpu;
|
||||||
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 ||
|
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) {
|
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.");
|
ESP_EARLY_LOGW(TAG, "PRO CPU has been reset by WDT.");
|
||||||
wdt_rst = 1;
|
return true;
|
||||||
}
|
}
|
||||||
if (wdt_rst) {
|
return false;
|
||||||
// if reset by WDT dump info from trace port
|
|
||||||
wdt_reset_info_dump(0);
|
|
||||||
}
|
|
||||||
wdt_reset_cpu0_info_enable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bootloader_super_wdt_auto_feed(void)
|
static void bootloader_super_wdt_auto_feed(void)
|
||||||
@@ -166,10 +161,8 @@ esp_err_t bootloader_init(void)
|
|||||||
}
|
}
|
||||||
#endif // !CONFIG_APP_BUILD_TYPE_RAM
|
#endif // !CONFIG_APP_BUILD_TYPE_RAM
|
||||||
|
|
||||||
// check whether a WDT reset happened
|
// check reset reason and dump diagnostic info
|
||||||
#if SOC_RTC_WDT_SUPPORTED
|
bootloader_check_reset();
|
||||||
bootloader_check_wdt_reset();
|
|
||||||
#endif
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
|
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
|
||||||
// config WDT
|
// config WDT
|
||||||
bootloader_config_wdt();
|
bootloader_config_wdt();
|
||||||
|
|||||||
@@ -48,34 +48,29 @@
|
|||||||
ESP_LOG_ATTR_TAG(TAG, "boot.esp32h21");
|
ESP_LOG_ATTR_TAG(TAG, "boot.esp32h21");
|
||||||
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED
|
#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_SET_BIT(PCR_ASSIST_CONF_REG, PCR_ASSIST_CLK_EN);
|
||||||
REG_CLR_BIT(PCR_ASSIST_CONF_REG, PCR_ASSIST_RST_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);
|
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;
|
(void) cpu;
|
||||||
// saved PC was already printed by the ROM bootloader.
|
// saved PC was already printed by the ROM bootloader.
|
||||||
// nothing to do here.
|
// 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;
|
(void) cpu;
|
||||||
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 ||
|
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) {
|
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.");
|
ESP_EARLY_LOGW(TAG, "PRO CPU has been reset by WDT.");
|
||||||
wdt_rst = 1;
|
return true;
|
||||||
}
|
}
|
||||||
if (wdt_rst) {
|
return false;
|
||||||
// if reset by WDT dump info from trace port
|
|
||||||
wdt_reset_info_dump(0);
|
|
||||||
}
|
|
||||||
wdt_reset_cpu0_info_enable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bootloader_super_wdt_auto_feed(void)
|
static void bootloader_super_wdt_auto_feed(void)
|
||||||
@@ -163,10 +158,8 @@ esp_err_t bootloader_init(void)
|
|||||||
}
|
}
|
||||||
#endif // !CONFIG_APP_BUILD_TYPE_RAM
|
#endif // !CONFIG_APP_BUILD_TYPE_RAM
|
||||||
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED
|
// check reset reason and dump diagnostic info
|
||||||
// check whether a WDT reset happened
|
bootloader_check_reset();
|
||||||
bootloader_check_wdt_reset();
|
|
||||||
#endif
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
|
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
|
||||||
// config WDT
|
// config WDT
|
||||||
bootloader_config_wdt();
|
bootloader_config_wdt();
|
||||||
|
|||||||
@@ -44,43 +44,54 @@
|
|||||||
|
|
||||||
ESP_LOG_ATTR_TAG(TAG, "boot.esp32h4");
|
ESP_LOG_ATTR_TAG(TAG, "boot.esp32h4");
|
||||||
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED
|
#if SOC_RTC_WDT_SUPPORTED || SOC_CPU_LOCKUP_DEBUG_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_bus_clock(0, true);
|
||||||
assist_debug_ll_enable_pc_recording(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;
|
(void) cpu;
|
||||||
// saved PC was already printed by the ROM bootloader.
|
// saved PC was already printed by the ROM bootloader.
|
||||||
// nothing to do here.
|
// 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;
|
if (cpu == 0 && (reset_reason == RESET_REASON_CORE_RTC_WDT || reset_reason == RESET_REASON_CORE_MWDT0 ||
|
||||||
soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0);
|
reset_reason == RESET_REASON_CORE_MWDT1 || reset_reason == RESET_REASON_CPU0_MWDT0 ||
|
||||||
if (rst_reason == RESET_REASON_CORE_RTC_WDT || rst_reason == RESET_REASON_CORE_MWDT0 || rst_reason == RESET_REASON_CORE_MWDT1 ||
|
reset_reason == RESET_REASON_CPU0_MWDT1 || reset_reason == RESET_REASON_CPU0_RTC_WDT)) {
|
||||||
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.");
|
ESP_LOGW(TAG, "PRO CPU has been reset by WDT.");
|
||||||
wdt_rst = 1;
|
return true;
|
||||||
}
|
}
|
||||||
if (wdt_rst) {
|
if (cpu == 1 && (reset_reason == RESET_REASON_CORE_RTC_WDT || reset_reason == RESET_REASON_CORE_MWDT0 ||
|
||||||
// if reset by WDT dump info from trace port
|
reset_reason == RESET_REASON_CORE_MWDT1 || reset_reason == RESET_REASON_CPU0_MWDT0 ||
|
||||||
wdt_reset_info_dump(0);
|
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)
|
static void bootloader_super_wdt_auto_feed(void)
|
||||||
{
|
{
|
||||||
REG_WRITE(LP_WDT_SWD_WPROTECT_REG, LP_WDT_SWD_WKEY_VALUE);
|
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_SET_BIT(LP_WDT_SWD_CONFIG_REG, LP_WDT_SWD_AUTO_FEED_EN);
|
||||||
REG_WRITE(LP_WDT_SWD_WPROTECT_REG, 0);
|
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)
|
static inline void bootloader_hardware_init(void)
|
||||||
{
|
{
|
||||||
@@ -178,10 +189,8 @@ esp_err_t bootloader_init(void)
|
|||||||
#endif // !CONFIG_APP_BUILD_TYPE_RAM
|
#endif // !CONFIG_APP_BUILD_TYPE_RAM
|
||||||
bootloader_config_dcache();
|
bootloader_config_dcache();
|
||||||
bootloader_config_icache1();
|
bootloader_config_icache1();
|
||||||
#if SOC_RTC_WDT_SUPPORTED
|
// check reset reason and dump diagnostic info
|
||||||
// check whether a WDT reset happened
|
bootloader_check_reset();
|
||||||
bootloader_check_wdt_reset();
|
|
||||||
#endif
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
|
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
|
||||||
// config WDT
|
// config WDT
|
||||||
bootloader_config_wdt();
|
bootloader_config_wdt();
|
||||||
|
|||||||
@@ -55,36 +55,28 @@
|
|||||||
ESP_LOG_ATTR_TAG(TAG, "boot.esp32p4");
|
ESP_LOG_ATTR_TAG(TAG, "boot.esp32p4");
|
||||||
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED
|
#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_bus_clock(0, true);
|
||||||
assist_debug_ll_enable_pc_recording(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;
|
(void) cpu;
|
||||||
// saved PC was already printed by the ROM bootloader.
|
// saved PC was already printed by the ROM bootloader.
|
||||||
// nothing to do here.
|
// 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;
|
if (cpu == 0 && (rst_reason == RESET_REASON_CPU_MWDT || rst_reason == RESET_REASON_CPU_RWDT ||
|
||||||
soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0);
|
rst_reason == RESET_REASON_CORE_MWDT || rst_reason == RESET_REASON_CORE_RWDT ||
|
||||||
if (rst_reason == RESET_REASON_CPU_MWDT || rst_reason == RESET_REASON_CPU_RWDT || rst_reason == RESET_REASON_CORE_MWDT ||
|
rst_reason == RESET_REASON_SYS_RWDT)) {
|
||||||
rst_reason == RESET_REASON_CORE_RWDT || rst_reason == RESET_REASON_SYS_RWDT) {
|
|
||||||
ESP_LOGW(TAG, "CPU has been reset by WDT.");
|
ESP_LOGW(TAG, "CPU has been reset by WDT.");
|
||||||
wdt_rst = 1;
|
return true;
|
||||||
}
|
}
|
||||||
if (wdt_rst) {
|
return false;
|
||||||
// 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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bootloader_super_wdt_auto_feed(void)
|
static void bootloader_super_wdt_auto_feed(void)
|
||||||
@@ -187,10 +179,8 @@ esp_err_t bootloader_init(void)
|
|||||||
}
|
}
|
||||||
#endif // !CONFIG_APP_BUILD_TYPE_RAM
|
#endif // !CONFIG_APP_BUILD_TYPE_RAM
|
||||||
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED
|
// check reset reason and dump diagnostic info
|
||||||
// check whether a WDT reset happened
|
bootloader_check_reset();
|
||||||
bootloader_check_wdt_reset();
|
|
||||||
#endif
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
|
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
|
||||||
// config WDT
|
// config WDT
|
||||||
bootloader_config_wdt();
|
bootloader_config_wdt();
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
ESP_LOG_ATTR_TAG(TAG, "boot.esp32s2");
|
ESP_LOG_ATTR_TAG(TAG, "boot.esp32s2");
|
||||||
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED
|
#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_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);
|
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);
|
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,
|
uint32_t inst = 0, pid = 0, stat = 0, data = 0, pc = 0,
|
||||||
lsstat = 0, lsaddr = 0, lsdata = 0, dstat = 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);
|
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;
|
(void) cpu;
|
||||||
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 ||
|
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) {
|
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.");
|
ESP_LOGW(TAG, "PRO CPU has been reset by WDT.");
|
||||||
wdt_rst = 1;
|
return true;
|
||||||
}
|
}
|
||||||
if (wdt_rst) {
|
return false;
|
||||||
// if reset by WDT dump info from trace port
|
|
||||||
wdt_reset_info_dump(0);
|
|
||||||
}
|
|
||||||
wdt_reset_cpu0_info_enable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bootloader_super_wdt_auto_feed(void)
|
static void bootloader_super_wdt_auto_feed(void)
|
||||||
@@ -169,10 +164,8 @@ esp_err_t bootloader_init(void)
|
|||||||
}
|
}
|
||||||
#endif // !CONFIG_APP_BUILD_TYPE_RAM
|
#endif // !CONFIG_APP_BUILD_TYPE_RAM
|
||||||
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED
|
// check reset reason and dump diagnostic info
|
||||||
// check whether a WDT reset happened
|
bootloader_check_reset();
|
||||||
bootloader_check_wdt_reset();
|
|
||||||
#endif
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
|
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
|
||||||
// config WDT
|
// config WDT
|
||||||
bootloader_config_wdt();
|
bootloader_config_wdt();
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
ESP_LOG_ATTR_TAG(TAG, "boot.esp32s3");
|
ESP_LOG_ATTR_TAG(TAG, "boot.esp32s3");
|
||||||
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED
|
#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_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_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);
|
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,
|
uint32_t inst = 0, pid = 0, stat = 0, data = 0, pc = 0,
|
||||||
lsstat = 0, lsaddr = 0, lsdata = 0, dstat = 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);
|
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;
|
if (cpu == 0 && (rst_reason == RESET_REASON_CORE_RTC_WDT || rst_reason == RESET_REASON_CORE_MWDT0 ||
|
||||||
soc_reset_reason_t rst_reas[2];
|
rst_reason == RESET_REASON_CORE_MWDT1 || rst_reason == RESET_REASON_CPU0_MWDT0 ||
|
||||||
|
rst_reason == RESET_REASON_CPU0_RTC_WDT)) {
|
||||||
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) {
|
|
||||||
ESP_LOGW(TAG, "PRO CPU has been reset by 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 ||
|
if (cpu == 1 && (rst_reason == RESET_REASON_CORE_RTC_WDT || rst_reason == RESET_REASON_CORE_MWDT0 ||
|
||||||
rst_reas[1] == RESET_REASON_CPU1_MWDT1 || rst_reas[1] == RESET_REASON_CPU1_RTC_WDT) {
|
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.");
|
ESP_LOGW(TAG, "APP CPU has been reset by WDT.");
|
||||||
wdt_rst = 1;
|
return true;
|
||||||
}
|
}
|
||||||
if (wdt_rst) {
|
return false;
|
||||||
// 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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bootloader_super_wdt_auto_feed(void)
|
static void bootloader_super_wdt_auto_feed(void)
|
||||||
@@ -208,10 +198,8 @@ esp_err_t bootloader_init(void)
|
|||||||
}
|
}
|
||||||
#endif // !CONFIG_APP_BUILD_TYPE_RAM
|
#endif // !CONFIG_APP_BUILD_TYPE_RAM
|
||||||
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED
|
// check reset reason and dump diagnostic info
|
||||||
// check whether a WDT reset happened
|
bootloader_check_reset();
|
||||||
bootloader_check_wdt_reset();
|
|
||||||
#endif
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
|
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
|
||||||
// config WDT
|
// config WDT
|
||||||
bootloader_config_wdt();
|
bootloader_config_wdt();
|
||||||
|
|||||||
@@ -26,6 +26,9 @@
|
|||||||
#include "soc/pmu_reg.h"
|
#include "soc/pmu_reg.h"
|
||||||
#include "hal/regi2c_ctrl_ll.h"
|
#include "hal/regi2c_ctrl_ll.h"
|
||||||
#include "hal/modem_lpcon_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");
|
ESP_LOG_ATTR_TAG(TAG, "boot.esp32s31");
|
||||||
|
|
||||||
@@ -44,6 +47,44 @@ static inline void bootloader_hardware_init(void)
|
|||||||
#endif
|
#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
|
#if SOC_RTC_WDT_SUPPORTED
|
||||||
static void bootloader_super_wdt_auto_feed(void)
|
static void bootloader_super_wdt_auto_feed(void)
|
||||||
{
|
{
|
||||||
@@ -112,10 +153,8 @@ esp_err_t bootloader_init(void)
|
|||||||
}
|
}
|
||||||
#endif // !CONFIG_APP_BUILD_TYPE_RAM
|
#endif // !CONFIG_APP_BUILD_TYPE_RAM
|
||||||
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED
|
// check reset reason and dump diagnostic info
|
||||||
// check whether a WDT reset happened
|
bootloader_check_reset();
|
||||||
// bootloader_check_wdt_reset(); // TODO: IDF-14678
|
|
||||||
#endif
|
|
||||||
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
|
#if SOC_RTC_WDT_SUPPORTED || SOC_WDT_SUPPORTED
|
||||||
// config WDT
|
// config WDT
|
||||||
bootloader_config_wdt();
|
bootloader_config_wdt();
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ static inline void periph_ll_clk_gate_set_default(soc_reset_reason_t rst_reason,
|
|||||||
|
|
||||||
if (config->disable_assist_clk) {
|
if (config->disable_assist_clk) {
|
||||||
/* Disable ASSIST Debug module clock if PC recoreding function is not used,
|
/* Disable ASSIST Debug module clock if PC recoreding function is not used,
|
||||||
* if stack guard function needs it, it will be re-enabled at esp_hw_stack_guard_init */
|
* if stack guard function needs it, it will be re-enabled at esp_hw_debug_assist_init */
|
||||||
PCR.assist_conf.assist_clk_en = 0;
|
PCR.assist_conf.assist_clk_en = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ static inline void periph_ll_clk_gate_set_default(soc_reset_reason_t rst_reason,
|
|||||||
|
|
||||||
if (config->disable_assist_clk) {
|
if (config->disable_assist_clk) {
|
||||||
/* Disable ASSIST Debug module clock if PC recoreding function is not used,
|
/* Disable ASSIST Debug module clock if PC recoreding function is not used,
|
||||||
* if stack guard function needs it, it will be re-enabled at esp_hw_stack_guard_init */
|
* if stack guard function needs it, it will be re-enabled at esp_hw_debug_assist_init */
|
||||||
PCR.assist_conf.assist_clk_en = 0;
|
PCR.assist_conf.assist_clk_en = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ static inline void periph_ll_clk_gate_set_default(soc_reset_reason_t rst_reason,
|
|||||||
|
|
||||||
if (config->disable_assist_clk) {
|
if (config->disable_assist_clk) {
|
||||||
/* Disable ASSIST Debug module clock if PC recording is not used;
|
/* Disable ASSIST Debug module clock if PC recording is not used;
|
||||||
* stack guard may re-enable in esp_hw_stack_guard_init */
|
* stack guard may re-enable in esp_hw_debug_assist_init */
|
||||||
PCR.assist_conf.assist_clk_en = 0;
|
PCR.assist_conf.assist_clk_en = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -291,7 +291,7 @@ static inline void periph_ll_clk_gate_set_default(soc_reset_reason_t rst_reason,
|
|||||||
|
|
||||||
if (config->disable_assist_clk) {
|
if (config->disable_assist_clk) {
|
||||||
/* Disable ASSIST Debug module clock if PC recoreding function is not used,
|
/* Disable ASSIST Debug module clock if PC recoreding function is not used,
|
||||||
* if stack guard function needs it, it will be re-enabled at esp_hw_stack_guard_init */
|
* if stack guard function needs it, it will be re-enabled at esp_hw_debug_assist_init */
|
||||||
REG_CLR_BIT(HP_SYS_CLKRST_SOC_CLK_CTRL0_REG, HP_SYS_CLKRST_REG_BUSMON_CPU_CLK_EN);
|
REG_CLR_BIT(HP_SYS_CLKRST_SOC_CLK_CTRL0_REG, HP_SYS_CLKRST_REG_BUSMON_CPU_CLK_EN);
|
||||||
REG_CLR_BIT(ASSIST_DEBUG_CLOCK_GATE_REG, ASSIST_DEBUG_CLK_EN);
|
REG_CLR_BIT(ASSIST_DEBUG_CLOCK_GATE_REG, ASSIST_DEBUG_CLK_EN);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,3 +74,7 @@ config ESP_ROM_HAS_VERSION
|
|||||||
config ESP_ROM_MULTI_HEAP_WALK_PATCH
|
config ESP_ROM_MULTI_HEAP_WALK_PATCH
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
config ESP_ROM_PRINTS_LOCKUP_STATUS
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|||||||
@@ -24,3 +24,4 @@
|
|||||||
#define ESP_ROM_HAS_NEWLIB_NANO_FORMAT (1) // ROM has the newlib nano version of formatting functions
|
#define ESP_ROM_HAS_NEWLIB_NANO_FORMAT (1) // ROM has the newlib nano version of formatting functions
|
||||||
#define ESP_ROM_HAS_VERSION (1) // ROM has version/eco information
|
#define ESP_ROM_HAS_VERSION (1) // ROM has version/eco information
|
||||||
#define ESP_ROM_MULTI_HEAP_WALK_PATCH (1) // ROM does not contain the patch of multi_heap_walk()
|
#define ESP_ROM_MULTI_HEAP_WALK_PATCH (1) // ROM does not contain the patch of multi_heap_walk()
|
||||||
|
#define ESP_ROM_PRINTS_LOCKUP_STATUS (1) // ROM bootloader already prints CPU lockup diagnostic status
|
||||||
|
|||||||
@@ -83,8 +83,8 @@ else()
|
|||||||
list(APPEND srcs "systick_etm.c")
|
list(APPEND srcs "systick_etm.c")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CONFIG_ESP_SYSTEM_HW_STACK_GUARD)
|
if(CONFIG_ESP_SYSTEM_HW_STACK_GUARD OR CONFIG_ESP_SYSTEM_HW_PC_RECORD OR CONFIG_SOC_CPU_LOCKUP_DEBUG_SUPPORTED)
|
||||||
list(APPEND srcs "hw_stack_guard.c")
|
list(APPEND srcs "debug_assist.c")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
idf_component_register(SRCS "${srcs}"
|
idf_component_register(SRCS "${srcs}"
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
#include "hal/assist_debug_hal.h"
|
#include "hal/assist_debug_hal.h"
|
||||||
|
#include "hal/assist_debug_ll.h"
|
||||||
#include "esp_private/hw_stack_guard.h"
|
#include "esp_private/hw_stack_guard.h"
|
||||||
#include "esp_private/periph_ctrl.h"
|
#include "esp_private/periph_ctrl.h"
|
||||||
#include "esp_private/startup_internal.h"
|
#include "esp_private/startup_internal.h"
|
||||||
@@ -12,12 +13,8 @@
|
|||||||
#include "esp_rom_sys.h"
|
#include "esp_rom_sys.h"
|
||||||
#include "esp_cpu.h"
|
#include "esp_cpu.h"
|
||||||
|
|
||||||
ESP_SYSTEM_INIT_FN(esp_hw_stack_guard_init, SECONDARY, ESP_SYSTEM_INIT_ALL_CORES, 101)
|
static void esp_hw_debug_assist_enable_module(uint32_t core_id)
|
||||||
{
|
{
|
||||||
uint32_t core_id = esp_cpu_get_core_id();
|
|
||||||
|
|
||||||
ESP_INTR_DISABLE(ETS_ASSIST_DEBUG_INUM);
|
|
||||||
|
|
||||||
#if SOC_CPU_CORES_NUM > 1
|
#if SOC_CPU_CORES_NUM > 1
|
||||||
PERIPH_RCC_ATOMIC()
|
PERIPH_RCC_ATOMIC()
|
||||||
#endif
|
#endif
|
||||||
@@ -25,16 +22,20 @@ ESP_SYSTEM_INIT_FN(esp_hw_stack_guard_init, SECONDARY, ESP_SYSTEM_INIT_ALL_CORES
|
|||||||
assist_debug_ll_enable_bus_clock(core_id, true);
|
assist_debug_ll_enable_bus_clock(core_id, true);
|
||||||
assist_debug_ll_reset_register(core_id);
|
assist_debug_ll_reset_register(core_id);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
assist_debug_ll_enable_pc_recording(core_id, true);
|
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
|
||||||
|
static void esp_hw_stack_guard_init(uint32_t core_id)
|
||||||
|
{
|
||||||
|
ESP_INTR_DISABLE(ETS_ASSIST_DEBUG_INUM);
|
||||||
|
|
||||||
/* set interrupt to matrix */
|
/* Set interrupt to matrix. */
|
||||||
esp_rom_route_intr_matrix(core_id, ETS_ASSIST_DEBUG_INTR_SOURCE, ETS_ASSIST_DEBUG_INUM);
|
esp_rom_route_intr_matrix(core_id, ETS_ASSIST_DEBUG_INTR_SOURCE, ETS_ASSIST_DEBUG_INUM);
|
||||||
esprv_int_set_type(ETS_ASSIST_DEBUG_INUM, INTR_TYPE_LEVEL);
|
esprv_int_set_type(ETS_ASSIST_DEBUG_INUM, INTR_TYPE_LEVEL);
|
||||||
esprv_int_set_priority(ETS_ASSIST_DEBUG_INUM, SOC_INTERRUPT_LEVEL_MEDIUM);
|
esprv_int_set_priority(ETS_ASSIST_DEBUG_INUM, SOC_INTERRUPT_LEVEL_MEDIUM);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* enable interrupt
|
* Enable interrupt.
|
||||||
* Note: to control hw_stack_guard use monitor enable/disable because in case:
|
* Note: to control hw_stack_guard use monitor enable/disable because in case:
|
||||||
* - monitor == active
|
* - monitor == active
|
||||||
* - interrupt != active
|
* - interrupt != active
|
||||||
@@ -46,6 +47,27 @@ ESP_SYSTEM_INIT_FN(esp_hw_stack_guard_init, SECONDARY, ESP_SYSTEM_INIT_ALL_CORES
|
|||||||
assist_debug_hal_sp_int_enable(core_id);
|
assist_debug_hal_sp_int_enable(core_id);
|
||||||
|
|
||||||
ESP_INTR_ENABLE(ETS_ASSIST_DEBUG_INUM);
|
ESP_INTR_ENABLE(ETS_ASSIST_DEBUG_INUM);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ESP_SYSTEM_INIT_FN(esp_hw_debug_assist_init, SECONDARY, ESP_SYSTEM_INIT_ALL_CORES, 101)
|
||||||
|
{
|
||||||
|
uint32_t core_id = esp_cpu_get_core_id();
|
||||||
|
|
||||||
|
esp_hw_debug_assist_enable_module(core_id);
|
||||||
|
|
||||||
|
#if CONFIG_ESP_SYSTEM_HW_PC_RECORD
|
||||||
|
assist_debug_ll_enable_pc_recording(core_id, true);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
|
||||||
|
esp_hw_stack_guard_init(core_id);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SOC_CPU_LOCKUP_DEBUG_SUPPORTED
|
||||||
|
assist_debug_ll_lockup_monitor_enable(core_id, true);
|
||||||
|
#endif
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,14 +78,15 @@ void esp_hw_stack_guard_monitor_start(void)
|
|||||||
{
|
{
|
||||||
uint32_t core_id = esp_cpu_get_core_id();
|
uint32_t core_id = esp_cpu_get_core_id();
|
||||||
|
|
||||||
/* enable monitor. Interrupt is always enabled (see comment in esp_hw_stack_guard_init()) */
|
/* Enable monitor. Interrupt is configured during assist-debug init. */
|
||||||
assist_debug_hal_sp_mon_enable(core_id);
|
assist_debug_hal_sp_mon_enable(core_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void esp_hw_stack_guard_monitor_stop(void)
|
void esp_hw_stack_guard_monitor_stop(void)
|
||||||
{
|
{
|
||||||
uint32_t core_id = esp_cpu_get_core_id();
|
uint32_t core_id = esp_cpu_get_core_id();
|
||||||
/* disable monitor. Interrupt is always enabled (see comment in esp_hw_stack_guard_init()) */
|
|
||||||
|
/* Disable monitor. Interrupt is configured during assist-debug init. */
|
||||||
assist_debug_hal_sp_mon_disable(core_id);
|
assist_debug_hal_sp_mon_disable(core_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8,9 +8,9 @@ entries:
|
|||||||
cache_err_int (noflash)
|
cache_err_int (noflash)
|
||||||
reset_reason:esp_reset_reason_get_hint (noflash)
|
reset_reason:esp_reset_reason_get_hint (noflash)
|
||||||
if ESP_SYSTEM_HW_STACK_GUARD = y:
|
if ESP_SYSTEM_HW_STACK_GUARD = y:
|
||||||
hw_stack_guard:esp_hw_stack_guard_get_bounds (noflash)
|
debug_assist:esp_hw_stack_guard_get_bounds (noflash)
|
||||||
hw_stack_guard:esp_hw_stack_guard_get_fired_cpu (noflash)
|
debug_assist:esp_hw_stack_guard_get_fired_cpu (noflash)
|
||||||
hw_stack_guard:esp_hw_stack_guard_get_pc (noflash)
|
debug_assist:esp_hw_stack_guard_get_pc (noflash)
|
||||||
|
|
||||||
# These functions are called when the cache is disabled
|
# These functions are called when the cache is disabled
|
||||||
system_internal:esp_restart_noos (noflash)
|
system_internal:esp_restart_noos (noflash)
|
||||||
|
|||||||
@@ -257,7 +257,7 @@ __attribute__((weak)) void esp_perip_clk_init(void)
|
|||||||
|
|
||||||
#if !CONFIG_ESP_SYSTEM_HW_PC_RECORD
|
#if !CONFIG_ESP_SYSTEM_HW_PC_RECORD
|
||||||
/* Disable ASSIST Debug module clock if PC recoreding function is not used,
|
/* Disable ASSIST Debug module clock if PC recoreding function is not used,
|
||||||
* if stack guard function needs it, it will be re-enabled at esp_hw_stack_guard_init */
|
* if stack guard function needs it, it will be re-enabled at esp_hw_debug_assist_init */
|
||||||
CLEAR_PERI_REG_MASK(SYSTEM_CPU_PERI_CLK_EN_REG, SYSTEM_CLK_EN_ASSIST_DEBUG);
|
CLEAR_PERI_REG_MASK(SYSTEM_CPU_PERI_CLK_EN_REG, SYSTEM_CLK_EN_ASSIST_DEBUG);
|
||||||
SET_PERI_REG_MASK(SYSTEM_CPU_PERI_RST_EN_REG, SYSTEM_RST_EN_ASSIST_DEBUG);
|
SET_PERI_REG_MASK(SYSTEM_CPU_PERI_RST_EN_REG, SYSTEM_RST_EN_ASSIST_DEBUG);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -299,7 +299,7 @@ __attribute__((weak)) void esp_perip_clk_init(void)
|
|||||||
|
|
||||||
#if !CONFIG_ESP_SYSTEM_HW_PC_RECORD
|
#if !CONFIG_ESP_SYSTEM_HW_PC_RECORD
|
||||||
/* Disable ASSIST Debug module clock if PC recoreding function is not used,
|
/* Disable ASSIST Debug module clock if PC recoreding function is not used,
|
||||||
* if stack guard function needs it, it will be re-enabled at esp_hw_stack_guard_init */
|
* if stack guard function needs it, it will be re-enabled at esp_hw_debug_assist_init */
|
||||||
CLEAR_PERI_REG_MASK(SYSTEM_CPU_PERI_CLK_EN_REG, SYSTEM_CLK_EN_ASSIST_DEBUG);
|
CLEAR_PERI_REG_MASK(SYSTEM_CPU_PERI_CLK_EN_REG, SYSTEM_CLK_EN_ASSIST_DEBUG);
|
||||||
SET_PERI_REG_MASK(SYSTEM_CPU_PERI_RST_EN_REG, SYSTEM_RST_EN_ASSIST_DEBUG);
|
SET_PERI_REG_MASK(SYSTEM_CPU_PERI_RST_EN_REG, SYSTEM_RST_EN_ASSIST_DEBUG);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -72,8 +72,8 @@ CORE: 170: init_xt_wdt in components/esp_system/startup_funcs.c on BIT(0)
|
|||||||
# esp_timer has to be initialized early, since it is used by several other components
|
# esp_timer has to be initialized early, since it is used by several other components
|
||||||
SECONDARY: 100: esp_timer_init_os in components/esp_timer/src/esp_timer.c on ESP_TIMER_INIT_MASK
|
SECONDARY: 100: esp_timer_init_os in components/esp_timer/src/esp_timer.c on ESP_TIMER_INIT_MASK
|
||||||
|
|
||||||
# HW stack guard via assist-debug module.
|
# Assist-debug early init for stack guard and PC recording.
|
||||||
SECONDARY: 101: esp_hw_stack_guard_init in components/esp_system/hw_stack_guard.c on ESP_SYSTEM_INIT_ALL_CORES
|
SECONDARY: 101: esp_hw_debug_assist_init in components/esp_system/debug_assist.c on ESP_SYSTEM_INIT_ALL_CORES
|
||||||
|
|
||||||
# Initialize RNG (enable clock which is disabled in `esp_perip_clk_init`, configure entropy sources)
|
# Initialize RNG (enable clock which is disabled in `esp_perip_clk_init`, configure entropy sources)
|
||||||
SECONDARY: 102: init_rng in components/esp_hw_support/hw_random.c on BIT(0)
|
SECONDARY: 102: init_rng in components/esp_hw_support/hw_random.c on BIT(0)
|
||||||
|
|||||||
@@ -8,13 +8,14 @@ set(requires "unity"
|
|||||||
"esp_psram")
|
"esp_psram")
|
||||||
|
|
||||||
set(SRC "test_app_main.c"
|
set(SRC "test_app_main.c"
|
||||||
"test_backtrace.c"
|
"test_backtrace.c"
|
||||||
"test_ipc.c"
|
"test_ipc.c"
|
||||||
"test_reset_reason.c"
|
"test_panic.c"
|
||||||
"test_shared_stack_printf.c"
|
"test_reset_reason.c"
|
||||||
"test_stack_check.c"
|
"test_shared_stack_printf.c"
|
||||||
"test_system_time.c"
|
"test_stack_check.c"
|
||||||
"test_task_wdt.c")
|
"test_system_time.c"
|
||||||
|
"test_task_wdt.c")
|
||||||
|
|
||||||
if(CONFIG_SOC_LIGHT_SLEEP_SUPPORTED OR CONFIG_SOC_DEEP_SLEEP_SUPPORTED)
|
if(CONFIG_SOC_LIGHT_SLEEP_SUPPORTED OR CONFIG_SOC_DEEP_SLEEP_SUPPORTED)
|
||||||
list(APPEND SRC "test_sleep.c"
|
list(APPEND SRC "test_sleep.c"
|
||||||
@@ -42,3 +43,9 @@ idf_component_register(SRCS ${SRC}
|
|||||||
PRIV_INCLUDE_DIRS .
|
PRIV_INCLUDE_DIRS .
|
||||||
PRIV_REQUIRES "${requires}"
|
PRIV_REQUIRES "${requires}"
|
||||||
WHOLE_ARCHIVE)
|
WHOLE_ARCHIVE)
|
||||||
|
|
||||||
|
if(CONFIG_SOC_CPU_LOCKUP_DEBUG_SUPPORTED)
|
||||||
|
# Wrap esp_panic_handler so the lockup test can inject a second exception
|
||||||
|
# inside the panic handler. All other panics in the test binary are unaffected.
|
||||||
|
target_link_options(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=esp_panic_handler")
|
||||||
|
endif()
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
#include "unity.h"
|
||||||
|
#include "soc/soc_caps.h"
|
||||||
|
|
||||||
|
#if SOC_CPU_LOCKUP_DEBUG_SUPPORTED
|
||||||
|
|
||||||
|
static bool s_trigger_lockup_in_panic;
|
||||||
|
|
||||||
|
/* __wrap_esp_panic_handler intercepts all panics in this test binary.
|
||||||
|
* Normally it calls through to the real handler. When s_trigger_lockup_in_panic
|
||||||
|
* is set it causes a second exception inside the handler, which triggers a
|
||||||
|
* hardware CPU lockup reset.
|
||||||
|
*/
|
||||||
|
void __real_esp_panic_handler(void *info);
|
||||||
|
void __wrap_esp_panic_handler(void *info)
|
||||||
|
{
|
||||||
|
if (s_trigger_lockup_in_panic) {
|
||||||
|
__asm__ volatile("unimp"); /* exception inside exception handler -> lockup */
|
||||||
|
}
|
||||||
|
__real_esp_panic_handler(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("CPU lockup output", "[cpu_lockup][ignore]")
|
||||||
|
{
|
||||||
|
s_trigger_lockup_in_panic = true;
|
||||||
|
__asm__ volatile("unimp"); /* first exception -> panic handler -> second exception -> lockup */
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // SOC_CPU_LOCKUP_DEBUG_SUPPORTED
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
*/
|
*/
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include "unity.h"
|
#include "unity.h"
|
||||||
|
#include "soc/soc_caps.h"
|
||||||
#include "esp_system.h"
|
#include "esp_system.h"
|
||||||
#include "esp_task_wdt.h"
|
#include "esp_task_wdt.h"
|
||||||
#include "esp_attr.h"
|
#include "esp_attr.h"
|
||||||
|
|||||||
+34
@@ -123,6 +123,40 @@ def test_sleep_uart_handling(dut: Dut) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.generic
|
||||||
|
@idf_parametrize('config', ['default'], indirect=['config'])
|
||||||
|
@idf_parametrize(
|
||||||
|
'target',
|
||||||
|
[target for target in soc_filtered_targets('SOC_CPU_LOCKUP_DEBUG_SUPPORTED == 1')],
|
||||||
|
indirect=['target'],
|
||||||
|
)
|
||||||
|
def test_cpu_lockup_trap_chain(dut: Dut) -> None:
|
||||||
|
"""Trigger a PRO CPU lockup and verify the lockup output."""
|
||||||
|
esp_reset_and_wait_ready(dut)
|
||||||
|
dut.write('"CPU lockup output"')
|
||||||
|
|
||||||
|
if dut.target == 'esp32s31':
|
||||||
|
# ROM should print a non-zero Core0 trap PC for both exceptions.
|
||||||
|
dut.expect(r'\[Core0\]', timeout=10)
|
||||||
|
dut.expect(r'1st Exception:', timeout=5)
|
||||||
|
dut.expect(r'PCAddr:\s+0x(?!00000000)[0-9a-f]{8}', timeout=5)
|
||||||
|
dut.expect(r'2nd Exception:', timeout=5)
|
||||||
|
dut.expect(r'PCAddr:\s+0x(?!00000000)[0-9a-f]{8}', timeout=5)
|
||||||
|
else:
|
||||||
|
# 2nd stage bootloader should log the trap chain after the lockup reset.
|
||||||
|
dut.expect('PRO CPU reset due to CPU lockup', timeout=10)
|
||||||
|
dut.expect('PRO CPU trap chain:', timeout=5)
|
||||||
|
# Both traps should be illegal instruction (RISC-V mcause=2)
|
||||||
|
dut.expect(
|
||||||
|
r'\[latest trap\] cause=0x02 PCAddr=0x(?!00000000)[0-9a-f]{8} tval=0x[0-9a-f]{8} priv=[0-9]+', timeout=5
|
||||||
|
)
|
||||||
|
dut.expect(
|
||||||
|
r'\[previous trap\] cause=0x02 PCAddr=0x(?!00000000)[0-9a-f]{8} tval=0x[0-9a-f]{8} priv=[0-9]+', timeout=5
|
||||||
|
)
|
||||||
|
|
||||||
|
dut.expect_exact('Press ENTER to see the list of tests', timeout=30)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.generic
|
@pytest.mark.generic
|
||||||
@idf_parametrize('config', ['default'], indirect=['config'])
|
@idf_parametrize('config', ['default'], indirect=['config'])
|
||||||
@idf_parametrize('target', ['supported_targets'], indirect=['target'])
|
@idf_parametrize('target', ['supported_targets'], indirect=['target'])
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include "esp_attr.h"
|
#include "esp_attr.h"
|
||||||
#include "soc/pcr_struct.h"
|
#include "soc/pcr_struct.h"
|
||||||
#include "soc/bus_monitor_struct.h"
|
#include "soc/bus_monitor_struct.h"
|
||||||
|
#include "soc/lp_clkrst_struct.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -172,6 +173,73 @@ FORCE_INLINE_ATTR bool assist_debug_ll_is_debugger_active(void)
|
|||||||
return BUS_MONITOR.monitor_core_0_debug_mode.monitor_core_0_debug_module_active;
|
return BUS_MONITOR.monitor_core_0_debug_mode.monitor_core_0_debug_module_active;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE_ATTR void assist_debug_ll_lockup_monitor_enable(uint32_t core_id, bool enable)
|
||||||
|
{
|
||||||
|
if (core_id) {
|
||||||
|
BUS_MONITOR.monitor_core_1_montr_ena.monitor_core_1_trace_lockup_ena = enable;
|
||||||
|
} else {
|
||||||
|
BUS_MONITOR.monitor_core_0_montr_ena.monitor_core_0_trace_lockup_ena = enable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// trap_idx: 0 = latest trap, 1 = previous trap
|
||||||
|
// MCause for the exception
|
||||||
|
FORCE_INLINE_ATTR uint32_t assist_debug_ll_lockup_get_cause(uint32_t core_id, int trap_idx)
|
||||||
|
{
|
||||||
|
if (core_id) {
|
||||||
|
return trap_idx ? BUS_MONITOR.monitor_core_1_trace_lockup_cause_1.monitor_core_1_trace_lockup_recording_cause_1
|
||||||
|
: BUS_MONITOR.monitor_core_1_trace_lockup_cause_0.monitor_core_1_trace_lockup_recording_cause_0;
|
||||||
|
} else {
|
||||||
|
return trap_idx ? BUS_MONITOR.monitor_core_0_trace_lockup_cause_1.monitor_core_0_trace_lockup_recording_cause_1
|
||||||
|
: BUS_MONITOR.monitor_core_0_trace_lockup_cause_0.monitor_core_0_trace_lockup_recording_cause_0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE_ATTR uint32_t assist_debug_ll_lockup_get_tval(uint32_t core_id, int trap_idx)
|
||||||
|
{
|
||||||
|
if (core_id) {
|
||||||
|
return trap_idx ? BUS_MONITOR.monitor_core_1_trace_lockup_tval_1.monitor_core_1_trace_lockup_recording_tval_1
|
||||||
|
: BUS_MONITOR.monitor_core_1_trace_lockup_tval_0.monitor_core_1_trace_lockup_recording_tval_0;
|
||||||
|
} else {
|
||||||
|
return trap_idx ? BUS_MONITOR.monitor_core_0_trace_lockup_tval_1.monitor_core_0_trace_lockup_recording_tval_1
|
||||||
|
: BUS_MONITOR.monitor_core_0_trace_lockup_tval_0.monitor_core_0_trace_lockup_recording_tval_0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE_ATTR uint32_t assist_debug_ll_lockup_get_iaddr(uint32_t core_id, int trap_idx)
|
||||||
|
{
|
||||||
|
if (core_id) {
|
||||||
|
return trap_idx ? BUS_MONITOR.monitor_core_1_trace_lockup_iaddr_1.monitor_core_1_trace_lockup_recording_iaddr_1
|
||||||
|
: BUS_MONITOR.monitor_core_1_trace_lockup_iaddr_0.monitor_core_1_trace_lockup_recording_iaddr_0;
|
||||||
|
} else {
|
||||||
|
return trap_idx ? BUS_MONITOR.monitor_core_0_trace_lockup_iaddr_1.monitor_core_0_trace_lockup_recording_iaddr_1
|
||||||
|
: BUS_MONITOR.monitor_core_0_trace_lockup_iaddr_0.monitor_core_0_trace_lockup_recording_iaddr_0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE_ATTR uint32_t assist_debug_ll_lockup_get_priv(uint32_t core_id, int trap_idx)
|
||||||
|
{
|
||||||
|
if (core_id) {
|
||||||
|
return trap_idx ? BUS_MONITOR.monitor_core_1_trace_lockup_priv_1.monitor_core_1_trace_lockup_recording_priv_1
|
||||||
|
: BUS_MONITOR.monitor_core_1_trace_lockup_priv_0.monitor_core_1_trace_lockup_recording_priv_0;
|
||||||
|
} else {
|
||||||
|
return trap_idx ? BUS_MONITOR.monitor_core_0_trace_lockup_priv_1.monitor_core_0_trace_lockup_recording_priv_1
|
||||||
|
: BUS_MONITOR.monitor_core_0_trace_lockup_priv_0.monitor_core_0_trace_lockup_recording_priv_0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enable the hardware lockup reset for the given core via LP_CLKRST.
|
||||||
|
* This controls whether a CPU lockup (exception inside exception handler) triggers
|
||||||
|
* a system reset. Defaults to 1 on H4 but must be set explicitly to be safe. */
|
||||||
|
FORCE_INLINE_ATTR void assist_debug_ll_lockup_reset_enable(uint32_t core_id)
|
||||||
|
{
|
||||||
|
if (core_id) {
|
||||||
|
LP_CLKRST.cpu_core1_reset.hpcore1_lockup_reset_en = 1;
|
||||||
|
} else {
|
||||||
|
LP_CLKRST.cpu_core0_reset.hpcore0_lockup_reset_en = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include "esp_attr.h"
|
#include "esp_attr.h"
|
||||||
#include "soc/hp_sys_clkrst_struct.h"
|
#include "soc/hp_sys_clkrst_struct.h"
|
||||||
#include "soc/bus_monitor_struct.h"
|
#include "soc/bus_monitor_struct.h"
|
||||||
|
#include "soc/lp_clkrst_struct.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -172,6 +173,73 @@ FORCE_INLINE_ATTR bool assist_debug_ll_is_debugger_active(void)
|
|||||||
return BUS_MONITOR.core_0_debug_mode.core_0_debug_module_active;
|
return BUS_MONITOR.core_0_debug_mode.core_0_debug_module_active;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE_ATTR void assist_debug_ll_lockup_monitor_enable(uint32_t core_id, bool enable)
|
||||||
|
{
|
||||||
|
if (core_id) {
|
||||||
|
BUS_MONITOR.core_1_montr_ena.core_1_trace_lockup_ena = enable;
|
||||||
|
} else {
|
||||||
|
BUS_MONITOR.core_0_montr_ena.core_0_trace_lockup_ena = enable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// trap_idx: 0 = latest trap, 1 = previous trap
|
||||||
|
// MCause for the exception
|
||||||
|
FORCE_INLINE_ATTR uint32_t assist_debug_ll_lockup_get_cause(uint32_t core_id, int trap_idx)
|
||||||
|
{
|
||||||
|
if (core_id) {
|
||||||
|
return trap_idx ? BUS_MONITOR.core_1_trace_lockup_cause_1.core_1_trace_lockup_recording_cause_1
|
||||||
|
: BUS_MONITOR.core_1_trace_lockup_cause_0.core_1_trace_lockup_recording_cause_0;
|
||||||
|
} else {
|
||||||
|
return trap_idx ? BUS_MONITOR.core_0_trace_lockup_cause_1.core_0_trace_lockup_recording_cause_1
|
||||||
|
: BUS_MONITOR.core_0_trace_lockup_cause_0.core_0_trace_lockup_recording_cause_0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE_ATTR uint32_t assist_debug_ll_lockup_get_tval(uint32_t core_id, int trap_idx)
|
||||||
|
{
|
||||||
|
if (core_id) {
|
||||||
|
return trap_idx ? BUS_MONITOR.core_1_trace_lockup_tval_1.core_1_trace_lockup_recording_tval_1
|
||||||
|
: BUS_MONITOR.core_1_trace_lockup_tval_0.core_1_trace_lockup_recording_tval_0;
|
||||||
|
} else {
|
||||||
|
return trap_idx ? BUS_MONITOR.core_0_trace_lockup_tval_1.core_0_trace_lockup_recording_tval_1
|
||||||
|
: BUS_MONITOR.core_0_trace_lockup_tval_0.core_0_trace_lockup_recording_tval_0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE_ATTR uint32_t assist_debug_ll_lockup_get_iaddr(uint32_t core_id, int trap_idx)
|
||||||
|
{
|
||||||
|
if (core_id) {
|
||||||
|
return trap_idx ? BUS_MONITOR.core_1_trace_lockup_iaddr_1.core_1_trace_lockup_recording_iaddr_1
|
||||||
|
: BUS_MONITOR.core_1_trace_lockup_iaddr_0.core_1_trace_lockup_recording_iaddr_0;
|
||||||
|
} else {
|
||||||
|
return trap_idx ? BUS_MONITOR.core_0_trace_lockup_iaddr_1.core_0_trace_lockup_recording_iaddr_1
|
||||||
|
: BUS_MONITOR.core_0_trace_lockup_iaddr_0.core_0_trace_lockup_recording_iaddr_0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE_ATTR uint32_t assist_debug_ll_lockup_get_priv(uint32_t core_id, int trap_idx)
|
||||||
|
{
|
||||||
|
if (core_id) {
|
||||||
|
return trap_idx ? BUS_MONITOR.core_1_trace_lockup_priv_1.core_1_trace_lockup_recording_priv_1
|
||||||
|
: BUS_MONITOR.core_1_trace_lockup_priv_0.core_1_trace_lockup_recording_priv_0;
|
||||||
|
} else {
|
||||||
|
return trap_idx ? BUS_MONITOR.core_0_trace_lockup_priv_1.core_0_trace_lockup_recording_priv_1
|
||||||
|
: BUS_MONITOR.core_0_trace_lockup_priv_0.core_0_trace_lockup_recording_priv_0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enable the hardware lockup reset for the given core via LP_CLKRST.
|
||||||
|
* This controls whether a CPU lockup (exception inside exception handler) triggers
|
||||||
|
* a system reset. Defaults to 0 on S31 so must be explicitly set. */
|
||||||
|
FORCE_INLINE_ATTR void assist_debug_ll_lockup_reset_enable(uint32_t core_id)
|
||||||
|
{
|
||||||
|
if (core_id) {
|
||||||
|
LP_CLKRST.hpcore1_reset_ctrl.hpcore1_lockup_reset_en = 1;
|
||||||
|
} else {
|
||||||
|
LP_CLKRST.hpcore0_reset_ctrl.hpcore0_lockup_reset_en = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -171,6 +171,10 @@ config SOC_ASSIST_DEBUG_SUPPORTED
|
|||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
config SOC_CPU_LOCKUP_DEBUG_SUPPORTED
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
config SOC_WDT_SUPPORTED
|
config SOC_WDT_SUPPORTED
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|||||||
@@ -85,6 +85,7 @@
|
|||||||
#define SOC_REGI2C_SUPPORTED 1
|
#define SOC_REGI2C_SUPPORTED 1
|
||||||
#define SOC_CLK_TREE_SUPPORTED 1
|
#define SOC_CLK_TREE_SUPPORTED 1
|
||||||
#define SOC_ASSIST_DEBUG_SUPPORTED 1
|
#define SOC_ASSIST_DEBUG_SUPPORTED 1
|
||||||
|
#define SOC_CPU_LOCKUP_DEBUG_SUPPORTED 1
|
||||||
#define SOC_WDT_SUPPORTED 1
|
#define SOC_WDT_SUPPORTED 1
|
||||||
#define SOC_RTC_WDT_SUPPORTED 1
|
#define SOC_RTC_WDT_SUPPORTED 1
|
||||||
#define SOC_SPI_FLASH_SUPPORTED 1
|
#define SOC_SPI_FLASH_SUPPORTED 1
|
||||||
|
|||||||
@@ -123,6 +123,10 @@ config SOC_ASSIST_DEBUG_SUPPORTED
|
|||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
config SOC_CPU_LOCKUP_DEBUG_SUPPORTED
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
config SOC_WDT_SUPPORTED
|
config SOC_WDT_SUPPORTED
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|||||||
@@ -86,6 +86,7 @@
|
|||||||
// #define SOC_SDMMC_HOST_SUPPORTED 1 // TODO: [ESP32S31] IDF-14705
|
// #define SOC_SDMMC_HOST_SUPPORTED 1 // TODO: [ESP32S31] IDF-14705
|
||||||
#define SOC_CLK_TREE_SUPPORTED 1
|
#define SOC_CLK_TREE_SUPPORTED 1
|
||||||
#define SOC_ASSIST_DEBUG_SUPPORTED 1
|
#define SOC_ASSIST_DEBUG_SUPPORTED 1
|
||||||
|
#define SOC_CPU_LOCKUP_DEBUG_SUPPORTED 1
|
||||||
// #define SOC_DEBUG_PROBE_SUPPORTED 1 // TODO: [ESP32S31] IDF-14798
|
// #define SOC_DEBUG_PROBE_SUPPORTED 1 // TODO: [ESP32S31] IDF-14798
|
||||||
#define SOC_WDT_SUPPORTED 1
|
#define SOC_WDT_SUPPORTED 1
|
||||||
#define SOC_RTC_WDT_SUPPORTED 1
|
#define SOC_RTC_WDT_SUPPORTED 1
|
||||||
|
|||||||
Reference in New Issue
Block a user