Merge branch 'feature/esp32p4-coredump-support' into 'master'

esp32p4: panic tests support

Closes IDF-7565, IDF-7861, IDF-9035, and IDF-9075

See merge request espressif/esp-idf!28586
pull/13473/head
Alexey Lapshin 2024-03-21 21:12:25 +08:00
commit 0e3673a2bd
26 zmienionych plików z 420 dodań i 110 usunięć

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -15,15 +15,20 @@ ESP_SYSTEM_INIT_FN(esp_hw_stack_guard_init, SECONDARY, ESP_SYSTEM_INIT_ALL_CORES
{
uint32_t core_id = esp_cpu_get_core_id();
if (core_id == 0) {
/* initialize the peripheral only when running on core 0 */
periph_module_enable(PERIPH_ASSIST_DEBUG_MODULE);
periph_module_reset(PERIPH_ASSIST_DEBUG_MODULE);
ESP_INTR_DISABLE(ETS_ASSIST_DEBUG_INUM);
#if SOC_CPU_CORES_NUM > 1
PERIPH_RCC_ATOMIC()
#endif
{
assist_debug_ll_enable_bus_clock(true);
assist_debug_ll_reset_register();
}
/* just in case, disable the interrupt and clear pending status */
assist_debug_hal_sp_int_disable(core_id);
assist_debug_hal_sp_int_clear(core_id);
/* set interrupt to matrix */
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_priority(ETS_ASSIST_DEBUG_INUM, SOC_INTERRUPT_LEVEL_MEDIUM);
/*
* enable interrupt
@ -37,12 +42,6 @@ ESP_SYSTEM_INIT_FN(esp_hw_stack_guard_init, SECONDARY, ESP_SYSTEM_INIT_ALL_CORES
*/
assist_debug_hal_sp_int_enable(core_id);
/* enable interrup routine */
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_priority(ETS_ASSIST_DEBUG_INUM, SOC_INTERRUPT_LEVEL_MEDIUM);
ESP_INTR_ENABLE(ETS_ASSIST_DEBUG_INUM);
return ESP_OK;
}
@ -72,23 +71,22 @@ void esp_hw_stack_guard_set_bounds(uint32_t sp_min, uint32_t sp_max)
assist_debug_hal_set_sp_bounds(core_id, sp_min, sp_max);
}
void esp_hw_stack_guard_get_bounds(uint32_t *sp_min, uint32_t *sp_max)
void esp_hw_stack_guard_get_bounds(uint32_t core_id, uint32_t *sp_min, uint32_t *sp_max)
{
uint32_t core_id = esp_cpu_get_core_id();
assist_debug_hal_get_sp_bounds(core_id, sp_min, sp_max);
}
bool esp_hw_stack_guard_is_fired(void)
uint32_t esp_hw_stack_guard_get_fired_cpu(void)
{
uint32_t core_id = esp_cpu_get_core_id();
return assist_debug_hal_is_sp_ovf_fired(core_id);
for (uint32_t i = 0; i < SOC_CPU_CORES_NUM; i++) {
if (assist_debug_hal_is_sp_ovf_fired(i)) {
return i;
}
}
return ESP_HW_STACK_GUARD_NOT_FIRED;
}
uint32_t esp_hw_stack_guard_get_pc(void)
uint32_t esp_hw_stack_guard_get_pc(uint32_t core_id)
{
uint32_t core_id = esp_cpu_get_core_id();
return assist_debug_hal_get_sp_ovf_pc(core_id);
}

Wyświetl plik

@ -217,7 +217,7 @@ SECTIONS
.dram0.data :
{
_data_start = ABSOLUTE(.);
_data_start_low = ABSOLUTE(.);
*(.gnu.linkonce.d.*)
*(.data1)
__global_pointer$ = . + 0x800;
@ -230,9 +230,18 @@ SECTIONS
arrays[dram0_data]
mapping[dram0_data]
_data_end = ABSOLUTE(.);
_data_end_low = ABSOLUTE(.);
} > sram_low
.dram1.data :
{
_data_start_high = ABSOLUTE(.);
mapping[dram0_data]
_data_end_high = ABSOLUTE(.);
} > sram_high
/**
* This section holds data that should not be initialized at power up.
* The section located in Internal SRAM memory region. The macro _NOINIT

Wyświetl plik

@ -9,7 +9,7 @@ entries:
reset_reason:esp_reset_reason_get_hint (noflash)
if ESP_SYSTEM_HW_STACK_GUARD = y:
hw_stack_guard:esp_hw_stack_guard_get_bounds (noflash)
hw_stack_guard:esp_hw_stack_guard_is_fired (noflash)
hw_stack_guard:esp_hw_stack_guard_get_fired_cpu (noflash)
hw_stack_guard:esp_hw_stack_guard_get_pc (noflash)
esp_err (noflash)

Wyświetl plik

@ -55,20 +55,21 @@ static inline void print_cache_err_details(const void *frame)
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
static inline void print_assist_debug_details(const void *frame)
{
uint32_t core_id = esp_cpu_get_core_id();
uint32_t core_id = esp_hw_stack_guard_get_fired_cpu();
if (core_id == ESP_HW_STACK_GUARD_NOT_FIRED) {
panic_print_str("ASSIST_DEBUG is not triggered BUT interrupt occured!\r\n\r\n");
core_id = 0;
}
uint32_t sp_min, sp_max;
const char *task_name = pcTaskGetName(xTaskGetCurrentTaskHandleForCore(core_id));
esp_hw_stack_guard_get_bounds(&sp_min, &sp_max);
esp_hw_stack_guard_get_bounds(core_id, &sp_min, &sp_max);
panic_print_str("\r\n");
if (!esp_hw_stack_guard_is_fired()) {
panic_print_str("ASSIST_DEBUG is not triggered BUT interrupt occured!\r\n\r\n");
}
panic_print_str("Detected in task \"");
panic_print_str(task_name);
panic_print_str("\" at 0x");
panic_print_hex((int) esp_hw_stack_guard_get_pc());
panic_print_hex((int) esp_hw_stack_guard_get_pc(core_id));
panic_print_str("\r\n");
panic_print_str("Stack pointer: 0x");
panic_print_hex((int)((RvExcFrame *)frame)->sp);
@ -245,7 +246,10 @@ void panic_soc_fill_info(void *f, panic_info_t *info)
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
else if (frame->mcause == ETS_ASSIST_DEBUG_INUM) {
info->core = esp_cache_err_get_cpuid();
info->core = esp_hw_stack_guard_get_fired_cpu();
if (info->core == ESP_HW_STACK_GUARD_NOT_FIRED) {
info->core = 0;
}
info->reason = "Stack protection fault";
info->details = print_assist_debug_details;
}

Wyświetl plik

@ -14,15 +14,17 @@
extern "C" {
#endif
#define ESP_HW_STACK_GUARD_NOT_FIRED UINT32_MAX
/* The functions below are designed to be used in interrupt/panic handler
* In case using them in user's code put them into critical section.*/
void esp_hw_stack_guard_monitor_start(void);
void esp_hw_stack_guard_monitor_stop(void);
void esp_hw_stack_guard_set_bounds(uint32_t sp_min, uint32_t sp_max);
void esp_hw_stack_guard_get_bounds(uint32_t *sp_min, uint32_t *sp_max);
bool esp_hw_stack_guard_is_fired(void);
uint32_t esp_hw_stack_guard_get_pc(void);
void esp_hw_stack_guard_get_bounds(uint32_t core_id, uint32_t *sp_min, uint32_t *sp_max);
uint32_t esp_hw_stack_guard_get_fired_cpu(void);
uint32_t esp_hw_stack_guard_get_pc(uint32_t core_id);
#ifdef __cplusplus
};
@ -33,8 +35,9 @@ uint32_t esp_hw_stack_guard_get_pc(void);
#include "hal/assist_debug_ll.h"
#define ASSIST_DEBUG_CORE_0_INTR_ENA_REG_IMM (ASSIST_DEBUG_CORE_0_INTR_ENA_REG >> 12)
#define ASSIST_DEBUG_CORE_0_SP_MIN_OFFSET (ASSIST_DEBUG_CORE_0_SP_MIN_REG - ASSIST_DEBUG_CORE_0_INTR_ENA_REG)
#define ASSIST_DEBUG_CORE_0_SP_MAX_OFFSET (ASSIST_DEBUG_CORE_0_SP_MAX_REG - ASSIST_DEBUG_CORE_0_INTR_ENA_REG)
#define ASSIST_DEBUG_CORE_0_SP_MIN_OFFSET (ASSIST_DEBUG_CORE_0_SP_MIN_REG - DR_REG_ASSIST_DEBUG_BASE)
#define ASSIST_DEBUG_CORE_0_SP_MAX_OFFSET (ASSIST_DEBUG_CORE_0_SP_MAX_REG - DR_REG_ASSIST_DEBUG_BASE)
#define ASSIST_DEBUG_CORE_0_SP_SPILL_OFFSET (ASSIST_DEBUG_CORE_0_INTR_ENA_REG - DR_REG_ASSIST_DEBUG_BASE)
.macro ESP_HW_STACK_GUARD_SET_BOUNDS_CPU0 reg1
lui \reg1, ASSIST_DEBUG_CORE_0_INTR_ENA_REG_IMM
@ -44,23 +47,24 @@ sw a1, ASSIST_DEBUG_CORE_0_SP_MAX_OFFSET(\reg1)
.macro ESP_HW_STACK_GUARD_MONITOR_STOP_CPU0 reg1 reg2
lui \reg1, ASSIST_DEBUG_CORE_0_INTR_ENA_REG_IMM
lw \reg2, 0(\reg1)
lw \reg2, ASSIST_DEBUG_CORE_0_SP_SPILL_OFFSET(\reg1)
andi \reg2, \reg2, ~ASSIST_DEBUG_SP_SPILL_BITS
sw \reg2, 0(\reg1)
sw \reg2, ASSIST_DEBUG_CORE_0_SP_SPILL_OFFSET(\reg1)
.endm
.macro ESP_HW_STACK_GUARD_MONITOR_START_CPU0 reg1 reg2
lui \reg1, ASSIST_DEBUG_CORE_0_INTR_ENA_REG_IMM
lw \reg2, 0(\reg1)
lw \reg2, ASSIST_DEBUG_CORE_0_SP_SPILL_OFFSET(\reg1)
ori \reg2, \reg2, ASSIST_DEBUG_SP_SPILL_BITS
sw \reg2, 0(\reg1)
sw \reg2, ASSIST_DEBUG_CORE_0_SP_SPILL_OFFSET(\reg1)
.endm
#if SOC_CPU_CORES_NUM > 1
#define ASSIST_DEBUG_CORE_1_INTR_ENA_REG_IMM (ASSIST_DEBUG_CORE_1_INTR_ENA_REG >> 12)
#define ASSIST_DEBUG_CORE_1_SP_MIN_OFFSET (ASSIST_DEBUG_CORE_1_SP_MIN_REG - ASSIST_DEBUG_CORE_1_INTR_ENA_REG)
#define ASSIST_DEBUG_CORE_1_SP_MAX_OFFSET (ASSIST_DEBUG_CORE_1_SP_MAX_REG - ASSIST_DEBUG_CORE_1_INTR_ENA_REG)
#define ASSIST_DEBUG_CORE_1_SP_MIN_OFFSET (ASSIST_DEBUG_CORE_1_SP_MIN_REG - DR_REG_ASSIST_DEBUG_BASE)
#define ASSIST_DEBUG_CORE_1_SP_MAX_OFFSET (ASSIST_DEBUG_CORE_1_SP_MAX_REG - DR_REG_ASSIST_DEBUG_BASE)
#define ASSIST_DEBUG_CORE_1_SP_SPILL_OFFSET (ASSIST_DEBUG_CORE_1_INTR_ENA_REG - DR_REG_ASSIST_DEBUG_BASE)
.macro ESP_HW_STACK_GUARD_SET_BOUNDS_CPU1 reg1
lui \reg1, ASSIST_DEBUG_CORE_1_INTR_ENA_REG_IMM
@ -70,22 +74,22 @@ sw a1, ASSIST_DEBUG_CORE_1_SP_MAX_OFFSET(\reg1)
.macro ESP_HW_STACK_GUARD_MONITOR_STOP_CPU1 reg1 reg2
lui \reg1, ASSIST_DEBUG_CORE_1_INTR_ENA_REG_IMM
lw \reg2, 0(\reg1)
lw \reg2, ASSIST_DEBUG_CORE_1_SP_SPILL_OFFSET(\reg1)
andi \reg2, \reg2, ~ASSIST_DEBUG_SP_SPILL_BITS
sw \reg2, 0(\reg1)
sw \reg2, ASSIST_DEBUG_CORE_1_SP_SPILL_OFFSET(\reg1)
.endm
.macro ESP_HW_STACK_GUARD_MONITOR_START_CPU1 reg1 reg2
lui \reg1, ASSIST_DEBUG_CORE_1_INTR_ENA_REG_IMM
lw \reg2, 0(\reg1)
lw \reg2, ASSIST_DEBUG_CORE_1_SP_SPILL_OFFSET(\reg1)
ori \reg2, \reg2, ASSIST_DEBUG_SP_SPILL_BITS
sw \reg2, 0(\reg1)
sw \reg2, ASSIST_DEBUG_CORE_1_SP_SPILL_OFFSET(\reg1)
.endm
.macro ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE reg1
/* Check the current core ID */
csrr \reg1, mhartid
beqz \reg1, @1f
beqz \reg1, 1f
/* Core 1 */
ESP_HW_STACK_GUARD_SET_BOUNDS_CPU1 \reg1
j 2f
@ -98,7 +102,7 @@ ESP_HW_STACK_GUARD_SET_BOUNDS_CPU0 \reg1
.macro ESP_HW_STACK_GUARD_MONITOR_START_CUR_CORE reg1 reg2
/* Check the current core ID */
csrr \reg1, mhartid
beqz \reg1, @1f
beqz \reg1, 1f
/* Core 1 */
ESP_HW_STACK_GUARD_MONITOR_START_CPU1 \reg1 \reg2
j 2f
@ -111,7 +115,7 @@ ESP_HW_STACK_GUARD_MONITOR_START_CPU0 \reg1 \reg2
.macro ESP_HW_STACK_GUARD_MONITOR_STOP_CUR_CORE reg1 reg2
/* Check the current core ID */
csrr \reg1, mhartid
beqz \reg1, @1f
beqz \reg1, 1f
/* Core 1 */
ESP_HW_STACK_GUARD_MONITOR_STOP_CPU1 \reg1 \reg2
j 2f

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -37,6 +37,10 @@
#include "hal/wdt_types.h"
#include "hal/wdt_hal.h"
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
#include "esp_private/hw_stack_guard.h"
#endif
extern int _invalid_pc_placeholder;
extern void esp_panic_handler_reconfigure_wdts(uint32_t timeout_ms);
@ -117,6 +121,14 @@ static void frame_to_panic_info(void *frame, panic_info_t *info, bool pseudo_exc
info->frame = frame;
}
#if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
FORCE_INLINE_ATTR __attribute__((__noreturn__))
void busy_wait(void)
{
while (1) {;} // infinite loop
}
#endif // !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
static void panic_handler(void *frame, bool pseudo_excause)
{
panic_info_t info = { 0 };
@ -134,19 +146,24 @@ static void panic_handler(void *frame, bool pseudo_excause)
// These are cases where both CPUs both go into panic handler. The following code ensures
// only one core proceeds to the system panic handler.
if (pseudo_excause) {
#define BUSY_WAIT_IF_TRUE(b) { if (b) while(1); }
// For WDT expiry, pause the non-offending core - offending core handles panic
BUSY_WAIT_IF_TRUE(panic_get_cause(frame) == PANIC_RSN_INTWDT_CPU0 && core_id == 1);
BUSY_WAIT_IF_TRUE(panic_get_cause(frame) == PANIC_RSN_INTWDT_CPU1 && core_id == 0);
// For cache error, pause the non-offending core - offending core handles panic
if (panic_get_cause(frame) == PANIC_RSN_CACHEERR && core_id != esp_cache_err_get_cpuid()) {
// Only print the backtrace for the offending core in case of the cache error
g_exc_frames[core_id] = NULL;
while (1) {
;
}
// For WDT expiry, pause the non-offending core - offending core handles panic
if (panic_get_cause(frame) == PANIC_RSN_INTWDT_CPU0 && core_id == 1) {
busy_wait();
} else if (panic_get_cause(frame) == PANIC_RSN_INTWDT_CPU1 && core_id == 0) {
busy_wait();
} else if (panic_get_cause(frame) == PANIC_RSN_CACHEERR && core_id != esp_cache_err_get_cpuid()) {
g_exc_frames[core_id] = NULL; // Only print the backtrace for the offending core
busy_wait();
}
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
else if (panic_get_cause(frame) == ETS_ASSIST_DEBUG_INUM &&
esp_hw_stack_guard_get_fired_cpu() != core_id &&
esp_hw_stack_guard_get_fired_cpu() != ESP_HW_STACK_GUARD_NOT_FIRED) {
g_exc_frames[core_id] = NULL; // Only print the backtrace for the offending core
busy_wait();
}
#endif // CONFIG_ESP_SYSTEM_HW_STACK_GUARD
}
// Need to reconfigure WDTs before we stall any other CPU

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -17,6 +17,7 @@
#include <stdint.h>
#include "esp_attr.h"
#include "hal/assert.h"
#include "soc/system_struct.h"
#ifdef __cplusplus
extern "C" {
@ -54,7 +55,7 @@ extern "C" {
* interrupt, instead of "ENA".
*/
/* These functions are optimazed and designed for internal usage.
/* These functions are optimized and designed for internal usage.
* So, the API may differ from general ll layer pattern */
FORCE_INLINE_ATTR void assist_debug_ll_sp_spill_monitor_enable(__attribute__((unused)) uint32_t core_id)
@ -112,6 +113,17 @@ FORCE_INLINE_ATTR uint32_t assist_debug_ll_sp_spill_get_pc(__attribute__((unused
return REG_READ(ASSIST_DEBUG_CORE_0_SP_PC_REG);
}
FORCE_INLINE_ATTR void assist_debug_ll_enable_bus_clock(bool enable)
{
SYSTEM.cpu_peri_clk_en.clk_en_assist_debug = enable;
}
FORCE_INLINE_ATTR void assist_debug_ll_reset_register(void)
{
SYSTEM.cpu_peri_rst_en.rst_en_assist_debug = true;
SYSTEM.cpu_peri_rst_en.rst_en_assist_debug = false;
}
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -17,6 +17,7 @@
#include <stdint.h>
#include "esp_attr.h"
#include "hal/assert.h"
#include "soc/system_struct.h"
#ifdef __cplusplus
extern "C" {
@ -54,7 +55,7 @@ extern "C" {
* interrupt, instead of "ENA".
*/
/* These functions are optimazed and designed for internal usage.
/* These functions are optimized and designed for internal usage.
* So, the API may differ from general ll layer pattern */
FORCE_INLINE_ATTR void assist_debug_ll_sp_spill_monitor_enable(__attribute__((unused)) uint32_t core_id)
@ -112,6 +113,17 @@ FORCE_INLINE_ATTR uint32_t assist_debug_ll_sp_spill_get_pc(__attribute__((unused
return REG_READ(ASSIST_DEBUG_CORE_0_SP_PC_REG);
}
FORCE_INLINE_ATTR void assist_debug_ll_enable_bus_clock(bool enable)
{
SYSTEM.cpu_peri_clk_en.reg_clk_en_assist_debug = enable;
}
FORCE_INLINE_ATTR void assist_debug_ll_reset_register(void)
{
SYSTEM.cpu_peri_rst_en.reg_rst_en_assist_debug = true;
SYSTEM.cpu_peri_rst_en.reg_rst_en_assist_debug = false;
}
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -17,6 +17,7 @@
#include <stdint.h>
#include "esp_attr.h"
#include "hal/assert.h"
#include "soc/pcr_struct.h"
#ifdef __cplusplus
extern "C" {
@ -54,7 +55,7 @@ extern "C" {
* interrupt, instead of "ENA".
*/
/* These functions are optimazed and designed for internal usage.
/* These functions are optimized and designed for internal usage.
* So, the API may differ from general ll layer pattern */
FORCE_INLINE_ATTR void assist_debug_ll_sp_spill_monitor_enable(__attribute__((unused)) uint32_t core_id)
@ -112,6 +113,17 @@ FORCE_INLINE_ATTR uint32_t assist_debug_ll_sp_spill_get_pc(__attribute__((unused
return REG_READ(ASSIST_DEBUG_CORE_0_SP_PC_REG);
}
FORCE_INLINE_ATTR void assist_debug_ll_enable_bus_clock(bool enable)
{
PCR.assist_conf.assist_clk_en = enable;
}
FORCE_INLINE_ATTR void assist_debug_ll_reset_register(void)
{
PCR.assist_conf.assist_rst_en = true;
PCR.assist_conf.assist_rst_en = false;
}
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -17,6 +17,7 @@
#include <stdint.h>
#include "esp_attr.h"
#include "hal/assert.h"
#include "soc/pcr_struct.h"
#ifdef __cplusplus
extern "C" {
@ -54,7 +55,7 @@ extern "C" {
* interrupt, instead of "ENA".
*/
/* These functions are optimazed and designed for internal usage.
/* These functions are optimized and designed for internal usage.
* So, the API may differ from general ll layer pattern */
FORCE_INLINE_ATTR void assist_debug_ll_sp_spill_monitor_enable(__attribute__((unused)) uint32_t core_id)
@ -112,6 +113,17 @@ FORCE_INLINE_ATTR uint32_t assist_debug_ll_sp_spill_get_pc(__attribute__((unused
return REG_READ(ASSIST_DEBUG_CORE_0_SP_PC_REG);
}
FORCE_INLINE_ATTR void assist_debug_ll_enable_bus_clock(bool enable)
{
PCR.assist_conf.assist_clk_en = enable;
}
FORCE_INLINE_ATTR void assist_debug_ll_reset_register(void)
{
PCR.assist_conf.assist_rst_en = true;
PCR.assist_conf.assist_rst_en = false;
}
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -0,0 +1,143 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
// The LL layer for DEBUG_ASSIST peripheral
#pragma once
#include "soc/assist_debug_reg.h"
#define ASSIST_DEBUG_SP_SPILL_BITS (ASSIST_DEBUG_CORE_0_SP_SPILL_MIN_ENA | ASSIST_DEBUG_CORE_0_SP_SPILL_MAX_ENA)
#ifndef __ASSEMBLER__
#include <stdbool.h>
#include <stdint.h>
#include "esp_attr.h"
#include "hal/assert.h"
#include "soc/hp_sys_clkrst_struct.h"
#include "sdkconfig.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Most other peripherals have 4 interrupt-related registers: INT_ENA_REG, INT_CLR_REG, INT_RAW_REG, INT_ST_REG, the
* meaning of which is well-understood.
*
* Assist_debug peripheral uses a different structure of interrupt registers:
* INT_ENA_REG, INT_RLS_REG, INT_CLR_REG, INT_RAW_REG.
*
* Their behavior can be explained using the following (verilog-like) pseudo-code:
* reg sp_spill_max_st
* assign sp_spill_max = (sp > SP_MAX_REG)
* assign SP_SPILL_MAX_RAW = sp_spill_max & SPILL_MAX_ENA
* always (@posedge clk) begin
* if (reset) then sp_spill_max_st <= 0
* elif SP_SPILL_MAX_CLR then sp_spill_max_st <= 0
* else sp_spill_max_st <= SP_SPILL_MAX_RAW & SP_SPILL_MAX_RLS
* end
* // ...same for sp_spill_min and other things dsoc/hp_sys_clkrst_struct.hebug_assist can check.
*
* // this is the final interrupt line coming out of the peripheral:
* assign DEBUG_ASSIST_INT = sp_spill_max_st | sp_spill_min_st | ...
*
* Basically, there is no "ST" register showing the final (latched) interrupt state, and there is an additional
* "RLS" register which just like "ENA" can be used to mask the interrupt.
* Note that writing to CLR clears the (internal) latched interrupt state 'sp_spill_max_st',
* but doesn't affect the software-readable RAW register.
*
* In this code, we use "ENA" to enable monitoring of a particular condition, and "RLS" to enable the interrupt.
* This allows checking whether the condition (e.g. sp > SP_MAX) has occurred by reading the RAW register, without
* actually triggering the interrupt. Hence you will see the somewhat counter-intuitive use of "RLS" to enable the
* interrupt, instead of "ENA".
*/
/* These functions are optimized and designed for internal usage.
* So, the API may differ from general ll layer pattern */
FORCE_INLINE_ATTR void assist_debug_ll_sp_spill_monitor_enable(uint32_t core_id)
{
REG_SET_BIT(core_id ? ASSIST_DEBUG_CORE_1_INTR_ENA_REG : ASSIST_DEBUG_CORE_0_INTR_ENA_REG, ASSIST_DEBUG_SP_SPILL_BITS);
}
FORCE_INLINE_ATTR void assist_debug_ll_sp_spill_monitor_disable(uint32_t core_id)
{
REG_CLR_BIT(core_id ? ASSIST_DEBUG_CORE_1_INTR_ENA_REG : ASSIST_DEBUG_CORE_0_INTR_ENA_REG, ASSIST_DEBUG_SP_SPILL_BITS);
}
FORCE_INLINE_ATTR void assist_debug_ll_sp_spill_interrupt_enable(uint32_t core_id)
{
REG_SET_BIT(core_id ? ASSIST_DEBUG_CORE_1_INTR_RLS_REG : ASSIST_DEBUG_CORE_0_INTR_RLS_REG, ASSIST_DEBUG_SP_SPILL_BITS);
}
FORCE_INLINE_ATTR void assist_debug_ll_sp_spill_interrupt_disable(uint32_t core_id)
{
REG_CLR_BIT(core_id ? ASSIST_DEBUG_CORE_1_INTR_RLS_REG : ASSIST_DEBUG_CORE_0_INTR_RLS_REG, ASSIST_DEBUG_SP_SPILL_BITS);
}
FORCE_INLINE_ATTR bool assist_debug_ll_sp_spill_is_fired(uint32_t core_id)
{
return REG_READ(core_id ? ASSIST_DEBUG_CORE_1_INTR_RAW_REG : ASSIST_DEBUG_CORE_0_INTR_RAW_REG) & ASSIST_DEBUG_SP_SPILL_BITS;
}
FORCE_INLINE_ATTR void assist_debug_ll_sp_spill_interrupt_clear(uint32_t core_id)
{
REG_WRITE(core_id ? ASSIST_DEBUG_CORE_1_INTR_CLR_REG : ASSIST_DEBUG_CORE_0_INTR_CLR_REG, ASSIST_DEBUG_SP_SPILL_BITS);
}
FORCE_INLINE_ATTR void assist_debug_ll_sp_spill_set_min(uint32_t core_id, uint32_t min)
{
REG_WRITE(core_id ? ASSIST_DEBUG_CORE_1_SP_MIN_REG : ASSIST_DEBUG_CORE_0_SP_MIN_REG, min);
}
FORCE_INLINE_ATTR uint32_t assist_debug_ll_sp_spill_get_min(uint32_t core_id)
{
return REG_READ(core_id ? ASSIST_DEBUG_CORE_1_SP_MIN_REG : ASSIST_DEBUG_CORE_0_SP_MIN_REG);
}
FORCE_INLINE_ATTR void assist_debug_ll_sp_spill_set_max(uint32_t core_id, uint32_t max)
{
REG_WRITE(core_id ? ASSIST_DEBUG_CORE_1_SP_MAX_REG : ASSIST_DEBUG_CORE_0_SP_MAX_REG, max);
}
FORCE_INLINE_ATTR uint32_t assist_debug_ll_sp_spill_get_max(uint32_t core_id)
{
return REG_READ(core_id ? ASSIST_DEBUG_CORE_1_SP_MAX_REG : ASSIST_DEBUG_CORE_0_SP_MAX_REG);
}
FORCE_INLINE_ATTR uint32_t assist_debug_ll_sp_spill_get_pc(uint32_t core_id)
{
return REG_READ(core_id ? ASSIST_DEBUG_CORE_1_SP_PC_REG : ASSIST_DEBUG_CORE_0_SP_PC_REG);
}
FORCE_INLINE_ATTR void assist_debug_ll_enable_bus_clock(bool enable)
{
HP_SYS_CLKRST.soc_clk_ctrl0.reg_busmon_cpu_clk_en = enable;
}
#define assist_debug_ll_enable_bus_clock(...) \
(void)__DECLARE_RCC_ATOMIC_ENV; assist_debug_ll_enable_bus_clock(__VA_ARGS__)
FORCE_INLINE_ATTR void assist_debug_ll_reset_register(void)
{
/* esp32p4 has no assist_debug reset register: disable & clear interrupts manually. */
for (int i = 0; i < CONFIG_SOC_CPU_CORES_NUM; i++) {
assist_debug_ll_sp_spill_monitor_disable(i);
assist_debug_ll_sp_spill_interrupt_clear(i);
assist_debug_ll_sp_spill_set_min(i, 0);
assist_debug_ll_sp_spill_set_max(i, 0xffffffff);
/* Enable PC register storing when trigger stack monitor. */
REG_WRITE(i ? ASSIST_DEBUG_CORE_1_RCD_EN_REG : ASSIST_DEBUG_CORE_0_RCD_EN_REG, ASSIST_DEBUG_CORE_1_RCD_PDEBUGEN | ASSIST_DEBUG_CORE_1_RCD_RECORDEN);
}
}
#define assist_debug_ll_reset_register(...) \
(void)__DECLARE_RCC_ATOMIC_ENV; assist_debug_ll_reset_register(__VA_ARGS__)
#ifdef __cplusplus
}
#endif
#endif // __ASSEMBLER__

Wyświetl plik

@ -89,7 +89,7 @@ const soc_memory_region_t soc_memory_regions[] = {
const size_t soc_memory_region_count = sizeof(soc_memory_regions) / sizeof(soc_memory_region_t);
extern int _data_start, _bss_start_high, _heap_start_low, _heap_start_high, _iram_start, _iram_end, _rtc_force_slow_end;
extern int _data_start_low, _data_start_high, _heap_start_low, _heap_start_high, _iram_start, _iram_end, _rtc_force_slow_end;
extern int _tcm_text_start, _tcm_data_end;
extern int _rtc_reserved_start, _rtc_reserved_end;
@ -100,8 +100,8 @@ extern int _rtc_reserved_start, _rtc_reserved_end;
*/
// Static data region. DRAM used by data+bss and possibly rodata
SOC_RESERVE_MEMORY_REGION((intptr_t)&_data_start, (intptr_t)&_heap_start_low, dram_data_low);
SOC_RESERVE_MEMORY_REGION((intptr_t)&_bss_start_high, (intptr_t)&_heap_start_high, dram_data_high);
SOC_RESERVE_MEMORY_REGION((intptr_t)&_data_start_low, (intptr_t)&_heap_start_low, dram_data_low);
SOC_RESERVE_MEMORY_REGION((intptr_t)&_data_start_high, (intptr_t)&_heap_start_high, dram_data_high);
// Target has a shared D/IRAM virtual address, no need to calculate I_D_OFFSET like previous chips
SOC_RESERVE_MEMORY_REGION((intptr_t)&_iram_start, (intptr_t)&_iram_end, iram_code);

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -14,6 +14,12 @@
#define MEMPROT_ISR _interrupt_handler
#endif // CONFIG_ESP_SYSTEM_MEMPROT_FEATURE
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
#define ASTDBG_ISR _panic_handler
#else
#define ASTDBG_ISR _interrupt_handler
#endif // CONFIG_ESP_SYSTEM_HW_STACK_GUARD
#if CONFIG_ESP_IPC_ISR_ENABLE
#define IPC_ISR_HANDLER esp_ipc_isr_handler
#else
@ -109,7 +115,7 @@ _mtvt_table:
.word _panic_handler /* 40: ETS_INT_WDT_INUM (+16) panic-interrupt (soc-level panic) */
.word _panic_handler /* 41: ETS_CACHEERR_INUM (+16) panic-interrupt (soc-level panic) */
.word MEMPROT_ISR /* 42: ETS_MEMPROT_ERR_INUM (+16) handler (soc-level panic) */
.word _interrupt_handler /* 43: Free interrupt number */
.word ASTDBG_ISR /* 43: ETS_ASSIST_DEBUG_INUM (+16) handler (soc-level panic) */
.word IPC_ISR_HANDLER /* 44: ETS_IPC_ISR_INUM (+16) handler*/
.word _interrupt_handler /* 45: Free interrupt number */
.word _interrupt_handler /* 46: Free interrupt number */

Wyświetl plik

@ -211,6 +211,10 @@ config SOC_CLK_TREE_SUPPORTED
bool
default y
config SOC_ASSIST_DEBUG_SUPPORTED
bool
default y
config SOC_WDT_SUPPORTED
bool
default y

Wyświetl plik

@ -5,7 +5,6 @@
*/
#pragma once
#include <stdint.h>
#include "soc/soc.h"
#ifdef __cplusplus
extern "C" {

Wyświetl plik

@ -68,6 +68,7 @@ typedef enum {
PERIPH_AXI_PDMA_MODULE,
PERIPH_UHCI_MODULE,
PERIPH_PCNT_MODULE,
PERIPH_ASSIST_DEBUG_MODULE,
/* LP peripherals */
PERIPH_LP_I2C0_MODULE,
PERIPH_LP_UART0_MODULE,

Wyświetl plik

@ -231,6 +231,7 @@
#define ETS_T1_WDT_INUM 24
#define ETS_CACHEERR_INUM 25
#define ETS_MEMPROT_ERR_INUM 26
#define ETS_ASSIST_DEBUG_INUM 27 // Note: this interrupt can be combined with others (e.g., CACHEERR), as we can identify its trigger is activated
#define ETS_IPC_ISR_INUM 28
//CPU0 Max valid interrupt number
#define ETS_MAX_INUM 31

Wyświetl plik

@ -80,7 +80,7 @@
// #define SOC_ULP_SUPPORTED 1 //TODO: IDF-7534
#define SOC_SDMMC_HOST_SUPPORTED 1
#define SOC_CLK_TREE_SUPPORTED 1
// #define SOC_ASSIST_DEBUG_SUPPORTED 1 //TODO: IDF-7565
#define SOC_ASSIST_DEBUG_SUPPORTED 1
#define SOC_WDT_SUPPORTED 1
#define SOC_SPI_FLASH_SUPPORTED 1
// #define SOC_TOUCH_SENSOR_SUPPORTED 1 //TODO: IDF-7477

Wyświetl plik

@ -208,10 +208,8 @@ tools/test_apps/system/no_embedded_paths:
reason: the other targets are not tested yet
tools/test_apps/system/panic:
disable:
- if: IDF_TARGET in ["esp32p4"]
temporary: true
reason: target(s) not supported yet # TODO: IDF-7511
enable:
- if: INCLUDE_DEFAULT == 1 or IDF_TARGET in ["esp32p4"] # preview targets
tools/test_apps/system/ram_loadable_app:
disable_test:

Wyświetl plik

@ -0,0 +1 @@
CONFIG_ESP_SYSTEM_HW_STACK_GUARD=n

Wyświetl plik

@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
# Introduction

Wyświetl plik

@ -24,7 +24,12 @@ void test_int_wdt(void);
void test_task_wdt_cpu0(void);
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
void test_hw_stack_guard_cpu0(void);
#if !CONFIG_FREERTOS_UNICORE
void test_hw_stack_guard_cpu1(void);
#endif // CONFIG_FREERTOS_UNICORE
#endif // CONFIG_ESP_SYSTEM_HW_STACK_GUARD
#if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH && CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY
void test_panic_extram_stack(void);

Wyświetl plik

@ -31,9 +31,7 @@
static const char* get_test_name(void)
{
static char test_name_str[BOOT_CMD_MAX_LEN] = {0};
printf("Enter test name: ");
fflush(stdout);
bool print_prompt = true;
/* Not using blocking fgets(stdin) here, as QEMU doesn't yet implement RX timeout interrupt,
* which is required for the UART driver and blocking stdio to work.
@ -42,16 +40,24 @@ static const char* get_test_name(void)
char *p = test_name_str;
const char *end = test_name_str + sizeof(test_name_str) - 1;
while (p < end) {
if (print_prompt) {
printf("Enter test name: ");
fflush(stdout);
print_prompt = false;
}
c = getchar();
if (c == EOF) {
vTaskDelay(pdMS_TO_TICKS(10));
} else if ((c == '\r' || c == '\n') && p != test_name_str) {
} else if (c == '\r' || c == '\n') {
/* terminate the line */
puts("\n\r");
fflush(stdout);
*p = '\0';
break;
} else {
print_prompt = true;
if (p != test_name_str) {
*p = '\0';
break;
}
} else if (c >= '0' && c <= 'z') {
/* echo the received character */
putchar(c);
fflush(stdout);
@ -83,7 +89,12 @@ void app_main(void)
HANDLE_TEST(test_name, test_abort_cache_disabled);
HANDLE_TEST(test_name, test_int_wdt);
HANDLE_TEST(test_name, test_task_wdt_cpu0);
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
HANDLE_TEST(test_name, test_hw_stack_guard_cpu0);
#if !CONFIG_FREERTOS_UNICORE
HANDLE_TEST(test_name, test_hw_stack_guard_cpu1);
#endif // CONFIG_FREERTOS_UNICORE
#endif // CONFIG_ESP_SYSTEM_HW_STACK_GUARD
#if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH && CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY
HANDLE_TEST(test_name, test_panic_extram_stack);
#endif

Wyświetl plik

@ -63,6 +63,8 @@ void test_task_wdt_cpu0(void)
}
}
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
__attribute__((optimize("-O0")))
static void test_hw_stack_guard_cpu(void* arg)
{
@ -78,6 +80,18 @@ void test_hw_stack_guard_cpu0(void)
}
}
#if !CONFIG_FREERTOS_UNICORE
void test_hw_stack_guard_cpu1(void)
{
xTaskCreatePinnedToCore(test_hw_stack_guard_cpu, "HWSG1", 512, NULL, 1, NULL, 1);
while (true) {
vTaskDelay(100);
}
}
#endif // CONFIG_FREERTOS_UNICORE
#endif // CONFIG_ESP_SYSTEM_HW_STACK_GUARD
#if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH && CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY
static void stack_in_extram(void* arg) {

Wyświetl plik

@ -17,7 +17,8 @@ TARGETS_TESTED = [
pytest.mark.esp32s3,
pytest.mark.esp32c2,
pytest.mark.esp32c6,
pytest.mark.esp32h2
pytest.mark.esp32h2,
pytest.mark.esp32p4,
]
# Most tests run on all targets and with all configs.
@ -34,7 +35,11 @@ CONFIGS = [
]
# Some tests only run on dual-core targets, they use the config below.
TARGETS_DUAL_CORE = [pytest.mark.esp32, pytest.mark.esp32s3]
TARGETS_DUAL_CORE = [
pytest.mark.esp32,
pytest.mark.esp32s3,
pytest.mark.esp32p4,
]
CONFIGS_DUAL_CORE = [
pytest.param('coredump_flash_bin_crc', marks=TARGETS_DUAL_CORE),
pytest.param('coredump_flash_elf_sha', marks=TARGETS_DUAL_CORE),
@ -58,6 +63,7 @@ TARGETS_HW_STACK_GUARD = [
pytest.mark.esp32c3,
pytest.mark.esp32c6,
pytest.mark.esp32h2,
pytest.mark.esp32p4,
]
CONFIGS_HW_STACK_GUARD = [
@ -68,6 +74,14 @@ CONFIGS_HW_STACK_GUARD = [
pytest.param('panic', marks=TARGETS_HW_STACK_GUARD),
]
CONFIGS_HW_STACK_GUARD_DUAL_CORE = [
pytest.param('coredump_flash_bin_crc', marks=[pytest.mark.esp32p4]),
pytest.param('coredump_uart_bin_crc', marks=[pytest.mark.esp32p4]),
pytest.param('coredump_uart_elf_crc', marks=[pytest.mark.esp32p4]),
pytest.param('gdbstub', marks=[pytest.mark.esp32p4]),
pytest.param('panic', marks=[pytest.mark.esp32p4]),
]
# Panic abort information will start with this string.
PANIC_ABORT_PREFIX = 'Panic reason: '
@ -148,15 +162,16 @@ def test_task_wdt_cpu1(dut: PanicTestDut, config: str, test_func_name: str) -> N
'Task watchdog got triggered. The following tasks/users did not reset the watchdog in time:'
)
dut.expect_exact('CPU 1: Infinite loop')
expected_backtrace = ['infinite_loop', 'vPortTaskWrapper']
if dut.is_xtensa:
# see comment in test_task_wdt_cpu0
dut.expect_none('register dump:')
dut.expect_exact('Print CPU 1 backtrace')
dut.expect_backtrace()
# On Xtensa, we get incorrect backtrace from GDB in this test
expected_backtrace = ['infinite_loop', 'vPortTaskWrapper']
else:
assert False, 'No dual-core RISC-V chips yet, check this test case later'
# on RISC-V, need to dump both registers and stack memory to reconstruct the backtrace
dut.expect_reg_dump(core=1)
dut.expect_stack_dump()
dut.expect_elf_sha256()
dut.expect_none('Guru Meditation')
@ -204,9 +219,9 @@ def test_int_wdt(
dut.expect_stack_dump()
if target in TARGETS_DUAL_CORE_NAMES:
assert dut.is_xtensa, 'No dual-core RISC-V chips yet, check the test case'
dut.expect_reg_dump(1)
dut.expect_backtrace()
if dut.is_xtensa:
dut.expect_backtrace()
dut.expect_elf_sha256()
dut.expect_none('Guru Meditation')
@ -228,9 +243,9 @@ def test_int_wdt_cache_disabled(
dut.expect_stack_dump()
if target in TARGETS_DUAL_CORE_NAMES:
assert dut.is_xtensa, 'No dual-core RISC-V chips yet, check the test case'
dut.expect_reg_dump(1)
dut.expect_backtrace()
if dut.is_xtensa:
dut.expect_backtrace()
dut.expect_elf_sha256()
dut.expect_none('Guru Meditation')
@ -251,6 +266,8 @@ def test_cache_error(dut: PanicTestDut, config: str, test_func_name: str) -> Non
elif dut.target in ['esp32s2']:
# Cache error interrupt is not enabled, IDF-1558
dut.expect_gme('IllegalInstruction')
elif dut.target in ['esp32p4']: # TODO IDF-7515
dut.expect_gme('Instruction access fault')
else:
dut.expect_gme('Cache disabled but cached memory region accessed')
dut.expect_reg_dump(0)
@ -832,15 +849,36 @@ def test_gdbstub_coredump(dut: PanicTestDut) -> None:
return # don't expect "Rebooting" output below
def test_hw_stack_guard_cpu(dut: PanicTestDut, cpu: int) -> None:
dut.expect_exact(f'Guru Meditation Error: Core {cpu} panic\'ed (Stack protection fault).')
dut.expect_none('ASSIST_DEBUG is not triggered BUT interrupt occured!')
dut.expect_exact(f'Detected in task "HWSG{cpu}"')
addr = dut.expect('at 0x([0-9a-fA-F]{8})')
assert addr.group(1) != b'00000000'
addr = dut.expect('Stack pointer: 0x([0-9a-fA-F]{8})')
assert addr.group(1) != b'00000000'
addr = dut.expect(r'Stack bounds: 0x([0-9a-fA-F]{8})')
assert addr.group(1) != b'00000000'
start_addr = int(addr.group(1), 16)
addr = dut.expect(r' - 0x([0-9a-fA-F]{8})')
assert addr.group(1) != b'00000000'
end_addr = int(addr.group(1), 16)
assert end_addr > start_addr
@pytest.mark.parametrize('config', CONFIGS_HW_STACK_GUARD, indirect=True)
@pytest.mark.generic
def test_hw_stack_guard_cpu0(dut: PanicTestDut, config: str, test_func_name: str) -> None:
dut.run_test_func(test_func_name)
dut.expect_exact('Guru Meditation Error: Core 0 panic\'ed (Stack protection fault).')
dut.expect_none('ASSIST_DEBUG is not triggered BUT interrupt occured!')
dut.expect(r'Detected in task(.*)at 0x')
dut.expect_exact('Stack pointer: 0x')
dut.expect(r'Stack bounds: 0x(.*) - 0x')
test_hw_stack_guard_cpu(dut, 0)
common_test(dut, config)
@pytest.mark.parametrize('config', CONFIGS_HW_STACK_GUARD_DUAL_CORE, indirect=True)
@pytest.mark.generic
def test_hw_stack_guard_cpu1(dut: PanicTestDut, config: str, test_func_name: str) -> None:
dut.run_test_func(test_func_name)
test_hw_stack_guard_cpu(dut, 1)
common_test(dut, config)

Wyświetl plik

@ -1,14 +1,23 @@
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
import logging
import os
import re
import subprocess
import sys
from typing import Any, Dict, List, Optional, TextIO, Union
from typing import Any
from typing import Dict
from typing import List
from typing import Optional
from typing import TextIO
from typing import Union
import pexpect
from panic_utils import NoGdbProcessError, attach_logger, quote_string, sha256, verify_valid_gdb_subprocess
from panic_utils import attach_logger
from panic_utils import NoGdbProcessError
from panic_utils import quote_string
from panic_utils import sha256
from panic_utils import verify_valid_gdb_subprocess
from pygdbmi.gdbcontroller import GdbController
from pytest_embedded_idf.app import IdfApp
from pytest_embedded_idf.dut import IdfDut
@ -53,7 +62,7 @@ class PanicTestDut(IdfDut):
@property
def is_multi_core(self) -> bool:
return self.target in ['esp32', 'esp32s3']
return self.target in ['esp32', 'esp32s3', 'esp32p4']
def run_test_func(self, test_func_name: str) -> None:
self.expect_exact('Enter test name:')