feat: support cache safe assertion check

- Add support for cache safe assertion check to ensure that code expected to be in RAM is in IRAM
This commit is contained in:
wuzhenghui 2023-06-28 13:34:52 +08:00
parent ec82d1489e
commit b9550a1609
2 changed files with 57 additions and 0 deletions

View File

@ -155,6 +155,16 @@ menu "Hardware Settings"
If you are seeing "flash read err, 1000" message printed to the
console after deep sleep reset, try increasing this value.
config ESP_SLEEP_CACHE_SAFE_ASSERTION
bool "Check the cache safety of the sleep wakeup code in sleep process"
default n
help
Enabling it will check the cache safety of the code before the flash power is ready after
light sleep wakeup, and check PM_SLP_IRAM_OPT related code cache safety. This option is
only for code quality inspection. Enabling it will increase the time overhead of entering
and exiting sleep. It is not recommended to enable it in the release version.
endmenu
menu "ESP_SLEEP_WORKAROUND"

View File

@ -399,6 +399,26 @@ void esp_deep_sleep_deregister_hook(esp_deep_sleep_cb_t old_dslp_cb)
portEXIT_CRITICAL(&spinlock_rtc_deep_sleep);
}
#if (CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND) \
|| CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION
static int s_cache_suspend_cnt = 0;
static void IRAM_ATTR suspend_cache(void) {
s_cache_suspend_cnt++;
if (s_cache_suspend_cnt == 1) {
cache_hal_suspend(CACHE_TYPE_ALL);
}
}
static void IRAM_ATTR resume_cache(void) {
s_cache_suspend_cnt--;
assert(s_cache_suspend_cnt >= 0 && "cache resume doesn't match suspend ops");
if (s_cache_suspend_cnt == 0) {
cache_hal_resume(CACHE_TYPE_ALL);
}
}
#endif
// [refactor-todo] provide target logic for body of uart functions below
static void IRAM_ATTR flush_uarts(void)
{
@ -753,6 +773,14 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
#endif
}
#if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION
if (pd_flags & RTC_SLEEP_PD_VDDSDIO) {
/* Cache Suspend 2: If previous sleep powerdowned the flash, suspend cache here so that the
access to flash before flash ready can be explicitly exposed. */
suspend_cache();
}
#endif
#if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND
if (!(pd_flags & RTC_SLEEP_PD_XTAL)) {
rtc_sleep_systimer_enable(true);
@ -897,6 +925,13 @@ static esp_err_t esp_light_sleep_inner(uint32_t pd_flags,
esp_rom_delay_us(flash_enable_time_us);
}
#if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION
if (pd_flags & RTC_SLEEP_PD_VDDSDIO) {
/* Cache Resume 2: flash is ready now, we can resume the cache and access flash safely after */
resume_cache();
}
#endif
return reject;
}
@ -961,6 +996,12 @@ esp_err_t esp_light_sleep_start(void)
esp_ipc_isr_stall_other_cpu();
#if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION && CONFIG_PM_SLP_IRAM_OPT
/* Cache Suspend 0: if CONFIG_PM_SLP_IRAM_OPT is enabled, suspend cache here so that the access to flash
during the sleep process can be explicitly exposed. */
suspend_cache();
#endif
// Decide which power domains can be powered down
uint32_t pd_flags = get_power_down_flags();
@ -1113,6 +1154,12 @@ esp_err_t esp_light_sleep_start(void)
esp_clk_private_unlock();
esp_timer_private_unlock();
#if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION && CONFIG_PM_SLP_IRAM_OPT
/* Cache Resume 0: sleep process done, resume cache for continue running */
resume_cache();
#endif
esp_ipc_isr_release_other_cpu();
if (!wdt_was_enabled) {
wdt_hal_write_protect_disable(&rtc_wdt_ctx);