diff --git a/components/esp_system/port/arch/riscv/esp_ipc_isr_routines.c b/components/esp_system/port/arch/riscv/esp_ipc_isr_routines.c index 564690a4475..c981524b33e 100644 --- a/components/esp_system/port/arch/riscv/esp_ipc_isr_routines.c +++ b/components/esp_system/port/arch/riscv/esp_ipc_isr_routines.c @@ -5,9 +5,21 @@ */ #include "stdint.h" +#include "soc/soc_caps.h" #include "esp_attr.h" +#include "esp_cpu.h" void IRAM_ATTR esp_ipc_isr_waiting_for_finish_cmd(void* ipc_isr_finish_cmd) { +#if SOC_BRANCH_PREDICTOR_SUPPORTED + /* The branch predictor keeps issuing speculative instruction fetches while + * this core spins here. The other core may suspend the external memory + * cache during the stall, in which case a speculative fetch into cached + * address space raises a cache access-fail interrupt. */ + esp_cpu_branch_prediction_disable(); +#endif while (*(volatile uint32_t *)ipc_isr_finish_cmd == 0) { }; +#if SOC_BRANCH_PREDICTOR_SUPPORTED + esp_cpu_branch_prediction_enable(); +#endif } diff --git a/components/esp_system/port/panic_handler.c b/components/esp_system/port/panic_handler.c index 7a0879b926d..3328c40cabb 100644 --- a/components/esp_system/port/panic_handler.c +++ b/components/esp_system/port/panic_handler.c @@ -130,6 +130,15 @@ static void frame_to_panic_info(void *frame, panic_info_t *info, bool pseudo_exc FORCE_INLINE_ATTR __attribute__((__noreturn__)) void busy_wait(void) { +#if SOC_BRANCH_PREDICTOR_SUPPORTED + /* This core parks here while the offending core handles the panic, which + * may include flash accesses with the cache suspended (e.g. writing a core + * dump). Stop the branch predictor so its speculative fetches cannot latch + * spurious cache access-fail errors that would corrupt the cache error + * status of the panic being reported. This core never resumes, so the + * predictor is not re-enabled. */ + esp_cpu_branch_prediction_disable(); +#endif ESP_INFINITE_LOOP(); } #endif // !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE diff --git a/components/spi_flash/cache_utils.c b/components/spi_flash/cache_utils.c index 17686bbb5b3..30321921654 100644 --- a/components/spi_flash/cache_utils.c +++ b/components/spi_flash/cache_utils.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -126,6 +126,13 @@ void IRAM_ATTR spi_flash_op_block_func(void *arg) // Restore interrupts that aren't located in IRAM esp_intr_noniram_disable(); uint32_t cpuid = (uint32_t) arg; +#if SOC_BRANCH_PREDICTOR_SUPPORTED + /* The branch predictor issues speculative cache requests while this core + * spins in IRAM. The flash-op core is about to suspend the (shared) cache, + * so speculative fetches into flash would raise a cache access-fail on + * this core. spi_flash_restore_cache() below re-enables prediction. */ + esp_cpu_branch_prediction_disable(); +#endif // s_flash_op_complete flag is cleared on *this* CPU, otherwise the other // CPU may reset the flag back to false before IPC task has a chance to check it // (if it is preempted by an ISR taking non-trivial amount of time)