From 9a201cdd1ebd4a49f26d6da8f93bfb74a57641f7 Mon Sep 17 00:00:00 2001 From: "harshal.patil" Date: Wed, 26 Aug 2026 15:04:50 +0530 Subject: [PATCH] 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. --- .../include/esp_private/panic_internal.h | 4 + components/esp_system/port/CMakeLists.txt | 4 + .../esp_system/port/arch/riscv/panic_arch.c | 78 +---------------- components/esp_system/port/panic_memprot.c | 87 +++++++++++++++++++ 4 files changed, 96 insertions(+), 77 deletions(-) create mode 100644 components/esp_system/port/panic_memprot.c diff --git a/components/esp_system/include/esp_private/panic_internal.h b/components/esp_system/include/esp_private/panic_internal.h index 170ee3fd65d..6fd164ae817 100644 --- a/components/esp_system/include/esp_private/panic_internal.h +++ b/components/esp_system/include/esp_private/panic_internal.h @@ -90,6 +90,10 @@ void panic_prepare_frame_from_ctx(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 * diff --git a/components/esp_system/port/CMakeLists.txt b/components/esp_system/port/CMakeLists.txt index 0aa682d0561..cadbf920c26 100644 --- a/components/esp_system/port/CMakeLists.txt +++ b/components/esp_system/port/CMakeLists.txt @@ -45,6 +45,10 @@ elseif(CONFIG_IDF_TARGET_ARCH_RISCV) "arch/riscv/debug_stubs.c") 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}) target_sources(${COMPONENT_LIB} PRIVATE ${srcs}) diff --git a/components/esp_system/port/arch/riscv/panic_arch.c b/components/esp_system/port/arch/riscv/panic_arch.c index 0d38d14212a..a64fc742bf2 100644 --- a/components/esp_system/port/arch/riscv/panic_arch.c +++ b/components/esp_system/port/arch/riscv/panic_arch.c @@ -13,11 +13,6 @@ #include "riscv/rv_utils.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 #include "esp_private/eh_frame_parser.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 -/** - * 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) { const int regs_per_line = 4; @@ -257,9 +183,7 @@ void panic_soc_fill_info(void *f, panic_info_t *info) #endif #if CONFIG_ESP_SYSTEM_MEMPROT && CONFIG_ESP_SYSTEM_MEMPROT_PMS else if (frame->mcause == ETS_MEMPROT_ERR_INUM) { - 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; + panic_memprot_fill_info(info); } #endif //CONFIG_ESP_SYSTEM_MEMPROT && CONFIG_ESP_SYSTEM_MEMPROT_PMS } diff --git a/components/esp_system/port/panic_memprot.c b/components/esp_system/port/panic_memprot.c new file mode 100644 index 00000000000..be321ad6900 --- /dev/null +++ b/components/esp_system/port/panic_memprot.c @@ -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; +}