From 1cbdfcc4933a12b9b001f17087534f66fe30674d Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Fri, 24 Aug 2018 17:58:04 +0530 Subject: [PATCH 1/2] bootloader: add API for erasing flash region Signed-off-by: Mahavir Jain Closes: https://github.com/espressif/esp-idf/issues/2166 --- .../include_priv/bootloader_flash.h | 11 +++++++ .../src/bootloader_common.c | 6 ++-- .../bootloader_support/src/bootloader_flash.c | 29 +++++++++++++++++++ 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/components/bootloader_support/include_priv/bootloader_flash.h b/components/bootloader_support/include_priv/bootloader_flash.h index 9f19b4b690..ce867d7573 100644 --- a/components/bootloader_support/include_priv/bootloader_flash.h +++ b/components/bootloader_support/include_priv/bootloader_flash.h @@ -21,6 +21,7 @@ #include "esp_spi_flash.h" #define FLASH_SECTOR_SIZE 0x1000 +#define FLASH_BLOCK_SIZE 0x10000 /* Provide a Flash API for bootloader_support code, that can be used from bootloader or app code. @@ -100,6 +101,16 @@ esp_err_t bootloader_flash_write(size_t dest_addr, void *src, size_t size, bool */ esp_err_t bootloader_flash_erase_sector(size_t sector); +/** + * @brief Erase the Flash range. + * + * @param start_addr start address of flash offset + * @param size sector aligned size to be erased + * + * @return esp_err_t + */ +esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size); + /* Cache MMU block size */ #define MMU_BLOCK_SIZE 0x00010000 diff --git a/components/bootloader_support/src/bootloader_common.c b/components/bootloader_support/src/bootloader_common.c index 36b4b8ba2d..cc00533f6b 100644 --- a/components/bootloader_support/src/bootloader_common.c +++ b/components/bootloader_support/src/bootloader_common.c @@ -102,8 +102,8 @@ bool bootloader_common_erase_part_type_data(const char *list_erase, bool ota_dat partitions = bootloader_mmap(ESP_PARTITION_TABLE_OFFSET, ESP_PARTITION_TABLE_MAX_LEN); if (!partitions) { - ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", ESP_PARTITION_TABLE_OFFSET, ESP_PARTITION_TABLE_MAX_LEN); - return false; + ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", ESP_PARTITION_TABLE_OFFSET, ESP_PARTITION_TABLE_MAX_LEN); + return false; } ESP_LOGD(TAG, "mapped partition table 0x%x at 0x%x", ESP_PARTITION_TABLE_OFFSET, (intptr_t)partitions); @@ -124,7 +124,7 @@ bool bootloader_common_erase_part_type_data(const char *list_erase, bool ota_dat // partition->label is not null-terminated string. strncpy(label, (char *)&partition->label, sizeof(partition->label)); if (fl_ota_data_erase == true || (bootloader_common_label_search(list_erase, label) == true)) { - err = esp_rom_spiflash_erase_area(partition->pos.offset, partition->pos.size); + err = bootloader_flash_erase_range(partition->pos.offset, partition->pos.size); if (err != ESP_OK) { ret = false; marker = "err"; diff --git a/components/bootloader_support/src/bootloader_flash.c b/components/bootloader_support/src/bootloader_flash.c index 1c45890f0d..dbdf84ee2b 100644 --- a/components/bootloader_support/src/bootloader_flash.c +++ b/components/bootloader_support/src/bootloader_flash.c @@ -73,6 +73,11 @@ esp_err_t bootloader_flash_erase_sector(size_t sector) return spi_flash_erase_sector(sector); } +esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size) +{ + return spi_flash_erase_range(start_addr, size); +} + #else /* Bootloader version, uses ROM functions only */ #include @@ -246,4 +251,28 @@ esp_err_t bootloader_flash_erase_sector(size_t sector) return spi_to_esp_err(esp_rom_spiflash_erase_sector(sector)); } +esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size) +{ + if (start_addr % FLASH_SECTOR_SIZE != 0) { + return ESP_ERR_INVALID_ARG; + } + if (size % FLASH_SECTOR_SIZE != 0) { + return ESP_ERR_INVALID_SIZE; + } + size_t start = start_addr / FLASH_SECTOR_SIZE; + size_t end = start + size / FLASH_SECTOR_SIZE; + const size_t sectors_per_block = FLASH_BLOCK_SIZE / FLASH_SECTOR_SIZE; + + esp_rom_spiflash_result_t rc = ESP_ROM_SPIFLASH_RESULT_OK; + for (size_t sector = start; sector != end && rc == ESP_ROM_SPIFLASH_RESULT_OK; ) { + if (sector % sectors_per_block == 0 && end - sector >= sectors_per_block) { + rc = esp_rom_spiflash_erase_block(sector / sectors_per_block); + sector += sectors_per_block; + } else { + rc = esp_rom_spiflash_erase_sector(sector); + ++sector; + } + } + return spi_to_esp_err(rc); +} #endif From 401c940434acbbc5e0b42b45ab1ad7be08e0e3d6 Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Mon, 27 Aug 2018 21:54:20 +0530 Subject: [PATCH 2/2] spi_flash: fix erase_range for block erase check Erase in block (64k) as much as possible, before falling back to sector (4k) erase. Signed-off-by: Mahavir Jain --- components/spi_flash/flash_ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/spi_flash/flash_ops.c b/components/spi_flash/flash_ops.c index aab0c1210f..89f9ef5e14 100644 --- a/components/spi_flash/flash_ops.c +++ b/components/spi_flash/flash_ops.c @@ -218,7 +218,7 @@ esp_err_t IRAM_ATTR spi_flash_erase_range(uint32_t start_addr, uint32_t size) if (rc == ESP_ROM_SPIFLASH_RESULT_OK) { for (size_t sector = start; sector != end && rc == ESP_ROM_SPIFLASH_RESULT_OK; ) { spi_flash_guard_start(); - if (sector % sectors_per_block == 0 && end - sector > sectors_per_block) { + if (sector % sectors_per_block == 0 && end - sector >= sectors_per_block) { rc = esp_rom_spiflash_erase_block(sector / sectors_per_block); sector += sectors_per_block; COUNTER_ADD_BYTES(erase, sectors_per_block * SPI_FLASH_SEC_SIZE);