This commit implements a workaround that allows ESP32-C5 to run at 240MHz CPU frequency
normally, while automatically reducing CPU frequency during encrypted flash writes to
ensure correct operation. The frequency limit is chip revision dependent:
- v1.2 and above: limited to 160MHz during encrypted writes
- v1.0 and below: limited to 80MHz during encrypted writes
Key implementation details:
- Frequency limiting is triggered automatically when esp_flash_write_encrypted() is called
- Uses start() flags (ESP_FLASH_START_FLAG_LIMIT_CPU_FREQ) to integrate with OS layer
- Works with both PM enabled and disabled configurations
- Frequency is automatically restored after encrypted write completes
- For ESP32-C5 with 120MHz flash, Flash clock and timing registers are adjusted when
CPU frequency is reduced to 80MHz
- SPI1 timing registers are configured during frequency switching since encrypted writes
use SPI1 and must work correctly at reduced CPU frequencies
Code improvements:
- Use SOC_MSPI_FREQ_AXI_CONSTRAINED capability macro instead of hardcoded chip checks
- Control workaround via Kconfig (CONFIG_PM_WORKAROUND_FREQ_LIMIT_ENABLED) instead of
hardcoded macros
- Add comprehensive test cases covering various PM configurations and edge cases
This workaround enables ESP32-C5 applications to benefit from 240MHz CPU performance
while maintaining reliable encrypted flash write functionality.
The issue is `esp_flash_write_encryped` function in ROM on ESP32C3, ESP32S3
calls legacy implementation, which uses old configuration. And this causes
write fails.
The solution in this commit is to compile and link this function(and related)
in IRAM instead of the ROM one.
The IRAM cost increases around 1.2KB after the fix
Prior to this change, `spi_flash_hal_supports_direct_write` and
`spi_flash_hal_supports_direct_read` will check the buffer pointer
place, which should be done in driver layer, instead of HAL layer.
esp_timer:
Control flow issues (DEADCODE)
Execution cannot reach this statement: "break;".
protocomm_httpd:
(UNUSED_VALUE)
Assigning value from "cookie_session_id" to "cur_cookie_session_id" here, but that stored value is overwritten before it can be used.
esp_flash_api:
Null pointer dereferences (REVERSE_INULL)
Null-checking "chip" suggests that it may be null, but it has already been dereferenced on all paths leading to the check.
There is a periodically yield in the esp_flash driver, to ensure the
cache will not be disabled for too long on ESP32.
On ESP32-S2 and later, we need to support more different kind of yield:
1. polling conditions, including timeout, SW read request, etc.
2. wait for events, including HW done/error/auto-suspend, timeout
semaphore, etc.
The check_yield() and yield() is separated into two parts, because we
may need to insert suspend, etc. between them.