}
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;
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 */
}
-int flash_write_unlock(struct target *target, struct image *image,
- uint32_t *written, bool 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;
* 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 *),
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;
}
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);
int flash_write(struct target *target, struct image *image,
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,