Skip to content

Commit

Permalink
Merge branch 'bugfix/fix_systick_lost_in_esp32_dfs_v5.1' into 'releas…
Browse files Browse the repository at this point in the history
…e/v5.1'

fix(esp_pm): safely check ccompare validity in DFS update_ccompare (v5.1)

See merge request espressif/esp-idf!28562
  • Loading branch information
jack0c committed Jan 19, 2024
2 parents 6824abb + ad9a195 commit e1b2579
Showing 1 changed file with 10 additions and 5 deletions.
15 changes: 10 additions & 5 deletions components/esp_pm/pm_impl.c
Expand Up @@ -56,10 +56,13 @@
*/
#define CCOMPARE_UPDATE_TIMEOUT 1000000

/* When changing CCOMPARE, don't allow changes if the difference is less
* than this. This is to prevent setting CCOMPARE below CCOUNT.
/* The number of CPU cycles required from obtaining the base ccount to configuring
the calculated ccompare value. (In order to avoid ccompare being updated to a value
smaller than the current ccount, this update should be discarded if the next tick
is too close to this moment, and this value is used to calculate the threshold for
determining whether or not a skip is required.)
*/
#define CCOMPARE_MIN_CYCLES_IN_FUTURE 1000
#define CCOMPARE_PREPARE_CYCLES_IN_FREQ_UPDATE 60
#endif // CONFIG_FREERTOS_SYSTICK_USES_CCOUNT

/* When light sleep is used, wake this number of microseconds earlier than
Expand Down Expand Up @@ -662,15 +665,17 @@ static void IRAM_ATTR do_switch(pm_mode_t new_mode)
* would happen without the frequency change.
* Assumes that the new_frequency = old_frequency * s_ccount_mul / s_ccount_div.
*/
static void IRAM_ATTR update_ccompare(void)
static __attribute__((optimize("-O2"))) void IRAM_ATTR update_ccompare(void)
{
uint32_t ccompare_min_cycles_in_future = ((s_ccount_div + s_ccount_mul - 1) / s_ccount_mul) * CCOMPARE_PREPARE_CYCLES_IN_FREQ_UPDATE;
#if CONFIG_PM_UPDATE_CCOMPARE_HLI_WORKAROUND
/* disable level 4 and below */
uint32_t irq_status = XTOS_SET_INTLEVEL(XCHAL_DEBUGLEVEL - 2);
#endif
uint32_t ccount = esp_cpu_get_cycle_count();
uint32_t ccompare = XTHAL_GET_CCOMPARE(XT_TIMER_INDEX);
if ((ccompare - CCOMPARE_MIN_CYCLES_IN_FUTURE) - ccount < UINT32_MAX / 2) {

if ((ccompare - ccompare_min_cycles_in_future) - ccount < UINT32_MAX / 2) {
uint32_t diff = ccompare - ccount;
uint32_t diff_scaled = (diff * s_ccount_mul + s_ccount_div - 1) / s_ccount_div;
if (diff_scaled < _xt_tick_divisor) {
Expand Down

0 comments on commit e1b2579

Please sign in to comment.