fix(spi_flash): disable branch prediction on the parked core during flash ops

This commit is contained in:
Ashish Sharma
2026-08-31 10:50:20 +08:00
committed by Armando (Dou Yiwen)
parent 3330e2460a
commit 8201d8c607
3 changed files with 29 additions and 1 deletions
@@ -5,9 +5,21 @@
*/ */
#include "stdint.h" #include "stdint.h"
#include "soc/soc_caps.h"
#include "esp_attr.h" #include "esp_attr.h"
#include "esp_cpu.h"
void IRAM_ATTR esp_ipc_isr_waiting_for_finish_cmd(void* ipc_isr_finish_cmd) 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) { }; while (*(volatile uint32_t *)ipc_isr_finish_cmd == 0) { };
#if SOC_BRANCH_PREDICTOR_SUPPORTED
esp_cpu_branch_prediction_enable();
#endif
} }
@@ -130,6 +130,15 @@ static void frame_to_panic_info(void *frame, panic_info_t *info, bool pseudo_exc
FORCE_INLINE_ATTR __attribute__((__noreturn__)) FORCE_INLINE_ATTR __attribute__((__noreturn__))
void busy_wait(void) 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(); ESP_INFINITE_LOOP();
} }
#endif // !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE #endif // !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
+8 -1
View File
@@ -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 * 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 // Restore interrupts that aren't located in IRAM
esp_intr_noniram_disable(); esp_intr_noniram_disable();
uint32_t cpuid = (uint32_t) arg; 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 // 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 // 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) // (if it is preempted by an ISR taking non-trivial amount of time)