X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fflash%2Fnor%2Fcore.c;h=4b5fe7dd8471c9c941cf0467bfe49babcd37b885;hb=d5b5f9f4fd1a2781600cc74a54d5c9a2b7e09e87;hp=2c1d9dee04dbcb29b12abb038e7d7f69679c8b8d;hpb=45e5d1d90acaff8cf57f694e70ec41ece9bddfcd;p=openocd.git diff --git a/src/flash/nor/core.c b/src/flash/nor/core.c index 2c1d9dee04..4b5fe7dd84 100644 --- a/src/flash/nor/core.c +++ b/src/flash/nor/core.c @@ -46,7 +46,7 @@ int flash_driver_erase(struct flash_bank *bank, int first, int last) retval = bank->driver->erase(bank, first, last); if (retval != ERROR_OK) { - LOG_ERROR("failed erasing sectors %d to %d (%d)", first, last, retval); + LOG_ERROR("failed erasing sectors %d to %d", first, last); } return retval; @@ -80,7 +80,7 @@ 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 areas %d to %d (%d)", first, last, retval); + LOG_ERROR("failed setting protection for areas %d to %d", first, last); } return retval; @@ -94,8 +94,8 @@ int flash_driver_write(struct flash_bank *bank, retval = bank->driver->write(bank, buffer, offset, count); if (retval != ERROR_OK) { - LOG_ERROR("error writing to flash at address 0x%08" PRIx32 " at offset 0x%8.8" PRIx32 " (%d)", - bank->base, offset, retval); + LOG_ERROR("error writing to flash at address 0x%08" PRIx32 " at offset 0x%8.8" PRIx32, + bank->base, offset); } return retval; @@ -111,8 +111,8 @@ int flash_driver_read(struct flash_bank *bank, retval = bank->driver->read(bank, buffer, offset, count); if (retval != ERROR_OK) { - LOG_ERROR("error reading to flash at address 0x%08" PRIx32 " at offset 0x%8.8" PRIx32 " (%d)", - bank->base, offset, retval); + LOG_ERROR("error reading to flash at address 0x%08" PRIx32 " at offset 0x%8.8" PRIx32, + bank->base, offset); } return retval; @@ -209,7 +209,7 @@ int get_flash_bank_by_name(const char *name, struct flash_bank **bank_result) if (retval != ERROR_OK) { - LOG_ERROR("auto_probe failed %d\n", retval); + LOG_ERROR("auto_probe failed"); return retval; } } @@ -232,7 +232,7 @@ int get_flash_bank_by_num(int num, struct flash_bank **bank) if (retval != ERROR_OK) { - LOG_ERROR("auto_probe failed %d\n", retval); + LOG_ERROR("auto_probe failed"); return retval; } *bank = p; @@ -253,7 +253,7 @@ int get_flash_bank_by_addr(struct target *target, uint32_t addr, bool check, str if (retval != ERROR_OK) { - LOG_ERROR("auto_probe failed %d\n", retval); + LOG_ERROR("auto_probe failed"); return retval; } /* check whether address belongs to this flash bank */ @@ -266,7 +266,7 @@ int get_flash_bank_by_addr(struct target *target, uint32_t addr, bool check, str *result_bank = NULL; if (check) { - LOG_ERROR("No flash at address 0x%08" PRIx32 "\n", addr); + LOG_ERROR("No flash at address 0x%08" PRIx32, addr); return ERROR_FAIL; } return ERROR_OK; @@ -379,7 +379,7 @@ int default_flash_blank_check(struct flash_bank *bank) * sectors will be added to the range, and that reason string is used when * warning about those additions. */ -static int flash_iterate_address_range(struct target *target, +static int flash_iterate_address_range_inner(struct target *target, char *pad_reason, uint32_t addr, uint32_t length, int (*callback)(struct flash_bank *bank, int first, int last)) { @@ -498,6 +498,43 @@ static int flash_iterate_address_range(struct target *target, return callback(c, first, last); } +/* The inner fn only handles a single bank, we could be spanning + * multiple chips. + */ +static int flash_iterate_address_range(struct target *target, + char *pad_reason, uint32_t addr, uint32_t length, + int (*callback)(struct flash_bank *bank, int first, int last)) +{ + struct flash_bank *c; + int retval = ERROR_OK; + + /* Danger! zero-length iterations means entire bank! */ + do + { + retval = get_flash_bank_by_addr(target, addr, true, &c); + if (retval != ERROR_OK) + return retval; + + uint32_t cur_length = length; + /* check whether it all fits in this bank */ + if (addr + length - 1 > c->base + c->size - 1) + { + LOG_DEBUG("iterating over more than one flash bank."); + cur_length = c->base + c->size - addr; + } + retval = flash_iterate_address_range_inner(target, + pad_reason, addr, cur_length, + callback); + if (retval != ERROR_OK) + break; + + length -= cur_length; + addr += cur_length; + } while (length > 0); + + return retval; +} + int flash_erase_address_range(struct target *target, bool pad, uint32_t addr, uint32_t length) { @@ -584,7 +621,6 @@ int flash_write_unlock(struct target *target, struct image *image, { uint32_t buffer_size; uint8_t *buffer; - int section_first; int section_last; uint32_t run_address = sections[section]->base_address + section_offset; uint32_t run_size = sections[section]->size - section_offset; @@ -612,7 +648,6 @@ int flash_write_unlock(struct target *target, struct image *image, } /* collect consecutive sections which fall into the same bank */ - section_first = section; section_last = section; padding[section] = 0; while ((run_address + run_size - 1 < c->base + c->size - 1) @@ -654,9 +689,13 @@ int flash_write_unlock(struct target *target, struct image *image, if (run_address + run_size - 1 > c->base + c->size - 1) { - LOG_ERROR("The image is too big for the flash"); - retval = ERROR_FAIL; - goto done; + /* If we have more than one flash chip back to back, then we limit + * the current write operation to the current chip. + */ + LOG_DEBUG("Truncate flash run size to the current flash chip."); + + run_size = c->base + c->size - run_address; + assert(run_size > 0); } /* If we're applying any sector automagic, then pad this