From 44dd14dde44ba49f74094afa61c71b58aedd5d7f Mon Sep 17 00:00:00 2001 From: gaoxu Date: Tue, 13 Sep 2022 10:26:59 +0800 Subject: [PATCH 1/4] support SPI_FLASH_VERIFY_WRITE feature on esp_flash driver and add config to test it --- components/spi_flash/esp_flash_api.c | 44 ++++++++++++++++++- .../esp_flash/main/test_esp_flash_drv.c | 1 + .../test_apps/esp_flash/sdkconfig.ci.verify | 4 ++ 3 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 components/spi_flash/test_apps/esp_flash/sdkconfig.ci.verify diff --git a/components/spi_flash/esp_flash_api.c b/components/spi_flash/esp_flash_api.c index 1ade196b5b9..09248e0d656 100644 --- a/components/spi_flash/esp_flash_api.c +++ b/components/spi_flash/esp_flash_api.c @@ -849,6 +849,10 @@ esp_err_t IRAM_ATTR esp_flash_read(esp_flash_t *chip, void *buffer, uint32_t add esp_err_t IRAM_ATTR esp_flash_write(esp_flash_t *chip, const void *buffer, uint32_t address, uint32_t length) { +#if CONFIG_SPI_FLASH_VERIFY_WRITE + const uint32_t *except_buf = buffer; +#endif //CONFIG_SPI_FLASH_VERIFY_WRITE + esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip); VERIFY_CHIP_OP(write); CHECK_WRITE_ADDRESS(chip, address, length); @@ -924,11 +928,31 @@ esp_err_t IRAM_ATTR esp_flash_write(esp_flash_t *chip, const void *buffer, uint3 buffer = (void *)((intptr_t)buffer + write_len); } - return rom_spiflash_api_funcs->flash_end_flush_cache(chip, err, bus_acquired, address, length); + err = rom_spiflash_api_funcs->flash_end_flush_cache(chip, err, bus_acquired, address, length); + +#if CONFIG_SPI_FLASH_VERIFY_WRITE + uint32_t *actual_buf = malloc(length);; + esp_flash_read(chip, actual_buf, address, length); + + for (int r = 0; r < length / sizeof(uint32_t); r++) { + if (actual_buf[r] != except_buf[r]) { + ESP_LOGE(TAG, "Bad write at %d offset: 0x%x, expected: 0x%08x, readback: 0x%08x",r, address + r, except_buf[r], actual_buf[r]); + err = ESP_FAIL; + } + } + + free(actual_buf); +#endif //CONFIG_SPI_FLASH_VERIFY_WRITE + + return err; } esp_err_t IRAM_ATTR esp_flash_write_encrypted(esp_flash_t *chip, uint32_t address, const void *buffer, uint32_t length) { +#if CONFIG_SPI_FLASH_VERIFY_WRITE + const uint32_t *except_buf = buffer; +#endif //CONFIG_SPI_FLASH_VERIFY_WRITE + esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip); // Flash encryption only support on main flash. if (chip != esp_flash_default_chip) { @@ -1046,7 +1070,23 @@ esp_err_t IRAM_ATTR esp_flash_write_encrypted(esp_flash_t *chip, uint32_t addres } bus_acquired = false; } - return rom_spiflash_api_funcs->flash_end_flush_cache(chip, err, bus_acquired, address, length); + err = rom_spiflash_api_funcs->flash_end_flush_cache(chip, err, bus_acquired, address, length); + +#if CONFIG_SPI_FLASH_VERIFY_WRITE + uint32_t *actual_buf = malloc(length);; + esp_flash_read(chip, actual_buf, address, length); + + for (int r = 0; r < length / sizeof(uint32_t); r++) { + if (actual_buf[r] != except_buf[r]) { + ESP_LOGE(TAG, "Bad write at %d offset: 0x%x, expected: 0x%08x, readback: 0x%08x",r, address + r, except_buf[r], actual_buf[r]); + err = ESP_FAIL; + } + } + + free(actual_buf); +#endif //CONFIG_SPI_FLASH_VERIFY_WRITE + + return err; } inline static IRAM_ATTR bool regions_overlap(uint32_t a_start, uint32_t a_len,uint32_t b_start, uint32_t b_len) diff --git a/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_drv.c b/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_drv.c index e563cd326c1..231615f5640 100644 --- a/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_drv.c +++ b/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_drv.c @@ -411,6 +411,7 @@ TEST_CASE_MULTI_FLASH("SPI flash three byte reads/writes", test_three_byte_read_ void test_erase_large_region(const esp_partition_t *part) { esp_flash_t* chip = part->flash_chip; + erase_test_region(part, 2); /* Write some noise at the start and the end of the region */ const char *ohai = "OHAI"; diff --git a/components/spi_flash/test_apps/esp_flash/sdkconfig.ci.verify b/components/spi_flash/test_apps/esp_flash/sdkconfig.ci.verify new file mode 100644 index 00000000000..f7ae153c3f3 --- /dev/null +++ b/components/spi_flash/test_apps/esp_flash/sdkconfig.ci.verify @@ -0,0 +1,4 @@ +CONFIG_ESP_TASK_WDT=n +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_SPI_FLASH_VERIFY_WRITE=y From 110853517a6197c71c5492134a81dd835fc882a5 Mon Sep 17 00:00:00 2001 From: Armando Date: Thu, 2 Mar 2023 16:10:02 +0800 Subject: [PATCH 2/4] spi_flash: support write verify feature on esp_flash_write API --- components/spi_flash/Kconfig | 1 + components/spi_flash/esp_flash_api.c | 133 +++++++++++++++--- components/spi_flash/include/esp_flash.h | 1 + .../test_apps/esp_flash/pytest_esp_flash.py | 1 + .../esp_flash/sdkconfig.ci.flash_qio | 2 - .../test_apps/esp_flash/sdkconfig.ci.release | 2 - .../test_apps/esp_flash/sdkconfig.ci.rom_impl | 2 - .../test_apps/esp_flash/sdkconfig.ci.verify | 4 +- 8 files changed, 119 insertions(+), 27 deletions(-) diff --git a/components/spi_flash/Kconfig b/components/spi_flash/Kconfig index f3f88ce8f54..0560ed937e1 100644 --- a/components/spi_flash/Kconfig +++ b/components/spi_flash/Kconfig @@ -3,6 +3,7 @@ menu "SPI Flash driver" config SPI_FLASH_VERIFY_WRITE bool "Verify SPI flash writes" + depends on !SPI_FLASH_ROM_IMPL default n help If this option is enabled, any time SPI flash is written then the data will be read diff --git a/components/spi_flash/esp_flash_api.c b/components/spi_flash/esp_flash_api.c index 09248e0d656..9bb8a2c9904 100644 --- a/components/spi_flash/esp_flash_api.c +++ b/components/spi_flash/esp_flash_api.c @@ -23,7 +23,7 @@ #include "esp_crypto_lock.h" // for locking flash encryption peripheral #endif //CONFIG_IDF_TARGET_ESP32S2 -static const char TAG[] = "spi_flash"; +DRAM_ATTR static const char TAG[] = "spi_flash"; #ifdef CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE #define MAX_WRITE_CHUNK CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE /* write in chunks */ @@ -32,6 +32,7 @@ static const char TAG[] = "spi_flash"; #endif // CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE #define MAX_READ_CHUNK 16384 +#define VERIFY_BUF_LEN 64 #ifdef CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS @@ -847,10 +848,89 @@ esp_err_t IRAM_ATTR esp_flash_read(esp_flash_t *chip, void *buffer, uint32_t add return err; } +#if CONFIG_SPI_FLASH_WARN_SETTING_ZERO_TO_ONE +static esp_err_t IRAM_ATTR s_check_setting_zero_to_one(esp_flash_t *chip, uint32_t verify_address, uint32_t remain_verify_len, const uint32_t *to_write_buf, bool is_encrypted) +{ + esp_err_t err = ESP_FAIL; + uint8_t verify_buffer[VERIFY_BUF_LEN]; + uint32_t *val_in_flash = (uint32_t *)verify_buffer; + + while (remain_verify_len) { + uint32_t this_len = MIN(remain_verify_len, VERIFY_BUF_LEN); + + err = chip->chip_drv->read(chip, verify_buffer, verify_address, this_len); + if (err != ESP_OK) { + ESP_DRAM_LOGE(TAG, "failed to read flash to verify if setting zero to one, err: 0x%x", err); + return err; + } + + for (int r = 0; r < this_len / sizeof(uint32_t); r++) { + if (is_encrypted) { + (void)to_write_buf; + if (val_in_flash[r] != 0xFFFFFFFF) { + ESP_DRAM_LOGW(TAG, "Write at offset 0x%x but not erased (0x%08x)", + verify_address + r, val_in_flash[r]); + } + } else { + if ((val_in_flash[r] & to_write_buf[r]) != to_write_buf[r]) { + ESP_DRAM_LOGW(TAG, "Write at offset 0x%x requests 0x%08x but will write 0x%08x -> 0x%08x", + verify_address + r, to_write_buf[r], val_in_flash[r], (val_in_flash[r] & to_write_buf[r])); + } + } + } + + remain_verify_len -= this_len; + verify_address += this_len; + } + + return ESP_OK; +} +#endif //#if CONFIG_SPI_FLASH_WARN_SETTING_ZERO_TO_ONE + +#if CONFIG_SPI_FLASH_VERIFY_WRITE +static esp_err_t IRAM_ATTR s_verify_write(esp_flash_t *chip, uint32_t verify_address, uint32_t remain_verify_len, const uint32_t *expected_buf, bool is_encrypted) +{ + esp_err_t err = ESP_FAIL; + uint8_t verify_buffer[VERIFY_BUF_LEN]; + uint32_t *val_in_flash = (uint32_t *)verify_buffer; + + while (remain_verify_len) { + uint32_t this_len = MIN(remain_verify_len, VERIFY_BUF_LEN); + + if (is_encrypted) { + err = esp_flash_read_encrypted(chip, verify_address, verify_buffer, this_len); + } else { + err = chip->chip_drv->read(chip, verify_buffer, verify_address, this_len); + } + if (err != ESP_OK) { + ESP_DRAM_LOGE(TAG, "failed to read flash to verify previous write, err: 0x%x", err); + return err; + } + + for (int r = 0; r < this_len / sizeof(uint32_t); r++) { + if (val_in_flash[r] != expected_buf[r]) { +#if CONFIG_SPI_FLASH_LOG_FAILED_WRITE + ESP_DRAM_LOGE(TAG, "Bad write at %d offset: 0x%x, expected: 0x%08x, readback: 0x%08x", r, verify_address + r, expected_buf[r], val_in_flash[r]); +#endif //#if CONFIG_SPI_FLASH_LOG_FAILED_WRITE + return ESP_FAIL; + } + } + + expected_buf = (uint32_t *)((void *)expected_buf + this_len); + remain_verify_len -= this_len; + verify_address += this_len; + } + + return ESP_OK; +} +#endif //#if CONFIG_SPI_FLASH_VERIFY_WRITE + esp_err_t IRAM_ATTR esp_flash_write(esp_flash_t *chip, const void *buffer, uint32_t address, uint32_t length) { + esp_err_t ret = ESP_FAIL; #if CONFIG_SPI_FLASH_VERIFY_WRITE - const uint32_t *except_buf = buffer; + //used for verify write + bool is_encrypted = false; #endif //CONFIG_SPI_FLASH_VERIFY_WRITE esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip); @@ -902,25 +982,45 @@ esp_err_t IRAM_ATTR esp_flash_write(esp_flash_t *chip, const void *buffer, uint3 err = rom_spiflash_api_funcs->start(chip); if (err != ESP_OK) { - break; + goto restore_cache; } bus_acquired = true; +#if CONFIG_SPI_FLASH_WARN_SETTING_ZERO_TO_ONE + err = s_check_setting_zero_to_one(chip, write_addr, write_len, write_buf, is_encrypted); + if (err != ESP_OK) { + //Error happens, we end flash operation. Re-enable cache and flush it + goto restore_cache; + } +#endif //#if CONFIG_SPI_FLASH_WARN_SETTING_ZERO_TO_ONE + err = chip->chip_drv->write(chip, write_buf, write_addr, write_len); len_remain -= write_len; assert(len_remain < length); - if (err != ESP_OK || len_remain == 0) { - // On ESP32, the cache re-enable is in the end() function, while flush_cache should - // happen when the cache is still disabled on ESP32. Break before the end() function and - // do end() later + if (err != ESP_OK) { + //Error happens, we end flash operation. Re-enable cache and flush it assert(bus_acquired); + goto restore_cache; + } + +#if CONFIG_SPI_FLASH_VERIFY_WRITE + err = s_verify_write(chip, write_addr, write_len, write_buf, is_encrypted); + if (err != ESP_OK) { + //Error happens, we end flash operation. Re-enable cache and flush it + goto restore_cache; + } +#endif //#if CONFIG_SPI_FLASH_VERIFY_WRITE + + + if (len_remain == 0) { + //Flash operation done break; } err = rom_spiflash_api_funcs->end(chip, err); if (err != ESP_OK) { - break; + goto restore_cache; } bus_acquired = false; @@ -930,19 +1030,14 @@ esp_err_t IRAM_ATTR esp_flash_write(esp_flash_t *chip, const void *buffer, uint3 err = rom_spiflash_api_funcs->flash_end_flush_cache(chip, err, bus_acquired, address, length); -#if CONFIG_SPI_FLASH_VERIFY_WRITE - uint32_t *actual_buf = malloc(length);; - esp_flash_read(chip, actual_buf, address, length); + return err; - for (int r = 0; r < length / sizeof(uint32_t); r++) { - if (actual_buf[r] != except_buf[r]) { - ESP_LOGE(TAG, "Bad write at %d offset: 0x%x, expected: 0x%08x, readback: 0x%08x",r, address + r, except_buf[r], actual_buf[r]); - err = ESP_FAIL; - } - } +restore_cache: - free(actual_buf); -#endif //CONFIG_SPI_FLASH_VERIFY_WRITE + ret = rom_spiflash_api_funcs->flash_end_flush_cache(chip, err, bus_acquired, address, length); + if (ret != ESP_OK) { + ESP_DRAM_LOGE(TAG, "restore cache fail\n"); + } return err; } diff --git a/components/spi_flash/include/esp_flash.h b/components/spi_flash/include/esp_flash.h index 634a6c47839..8a893e17cd6 100644 --- a/components/spi_flash/include/esp_flash.h +++ b/components/spi_flash/include/esp_flash.h @@ -317,6 +317,7 @@ esp_err_t esp_flash_read(esp_flash_t *chip, void *buffer, uint32_t address, uint * * @return * - ESP_OK on success, + * - ESP_FAIL, bad write, this will be detected only when CONFIG_SPI_FLASH_VERIFY_WRITE is enabled * - ESP_ERR_NOT_SUPPORTED if the chip is not able to perform the operation. This is indicated by WREN = 1 after the command is sent. * - Other flash error code if operation failed. */ diff --git a/components/spi_flash/test_apps/esp_flash/pytest_esp_flash.py b/components/spi_flash/test_apps/esp_flash/pytest_esp_flash.py index 5b3836f2afa..179b424b56c 100644 --- a/components/spi_flash/test_apps/esp_flash/pytest_esp_flash.py +++ b/components/spi_flash/test_apps/esp_flash/pytest_esp_flash.py @@ -16,6 +16,7 @@ [ 'release', 'flash_qio', + 'verify' ], indirect=True, ) diff --git a/components/spi_flash/test_apps/esp_flash/sdkconfig.ci.flash_qio b/components/spi_flash/test_apps/esp_flash/sdkconfig.ci.flash_qio index 45ef9b60976..9e24ff5cf40 100644 --- a/components/spi_flash/test_apps/esp_flash/sdkconfig.ci.flash_qio +++ b/components/spi_flash/test_apps/esp_flash/sdkconfig.ci.flash_qio @@ -1,4 +1,2 @@ CONFIG_ESP_TASK_WDT_EN=n -CONFIG_PARTITION_TABLE_CUSTOM=y -CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" CONFIG_ESPTOOLPY_FLASHMODE_QIO=y diff --git a/components/spi_flash/test_apps/esp_flash/sdkconfig.ci.release b/components/spi_flash/test_apps/esp_flash/sdkconfig.ci.release index ceab55e4bbf..7eb62a28529 100644 --- a/components/spi_flash/test_apps/esp_flash/sdkconfig.ci.release +++ b/components/spi_flash/test_apps/esp_flash/sdkconfig.ci.release @@ -3,5 +3,3 @@ CONFIG_FREERTOS_USE_TICKLESS_IDLE=y CONFIG_COMPILER_OPTIMIZATION_SIZE=y CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y -CONFIG_PARTITION_TABLE_CUSTOM=y -CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" diff --git a/components/spi_flash/test_apps/esp_flash/sdkconfig.ci.rom_impl b/components/spi_flash/test_apps/esp_flash/sdkconfig.ci.rom_impl index 1ad7ae28f9d..d878b890f7f 100644 --- a/components/spi_flash/test_apps/esp_flash/sdkconfig.ci.rom_impl +++ b/components/spi_flash/test_apps/esp_flash/sdkconfig.ci.rom_impl @@ -1,4 +1,2 @@ CONFIG_ESP_TASK_WDT_EN=n -CONFIG_PARTITION_TABLE_CUSTOM=y -CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" CONFIG_SPI_FLASH_ROM_IMPL=y diff --git a/components/spi_flash/test_apps/esp_flash/sdkconfig.ci.verify b/components/spi_flash/test_apps/esp_flash/sdkconfig.ci.verify index f7ae153c3f3..61d3f59eff4 100644 --- a/components/spi_flash/test_apps/esp_flash/sdkconfig.ci.verify +++ b/components/spi_flash/test_apps/esp_flash/sdkconfig.ci.verify @@ -1,4 +1,4 @@ CONFIG_ESP_TASK_WDT=n -CONFIG_PARTITION_TABLE_CUSTOM=y -CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" CONFIG_SPI_FLASH_VERIFY_WRITE=y +CONFIG_SPI_FLASH_LOG_FAILED_WRITE=y +CONFIG_SPI_FLASH_WARN_SETTING_ZERO_TO_ONE=y From d35b6dd8523e7d61969f2559b96f6d5e02fc9ea8 Mon Sep 17 00:00:00 2001 From: Armando Date: Thu, 2 Mar 2023 16:11:54 +0800 Subject: [PATCH 3/4] spi_flash: support write verify feature on esp_flash_write_encrypted API --- components/spi_flash/esp_flash_api.c | 47 +++++++++++++------ components/spi_flash/include/esp_flash.h | 1 + .../flash_encryption/sdkconfig.ci.verify | 19 ++++++++ 3 files changed, 52 insertions(+), 15 deletions(-) create mode 100644 components/spi_flash/test_apps/flash_encryption/sdkconfig.ci.verify diff --git a/components/spi_flash/esp_flash_api.c b/components/spi_flash/esp_flash_api.c index 9bb8a2c9904..e00f946d6bb 100644 --- a/components/spi_flash/esp_flash_api.c +++ b/components/spi_flash/esp_flash_api.c @@ -1044,8 +1044,10 @@ esp_err_t IRAM_ATTR esp_flash_write(esp_flash_t *chip, const void *buffer, uint3 esp_err_t IRAM_ATTR esp_flash_write_encrypted(esp_flash_t *chip, uint32_t address, const void *buffer, uint32_t length) { + esp_err_t ret = ESP_FAIL; #if CONFIG_SPI_FLASH_VERIFY_WRITE - const uint32_t *except_buf = buffer; + //used for verify write + bool is_encrypted = true; #endif //CONFIG_SPI_FLASH_VERIFY_WRITE esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip); @@ -1133,6 +1135,14 @@ esp_err_t IRAM_ATTR esp_flash_write_encrypted(esp_flash_t *chip, uint32_t addres row_size_length = row_size; #endif //CONFIG_IDF_TARGET_ESP32 +#if CONFIG_SPI_FLASH_WARN_SETTING_ZERO_TO_ONE + err = s_check_setting_zero_to_one(chip, row_addr, encrypt_byte, NULL, is_encrypted); + if (err != ESP_OK) { + //Error happens, we end flash operation. Re-enable cache and flush it + goto restore_cache; + } +#endif //#if CONFIG_SPI_FLASH_WARN_SETTING_ZERO_TO_ONE + #if CONFIG_IDF_TARGET_ESP32S2 esp_crypto_dma_lock_acquire(); #endif //CONFIG_IDF_TARGET_ESP32S2 @@ -1142,7 +1152,8 @@ esp_err_t IRAM_ATTR esp_flash_write_encrypted(esp_flash_t *chip, uint32_t addres #if CONFIG_IDF_TARGET_ESP32S2 esp_crypto_dma_lock_release(); #endif //CONFIG_IDF_TARGET_ESP32S2 - break; + //Error happens, we end flash operation. Re-enable cache and flush it + goto restore_cache; } bus_acquired = true; @@ -1153,7 +1164,8 @@ esp_err_t IRAM_ATTR esp_flash_write_encrypted(esp_flash_t *chip, uint32_t addres #endif //CONFIG_IDF_TARGET_ESP32S2 bus_acquired = false; assert(bus_acquired); - break; + //Error happens, we end flash operation. Re-enable cache and flush it + goto restore_cache; } err = rom_spiflash_api_funcs->end(chip, ESP_OK); #if CONFIG_IDF_TARGET_ESP32S2 @@ -1161,25 +1173,30 @@ esp_err_t IRAM_ATTR esp_flash_write_encrypted(esp_flash_t *chip, uint32_t addres #endif //CONFIG_IDF_TARGET_ESP32S2 if (err != ESP_OK) { bus_acquired = false; - break; + //Error happens, we end flash operation. Re-enable cache and flush it + goto restore_cache; } bus_acquired = false; - } - err = rom_spiflash_api_funcs->flash_end_flush_cache(chip, err, bus_acquired, address, length); #if CONFIG_SPI_FLASH_VERIFY_WRITE - uint32_t *actual_buf = malloc(length);; - esp_flash_read(chip, actual_buf, address, length); - - for (int r = 0; r < length / sizeof(uint32_t); r++) { - if (actual_buf[r] != except_buf[r]) { - ESP_LOGE(TAG, "Bad write at %d offset: 0x%x, expected: 0x%08x, readback: 0x%08x",r, address + r, except_buf[r], actual_buf[r]); - err = ESP_FAIL; + 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; } +#endif //CONFIG_SPI_FLASH_VERIFY_WRITE } - free(actual_buf); -#endif //CONFIG_SPI_FLASH_VERIFY_WRITE + err = rom_spiflash_api_funcs->flash_end_flush_cache(chip, err, bus_acquired, address, length); + + return err; + +restore_cache: + + ret = rom_spiflash_api_funcs->flash_end_flush_cache(chip, err, bus_acquired, address, length); + if (ret != ESP_OK) { + ESP_DRAM_LOGE(TAG, "restore cache fail\n"); + } return err; } diff --git a/components/spi_flash/include/esp_flash.h b/components/spi_flash/include/esp_flash.h index 8a893e17cd6..e5b92b94125 100644 --- a/components/spi_flash/include/esp_flash.h +++ b/components/spi_flash/include/esp_flash.h @@ -334,6 +334,7 @@ esp_err_t esp_flash_write(esp_flash_t *chip, const void *buffer, uint32_t addres * * @return * - ESP_OK: on success + * - ESP_FAIL: bad write, this will be detected only when CONFIG_SPI_FLASH_VERIFY_WRITE is enabled * - ESP_ERR_NOT_SUPPORTED: encrypted write not supported for this chip. * - ESP_ERR_INVALID_ARG: Either the address, buffer or length is invalid. */ diff --git a/components/spi_flash/test_apps/flash_encryption/sdkconfig.ci.verify b/components/spi_flash/test_apps/flash_encryption/sdkconfig.ci.verify new file mode 100644 index 00000000000..f5ead709735 --- /dev/null +++ b/components/spi_flash/test_apps/flash_encryption/sdkconfig.ci.verify @@ -0,0 +1,19 @@ +CONFIG_ESP_TASK_WDT_EN=n +CONFIG_FREERTOS_USE_TICKLESS_IDLE=y +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_SECURE_FLASH_ENC_ENABLED=y +CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT=y +CONFIG_SECURE_BOOT_ALLOW_ROM_BASIC=y +CONFIG_SECURE_BOOT_ALLOW_JTAG=y +CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC=y +CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_DEC=y +CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE=y +CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED=y + +CONFIG_SPI_FLASH_VERIFY_WRITE=y +CONFIG_SPI_FLASH_LOG_FAILED_WRITE=y +CONFIG_SPI_FLASH_WARN_SETTING_ZERO_TO_ONE=y From 75629ee6a83c9d8087d6b01536292139aa8b5612 Mon Sep 17 00:00:00 2001 From: Armando Date: Fri, 3 Mar 2023 15:23:32 +0800 Subject: [PATCH 4/4] spi_flash: added programming guide for ESP-IDF vs ESP-ROM flash driver --- docs/en/api-guides/performance/ram-usage.rst | 2 +- .../peripherals/spi_flash/index.rst | 14 +++++++ .../spi_flash/spi_flash_idf_vs_rom.rst | 37 +++++++++++++++++++ .../spi_flash/spi_flash_optional_feature.rst | 8 ++++ .../peripherals/spi_flash/index.rst | 14 +++++++ .../spi_flash/spi_flash_idf_vs_rom.rst | 1 + 6 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 docs/en/api-reference/peripherals/spi_flash/spi_flash_idf_vs_rom.rst create mode 100644 docs/zh_CN/api-reference/peripherals/spi_flash/spi_flash_idf_vs_rom.rst diff --git a/docs/en/api-guides/performance/ram-usage.rst b/docs/en/api-guides/performance/ram-usage.rst index 62cef4015d6..96e978994c8 100644 --- a/docs/en/api-guides/performance/ram-usage.rst +++ b/docs/en/api-guides/performance/ram-usage.rst @@ -134,7 +134,7 @@ The following options will reduce IRAM usage of some ESP-IDF features: - Enable :ref:`CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH`. Provided these functions are not (incorrectly) used from ISRs, this option is safe to enable in all configurations. - Enable :ref:`CONFIG_RINGBUF_PLACE_ISR_FUNCTIONS_INTO_FLASH`. This option is not safe to use if the ISR ringbuf functions are used from an IRAM interrupt context, e.g. if :ref:`CONFIG_UART_ISR_IN_IRAM` is enabled. For the IDF drivers where this is the case you will get an error at run-time when installing the driver in question. :SOC_WIFI_SUPPORTED: - Disable Wi-Fi options :ref:`CONFIG_ESP_WIFI_IRAM_OPT` and/or :ref:`CONFIG_ESP_WIFI_RX_IRAM_OPT`. Disabling these options will free available IRAM at the cost of Wi-Fi performance. - :esp32c3 or esp32s3: - :ref:`CONFIG_SPI_FLASH_ROM_IMPL` enabling this option will free some IRAM but will mean that esp_flash bugfixes and new flash chip support is not available. + :CONFIG_ESP_ROM_HAS_SPI_FLASH: - :ref:`CONFIG_SPI_FLASH_ROM_IMPL` enabling this option will free some IRAM but will mean that esp_flash bugfixes and new flash chip support is not available, see :doc:`/api-reference/peripherals/spi_flash/spi_flash_idf_vs_rom` for details. :esp32: - :ref:`CONFIG_SPI_FLASH_ROM_DRIVER_PATCH` disabling this option will free some IRAM but is only available in some flash configurations (see the configuration item help text). :esp32: - If the application uses PSRAM and is based on ESP32 rev. 3 (ECO3), setting :ref:`CONFIG_ESP32_REV_MIN` to ``3`` will disable PSRAM bug workarounds, saving ~10kB or more of IRAM. - Disabling :ref:`CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR` prevents posting ``esp_event`` events from :ref:`iram-safe-interrupt-handlers` but will save some IRAM. diff --git a/docs/en/api-reference/peripherals/spi_flash/index.rst b/docs/en/api-reference/peripherals/spi_flash/index.rst index b0d43a2d962..e88370d7511 100644 --- a/docs/en/api-reference/peripherals/spi_flash/index.rst +++ b/docs/en/api-reference/peripherals/spi_flash/index.rst @@ -250,6 +250,20 @@ Additionally, all API functions are protected with a mutex (``s_flash_op_mutex`` In a single core environment (:ref:`CONFIG_FREERTOS_UNICORE` enabled), you need to disable both caches, so that no inter-CPU communication can take place. + +.. toctree:: + :hidden: + + spi_flash_idf_vs_rom + +.. only:: CONFIG_ESP_ROM_HAS_SPI_FLASH + + ESP-IDF vs Chip-ROM SPI Flash Driver + ------------------------------------ + + Refer to :doc:`spi_flash_idf_vs_rom`. + + API Reference - SPI Flash ------------------------- diff --git a/docs/en/api-reference/peripherals/spi_flash/spi_flash_idf_vs_rom.rst b/docs/en/api-reference/peripherals/spi_flash/spi_flash_idf_vs_rom.rst new file mode 100644 index 00000000000..43a3ca78786 --- /dev/null +++ b/docs/en/api-reference/peripherals/spi_flash/spi_flash_idf_vs_rom.rst @@ -0,0 +1,37 @@ +SPI Flash API ESP-IDF version vs Chip-ROM version +================================================= + +.. toctree:: + :maxdepth: 1 + +There is a set of SPI Flash drivers in Chip-ROM which you can use by enabling :ref:`CONFIG_SPI_FLASH_ROM_IMPL`. Most of the ESP-IDF SPI Flash driver code are in internal RAM, therefore enabling this option will free some internal RAM usage. Note if you enable this option, this means some SPI Flash driver features and bugfixes that are done in ESP-IDF might not be included in the Chip-ROM version. + + +Feature Supported by ESP-IDF but not in Chip-ROM +------------------------------------------------ + +.. list:: + + - Octal Flash chip support. See :ref:`oct-flash-doc` for details. + - 32-bit-address support for GD25Q256. See :ref:`32-bit-flash-doc` for details. + - TH Flash chip support. + - Kconfig option :ref:`CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED`. + - :ref:`CONFIG_SPI_FLASH_VERIFY_WRITE`, enabling this option helps you detect bad writing. + - :ref:`CONFIG_SPI_FLASH_LOG_FAILED_WRITE`, enabling this option will print the bad writing. + - :ref:`CONFIG_SPI_FLASH_WARN_SETTING_ZERO_TO_ONE`, enabling this option will check if you're writing zero to one. + :esp32h2 or esp32c6: - Flash MMAP driver isn't ready in Chip-ROM. + + +Bugfixes Introduced in ESP-IDF but not in Chip-ROM +-------------------------------------------------- + +.. list:: + + - Detected Flash physical size correctly, for larger than 256MBit Flash chips. (Commit ID: b4964279d44f73cce7cfd5cf684567fbdfd6fd9e) + :esp32c3: - Improved SPI1 cs setup timing, otherwise issue may happen on ZB32Q128. (Commit ID: 08f1bbe0c75382f1702e40c941e93314285105d4) + :esp32s3: - Fixed issue that 4-line Flash encryption cannot work normally when 8-line PSRAM enabled. (Commit ID: 683d92bc884e0f2a7eebea40a551cf05f0c28256) + :esp32s2: - Fixed issue that only 4MB virtual address ranges can be mapped to read-only data on Flash. + :esp32s3: - Fixed issue that only 128KB virtual address ranges can be mapped to instructions on Flash. + :esp32s3: - Fixed issue that only 16MB virtual address ranges can be mapped to read-only data on Flash. + :esp32c3: - Fixed issue that only 128KB virtual address ranges can be mapped to instructions on Flash. + :esp32c2: - Fixed issue that only at most 128KB virtual address ranges can be mapped to instructions on Flash. diff --git a/docs/en/api-reference/peripherals/spi_flash/spi_flash_optional_feature.rst b/docs/en/api-reference/peripherals/spi_flash/spi_flash_optional_feature.rst index 93e52a829eb..b51f9912a80 100644 --- a/docs/en/api-reference/peripherals/spi_flash/spi_flash_optional_feature.rst +++ b/docs/en/api-reference/peripherals/spi_flash/spi_flash_optional_feature.rst @@ -59,6 +59,8 @@ Flash Chips List: 6. XMC 7. BOYA +.. _hpm-doc: + High performance mode --------------------- @@ -83,6 +85,9 @@ Flash Chips (name & ID) List: It is hard to create several strategies to cover all situations, so all flash chips using HPM need to be supported explicitly. Therefore, if you try to use a flash not listed as supported under high performance mode, it might cause some error. So, when you try to use the flash chip beyond supported list, please test properly. + +.. _oct-flash-doc: + OPI flash support ----------------- @@ -102,6 +107,9 @@ Flash Chips List: 1. MX25UM25645G + +.. _32-bit-flash-doc: + 32-bit Address Flash Chips -------------------------- diff --git a/docs/zh_CN/api-reference/peripherals/spi_flash/index.rst b/docs/zh_CN/api-reference/peripherals/spi_flash/index.rst index fdbc56a47ab..7816637816c 100644 --- a/docs/zh_CN/api-reference/peripherals/spi_flash/index.rst +++ b/docs/zh_CN/api-reference/peripherals/spi_flash/index.rst @@ -250,6 +250,20 @@ Flash 操作完成后,CPU A 上的函数将设置另一标志位,即 ``s_fla 在单核环境中(启用 :ref:`CONFIG_FREERTOS_UNICORE`),您需要禁用上述两个 cache 以防发生 CPU 间通信。 + +.. toctree:: + :hidden: + + spi_flash_idf_vs_rom + +.. only:: CONFIG_ESP_ROM_HAS_SPI_FLASH + + ESP-IDF 和 Chip-ROM 版本 SPI Flash 驱动对比 + ----------------------------------------------------------------- + + 请参考 :doc:`spi_flash_idf_vs_rom`. + + SPI Flash API 参考 ------------------------- diff --git a/docs/zh_CN/api-reference/peripherals/spi_flash/spi_flash_idf_vs_rom.rst b/docs/zh_CN/api-reference/peripherals/spi_flash/spi_flash_idf_vs_rom.rst new file mode 100644 index 00000000000..dccce3c7c40 --- /dev/null +++ b/docs/zh_CN/api-reference/peripherals/spi_flash/spi_flash_idf_vs_rom.rst @@ -0,0 +1 @@ +.. include:: /../en/api-reference/peripherals/spi_flash/spi_flash_idf_vs_rom.rst