mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
refactor(esp_system): factor the memprot panic report out of panic_arch.c
Move print_memprot_err_details() and its state out of the RISC-V panic_arch.c into port/panic_memprot.c behind panic_memprot_fill_info(), so the report can be shared with the Xtensa PMS targets. No functional change.
This commit is contained in:
@@ -90,6 +90,10 @@ void panic_prepare_frame_from_ctx(void* frame);
|
|||||||
|
|
||||||
void panic_clear_active_interrupts(const void* frame);
|
void panic_clear_active_interrupts(const void* frame);
|
||||||
|
|
||||||
|
#if CONFIG_ESP_SYSTEM_MEMPROT && CONFIG_ESP_SYSTEM_MEMPROT_PMS && !CONFIG_IDF_TARGET_ESP32S2
|
||||||
|
bool panic_memprot_fill_info(panic_info_t *info);
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Disable all watchdog timers
|
* @brief Disable all watchdog timers
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -45,6 +45,10 @@ elseif(CONFIG_IDF_TARGET_ARCH_RISCV)
|
|||||||
"arch/riscv/debug_stubs.c")
|
"arch/riscv/debug_stubs.c")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(CONFIG_ESP_SYSTEM_MEMPROT AND CONFIG_ESP_SYSTEM_MEMPROT_PMS AND NOT CONFIG_IDF_TARGET_ESP32S2)
|
||||||
|
list(APPEND srcs "panic_memprot.c")
|
||||||
|
endif()
|
||||||
|
|
||||||
add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" ${srcs})
|
add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" ${srcs})
|
||||||
|
|
||||||
target_sources(${COMPONENT_LIB} PRIVATE ${srcs})
|
target_sources(${COMPONENT_LIB} PRIVATE ${srcs})
|
||||||
|
|||||||
@@ -13,11 +13,6 @@
|
|||||||
#include "riscv/rv_utils.h"
|
#include "riscv/rv_utils.h"
|
||||||
#include "esp_private/cache_err_int.h"
|
#include "esp_private/cache_err_int.h"
|
||||||
|
|
||||||
#if CONFIG_ESP_SYSTEM_MEMPROT && CONFIG_ESP_SYSTEM_MEMPROT_PMS
|
|
||||||
#include "esp_private/esp_memprot_internal.h"
|
|
||||||
#include "esp_memprot.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CONFIG_ESP_SYSTEM_USE_EH_FRAME
|
#if CONFIG_ESP_SYSTEM_USE_EH_FRAME
|
||||||
#include "esp_private/eh_frame_parser.h"
|
#include "esp_private/eh_frame_parser.h"
|
||||||
#include "esp_private/cache_utils.h"
|
#include "esp_private/cache_utils.h"
|
||||||
@@ -83,75 +78,6 @@ static inline void print_assist_debug_details(const void *frame)
|
|||||||
}
|
}
|
||||||
#endif // CONFIG_ESP_SYSTEM_HW_STACK_GUARD
|
#endif // CONFIG_ESP_SYSTEM_HW_STACK_GUARD
|
||||||
|
|
||||||
/**
|
|
||||||
* Function called when a memory protection error occurs (PMS). It prints details such as the
|
|
||||||
* explanation of why the panic occurred.
|
|
||||||
*/
|
|
||||||
#if CONFIG_ESP_SYSTEM_MEMPROT && CONFIG_ESP_SYSTEM_MEMPROT_PMS
|
|
||||||
|
|
||||||
static esp_memp_intr_source_t s_memp_intr = {MEMPROT_TYPE_INVALID, -1};
|
|
||||||
|
|
||||||
#define PRINT_MEMPROT_ERROR(err) \
|
|
||||||
do { \
|
|
||||||
panic_print_str("N/A (error "); \
|
|
||||||
panic_print_str(esp_err_to_name(err)); \
|
|
||||||
panic_print_str(")"); \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
static inline void print_memprot_err_details(const void *frame __attribute__((unused)))
|
|
||||||
{
|
|
||||||
if (s_memp_intr.mem_type == MEMPROT_TYPE_INVALID && s_memp_intr.core == -1) {
|
|
||||||
panic_print_str(" - no details available -\r\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//common memprot fault info
|
|
||||||
panic_print_str(" memory type: ");
|
|
||||||
panic_print_str(esp_mprot_mem_type_to_str(s_memp_intr.mem_type));
|
|
||||||
|
|
||||||
panic_print_str("\r\n faulting address: ");
|
|
||||||
void *faulting_addr;
|
|
||||||
esp_err_t res = esp_mprot_get_violate_addr(s_memp_intr.mem_type, &faulting_addr, s_memp_intr.core);
|
|
||||||
if (res == ESP_OK) {
|
|
||||||
panic_print_str("0x");
|
|
||||||
panic_print_hex((int)faulting_addr);
|
|
||||||
} else {
|
|
||||||
PRINT_MEMPROT_ERROR(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
panic_print_str("\r\n world: ");
|
|
||||||
esp_mprot_pms_world_t world;
|
|
||||||
res = esp_mprot_get_violate_world(s_memp_intr.mem_type, &world, s_memp_intr.core);
|
|
||||||
if (res == ESP_OK) {
|
|
||||||
panic_print_str(esp_mprot_pms_world_to_str(world));
|
|
||||||
} else {
|
|
||||||
PRINT_MEMPROT_ERROR(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
panic_print_str("\r\n operation type: ");
|
|
||||||
uint32_t operation;
|
|
||||||
res = esp_mprot_get_violate_operation(s_memp_intr.mem_type, &operation, s_memp_intr.core);
|
|
||||||
if (res == ESP_OK) {
|
|
||||||
panic_print_str(esp_mprot_oper_type_to_str(operation));
|
|
||||||
} else {
|
|
||||||
PRINT_MEMPROT_ERROR(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (esp_mprot_has_byte_enables(s_memp_intr.mem_type)) {
|
|
||||||
panic_print_str("\r\n byte-enables: ");
|
|
||||||
uint32_t byte_enables;
|
|
||||||
res = esp_mprot_get_violate_byte_enables(s_memp_intr.mem_type, &byte_enables, s_memp_intr.core);
|
|
||||||
if (res == ESP_OK) {
|
|
||||||
panic_print_hex(byte_enables);
|
|
||||||
} else {
|
|
||||||
PRINT_MEMPROT_ERROR(res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
panic_print_str("\r\n");
|
|
||||||
}
|
|
||||||
#endif //CONFIG_ESP_SYSTEM_MEMPROT && CONFIG_ESP_SYSTEM_MEMPROT_PMS
|
|
||||||
|
|
||||||
static void panic_print_register_array(const char* names[], const uint32_t* regs, int size)
|
static void panic_print_register_array(const char* names[], const uint32_t* regs, int size)
|
||||||
{
|
{
|
||||||
const int regs_per_line = 4;
|
const int regs_per_line = 4;
|
||||||
@@ -257,9 +183,7 @@ void panic_soc_fill_info(void *f, panic_info_t *info)
|
|||||||
#endif
|
#endif
|
||||||
#if CONFIG_ESP_SYSTEM_MEMPROT && CONFIG_ESP_SYSTEM_MEMPROT_PMS
|
#if CONFIG_ESP_SYSTEM_MEMPROT && CONFIG_ESP_SYSTEM_MEMPROT_PMS
|
||||||
else if (frame->mcause == ETS_MEMPROT_ERR_INUM) {
|
else if (frame->mcause == ETS_MEMPROT_ERR_INUM) {
|
||||||
info->reason = "Memory protection fault";
|
panic_memprot_fill_info(info);
|
||||||
info->details = print_memprot_err_details;
|
|
||||||
info->core = esp_mprot_get_active_intr(&s_memp_intr) == ESP_OK ? s_memp_intr.core : -1;
|
|
||||||
}
|
}
|
||||||
#endif //CONFIG_ESP_SYSTEM_MEMPROT && CONFIG_ESP_SYSTEM_MEMPROT_PMS
|
#endif //CONFIG_ESP_SYSTEM_MEMPROT && CONFIG_ESP_SYSTEM_MEMPROT_PMS
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include "esp_private/panic_internal.h"
|
||||||
|
#include "esp_private/esp_memprot_internal.h"
|
||||||
|
#include "esp_memprot.h"
|
||||||
|
|
||||||
|
static esp_memp_intr_source_t s_memp_intr = {MEMPROT_TYPE_INVALID, -1};
|
||||||
|
|
||||||
|
#define PRINT_MEMPROT_ERROR(err) \
|
||||||
|
do { \
|
||||||
|
panic_print_str("N/A (error "); \
|
||||||
|
panic_print_str(esp_err_to_name(err)); \
|
||||||
|
panic_print_str(")"); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function called when a memory protection error occurs (PMS). It prints details such as the
|
||||||
|
* explanation of why the panic occurred.
|
||||||
|
*/
|
||||||
|
static void print_memprot_err_details(const void *frame __attribute__((unused)))
|
||||||
|
{
|
||||||
|
if (s_memp_intr.mem_type == MEMPROT_TYPE_INVALID && s_memp_intr.core == -1) {
|
||||||
|
panic_print_str(" - no details available -\r\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//common memprot fault info
|
||||||
|
panic_print_str(" memory type: ");
|
||||||
|
panic_print_str(esp_mprot_mem_type_to_str(s_memp_intr.mem_type));
|
||||||
|
|
||||||
|
panic_print_str("\r\n faulting address: ");
|
||||||
|
void *faulting_addr;
|
||||||
|
esp_err_t res = esp_mprot_get_violate_addr(s_memp_intr.mem_type, &faulting_addr, s_memp_intr.core);
|
||||||
|
if (res == ESP_OK) {
|
||||||
|
panic_print_str("0x");
|
||||||
|
panic_print_hex((int)faulting_addr);
|
||||||
|
} else {
|
||||||
|
PRINT_MEMPROT_ERROR(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
panic_print_str("\r\n world: ");
|
||||||
|
esp_mprot_pms_world_t world;
|
||||||
|
res = esp_mprot_get_violate_world(s_memp_intr.mem_type, &world, s_memp_intr.core);
|
||||||
|
if (res == ESP_OK) {
|
||||||
|
panic_print_str(esp_mprot_pms_world_to_str(world));
|
||||||
|
} else {
|
||||||
|
PRINT_MEMPROT_ERROR(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
panic_print_str("\r\n operation type: ");
|
||||||
|
uint32_t operation;
|
||||||
|
res = esp_mprot_get_violate_operation(s_memp_intr.mem_type, &operation, s_memp_intr.core);
|
||||||
|
if (res == ESP_OK) {
|
||||||
|
panic_print_str(esp_mprot_oper_type_to_str(operation));
|
||||||
|
} else {
|
||||||
|
PRINT_MEMPROT_ERROR(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (esp_mprot_has_byte_enables(s_memp_intr.mem_type)) {
|
||||||
|
panic_print_str("\r\n byte-enables: ");
|
||||||
|
uint32_t byte_enables;
|
||||||
|
res = esp_mprot_get_violate_byte_enables(s_memp_intr.mem_type, &byte_enables, s_memp_intr.core);
|
||||||
|
if (res == ESP_OK) {
|
||||||
|
panic_print_hex(byte_enables);
|
||||||
|
} else {
|
||||||
|
PRINT_MEMPROT_ERROR(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
panic_print_str("\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool panic_memprot_fill_info(panic_info_t *info)
|
||||||
|
{
|
||||||
|
info->reason = "Memory protection fault";
|
||||||
|
info->details = print_memprot_err_details;
|
||||||
|
info->core = esp_mprot_get_active_intr(&s_memp_intr) == ESP_OK ? s_memp_intr.core : -1;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user