From a2a4dec210484ec680093ae2bf5a55fa6babaeda Mon Sep 17 00:00:00 2001 From: "Michael.B" Date: Thu, 27 Aug 2026 02:21:17 +0800 Subject: [PATCH] fix(psram): suspend external cache during CPU freq switch on esp32p4 Suspend the external-memory cache around the boot CPU frequency switch so PSRAM-XIP / write-back cache state cannot be corrupted mid-switch. --- components/esp_system/port/soc/esp32p4/clk.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/components/esp_system/port/soc/esp32p4/clk.c b/components/esp_system/port/soc/esp32p4/clk.c index 6d5bf4defc1..2beb05fcc1f 100644 --- a/components/esp_system/port/soc/esp32p4/clk.c +++ b/components/esp_system/port/soc/esp32p4/clk.c @@ -62,6 +62,7 @@ #include "esp_private/periph_ctrl.h" #include "esp_private/esp_clk.h" #include "esp_private/esp_pmu.h" +#include "esp_private/esp_cache_private.h" #include "esp_rom_uart.h" #include "esp_rom_sys.h" @@ -84,6 +85,22 @@ void IRAM_ATTR esp_rtc_init(void) #endif //SOC_PMU_SUPPORTED } +/* + * Perform the CPU frequency switch with the external memory (PSRAM) cache + * suspended. The frequency switch stalls the HP_ROOT clock and toggles PLL / + * clock gating; when the switch code runs from PSRAM-XIP, a cache-coherency + * transient during the switch can corrupt the external .bss region. Suspending + * the external-memory cache for the duration of the switch keeps the CPU off + * the XIP path, isolating the two. + * Must be IRAM-resident because it runs while the external cache is suspended. + */ +static void IRAM_ATTR esp_clk_cpu_freq_set_config_isolated(const rtc_cpu_freq_config_t *config) +{ + esp_cache_suspend_ext_mem_cache(); + rtc_clk_cpu_freq_set_config(config); + esp_cache_resume_ext_mem_cache(); +} + __attribute__((weak)) void esp_clk_init(void) { assert(rtc_clk_xtal_freq_get() == SOC_XTAL_FREQ_40M); @@ -145,7 +162,7 @@ __attribute__((weak)) void esp_clk_init(void) } if (res) { - rtc_clk_cpu_freq_set_config(&new_config); + esp_clk_cpu_freq_set_config_isolated(&new_config); } // Re calculate the ccount to make time calculation correct.