From 46dd957c11091c5f7444e5bf0a40a1ce9bb79880 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Mon, 31 Jul 2023 19:49:37 +0800 Subject: [PATCH 1/2] fix(lightsleep): suspend cache before goto sleep to avoid cache load wrong data after spi io isolation --- components/esp_system/sleep_modes.c | 5 +++++ components/spi_flash/cache_utils.c | 7 ++----- components/spi_flash/include/esp_spi_flash.h | 14 ++++++++++++++ 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/components/esp_system/sleep_modes.c b/components/esp_system/sleep_modes.c index a6325cbe54..21108cd6c1 100644 --- a/components/esp_system/sleep_modes.c +++ b/components/esp_system/sleep_modes.c @@ -19,6 +19,7 @@ #include "esp_attr.h" #include "esp_sleep.h" +#include "esp_spi_flash.h" #include "esp_private/esp_timer_private.h" #include "esp_private/system_internal.h" #include "esp_log.h" @@ -704,7 +705,11 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) portEXIT_CRITICAL(&spinlock_rtc_deep_sleep); } else { + uint32_t cache_state; + uint32_t cpuid = cpu_ll_get_core_id(); + spi_flash_disable_cache(cpuid, &cache_state); result = call_rtc_sleep_start(reject_triggers); + spi_flash_restore_cache(cpuid, cache_state); } // Restore CPU frequency diff --git a/components/spi_flash/cache_utils.c b/components/spi_flash/cache_utils.c index 1394e0b589..0f6112ab66 100644 --- a/components/spi_flash/cache_utils.c +++ b/components/spi_flash/cache_utils.c @@ -58,9 +58,6 @@ static __attribute__((unused)) const char *TAG = "cache"; #define DPORT_CACHE_GET_VAL(cpuid) (cpuid == 0) ? DPORT_CACHE_VAL(PRO) : DPORT_CACHE_VAL(APP) #define DPORT_CACHE_GET_MASK(cpuid) (cpuid == 0) ? DPORT_CACHE_MASK(PRO) : DPORT_CACHE_MASK(APP) -static void IRAM_ATTR spi_flash_disable_cache(uint32_t cpuid, uint32_t *saved_state); -static void IRAM_ATTR spi_flash_restore_cache(uint32_t cpuid, uint32_t saved_state); - static uint32_t s_flash_op_cache_state[2]; #ifndef CONFIG_FREERTOS_UNICORE @@ -295,7 +292,7 @@ void IRAM_ATTR spi_flash_enable_interrupts_caches_no_os(void) * function in ROM. They are used to work around a bug where Cache_Read_Disable requires a call to * Cache_Flush before Cache_Read_Enable, even if cached data was not modified. */ -static void IRAM_ATTR spi_flash_disable_cache(uint32_t cpuid, uint32_t *saved_state) +void IRAM_ATTR spi_flash_disable_cache(uint32_t cpuid, uint32_t *saved_state) { #if CONFIG_IDF_TARGET_ESP32 uint32_t ret = 0; @@ -331,7 +328,7 @@ static void IRAM_ATTR spi_flash_disable_cache(uint32_t cpuid, uint32_t *saved_st #endif } -static void IRAM_ATTR spi_flash_restore_cache(uint32_t cpuid, uint32_t saved_state) +void IRAM_ATTR spi_flash_restore_cache(uint32_t cpuid, uint32_t saved_state) { #if CONFIG_IDF_TARGET_ESP32 const uint32_t cache_mask = DPORT_CACHE_GET_MASK(cpuid); diff --git a/components/spi_flash/include/esp_spi_flash.h b/components/spi_flash/include/esp_spi_flash.h index 5e7b77de8a..70849fb177 100644 --- a/components/spi_flash/include/esp_spi_flash.h +++ b/components/spi_flash/include/esp_spi_flash.h @@ -321,6 +321,20 @@ bool spi_flash_cache_enabled(void); */ void spi_flash_enable_cache(uint32_t cpuid); +/** + * Suspend the I/DCACHE for core,suspends the CPU access to cache for a while, without invalidation. + * @param cpuid the core number to suspend cache for (valid only on esp32) + * @param saved_state uint32_t variable pointer to record cache autoload status + */ +void spi_flash_disable_cache(uint32_t cpuid, uint32_t *saved_state); + +/** + * Resume the I/DCache for core. + * @param cpuid the core number to suspend cache for (valid only on esp32) + * @param saved_state uint32_t variable recorded the cache autoload status + */ +void spi_flash_restore_cache(uint32_t cpuid, uint32_t saved_state); + /** * @brief SPI flash critical section enter function. * From bc13d808e326b27924f76e83c70c29e396503fd3 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Tue, 1 Aug 2023 16:39:37 +0800 Subject: [PATCH 2/2] fix(lightsleep): fix access pu_cfg after sleep wake wakeup which is linked to flash --- components/esp_hw_support/port/esp32c3/rtc_sleep.c | 5 +++-- components/esp_hw_support/port/esp32s3/rtc_sleep.c | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/components/esp_hw_support/port/esp32c3/rtc_sleep.c b/components/esp_hw_support/port/esp32c3/rtc_sleep.c index b985152ef8..9f27f8bc8e 100644 --- a/components/esp_hw_support/port/esp32c3/rtc_sleep.c +++ b/components/esp_hw_support/port/esp32c3/rtc_sleep.c @@ -14,6 +14,7 @@ #include #include +#include "esp_attr.h" #include "soc/soc.h" #include "soc/rtc.h" #include "soc/rtc_cntl_reg.h" @@ -32,6 +33,8 @@ #include "regi2c_ctrl.h" #include "hal/efuse_hal.h" +static const DRAM_ATTR rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1); + /** * Configure whether certain peripherals are powered down in deep sleep * @param cfg power down flags as rtc_sleep_pu_config_t structure @@ -173,7 +176,6 @@ void rtc_sleep_get_default_config(uint32_t sleep_flags, rtc_sleep_config_t *out_ void rtc_sleep_init(rtc_sleep_config_t cfg) { if (cfg.lslp_mem_inf_fpu) { - rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1); rtc_sleep_pu(pu_cfg); } /* mem force pu */ @@ -364,7 +366,6 @@ static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu) /* restore config if it is a light sleep */ if (lslp_mem_inf_fpu) { - rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1); rtc_sleep_pu(pu_cfg); } return reject; diff --git a/components/esp_hw_support/port/esp32s3/rtc_sleep.c b/components/esp_hw_support/port/esp32s3/rtc_sleep.c index cfa52baf96..96831a90e7 100644 --- a/components/esp_hw_support/port/esp32s3/rtc_sleep.c +++ b/components/esp_hw_support/port/esp32s3/rtc_sleep.c @@ -13,6 +13,7 @@ // limitations under the License. #include +#include "esp_attr.h" #include "soc/soc.h" #include "soc/rtc.h" #include "soc/rtc_cntl_reg.h" @@ -27,6 +28,8 @@ #include "soc/rtc.h" #include "regi2c_ctrl.h" +static const DRAM_ATTR rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1); + /** * Configure whether certain peripherals are powered up in sleep * @param cfg power down flags as rtc_sleep_pu_config_t structure @@ -111,7 +114,6 @@ void rtc_sleep_get_default_config(uint32_t sleep_flags, rtc_sleep_config_t *out_ void rtc_sleep_init(rtc_sleep_config_t cfg) { if (cfg.lslp_mem_inf_fpu) { - rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1); rtc_sleep_pu(pu_cfg); } @@ -220,7 +222,6 @@ __attribute__((weak)) uint32_t rtc_sleep_start(uint32_t wakeup_opt, uint32_t rej /* restore config if it is a light sleep */ if (lslp_mem_inf_fpu) { - rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1); rtc_sleep_pu(pu_cfg); } return reject;