Merge branch 'fix/move_cache_lock_workaround_out_of_ipc_stall_v6.0' into 'release/v6.0'

fix(esp_hw_support): disable esp32 livelock workaround before stall another core (v6.0)

See merge request espressif/esp-idf!50770
This commit is contained in:
Jiang Jiang Jian
2026-07-17 11:26:23 +08:00
+10 -7
View File
@@ -1187,16 +1187,18 @@ static esp_err_t FORCE_IRAM_ATTR deep_sleep_start(bool allow_sleep_rejection)
esp_clk_private_lock(); // Maybe acquired from esp_clk_slowclk_cal_set esp_clk_private_lock(); // Maybe acquired from esp_clk_slowclk_cal_set
#endif #endif
#if CONFIG_ESP_INT_WDT && CONFIG_ESP32_ECO3_CACHE_LOCK_FIX
// The other core will be stalled by high-priority interrupt and spins on variables in internal RAM,
// which naturally avoids cache livelock, so the 20ms livelock workaround timeout is not needed.
// Must do it before stalling another core, since s_iwdt_configure_lock spinlock is acquired in
// esp_int_wdt_livelock_workaround, which may cause deadlock.
esp_int_wdt_livelock_workaround(false);
#endif
/* Disable interrupts and stall another core in case another task writes /* Disable interrupts and stall another core in case another task writes
* to RTC memory while we calculate RTC memory CRC. * to RTC memory while we calculate RTC memory CRC.
*/ */
esp_ipc_isr_stall_other_cpu(); esp_ipc_isr_stall_other_cpu();
esp_ipc_isr_stall_pause(); esp_ipc_isr_stall_pause();
#if CONFIG_ESP_INT_WDT && CONFIG_ESP32_ECO3_CACHE_LOCK_FIX
// The other core will be stalled by high-priority interrupt and spins on variables in internal RAM,
// which naturally avoids cache livelock, so the 20ms livelock workaround timeout is not needed.
esp_int_wdt_livelock_workaround(false);
#endif
// record current RTC time // record current RTC time
s_config.rtc_ticks_at_sleep_start = rtc_time_get(); s_config.rtc_ticks_at_sleep_start = rtc_time_get();
@@ -1263,12 +1265,13 @@ static esp_err_t FORCE_IRAM_ATTR deep_sleep_start(bool allow_sleep_rejection)
ESP_INFINITE_LOOP(); ESP_INFINITE_LOOP();
} }
// Never returns here, except that the sleep is rejected. // Never returns here, except that the sleep is rejected.
esp_ipc_isr_stall_resume();
esp_ipc_isr_release_other_cpu();
#if CONFIG_ESP_INT_WDT && CONFIG_ESP32_ECO3_CACHE_LOCK_FIX #if CONFIG_ESP_INT_WDT && CONFIG_ESP32_ECO3_CACHE_LOCK_FIX
// Configure WDT to use livelock workaround timeout after releasing other CPU // Configure WDT to use livelock workaround timeout after releasing other CPU
esp_int_wdt_livelock_workaround(true); esp_int_wdt_livelock_workaround(true);
#endif #endif
esp_ipc_isr_stall_resume();
esp_ipc_isr_release_other_cpu();
#if !CONFIG_FREERTOS_UNICORE #if !CONFIG_FREERTOS_UNICORE
esp_clk_private_unlock(); esp_clk_private_unlock();
esp_os_exit_critical_safe(&rtc_spinlock); esp_os_exit_critical_safe(&rtc_spinlock);