From 5ea148a80c2aa4817063e6f476524037570e0df5 Mon Sep 17 00:00:00 2001 From: "C.S.M" Date: Thu, 27 Feb 2025 15:20:20 +0800 Subject: [PATCH 1/3] fix(spi_flash): Fix flash encryption write verify, Closes https://github.com/espressif/esp-idf/issues/15380 --- components/spi_flash/Kconfig | 2 ++ components/spi_flash/esp_flash_api.c | 20 +++++++++++++++++++ .../pytest_flash_encrypted.py | 2 ++ 3 files changed, 24 insertions(+) diff --git a/components/spi_flash/Kconfig b/components/spi_flash/Kconfig index e3011eb8f7..0fc846e61d 100644 --- a/components/spi_flash/Kconfig +++ b/components/spi_flash/Kconfig @@ -169,6 +169,8 @@ menu "SPI Flash driver" back and verified. This can catch hardware problems with SPI flash, or flash which was not erased before verification. + This will slightly influence the write performance. + config SPI_FLASH_LOG_FAILED_WRITE bool "Log errors if verification fails" depends on SPI_FLASH_VERIFY_WRITE diff --git a/components/spi_flash/esp_flash_api.c b/components/spi_flash/esp_flash_api.c index a4cb822718..13c97f2a21 100644 --- a/components/spi_flash/esp_flash_api.c +++ b/components/spi_flash/esp_flash_api.c @@ -1378,11 +1378,31 @@ esp_err_t IRAM_ATTR esp_flash_write_encrypted(esp_flash_t *chip, uint32_t addres COUNTER_ADD_BYTES(write, encrypt_byte); #if CONFIG_SPI_FLASH_VERIFY_WRITE + + if (lock_once == true) { + err = s_encryption_write_unlock(chip); + if (err != ESP_OK) { + bus_acquired = false; + //Error happens, we end flash operation. Re-enable cache and flush it + goto restore_cache; + } + bus_acquired = false; + } err = s_verify_write(chip, row_addr, encrypt_byte, (uint32_t *)encrypt_buf, is_encrypted); if (err != ESP_OK) { //Error happens, we end flash operation. Re-enable cache and flush it goto restore_cache; } + + if (lock_once == true) { + err = s_encryption_write_lock(chip); + if (err != ESP_OK) { + bus_acquired = false; + //Error happens, we end flash operation. Re-enable cache and flush it + goto restore_cache; + } + bus_acquired = true; + } #endif //CONFIG_SPI_FLASH_VERIFY_WRITE } diff --git a/components/spi_flash/test_apps/flash_encryption/pytest_flash_encrypted.py b/components/spi_flash/test_apps/flash_encryption/pytest_flash_encrypted.py index 572231288d..58112e1432 100644 --- a/components/spi_flash/test_apps/flash_encryption/pytest_flash_encrypted.py +++ b/components/spi_flash/test_apps/flash_encryption/pytest_flash_encrypted.py @@ -11,6 +11,7 @@ from pytest_embedded import Dut 'config', [ 'release', + 'verify', ], indirect=True, ) @@ -38,6 +39,7 @@ def test_flash_encryption_rom_impl(dut: Dut) -> None: [ 'release_f4r8', 'rom_impl', + 'verify', ], indirect=True, ) From 04a0c758e73130451e509a045db2d3e882893035 Mon Sep 17 00:00:00 2001 From: "C.S.M" Date: Fri, 7 Mar 2025 11:18:39 +0800 Subject: [PATCH 2/3] fix(spi_flash): Return false directly in suspend caps check --- components/spi_flash/esp_flash_api.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/components/spi_flash/esp_flash_api.c b/components/spi_flash/esp_flash_api.c index 13c97f2a21..e7582d0d83 100644 --- a/components/spi_flash/esp_flash_api.c +++ b/components/spi_flash/esp_flash_api.c @@ -1442,10 +1442,12 @@ esp_err_t esp_flash_suspend_cmd_init(esp_flash_t* chip) ESP_EARLY_LOGW(TAG, "Flash suspend feature is enabled"); if (chip->chip_drv->get_chip_caps == NULL) { // chip caps get failed, pass the flash capability check. - ESP_EARLY_LOGW(TAG, "get_chip_caps function pointer hasn't been initialized"); + ESP_EARLY_LOGE(TAG, "get_chip_caps function pointer hasn't been initialized"); + return ESP_ERR_INVALID_ARG; } else { if ((chip->chip_drv->get_chip_caps(chip) & SPI_FLASH_CHIP_CAP_SUSPEND) == 0) { - ESP_EARLY_LOGW(TAG, "Suspend and resume may not supported for this flash model yet."); + ESP_EARLY_LOGE(TAG, "Suspend and resume may not supported for this flash model yet."); + return ESP_ERR_NOT_SUPPORTED; } } return chip->chip_drv->sus_setup(chip); From 9282eec54111e00c509dab76c5512e24b516e6f7 Mon Sep 17 00:00:00 2001 From: "C.S.M" Date: Fri, 7 Mar 2025 14:55:11 +0800 Subject: [PATCH 3/3] fix(spi_flash): Add suspend check on esp32c6 and esp32h2 for some reason --- components/spi_flash/Kconfig | 11 +++++++++++ components/spi_flash/esp_flash_api.c | 16 ++++++++++++++++ .../sdkconfig.ci.esp32c3_suspend | 1 + .../test_apps/flash_suspend/sdkconfig.defaults | 3 ++- .../flash_suspend/sdkconfig.ci.flash_suspend | 1 + 5 files changed, 31 insertions(+), 1 deletion(-) diff --git a/components/spi_flash/Kconfig b/components/spi_flash/Kconfig index 0fc846e61d..21c59b4b54 100644 --- a/components/spi_flash/Kconfig +++ b/components/spi_flash/Kconfig @@ -120,6 +120,17 @@ menu "Main Flash configuration" For new users, DO NOT enable this config. + config SPI_FLASH_FORCE_ENABLE_C6_H2_SUSPEND + bool "Enable chip suspend feature on c6 or h2 anyway (DO NOT ENABLE FOR NEW USERS OR APPLICATIONS)" + default n + help + Flash suspend has defect on ESP32C6 until v0.2 and ESP32H2 until v1.2. If you already use suspend + feature for massive protection, you can enable this for bypassing check after knowing the risk. + But if you are new users, or developing new applications, or producing a new batch, + please DO NOT enable this config option. + + For more information, please refer to errata or connect to Espressif business support team. + config SPI_FLASH_SOFTWARE_RESUME bool "Resume flash program/erase form suspend state by software control" default n diff --git a/components/spi_flash/esp_flash_api.c b/components/spi_flash/esp_flash_api.c index e7582d0d83..c6fa0e3cbe 100644 --- a/components/spi_flash/esp_flash_api.c +++ b/components/spi_flash/esp_flash_api.c @@ -22,6 +22,8 @@ #include "esp_private/esp_clk.h" #include "esp_spi_flash_counters.h" #include "esp_check.h" +#include "hal/efuse_hal.h" +#include "soc/chip_revision.h" #if CONFIG_IDF_TARGET_ESP32S2 #include "esp_crypto_lock.h" // for locking flash encryption peripheral @@ -1439,6 +1441,20 @@ restore_cache: //init suspend mode cmd, uses internal. esp_err_t esp_flash_suspend_cmd_init(esp_flash_t* chip) { +#if !CONFIG_SPI_FLASH_FORCE_ENABLE_C6_H2_SUSPEND +#if CONFIG_IDF_TARGET_ESP32H2 + if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 102)) { + ESP_LOGE(TAG, "ESP32H2 chips lower than v1.2 are not recommended to suspend the Flash"); + return ESP_ERR_NOT_SUPPORTED; + } +#endif +#if CONFIG_IDF_TARGET_ESP32C6 + if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 2)) { + ESP_LOGE(TAG, "ESP32C6 chips lower than v0.2 are not recommended to suspend the Flash"); + return ESP_ERR_NOT_SUPPORTED; + } +#endif +#endif ESP_EARLY_LOGW(TAG, "Flash suspend feature is enabled"); if (chip->chip_drv->get_chip_caps == NULL) { // chip caps get failed, pass the flash capability check. diff --git a/components/spi_flash/test_apps/esp_flash_stress/sdkconfig.ci.esp32c3_suspend b/components/spi_flash/test_apps/esp_flash_stress/sdkconfig.ci.esp32c3_suspend index 0addf025a2..60f9b137c9 100644 --- a/components/spi_flash/test_apps/esp_flash_stress/sdkconfig.ci.esp32c3_suspend +++ b/components/spi_flash/test_apps/esp_flash_stress/sdkconfig.ci.esp32c3_suspend @@ -2,3 +2,4 @@ CONFIG_IDF_TARGET="esp32c3" CONFIG_SPI_FLASH_AUTO_SUSPEND=y +CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND=y diff --git a/components/spi_flash/test_apps/flash_suspend/sdkconfig.defaults b/components/spi_flash/test_apps/flash_suspend/sdkconfig.defaults index cdb818d6f9..223b872891 100644 --- a/components/spi_flash/test_apps/flash_suspend/sdkconfig.defaults +++ b/components/spi_flash/test_apps/flash_suspend/sdkconfig.defaults @@ -1,4 +1,5 @@ -CONFIG_ESP_TASK_WDT=n +CONFIG_ESP_TASK_WDT_INIT=n CONFIG_SPI_FLASH_AUTO_SUSPEND=y CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND=y diff --git a/examples/system/flash_suspend/sdkconfig.ci.flash_suspend b/examples/system/flash_suspend/sdkconfig.ci.flash_suspend index 8c84ea2be2..5d2e7c157f 100644 --- a/examples/system/flash_suspend/sdkconfig.ci.flash_suspend +++ b/examples/system/flash_suspend/sdkconfig.ci.flash_suspend @@ -2,3 +2,4 @@ CONFIG_SPI_FLASH_AUTO_SUSPEND=y CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" +CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND=y