openocd: src: fix incorrect SPDX tags
[openocd.git] / src / flash / nor / core.c
index 11b7ce4a0af176553fa4c33952fa26b70df7b527..f4ff5dfb386af98c8309f4e623c983028c2236d8 100644 (file)
 
 static struct flash_bank *flash_banks;
 
-int flash_driver_erase(struct flash_bank *bank, int first, int last)
+int flash_driver_erase(struct flash_bank *bank, unsigned int first,
+               unsigned int last)
 {
        int retval;
 
        retval = bank->driver->erase(bank, first, last);
        if (retval != ERROR_OK)
-               LOG_ERROR("failed erasing sectors %d to %d", first, last);
+               LOG_ERROR("failed erasing sectors %u to %u", first, last);
 
        return retval;
 }
 
-int flash_driver_protect(struct flash_bank *bank, int set, int first, int last)
+int flash_driver_protect(struct flash_bank *bank, int set, unsigned int first,
+               unsigned int last)
 {
        int retval;
-       int num_blocks;
+       unsigned int num_blocks;
 
        if (bank->num_prot_blocks)
                num_blocks = bank->num_prot_blocks;
@@ -60,7 +62,7 @@ int flash_driver_protect(struct flash_bank *bank, int set, int first, int last)
 
 
        /* callers may not supply illegal parameters ... */
-       if (first < 0 || first > last || last >= num_blocks) {
+       if (first > last || last >= num_blocks) {
                LOG_ERROR("illegal protection block range");
                return ERROR_FAIL;
        }
@@ -68,7 +70,7 @@ int flash_driver_protect(struct flash_bank *bank, int set, int first, int last)
        /* force "set" to 0/1 */
        set = !!set;
 
-       if (bank->driver->protect == NULL) {
+       if (!bank->driver->protect) {
                LOG_ERROR("Flash protection is not supported.");
                return ERROR_FLASH_OPER_UNSUPPORTED;
        }
@@ -86,13 +88,13 @@ int flash_driver_protect(struct flash_bank *bank, int set, int first, int last)
         */
        retval = bank->driver->protect(bank, set, first, last);
        if (retval != ERROR_OK)
-               LOG_ERROR("failed setting protection for blocks %d to %d", first, last);
+               LOG_ERROR("failed setting protection for blocks %u to %u", first, last);
 
        return retval;
 }
 
 int flash_driver_write(struct flash_bank *bank,
-       uint8_t *buffer, uint32_t offset, uint32_t count)
+       const uint8_t *buffer, uint32_t offset, uint32_t count)
 {
        int retval;
 
@@ -133,6 +135,43 @@ int default_flash_read(struct flash_bank *bank,
        return target_read_buffer(bank->target, offset + bank->base, count, buffer);
 }
 
+int flash_driver_verify(struct flash_bank *bank,
+       const uint8_t *buffer, uint32_t offset, uint32_t count)
+{
+       int retval;
+
+       retval = bank->driver->verify ? bank->driver->verify(bank, buffer, offset, count) :
+               default_flash_verify(bank, buffer, offset, count);
+       if (retval != ERROR_OK) {
+               LOG_ERROR("verify failed in bank at " TARGET_ADDR_FMT " starting at 0x%8.8" PRIx32,
+                       bank->base, offset);
+       }
+
+       return retval;
+}
+
+int default_flash_verify(struct flash_bank *bank,
+       const uint8_t *buffer, uint32_t offset, uint32_t count)
+{
+       uint32_t target_crc, image_crc;
+       int retval;
+
+       retval = image_calculate_checksum(buffer, count, &image_crc);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = target_checksum_memory(bank->target, offset + bank->base, count, &target_crc);
+       if (retval != ERROR_OK)
+               return retval;
+
+       LOG_DEBUG("addr " TARGET_ADDR_FMT ", len 0x%08" PRIx32 ", crc 0x%08" PRIx32 " 0x%08" PRIx32,
+               offset + bank->base, count, ~image_crc, ~target_crc);
+       if (target_crc == image_crc)
+               return ERROR_OK;
+       else
+               return ERROR_FAIL;
+}
+
 void flash_bank_add(struct flash_bank *bank)
 {
        /* put flash bank in linked list */
@@ -140,7 +179,7 @@ void flash_bank_add(struct flash_bank *bank)
        if (flash_banks) {
                /* find last flash bank */
                struct flash_bank *p = flash_banks;
-               while (NULL != p->next) {
+               while (p->next) {
                        bank_num += 1;
                        p = p->next;
                }
@@ -157,10 +196,10 @@ struct flash_bank *flash_bank_list(void)
        return flash_banks;
 }
 
-struct flash_bank *get_flash_bank_by_num_noprobe(int num)
+struct flash_bank *get_flash_bank_by_num_noprobe(unsigned int num)
 {
        struct flash_bank *p;
-       int i = 0;
+       unsigned int i = 0;
 
        for (p = flash_banks; p; p = p->next) {
                if (i++ == num)
@@ -170,10 +209,10 @@ struct flash_bank *get_flash_bank_by_num_noprobe(int num)
        return NULL;
 }
 
-int flash_get_bank_count(void)
+unsigned int flash_get_bank_count(void)
 {
        struct flash_bank *p;
-       int i = 0;
+       unsigned int i = 0;
        for (p = flash_banks; p; p = p->next)
                i++;
        return i;
@@ -218,7 +257,7 @@ struct flash_bank *get_flash_bank_by_name_noprobe(const char *name)
        unsigned found = 0;
 
        struct flash_bank *bank;
-       for (bank = flash_banks; NULL != bank; bank = bank->next) {
+       for (bank = flash_banks; bank; bank = bank->next) {
                if (strcmp(bank->name, name) == 0)
                        return bank;
                if (!flash_driver_name_matches(bank->driver->name, name))
@@ -236,7 +275,7 @@ int get_flash_bank_by_name(const char *name, struct flash_bank **bank_result)
        int retval;
 
        bank = get_flash_bank_by_name_noprobe(name);
-       if (bank != NULL) {
+       if (bank) {
                retval = bank->driver->auto_probe(bank);
 
                if (retval != ERROR_OK) {
@@ -249,12 +288,12 @@ int get_flash_bank_by_name(const char *name, struct flash_bank **bank_result)
        return ERROR_OK;
 }
 
-int get_flash_bank_by_num(int num, struct flash_bank **bank)
+int get_flash_bank_by_num(unsigned int num, struct flash_bank **bank)
 {
        struct flash_bank *p = get_flash_bank_by_num_noprobe(num);
        int retval;
 
-       if (p == NULL)
+       if (!p)
                return ERROR_FAIL;
 
        retval = p->driver->auto_probe(p);
@@ -306,8 +345,7 @@ static int default_flash_mem_blank_check(struct flash_bank *bank)
 {
        struct target *target = bank->target;
        const int buffer_size = 1024;
-       int i;
-       uint32_t nBytes;
+       uint32_t n_bytes;
        int retval = ERROR_OK;
 
        if (bank->target->state != TARGET_HALTED) {
@@ -317,7 +355,7 @@ static int default_flash_mem_blank_check(struct flash_bank *bank)
 
        uint8_t *buffer = malloc(buffer_size);
 
-       for (i = 0; i < bank->num_sectors; i++) {
+       for (unsigned int i = 0; i < bank->num_sectors; i++) {
                uint32_t j;
                bank->sectors[i].is_erased = 1;
 
@@ -335,8 +373,8 @@ static int default_flash_mem_blank_check(struct flash_bank *bank)
                        if (retval != ERROR_OK)
                                goto done;
 
-                       for (nBytes = 0; nBytes < chunk; nBytes++) {
-                               if (buffer[nBytes] != bank->erased_value) {
+                       for (n_bytes = 0; n_bytes < chunk; n_bytes++) {
+                               if (buffer[n_bytes] != bank->erased_value) {
                                        bank->sectors[i].is_erased = 0;
                                        break;
                                }
@@ -353,7 +391,6 @@ done:
 int default_flash_blank_check(struct flash_bank *bank)
 {
        struct target *target = bank->target;
-       int i;
        int retval;
 
        if (bank->target->state != TARGET_HALTED) {
@@ -363,17 +400,17 @@ int default_flash_blank_check(struct flash_bank *bank)
 
        struct target_memory_check_block *block_array;
        block_array = malloc(bank->num_sectors * sizeof(struct target_memory_check_block));
-       if (block_array == NULL)
+       if (!block_array)
                return default_flash_mem_blank_check(bank);
 
-       for (i = 0; i < bank->num_sectors; i++) {
+       for (unsigned int i = 0; i < bank->num_sectors; i++) {
                block_array[i].address = bank->base + bank->sectors[i].offset;
                block_array[i].size = bank->sectors[i].size;
                block_array[i].result = UINT32_MAX; /* erase state unknown */
        }
 
        bool fast_check = true;
-       for (i = 0; i < bank->num_sectors; ) {
+       for (unsigned int i = 0; i < bank->num_sectors; ) {
                retval = target_blank_check_memory(target,
                                block_array + i, bank->num_sectors - i,
                                bank->erased_value);
@@ -388,11 +425,15 @@ int default_flash_blank_check(struct flash_bank *bank)
        }
 
        if (fast_check) {
-               for (i = 0; i < bank->num_sectors; i++)
+               for (unsigned int i = 0; i < bank->num_sectors; i++)
                        bank->sectors[i].is_erased = block_array[i].result;
                retval = ERROR_OK;
        } else {
-               LOG_USER("Running slow fallback erase check - add working memory");
+               if (retval == ERROR_NOT_IMPLEMENTED)
+                       LOG_USER("Running slow fallback erase check");
+               else
+                       LOG_USER("Running slow fallback erase check - add working memory");
+
                retval = default_flash_mem_blank_check(bank);
        }
        free(block_array);
@@ -418,11 +459,12 @@ int default_flash_blank_check(struct flash_bank *bank)
 static int flash_iterate_address_range_inner(struct target *target,
        char *pad_reason, target_addr_t addr, uint32_t length,
        bool iterate_protect_blocks,
-       int (*callback)(struct flash_bank *bank, int first, int last))
+       int (*callback)(struct flash_bank *bank, unsigned int first,
+               unsigned int last))
 {
        struct flash_bank *c;
        struct flash_sector *block_array;
-       target_addr_t last_addr = addr + length;        /* first address AFTER end */
+       target_addr_t last_addr = addr + length - 1;    /* the last address of range */
        int first = -1;
        int last = -1;
        int i;
@@ -448,12 +490,12 @@ static int flash_iterate_address_range_inner(struct target *target,
        }
 
        /* check whether it all fits in this bank */
-       if (addr + length - 1 > c->base + c->size - 1) {
+       if (last_addr > c->base + c->size - 1) {
                LOG_ERROR("Flash access does not fit into bank.");
                return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
        }
 
-       if (c->prot_blocks == NULL || c->num_prot_blocks == 0) {
+       if (!c->prot_blocks || c->num_prot_blocks == 0) {
                /* flash driver does not define protect blocks, use sectors instead */
                iterate_protect_blocks = false;
        }
@@ -466,21 +508,19 @@ static int flash_iterate_address_range_inner(struct target *target,
                num_blocks = c->num_sectors;
        }
 
-       addr -= c->base;
-       last_addr -= c->base;
-
        for (i = 0; i < num_blocks; i++) {
                struct flash_sector *f = &block_array[i];
-               uint32_t end = f->offset + f->size;
+               target_addr_t sector_addr = c->base + f->offset;
+               target_addr_t sector_last_addr = sector_addr + f->size - 1;
 
                /* start only on a sector boundary */
                if (first < 0) {
                        /* scanned past the first sector? */
-                       if (addr < f->offset)
+                       if (addr < sector_addr)
                                break;
 
                        /* is this the first sector? */
-                       if (addr == f->offset)
+                       if (addr == sector_addr)
                                first = i;
 
                        /* Does this need head-padding?  If so, pad and warn;
@@ -490,12 +530,12 @@ static int flash_iterate_address_range_inner(struct target *target,
                         * ever know if that data was in use.  The warning
                         * should help users sort out messes later.
                         */
-                       else if (addr < end && pad_reason) {
+                       else if (addr <= sector_last_addr && pad_reason) {
                                /* FIXME say how many bytes (e.g. 80 KB) */
                                LOG_WARNING("Adding extra %s range, "
-                                       "%#8.8x to " TARGET_ADDR_FMT,
+                                       TARGET_ADDR_FMT " .. " TARGET_ADDR_FMT,
                                        pad_reason,
-                                       (unsigned) f->offset,
+                                       sector_addr,
                                        addr - 1);
                                first = i;
                        } else
@@ -503,7 +543,7 @@ static int flash_iterate_address_range_inner(struct target *target,
                }
 
                /* is this (also?) the last sector? */
-               if (last_addr == end) {
+               if (last_addr == sector_last_addr) {
                        last = i;
                        break;
                }
@@ -511,19 +551,19 @@ static int flash_iterate_address_range_inner(struct target *target,
                /* Does this need tail-padding?  If so, pad and warn;
                 * or else force an error.
                 */
-               if (last_addr < end && pad_reason) {
+               if (last_addr < sector_last_addr && pad_reason) {
                        /* FIXME say how many bytes (e.g. 80 KB) */
                        LOG_WARNING("Adding extra %s range, "
-                               "%#8.8x to %#8.8x",
+                               TARGET_ADDR_FMT " .. " TARGET_ADDR_FMT,
                                pad_reason,
-                               (unsigned) last_addr,
-                               (unsigned) end - 1);
+                               last_addr + 1,
+                               sector_last_addr);
                        last = i;
                        break;
                }
 
                /* MUST finish on a sector boundary */
-               if (last_addr <= f->offset)
+               if (last_addr < sector_addr)
                        break;
        }
 
@@ -531,8 +571,8 @@ static int flash_iterate_address_range_inner(struct target *target,
        if (first == -1 || last == -1) {
                LOG_ERROR("address range " TARGET_ADDR_FMT " .. " TARGET_ADDR_FMT
                        " is not sector-aligned",
-                       c->base + addr,
-                       c->base + last_addr - 1);
+                       addr,
+                       last_addr);
                return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
        }
 
@@ -549,7 +589,8 @@ static int flash_iterate_address_range_inner(struct target *target,
 static int flash_iterate_address_range(struct target *target,
        char *pad_reason, target_addr_t addr, uint32_t length,
        bool iterate_protect_blocks,
-       int (*callback)(struct flash_bank *bank, int first, int last))
+       int (*callback)(struct flash_bank *bank, unsigned int first,
+               unsigned int last))
 {
        struct flash_bank *c;
        int retval = ERROR_OK;
@@ -587,7 +628,8 @@ int flash_erase_address_range(struct target *target,
                addr, length, false, &flash_driver_erase);
 }
 
-static int flash_driver_unprotect(struct flash_bank *bank, int first, int last)
+static int flash_driver_unprotect(struct flash_bank *bank, unsigned int first,
+               unsigned int last)
 {
        return flash_driver_protect(bank, 0, first, last);
 }
@@ -629,8 +671,7 @@ target_addr_t flash_write_align_start(struct flash_bank *bank, target_addr_t add
        if (bank->write_start_alignment == FLASH_WRITE_ALIGN_SECTOR) {
                uint32_t offset = addr - bank->base;
                uint32_t aligned = 0;
-               int sect;
-               for (sect = 0; sect < bank->num_sectors; sect++) {
+               for (unsigned int sect = 0; sect < bank->num_sectors; sect++) {
                        if (bank->sectors[sect].offset > offset)
                                break;
 
@@ -654,8 +695,7 @@ target_addr_t flash_write_align_end(struct flash_bank *bank, target_addr_t addr)
        if (bank->write_end_alignment == FLASH_WRITE_ALIGN_SECTOR) {
                uint32_t offset = addr - bank->base;
                uint32_t aligned = 0;
-               int sect;
-               for (sect = 0; sect < bank->num_sectors; sect++) {
+               for (unsigned int sect = 0; sect < bank->num_sectors; sect++) {
                        aligned = bank->sectors[sect].offset + bank->sectors[sect].size - 1;
                        if (aligned >= offset)
                                break;
@@ -678,7 +718,7 @@ static bool flash_write_check_gap(struct flash_bank *bank,
                return false;
 
        if (bank->minimal_write_gap == FLASH_WRITE_GAP_SECTOR) {
-               int sect;
+               unsigned int sect;
                uint32_t offset1 = addr1 - bank->base;
                /* find the sector following the one containing addr1 */
                for (sect = 0; sect < bank->num_sectors; sect++) {
@@ -698,12 +738,12 @@ static bool flash_write_check_gap(struct flash_bank *bank,
 }
 
 
-int flash_write_unlock(struct target *target, struct image *image,
-       uint32_t *written, int erase, bool unlock)
+int flash_write_unlock_verify(struct target *target, struct image *image,
+       uint32_t *written, bool erase, bool unlock, bool write, bool verify)
 {
        int retval = ERROR_OK;
 
-       int section;
+       unsigned int section;
        uint32_t section_offset;
        struct flash_bank *c;
        int *padding;
@@ -728,8 +768,8 @@ int flash_write_unlock(struct target *target, struct image *image,
         * whereas an image can have sections out of order. */
        struct imagesection **sections = malloc(sizeof(struct imagesection *) *
                        image->num_sections);
-       int i;
-       for (i = 0; i < image->num_sections; i++)
+
+       for (unsigned int i = 0; i < image->num_sections; i++)
                sections[i] = &image->sections[i];
 
        qsort(sections, image->num_sections, sizeof(struct imagesection *),
@@ -739,7 +779,7 @@ int flash_write_unlock(struct target *target, struct image *image,
        while (section < image->num_sections) {
                uint32_t buffer_idx;
                uint8_t *buffer;
-               int section_last;
+               unsigned int section_last;
                target_addr_t run_address = sections[section]->base_address + section_offset;
                uint32_t run_size = sections[section]->size - section_offset;
                int pad_bytes = 0;
@@ -755,7 +795,7 @@ int flash_write_unlock(struct target *target, struct image *image,
                retval = get_flash_bank_by_addr(target, run_address, false, &c);
                if (retval != ERROR_OK)
                        goto done;
-               if (c == NULL) {
+               if (!c) {
                        LOG_WARNING("no flash bank found for address " TARGET_ADDR_FMT, run_address);
                        section++;      /* and skip it */
                        section_offset = 0;
@@ -826,7 +866,7 @@ int flash_write_unlock(struct target *target, struct image *image,
                                LOG_WARNING("Section start address " TARGET_ADDR_FMT
                                        " breaks the required alignment of flash bank %s",
                                        run_address, c->name);
-                               LOG_WARNING("Padding %d bytes from " TARGET_ADDR_FMT,
+                               LOG_WARNING("Padding %" PRIu32 " bytes from " TARGET_ADDR_FMT,
                                        padding_at_start, aligned_start);
 
                                run_address -= padding_at_start;
@@ -849,12 +889,11 @@ int flash_write_unlock(struct target *target, struct image *image,
                        /* If we're applying any sector automagic, then pad this
                         * (maybe-combined) segment to the end of its last sector.
                         */
-                       int sector;
                        uint32_t offset_start = run_address - c->base;
                        uint32_t offset_end = offset_start + run_size;
                        uint32_t end = offset_end, delta;
 
-                       for (sector = 0; sector < c->num_sectors; sector++) {
+                       for (unsigned int sector = 0; sector < c->num_sectors; sector++) {
                                end = c->sectors[sector].offset
                                        + c->sectors[sector].size;
                                if (offset_end <= end)
@@ -868,7 +907,7 @@ int flash_write_unlock(struct target *target, struct image *image,
 
                /* allocate buffer */
                buffer = malloc(run_size);
-               if (buffer == NULL) {
+               if (!buffer) {
                        LOG_ERROR("Out of memory for flash bank buffer");
                        retval = ERROR_FAIL;
                        goto done;
@@ -934,8 +973,17 @@ int flash_write_unlock(struct target *target, struct image *image,
                }
 
                if (retval == ERROR_OK) {
-                       /* write flash sectors */
-                       retval = flash_driver_write(c, buffer, run_address - c->base, run_size);
+                       if (write) {
+                               /* write flash sectors */
+                               retval = flash_driver_write(c, buffer, run_address - c->base, run_size);
+                       }
+               }
+
+               if (retval == ERROR_OK) {
+                       if (verify) {
+                               /* verify flash sectors */
+                               retval = flash_driver_verify(c, buffer, run_address - c->base, run_size);
+                       }
                }
 
                free(buffer);
@@ -945,7 +993,7 @@ int flash_write_unlock(struct target *target, struct image *image,
                        goto done;
                }
 
-               if (written != NULL)
+               if (written)
                        *written += run_size;   /* add run size to total written counter */
        }
 
@@ -957,20 +1005,19 @@ done:
 }
 
 int flash_write(struct target *target, struct image *image,
-       uint32_t *written, int erase)
+       uint32_t *written, bool erase)
 {
-       return flash_write_unlock(target, image, written, erase, false);
+       return flash_write_unlock_verify(target, image, written, erase, false, true, false);
 }
 
-struct flash_sector *alloc_block_array(uint32_t offset, uint32_t size, int num_blocks)
+struct flash_sector *alloc_block_array(uint32_t offset, uint32_t size,
+               unsigned int num_blocks)
 {
-       int i;
-
        struct flash_sector *array = calloc(num_blocks, sizeof(struct flash_sector));
-       if (array == NULL)
+       if (!array)
                return NULL;
 
-       for (i = 0; i < num_blocks; i++) {
+       for (unsigned int i = 0; i < num_blocks; i++) {
                array[i].offset = offset;
                array[i].size = size;
                array[i].is_erased = -1;

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)