From 235fc7e7a73d13b95005a8c88e20c444f3cbd49d Mon Sep 17 00:00:00 2001 From: Rafael Silva Date: Fri, 8 Sep 2023 16:30:33 +0100 Subject: [PATCH] target: optimize flash erase using the mass erase routine When an erase is requested that would result in a complete erase of a flash and the mass erase routine is provided, use it as a speed optimization --- src/target/target_flash.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/target/target_flash.c b/src/target/target_flash.c index fcd23835811..b2eb86d0576 100644 --- a/src/target/target_flash.c +++ b/src/target/target_flash.c @@ -154,18 +154,29 @@ bool target_flash_erase(target_s *target, target_addr_t addr, size_t len) active_flash = flash; } + /* Align the start address to the erase block size */ const target_addr_t local_start_addr = addr & ~(flash->blocksize - 1U); - const target_addr_t local_end_addr = local_start_addr + flash->blocksize; - if (!flash_prepare(flash, FLASH_OPERATION_ERASE)) + /* Check if we can use mass erase */ + const bool can_use_mass_erase = flash->mass_erase != NULL && local_start_addr == flash->start && + (addr + len) >= (flash->start + flash->length); + + /* Calculate the address at the end of the erase block */ + const target_addr_t local_end_addr = + can_use_mass_erase ? flash->start + flash->length : local_start_addr + flash->blocksize; + + if (!flash_prepare(flash, can_use_mass_erase ? FLASH_OPERATION_MASS_ERASE : FLASH_OPERATION_ERASE)) return false; - result &= flash->erase(flash, local_start_addr, flash->blocksize); + /* Erase flash, either a single aligned block size or a full mass erase */ + result &= can_use_mass_erase ? flash->mass_erase(flash, NULL) : + flash->erase(flash, local_start_addr, flash->blocksize); if (!result) { DEBUG_ERROR("Erase failed at %" PRIx32 "\n", local_start_addr); break; } + /* Update the remaining length and address, taking into account the alignment */ len -= MIN(local_end_addr - addr, len); addr = local_end_addr; }