This is an automated email from Gerrit.

"Marc Schink <[email protected]>" just uploaded a new patch set to Gerrit, which you 
can find at https://review.openocd.org/c/openocd/+/9319

-- gerrit

commit e93a65009d7b9bce03e4376e73b3fed4506e68b0
Author: Marc Schink <[email protected]>
Date:   Wed Dec 17 11:07:45 2025 +0000

    flash/nor: Support erase check on banks without sectors
    
    The current implementation of the deletion check is closely tied to the
    concept of sectors. Implement a workaround to support sectorless banks
    without having to make many changes to the code base.
    
    Tested with nRF54L15-DK, tested for regression with AT32F421C8T7.
    
    Change-Id: I88fd5d56f2edbd8337663bea8d25cd499c09add6
    Signed-off-by: Marc Schink <[email protected]>

diff --git a/src/flash/nor/core.c b/src/flash/nor/core.c
index 93ad9bffb9..8e495730bd 100644
--- a/src/flash/nor/core.c
+++ b/src/flash/nor/core.c
@@ -368,6 +368,67 @@ done:
        return retval;
 }
 
+static int flash_blank_check_no_sectors_fast(struct flash_bank *bank)
+{
+       struct target_memory_check_block check_block;
+
+       check_block.address = bank->base;
+       check_block.size = bank->size;
+       // Erase state unknown.
+       check_block.result = UINT32_MAX;
+
+       int retval = target_blank_check_memory(bank->target, &check_block, 1,
+               bank->erased_value);
+
+       if (retval < 1)
+               return retval;
+
+       bank->is_erased = check_block.result;
+
+       return ERROR_OK;
+}
+
+static int flash_blank_check_no_sectors(struct flash_bank *bank)
+{
+       struct target *target = bank->target;
+       const uint32_t buffer_size = 1024;
+       uint8_t buffer[buffer_size];
+
+       if (bank->target->state != TARGET_HALTED) {
+               LOG_ERROR("Target not halted");
+               return ERROR_TARGET_NOT_HALTED;
+       }
+
+       int retval = flash_blank_check_no_sectors_fast(bank);
+       if (retval == ERROR_OK)
+               return retval;
+
+       LOG_WARNING("Fast erase check failed, running slow fallback");
+
+       bank->is_erased = 1;
+
+       for (uint32_t offset = 0; offset < bank->size; offset += buffer_size) {
+               uint32_t chunk_size = MIN(buffer_size, bank->size - offset);
+
+               retval = target_read_memory(target,
+                               bank->base + offset,
+                               4,
+                               chunk_size / 4,
+                               buffer);
+               if (retval != ERROR_OK)
+                       return retval;
+
+               for (uint32_t i = 0; i < chunk_size; i++) {
+                       if (buffer[i] != bank->erased_value) {
+                               bank->is_erased = 0;
+                               break;
+                       }
+               }
+       }
+
+       return ERROR_OK;
+}
+
 int default_flash_blank_check(struct flash_bank *bank)
 {
        struct target *target = bank->target;
@@ -378,6 +439,9 @@ int default_flash_blank_check(struct flash_bank *bank)
                return ERROR_TARGET_NOT_HALTED;
        }
 
+       if (bank->num_sectors == 0)
+               return flash_blank_check_no_sectors(bank);
+
        struct target_memory_check_block *block_array;
        block_array = malloc(bank->num_sectors * sizeof(struct 
target_memory_check_block));
        if (!block_array)
diff --git a/src/flash/nor/core.h b/src/flash/nor/core.h
index f8cf5e2698..369c6c3069 100644
--- a/src/flash/nor/core.h
+++ b/src/flash/nor/core.h
@@ -114,6 +114,17 @@ struct flash_bank {
        unsigned int num_sectors;
        /** Array of sectors, allocated and initialized by the flash driver */
        struct flash_sector *sectors;
+       /**
+        * Indication of erasure status: 0 = not erased, 1 = erased,
+        * other = unknown.  Set by @c flash_driver::erase_check only.
+        *
+        * Use this only if the flash bank has no sectors.
+        *
+        * This information must be considered stale immediately.
+        * Don't set it in flash_driver::erase or a device mass_erase
+        * Don't clear it in flash_driver::write
+        */
+       int is_erased;
 
        /**
         * The number of protection blocks in this bank. This value
diff --git a/src/flash/nor/tcl.c b/src/flash/nor/tcl.c
index 60bdad5562..d2566fe720 100644
--- a/src/flash/nor/tcl.c
+++ b/src/flash/nor/tcl.c
@@ -218,6 +218,9 @@ COMMAND_HANDLER(handle_flash_erase_check_command)
                        erase_state);
        }
 
+       if (p->num_sectors == 0)
+               blank = (p->is_erased == 1);
+
        if (blank)
                command_print(CMD, "\tBank is erased");
        return retval;

-- 

Reply via email to