From 9a6de4cb3efd2b95fb498ac247f2d5a560ebb3f9 Mon Sep 17 00:00:00 2001 From: Marius Vikhammer Date: Tue, 28 Nov 2023 09:57:44 +0800 Subject: [PATCH] fix(panic): fixed cache error being reported as illegal instruction On riscv chips accessing cache mapped memory regions over the ibus would result in an illegal instructions exception triggering faster than the cache error interrupt/exception. Added a cache error check in the panic handler, if any cache errors are active the panic handler will now report a cache error, even if the trigger exception was a illegal instructions. --- .../include/esp_private/panic_internal.h | 2 + components/esp_system/linker.lf | 2 +- .../esp_system/port/arch/riscv/panic_arch.c | 139 ++++-------------- .../esp_system/port/arch/xtensa/panic_arch.c | 11 ++ .../private/esp_private/cache_err_int.h | 21 ++- components/esp_system/port/panic_handler.c | 7 +- .../port/soc/esp32c2/cache_err_int.c | 115 ++++++++++++++- .../port/soc/esp32c3/cache_err_int.c | 114 +++++++++++++- .../port/soc/esp32c6/cache_err_int.c | 18 +++ .../port/soc/esp32h2/cache_err_int.c | 17 +++ .../port/soc/esp32p4/cache_err_int.c | 12 ++ .../riscv/include/esp_private/panic_reason.h | 2 + .../system/memprot/main/esp32c3/test_panic.c | 2 +- tools/test_apps/system/panic/pytest_panic.py | 9 +- 14 files changed, 349 insertions(+), 122 deletions(-) diff --git a/components/esp_system/include/esp_private/panic_internal.h b/components/esp_system/include/esp_private/panic_internal.h index 9d35c7524d..203643d069 100644 --- a/components/esp_system/include/esp_private/panic_internal.h +++ b/components/esp_system/include/esp_private/panic_internal.h @@ -75,6 +75,8 @@ void panic_arch_fill_info(void *frame, panic_info_t *info); void panic_soc_fill_info(void *frame, panic_info_t *info); +bool panic_soc_check_pseudo_cause(void *f, panic_info_t *info); + void panic_print_registers(const void *frame, int core); void panic_print_backtrace(const void *frame, int core); diff --git a/components/esp_system/linker.lf b/components/esp_system/linker.lf index e30a7fccec..f512f550a9 100644 --- a/components/esp_system/linker.lf +++ b/components/esp_system/linker.lf @@ -5,7 +5,7 @@ entries: panic (noflash) panic_handler (noflash) panic_arch (noflash) - cache_err_int:esp_cache_err_get_cpuid (noflash) + cache_err_int (noflash) 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) diff --git a/components/esp_system/port/arch/riscv/panic_arch.c b/components/esp_system/port/arch/riscv/panic_arch.c index ce8fe05148..a4f64dbdc7 100644 --- a/components/esp_system/port/arch/riscv/panic_arch.c +++ b/components/esp_system/port/arch/riscv/panic_arch.c @@ -41,124 +41,20 @@ #define DIM(array) (sizeof(array)/sizeof(*array)) -/** - * Structure used to define a flag/bit to test in case of cache error. - * The message describes the cause of the error when the bit is set in - * a given status register. - */ -typedef struct { - const uint32_t bit; - const char *msg; -} register_bit_t; - -/** - * Function to check each bits defined in the array reg_bits in the given - * status register. The first bit from the array to be set in the status - * register will have its associated message printed. This function returns - * true. If not bit was set in the register, it returns false. - * The order of the bits in the array is important as only the first bit to - * be set in the register will have its associated message printed. - */ -static inline bool test_and_print_register_bits(const uint32_t status, - const register_bit_t *reg_bits, - const uint32_t size) -{ - /* Browse the flag/bit array and test each one with the given status - * register. */ - for (int i = 0; i < size; i++) { - const uint32_t bit = reg_bits[i].bit; - if ((status & bit) == bit) { - /* Reason of the panic found, print the reason. */ - panic_print_str(reg_bits[i].msg); - panic_print_str("\r\n"); - - return true; - } - } - - /* Panic cause not found, no message was printed. */ - return false; -} - /** * Function called when a cache error occurs. It prints details such as the * explanation of why the panic occured. */ static inline void print_cache_err_details(const void *frame) { -#if !CONFIG_IDF_TARGET_ESP32C6 && !CONFIG_IDF_TARGET_ESP32H2 && !CONFIG_IDF_TARGET_ESP32P4 // ESP32P4-TODO, ESP32C6-TODO, ESP32H2-TODO: IDF-5657 - /* Define the array that contains the status (bits) to test on the register - * EXTMEM_CORE0_ACS_CACHE_INT_ST_REG. each bit is accompanied by a small - * message. - * The messages have been pulled from the header file where the status bit - * are defined. */ - const register_bit_t core0_acs_bits[] = { - { - .bit = EXTMEM_CORE0_DBUS_WR_ICACHE_ST, - .msg = "dbus tried to write cache" - }, - { - .bit = EXTMEM_CORE0_DBUS_REJECT_ST, - .msg = "dbus authentication failed" - }, - { - .bit = EXTMEM_CORE0_DBUS_ACS_MSK_ICACHE_ST, - .msg = "access to cache while dbus or cache is disabled" - }, - { - .bit = EXTMEM_CORE0_IBUS_REJECT_ST, - .msg = "ibus authentication failed" - }, - { - .bit = EXTMEM_CORE0_IBUS_WR_ICACHE_ST, - .msg = "ibus tried to write cache" - }, - { - .bit = EXTMEM_CORE0_IBUS_ACS_MSK_ICACHE_ST, - .msg = "access to cache while ibus or cache is disabled" - }, - }; - - /* Same goes for the register EXTMEM_CACHE_ILG_INT_ST_REG and its bits. */ - const register_bit_t cache_ilg_bits[] = { - { - .bit = EXTMEM_MMU_ENTRY_FAULT_ST, - .msg = "MMU entry fault" - }, - { - .bit = EXTMEM_ICACHE_PRELOAD_OP_FAULT_ST, - .msg = "preload configurations fault" - }, - { - .bit = EXTMEM_ICACHE_SYNC_OP_FAULT_ST, - .msg = "sync configurations fault" - }, - }; - - /* Read the status register EXTMEM_CORE0_ACS_CACHE_INT_ST_REG. This status - * register is not equal to 0 when a cache access error occured. */ - const uint32_t core0_status = REG_READ(EXTMEM_CORE0_ACS_CACHE_INT_ST_REG); - - /* If the panic is due to a cache access error, one of the bit of the - * register is set. Thus, this function will return true. */ - bool handled = test_and_print_register_bits(core0_status, core0_acs_bits, DIM(core0_acs_bits)); - - /* If the panic was due to a cache illegal error, the previous call returned false and this - * EXTMEM_CACHE_ILG_INT_ST_REG register should not me equal to 0. - * Check each bit of it and print the message associated if found. */ - if (!handled) { - const uint32_t cache_ilg_status = REG_READ(EXTMEM_CACHE_ILG_INT_ST_REG); - handled = test_and_print_register_bits(cache_ilg_status, cache_ilg_bits, DIM(cache_ilg_bits)); - - /* If the error was not found, print the both registers value */ - if (!handled) { - panic_print_str("EXTMEM_CORE0_ACS_CACHE_INT_ST_REG = 0x"); - panic_print_hex(core0_status); - panic_print_str("\r\nEXTMEM_CACHE_ILG_INT_ST_REG = 0x"); - panic_print_hex(cache_ilg_status); - panic_print_str("\r\n"); - } +#if !CONFIG_IDF_TARGET_ESP32P4 + const char* cache_err_msg = esp_cache_err_panic_string(); + if (cache_err_msg) { + panic_print_str(cache_err_msg); + } else { + panic_print_str("Cache error active, but failed to find a corresponding error message"); } + panic_print_str("\r\n"); #endif } @@ -294,6 +190,27 @@ void panic_print_registers(const void *f, int core) panic_print_register_array(desc, f, DIM(desc)); } +/** + * This function will be called before the SoC-level panic is handled, + * allowing us to check and override the exception cause for certain + * pseudo-causes that do not have their own trigger + */ +bool panic_soc_check_pseudo_cause(void *f, panic_info_t *info) +{ + RvExcFrame *frame = (RvExcFrame *) f; + bool pseudo_cause = false; + + /* Cache errors when reading instructions will result in an illegal instructions, + before any cache error interrupts trigger. We override the exception cause if + any cache errors are active to more accurately report the actual reason */ + if(esp_cache_err_has_active_err() && (frame->mcause == MCAUSE_ILLEGAL_INSTRUCTION) ) { + pseudo_cause = true; + frame->mcause = ETS_CACHEERR_INUM; + } + + return pseudo_cause; +} + /** * This function will be called when a SoC-level panic occurs. * SoC-level panics include cache errors and watchdog interrupts. diff --git a/components/esp_system/port/arch/xtensa/panic_arch.c b/components/esp_system/port/arch/xtensa/panic_arch.c index 2d670f577a..9042b0fdd8 100644 --- a/components/esp_system/port/arch/xtensa/panic_arch.c +++ b/components/esp_system/port/arch/xtensa/panic_arch.c @@ -392,6 +392,17 @@ void panic_arch_fill_info(void *f, panic_info_t *info) info->addr = ((void *) ((XtExcFrame *) frame)->pc); } +/** + * This function will be called before the SoC-level panic is handled, + * allowing us to check and override the exception cause for certain + * pseudo-causes that do not have their own trigger + */ +bool panic_soc_check_pseudo_cause(void *f, panic_info_t *info) +{ + // Currently only needed on riscv targets + return false; +} + void panic_soc_fill_info(void *f, panic_info_t *info) { // [refactor-todo] this should be in the common port panic_handler.c, once diff --git a/components/esp_system/port/include/private/esp_private/cache_err_int.h b/components/esp_system/port/include/private/esp_private/cache_err_int.h index 22e1c3ec7c..c070179a5f 100644 --- a/components/esp_system/port/include/private/esp_private/cache_err_int.h +++ b/components/esp_system/port/include/private/esp_private/cache_err_int.h @@ -1,15 +1,18 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once +#include + #ifdef __cplusplus extern "C" { #endif + /** * @brief initialize cache invalid access interrupt * @@ -32,6 +35,22 @@ void esp_cache_err_int_init(void); */ int esp_cache_err_get_cpuid(void); + +/** + * @brief Returns a pointer to the cache error message + * + * @return const char* Pointer to the error message + */ +const char *esp_cache_err_panic_string(void); + +/** + * @brief Checks if any cache errors are active + * + * @return true + * @return false + */ +bool esp_cache_err_has_active_err(void); + #ifdef __cplusplus } #endif diff --git a/components/esp_system/port/panic_handler.c b/components/esp_system/port/panic_handler.c index a936a01b4e..a8ccce4a8c 100644 --- a/components/esp_system/port/panic_handler.c +++ b/components/esp_system/port/panic_handler.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -104,9 +104,10 @@ static void frame_to_panic_info(void *frame, panic_info_t *info, bool pseudo_exc info->exception = PANIC_EXCEPTION_FAULT; info->details = NULL; info->reason = "Unknown"; - info->pseudo_excause = pseudo_excause; - if (pseudo_excause) { + info->pseudo_excause = panic_soc_check_pseudo_cause(frame, info) | pseudo_excause; + + if (info->pseudo_excause) { panic_soc_fill_info(frame, info); } else { panic_arch_fill_info(frame, info); diff --git a/components/esp_system/port/soc/esp32c2/cache_err_int.c b/components/esp_system/port/soc/esp32c2/cache_err_int.c index 4f241e021d..8215353313 100644 --- a/components/esp_system/port/soc/esp32c2/cache_err_int.c +++ b/components/esp_system/port/soc/esp32c2/cache_err_int.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,6 +20,119 @@ static const char *TAG = "CACHE_ERR"; + +#define DIM(array) (sizeof(array)/sizeof(*array)) + +/** + * Structure used to define a flag/bit to test in case of cache error. + * The message describes the cause of the error when the bit is set in + * a given status register. + */ +typedef struct { + const uint32_t bit; + const char *msg; +} register_bit_t; + +/* Define the array that contains the status (bits) to test on the register + * EXTMEM_CORE0_ACS_CACHE_INT_ST_REG. each bit is accompanied by a small + * message. + * The messages have been pulled from the header file where the status bit + * are defined. */ +const register_bit_t core0_acs_bits[] = { + { + .bit = EXTMEM_CORE0_DBUS_WR_ICACHE_ST, + .msg = "Dbus tried to write cache" + }, + { + .bit = EXTMEM_CORE0_DBUS_REJECT_ST, + .msg = "Dbus authentication failed" + }, + { + .bit = EXTMEM_CORE0_DBUS_ACS_MSK_ICACHE_ST, + .msg = "Cached memory region accessed while dbus or cache is disabled" + }, + { + .bit = EXTMEM_CORE0_IBUS_REJECT_ST, + .msg = "Ibus authentication failed" + }, + { + .bit = EXTMEM_CORE0_IBUS_WR_ICACHE_ST, + .msg = "Ibus tried to write cache" + }, + { + .bit = EXTMEM_CORE0_IBUS_ACS_MSK_ICACHE_ST, + .msg = "Cached memory region accessed while ibus or cache is disabled" + }, +}; + +/* Same goes for the register EXTMEM_CACHE_ILG_INT_ST_REG and its bits. */ +const register_bit_t cache_ilg_bits[] = { + { + .bit = EXTMEM_MMU_ENTRY_FAULT_ST, + .msg = "MMU entry fault" + }, + { + .bit = EXTMEM_ICACHE_PRELOAD_OP_FAULT_ST, + .msg = "Preload configurations fault" + }, + { + .bit = EXTMEM_ICACHE_SYNC_OP_FAULT_ST, + .msg = "Sync configurations fault" + }, +}; + +/** + * Function to check each bits defined in the array reg_bits in the given + * status register. The first bit from the array to be set in the status + * register will have its associated message printed. This function returns + * true. If not bit was set in the register, it returns false. + * The order of the bits in the array is important as only the first bit to + * be set in the register will have its associated message printed. + */ +static inline const char* test_and_print_register_bits(const uint32_t status, + const register_bit_t *reg_bits, + const uint32_t size) +{ + /* Browse the flag/bit array and test each one with the given status + * register. */ + for (int i = 0; i < size; i++) { + const uint32_t bit = reg_bits[i].bit; + if ((status & bit) == bit) { + /* Reason of the panic found, print the reason. */ + return reg_bits[i].msg; + } + } + + /* Panic cause not found, no message was printed. */ + return NULL; +} + +const char *esp_cache_err_panic_string(void) +{ + /* Read the status register EXTMEM_CORE0_ACS_CACHE_INT_ST_REG. This status + * register is not equal to 0 when a cache access error occured. */ + const uint32_t access_err_status = cache_ll_l1_get_access_error_intr_status(0, CACHE_LL_L1_ACCESS_EVENT_MASK); + + /* If the panic is due to a cache access error, one of the bit of the + * register is set. Thus, this function will return an error string. */ + const char* err_str = test_and_print_register_bits(access_err_status, core0_acs_bits, DIM(core0_acs_bits)); + + /* If the panic was due to a cache illegal error, the previous call returned NULL and this + * EXTMEM_CACHE_ILG_INT_ST_REG register should not be equal to 0. + * Check each bit of it and print the message associated if found. */ + if (err_str == NULL) { + const uint32_t cache_ilg_status = cache_ll_l1_get_illegal_error_intr_status(0, CACHE_LL_L1_ILG_EVENT_MASK); + err_str = test_and_print_register_bits(cache_ilg_status, cache_ilg_bits, DIM(cache_ilg_bits)); + } + + return err_str; +} + +bool esp_cache_err_has_active_err(void) +{ + return cache_ll_l1_get_access_error_intr_status(0, CACHE_LL_L1_ACCESS_EVENT_MASK) || cache_ll_l1_get_illegal_error_intr_status(0, CACHE_LL_L1_ILG_EVENT_MASK); +} + void esp_cache_err_int_init(void) { const uint32_t core_id = 0; diff --git a/components/esp_system/port/soc/esp32c3/cache_err_int.c b/components/esp_system/port/soc/esp32c3/cache_err_int.c index 05b5d6773c..28f9877cd2 100644 --- a/components/esp_system/port/soc/esp32c3/cache_err_int.c +++ b/components/esp_system/port/soc/esp32c3/cache_err_int.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,6 +20,118 @@ static const char *TAG = "CACHE_ERR"; +#define DIM(array) (sizeof(array)/sizeof(*array)) + +/** + * Structure used to define a flag/bit to test in case of cache error. + * The message describes the cause of the error when the bit is set in + * a given status register. + */ +typedef struct { + const uint32_t bit; + const char *msg; +} register_bit_t; + +/* Define the array that contains the status (bits) to test on the register + * EXTMEM_CORE0_ACS_CACHE_INT_ST_REG. each bit is accompanied by a small + * message. + * The messages have been pulled from the header file where the status bit + * are defined. */ +const register_bit_t core0_acs_bits[] = { + { + .bit = EXTMEM_CORE0_DBUS_WR_ICACHE_ST, + .msg = "Dbus tried to write cache" + }, + { + .bit = EXTMEM_CORE0_DBUS_REJECT_ST, + .msg = "Dbus authentication failed" + }, + { + .bit = EXTMEM_CORE0_DBUS_ACS_MSK_ICACHE_ST, + .msg = "Cached memory region accessed while dbus or cache is disabled" + }, + { + .bit = EXTMEM_CORE0_IBUS_REJECT_ST, + .msg = "Ibus authentication failed" + }, + { + .bit = EXTMEM_CORE0_IBUS_WR_ICACHE_ST, + .msg = "Ibus tried to write cache" + }, + { + .bit = EXTMEM_CORE0_IBUS_ACS_MSK_ICACHE_ST, + .msg = "Cached memory region accessed while ibus or cache is disabled" + }, +}; + +/* Same goes for the register EXTMEM_CACHE_ILG_INT_ST_REG and its bits. */ +const register_bit_t cache_ilg_bits[] = { + { + .bit = EXTMEM_MMU_ENTRY_FAULT_ST, + .msg = "MMU entry fault" + }, + { + .bit = EXTMEM_ICACHE_PRELOAD_OP_FAULT_ST, + .msg = "Preload configurations fault" + }, + { + .bit = EXTMEM_ICACHE_SYNC_OP_FAULT_ST, + .msg = "Sync configurations fault" + }, +}; + +/** + * Function to check each bits defined in the array reg_bits in the given + * status register. The first bit from the array to be set in the status + * register will have its associated message printed. This function returns + * true. If not bit was set in the register, it returns false. + * The order of the bits in the array is important as only the first bit to + * be set in the register will have its associated message printed. + */ +static inline const char* test_and_print_register_bits(const uint32_t status, + const register_bit_t *reg_bits, + const uint32_t size) +{ + /* Browse the flag/bit array and test each one with the given status + * register. */ + for (int i = 0; i < size; i++) { + const uint32_t bit = reg_bits[i].bit; + if ((status & bit) == bit) { + /* Reason of the panic found, print the reason. */ + return reg_bits[i].msg; + } + } + + /* Panic cause not found, no message was printed. */ + return NULL; +} + +const char *esp_cache_err_panic_string(void) +{ + /* Read the status register EXTMEM_CORE0_ACS_CACHE_INT_ST_REG. This status + * register is not equal to 0 when a cache access error occured. */ + const uint32_t access_err_status = cache_ll_l1_get_access_error_intr_status(0, CACHE_LL_L1_ACCESS_EVENT_MASK); + + /* If the panic is due to a cache access error, one of the bit of the + * register is set. Thus, this function will return an error string. */ + const char* err_str = test_and_print_register_bits(access_err_status, core0_acs_bits, DIM(core0_acs_bits)); + + /* If the panic was due to a cache illegal error, the previous call returned NULL and this + * EXTMEM_CACHE_ILG_INT_ST_REG register should not be equal to 0. + * Check each bit of it and return the message associated if found. */ + if (err_str == NULL) { + const uint32_t cache_ilg_status = cache_ll_l1_get_illegal_error_intr_status(0, CACHE_LL_L1_ILG_EVENT_MASK); + err_str = test_and_print_register_bits(cache_ilg_status, cache_ilg_bits, DIM(cache_ilg_bits)); + } + + return err_str; +} + +bool esp_cache_err_has_active_err(void) +{ + return cache_ll_l1_get_access_error_intr_status(0, CACHE_LL_L1_ACCESS_EVENT_MASK) || cache_ll_l1_get_illegal_error_intr_status(0, CACHE_LL_L1_ILG_EVENT_MASK); +} + void esp_cache_err_int_init(void) { const uint32_t core_id = 0; diff --git a/components/esp_system/port/soc/esp32c6/cache_err_int.c b/components/esp_system/port/soc/esp32c6/cache_err_int.c index 82cf3895e4..7f4eda7112 100644 --- a/components/esp_system/port/soc/esp32c6/cache_err_int.c +++ b/components/esp_system/port/soc/esp32c6/cache_err_int.c @@ -20,6 +20,24 @@ static const char *TAG = "CACHE_ERR"; + +const char cache_error_msg[] = "Cache access error"; + +const char *esp_cache_err_panic_string(void) +{ + const uint32_t access_err_status = cache_ll_l1_get_access_error_intr_status(0, CACHE_LL_L1_ACCESS_EVENT_MASK); + + /* Return the error string if a cache error is active */ + const char* err_str = access_err_status ? cache_error_msg : NULL; + + return err_str; +} + +bool esp_cache_err_has_active_err(void) +{ + return cache_ll_l1_get_access_error_intr_status(0, CACHE_LL_L1_ACCESS_EVENT_MASK); +} + void esp_cache_err_int_init(void) { const uint32_t core_id = 0; diff --git a/components/esp_system/port/soc/esp32h2/cache_err_int.c b/components/esp_system/port/soc/esp32h2/cache_err_int.c index 1997f547da..e989d69ce0 100644 --- a/components/esp_system/port/soc/esp32h2/cache_err_int.c +++ b/components/esp_system/port/soc/esp32h2/cache_err_int.c @@ -20,6 +20,23 @@ static const char *TAG = "CACHE_ERR"; +const char cache_error_msg[] = "Cache access error"; + +const char *esp_cache_err_panic_string(void) +{ + const uint32_t access_err_status = cache_ll_l1_get_access_error_intr_status(0, CACHE_LL_L1_ACCESS_EVENT_MASK); + + /* Return the error string if a cache error is active */ + const char* err_str = access_err_status ? cache_error_msg : NULL; + + return err_str; +} + +bool esp_cache_err_has_active_err(void) +{ + return cache_ll_l1_get_access_error_intr_status(0, CACHE_LL_L1_ACCESS_EVENT_MASK); +} + void esp_cache_err_int_init(void) { const uint32_t core_id = 0; diff --git a/components/esp_system/port/soc/esp32p4/cache_err_int.c b/components/esp_system/port/soc/esp32p4/cache_err_int.c index 673953660d..3e6b3ffca3 100644 --- a/components/esp_system/port/soc/esp32p4/cache_err_int.c +++ b/components/esp_system/port/soc/esp32p4/cache_err_int.c @@ -20,6 +20,18 @@ static const char *TAG = "CACHE_ERR"; +//TODO: IDF-7515 +const char *esp_cache_err_panic_string(void) +{ + return NULL; +} + +//TODO: IDF-7515 +bool esp_cache_err_has_active_err(void) +{ + return false; +} + //TODO: IDF-7515 void esp_cache_err_int_init(void) { diff --git a/components/riscv/include/esp_private/panic_reason.h b/components/riscv/include/esp_private/panic_reason.h index a89f5708f7..252f6de9c0 100644 --- a/components/riscv/include/esp_private/panic_reason.h +++ b/components/riscv/include/esp_private/panic_reason.h @@ -18,3 +18,5 @@ #endif #define PANIC_RSN_CACHEERR 3 + +#define MCAUSE_ILLEGAL_INSTRUCTION 2 diff --git a/tools/test_apps/system/memprot/main/esp32c3/test_panic.c b/tools/test_apps/system/memprot/main/esp32c3/test_panic.c index f75450ef2c..cd28a8b212 100644 --- a/tools/test_apps/system/memprot/main/esp32c3/test_panic.c +++ b/tools/test_apps/system/memprot/main/esp32c3/test_panic.c @@ -6,8 +6,8 @@ #include "riscv/rvruntime-frames.h" #include "esp_private/panic_internal.h" +#include "esp_private/panic_reason.h" -#define MCAUSE_ILLEGAL_INSTRUCTION 2 extern void esp_panic_handler(panic_info_t *info); volatile bool g_override_illegal_instruction = false; diff --git a/tools/test_apps/system/panic/pytest_panic.py b/tools/test_apps/system/panic/pytest_panic.py index 3f110d4e01..18f5a6ef38 100644 --- a/tools/test_apps/system/panic/pytest_panic.py +++ b/tools/test_apps/system/panic/pytest_panic.py @@ -260,9 +260,12 @@ def test_int_wdt_cache_disabled( @pytest.mark.generic def test_cache_error(dut: PanicTestDut, config: str, test_func_name: str) -> None: dut.run_test_func(test_func_name) - if dut.target in ['esp32c3', 'esp32c2', 'esp32c6', 'esp32h2']: - # Cache error interrupt is not raised, IDF-6398 - dut.expect_gme('Illegal instruction') + if dut.target in ['esp32c3', 'esp32c2']: + dut.expect_gme('Cache error') + dut.expect_exact('Cached memory region accessed while ibus or cache is disabled') + elif dut.target in ['esp32c6', 'esp32h2']: + dut.expect_gme('Cache error') + dut.expect_exact('Cache access error') elif dut.target in ['esp32s2']: # Cache error interrupt is not enabled, IDF-1558 dut.expect_gme('IllegalInstruction')