mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-30 02:37:19 +02:00
Merge branch 'bugfix/fix_cache_data_mem_corrupt_after_sleep_v4.3' into 'release/v4.3'
fix(lightsleep): Suspend cache before goto sleep to avoid cache load wrong data (backport v4.3) See merge request espressif/esp-idf!25106
This commit is contained in:
@ -14,6 +14,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#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;
|
||||
|
@ -13,6 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include <stdint.h>
|
||||
#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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
*
|
||||
|
Reference in New Issue
Block a user