build: cleanup src/flash/nand directory
[fw/openocd] / src / flash / nor / core.c
1 /***************************************************************************
2  *   Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de>              *
3  *   Copyright (C) 2007-2010 Øyvind Harboe <oyvind.harboe@zylin.com>       *
4  *   Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk>           *
5  *   Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net>             *
6  *   Copyright (C) 2010 by Antonio Borneo <borneo.antonio@gmail.com>       *
7  *                                                                         *
8  *   This program is free software; you can redistribute it and/or modify  *
9  *   it under the terms of the GNU General Public License as published by  *
10  *   the Free Software Foundation; either version 2 of the License, or     *
11  *   (at your option) any later version.                                   *
12  *                                                                         *
13  *   This program is distributed in the hope that it will be useful,       *
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
16  *   GNU General Public License for more details.                          *
17  *                                                                         *
18  *   You should have received a copy of the GNU General Public License     *
19  *   along with this program; if not, write to the                         *
20  *   Free Software Foundation, Inc.,                                       *
21  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
22  ***************************************************************************/
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27 #include <flash/common.h>
28 #include <flash/nor/core.h>
29 #include <flash/nor/imp.h>
30 #include <target/image.h>
31
32
33 /**
34  * @file
35  * Upper level of NOR flash framework.
36  * The lower level interfaces are to drivers.  These upper level ones
37  * primarily support access from Tcl scripts or from GDB.
38  */
39
40 static struct flash_bank *flash_banks;
41
42 int flash_driver_erase(struct flash_bank *bank, int first, int last)
43 {
44         int retval;
45
46         retval = bank->driver->erase(bank, first, last);
47         if (retval != ERROR_OK)
48         {
49                 LOG_ERROR("failed erasing sectors %d to %d", first, last);
50         }
51
52         return retval;
53 }
54
55 int flash_driver_protect(struct flash_bank *bank, int set, int first, int last)
56 {
57         int retval;
58
59         /* callers may not supply illegal parameters ... */
60         if (first < 0 || first > last || last >= bank->num_sectors)
61         {
62                 LOG_ERROR("illegal sector range");
63                 return ERROR_FAIL;
64         }
65
66         /* force "set" to 0/1 */
67         set = !!set;
68
69         /* DANGER!
70          *
71          * We must not use any cached information about protection state!!!!
72          *
73          * There are a million things that could change the protect state:
74          *
75          * the target could have reset, power cycled, been hot plugged,
76          * the application could have run, etc.
77          *
78          * Drivers only receive valid sector range.
79          */
80         retval = bank->driver->protect(bank, set, first, last);
81         if (retval != ERROR_OK)
82         {
83                 LOG_ERROR("failed setting protection for areas %d to %d", first, last);
84         }
85
86         return retval;
87 }
88
89 int flash_driver_write(struct flash_bank *bank,
90                 uint8_t *buffer, uint32_t offset, uint32_t count)
91 {
92         int retval;
93
94         retval = bank->driver->write(bank, buffer, offset, count);
95         if (retval != ERROR_OK)
96         {
97                 LOG_ERROR("error writing to flash at address 0x%08" PRIx32 " at offset 0x%8.8" PRIx32,
98                           bank->base, offset);
99         }
100
101         return retval;
102 }
103
104 int flash_driver_read(struct flash_bank *bank,
105                 uint8_t *buffer, uint32_t offset, uint32_t count)
106 {
107         int retval;
108
109         LOG_DEBUG("call flash_driver_read()");
110
111         retval = bank->driver->read(bank, buffer, offset, count);
112         if (retval != ERROR_OK)
113         {
114                 LOG_ERROR("error reading to flash at address 0x%08" PRIx32 " at offset 0x%8.8" PRIx32,
115                           bank->base, offset);
116         }
117
118         return retval;
119 }
120
121 int default_flash_read(struct flash_bank *bank,
122                 uint8_t *buffer, uint32_t offset, uint32_t count)
123 {
124         return target_read_buffer(bank->target, offset + bank->base, count, buffer);
125 }
126
127 void flash_bank_add(struct flash_bank *bank)
128 {
129         /* put flash bank in linked list */
130         unsigned bank_num = 0;
131         if (flash_banks)
132         {
133                 /* find last flash bank */
134                 struct flash_bank *p = flash_banks;
135                 while (NULL != p->next)
136                 {
137                         bank_num += 1;
138                         p = p->next;
139                 }
140                 p->next = bank;
141                 bank_num += 1;
142         }
143         else
144                 flash_banks = bank;
145
146         bank->bank_number = bank_num;
147 }
148
149 struct flash_bank *flash_bank_list(void)
150 {
151         return flash_banks;
152 }
153
154 struct flash_bank *get_flash_bank_by_num_noprobe(int num)
155 {
156         struct flash_bank *p;
157         int i = 0;
158
159         for (p = flash_banks; p; p = p->next)
160         {
161                 if (i++ == num)
162                 {
163                         return p;
164                 }
165         }
166         LOG_ERROR("flash bank %d does not exist", num);
167         return NULL;
168 }
169
170 int flash_get_bank_count(void)
171 {
172         struct flash_bank *p;
173         int i = 0;
174         for (p = flash_banks; p; p = p->next)
175         {
176                 i++;
177         }
178         return i;
179 }
180
181 struct flash_bank *get_flash_bank_by_name_noprobe(const char *name)
182 {
183         unsigned requested = get_flash_name_index(name);
184         unsigned found = 0;
185
186         struct flash_bank *bank;
187         for (bank = flash_banks; NULL != bank; bank = bank->next)
188         {
189                 if (strcmp(bank->name, name) == 0)
190                         return bank;
191                 if (!flash_driver_name_matches(bank->driver->name, name))
192                         continue;
193                 if (++found < requested)
194                         continue;
195                 return bank;
196         }
197         return NULL;
198 }
199
200 int get_flash_bank_by_name(const char *name, struct flash_bank **bank_result)
201 {
202         struct flash_bank *bank;
203         int retval;
204
205         bank = get_flash_bank_by_name_noprobe(name);
206         if (bank != NULL)
207         {
208                 retval = bank->driver->auto_probe(bank);
209
210                 if (retval != ERROR_OK)
211                 {
212                         LOG_ERROR("auto_probe failed");
213                         return retval;
214                 }
215         }
216
217         *bank_result = bank;
218         return ERROR_OK;
219 }
220
221 int get_flash_bank_by_num(int num, struct flash_bank **bank)
222 {
223         struct flash_bank *p = get_flash_bank_by_num_noprobe(num);
224         int retval;
225
226         if (p == NULL)
227         {
228                 return ERROR_FAIL;
229         }
230
231         retval = p->driver->auto_probe(p);
232
233         if (retval != ERROR_OK)
234         {
235                 LOG_ERROR("auto_probe failed");
236                 return retval;
237         }
238         *bank = p;
239         return ERROR_OK;
240 }
241
242 /* lookup flash bank by address, bank not found is success, but
243  * result_bank is set to NULL. */
244 int get_flash_bank_by_addr(struct target *target, uint32_t addr, bool check, struct flash_bank **result_bank)
245 {
246         struct flash_bank *c;
247
248         /* cycle through bank list */
249         for (c = flash_banks; c; c = c->next)
250         {
251                 int retval;
252                 retval = c->driver->auto_probe(c);
253
254                 if (retval != ERROR_OK)
255                 {
256                         LOG_ERROR("auto_probe failed");
257                         return retval;
258                 }
259                 /* check whether address belongs to this flash bank */
260                 if ((addr >= c->base) && (addr <= c->base + (c->size - 1)) && target == c->target)
261                 {
262                         *result_bank = c;
263                         return ERROR_OK;
264                 }
265         }
266         *result_bank = NULL;
267         if (check)
268         {
269                 LOG_ERROR("No flash at address 0x%08" PRIx32, addr);
270                 return ERROR_FAIL;
271         }
272         return ERROR_OK;
273 }
274
275 int default_flash_mem_blank_check(struct flash_bank *bank)
276 {
277         struct target *target = bank->target;
278         const int buffer_size = 1024;
279         int i;
280         uint32_t nBytes;
281         int retval = ERROR_OK;
282
283         if (bank->target->state != TARGET_HALTED)
284         {
285                 LOG_ERROR("Target not halted");
286                 return ERROR_TARGET_NOT_HALTED;
287         }
288
289         uint8_t *buffer = malloc(buffer_size);
290
291         for (i = 0; i < bank->num_sectors; i++)
292         {
293                 uint32_t j;
294                 bank->sectors[i].is_erased = 1;
295
296                 for (j = 0; j < bank->sectors[i].size; j += buffer_size)
297                 {
298                         uint32_t chunk;
299                         chunk = buffer_size;
300                         if (chunk > (j - bank->sectors[i].size))
301                         {
302                                 chunk = (j - bank->sectors[i].size);
303                         }
304
305                         retval = target_read_memory(target, bank->base + bank->sectors[i].offset + j, 4, chunk/4, buffer);
306                         if (retval != ERROR_OK)
307                         {
308                                 goto done;
309                         }
310
311                         for (nBytes = 0; nBytes < chunk; nBytes++)
312                         {
313                                 if (buffer[nBytes] != 0xFF)
314                                 {
315                                         bank->sectors[i].is_erased = 0;
316                                         break;
317                                 }
318                         }
319                 }
320         }
321
322         done:
323         free(buffer);
324
325         return retval;
326 }
327
328 int default_flash_blank_check(struct flash_bank *bank)
329 {
330         struct target *target = bank->target;
331         int i;
332         int retval;
333         int fast_check = 0;
334         uint32_t blank;
335
336         if (bank->target->state != TARGET_HALTED)
337         {
338                 LOG_ERROR("Target not halted");
339                 return ERROR_TARGET_NOT_HALTED;
340         }
341
342         for (i = 0; i < bank->num_sectors; i++)
343         {
344                 uint32_t address = bank->base + bank->sectors[i].offset;
345                 uint32_t size = bank->sectors[i].size;
346
347                 retval = target_blank_check_memory(target, address, size, &blank);
348                 if (retval != ERROR_OK)
349                 {
350                         fast_check = 0;
351                         break;
352                 }
353                 if (blank == 0xFF)
354                         bank->sectors[i].is_erased = 1;
355                 else
356                         bank->sectors[i].is_erased = 0;
357                 fast_check = 1;
358         }
359
360         if (!fast_check)
361         {
362                 LOG_USER("Running slow fallback erase check - add working memory");
363                 return default_flash_mem_blank_check(bank);
364         }
365
366         return ERROR_OK;
367 }
368
369 /* Manipulate given flash region, selecting the bank according to target
370  * and address.  Maps an address range to a set of sectors, and issues
371  * the callback() on that set ... e.g. to erase or unprotect its members.
372  *
373  * (Note a current bad assumption:  that protection operates on the same
374  * size sectors as erase operations use.)
375  *
376  * The "pad_reason" parameter is a kind of boolean:  when it's NULL, the
377  * range must fit those sectors exactly.  This is clearly safe; it can't
378  * erase data which the caller said to leave alone, for example.  If it's
379  * non-NULL, rather than failing, extra data in the first and/or last
380  * sectors will be added to the range, and that reason string is used when
381  * warning about those additions.
382  */
383 static int flash_iterate_address_range_inner(struct target *target,
384                 char *pad_reason, uint32_t addr, uint32_t length,
385                 int (*callback)(struct flash_bank *bank, int first, int last))
386 {
387         struct flash_bank *c;
388         uint32_t last_addr = addr + length;     /* first address AFTER end */
389         int first = -1;
390         int last = -1;
391         int i;
392
393         int retval = get_flash_bank_by_addr(target, addr, true, &c);
394         if (retval != ERROR_OK)
395                 return retval;
396
397         if (c->size == 0 || c->num_sectors == 0)
398         {
399                 LOG_ERROR("Bank is invalid");
400                 return ERROR_FLASH_BANK_INVALID;
401         }
402
403         if (length == 0)
404         {
405                 /* special case, erase whole bank when length is zero */
406                 if (addr != c->base)
407                 {
408                         LOG_ERROR("Whole bank access must start at beginning of bank.");
409                         return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
410                 }
411
412                 return callback(c, 0, c->num_sectors - 1);
413         }
414
415         /* check whether it all fits in this bank */
416         if (addr + length - 1 > c->base + c->size - 1)
417         {
418                 LOG_ERROR("Flash access does not fit into bank.");
419                 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
420         }
421
422         /** @todo: handle erasures that cross into adjacent banks */
423
424         addr -= c->base;
425         last_addr -= c->base;
426
427         for (i = 0; i < c->num_sectors; i++)
428         {
429                 struct flash_sector *f = c->sectors + i;
430                 uint32_t end = f->offset + f->size;
431
432                 /* start only on a sector boundary */
433                 if (first < 0) {
434                         /* scanned past the first sector? */
435                         if (addr < f->offset)
436                                 break;
437
438                         /* is this the first sector? */
439                         if (addr == f->offset)
440                                 first = i;
441
442                         /* Does this need head-padding?  If so, pad and warn;
443                          * or else force an error.
444                          *
445                          * Such padding can make trouble, since *WE* can't
446                          * ever know if that data was in use.  The warning
447                          * should help users sort out messes later.
448                          */
449                         else if (addr < end && pad_reason) {
450                                 /* FIXME say how many bytes (e.g. 80 KB) */
451                                 LOG_WARNING("Adding extra %s range, "
452                                                 "%#8.8x to %#8.8x",
453                                         pad_reason,
454                                         (unsigned) f->offset,
455                                         (unsigned) addr - 1);
456                                 first = i;
457                         } else
458                                 continue;
459                 }
460
461                 /* is this (also?) the last sector? */
462                 if (last_addr == end) {
463                         last = i;
464                         break;
465                 }
466
467                 /* Does this need tail-padding?  If so, pad and warn;
468                  * or else force an error.
469                  */
470                 if (last_addr < end && pad_reason) {
471                         /* FIXME say how many bytes (e.g. 80 KB) */
472                         LOG_WARNING("Adding extra %s range, "
473                                         "%#8.8x to %#8.8x",
474                                 pad_reason,
475                                 (unsigned) last_addr,
476                                 (unsigned) end - 1);
477                         last = i;
478                         break;
479                 }
480
481                 /* MUST finish on a sector boundary */
482                 if (last_addr <= f->offset)
483                         break;
484         }
485
486         /* invalid start or end address? */
487         if (first == -1 || last == -1) {
488                 LOG_ERROR("address range 0x%8.8x .. 0x%8.8x "
489                                 "is not sector-aligned",
490                                 (unsigned) (c->base + addr),
491                                 (unsigned) (c->base + last_addr - 1));
492                 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
493         }
494
495         /* The NOR driver may trim this range down, based on what
496          * sectors are already erased/unprotected.  GDB currently
497          * blocks such optimizations.
498          */
499         return callback(c, first, last);
500 }
501
502 /* The inner fn only handles a single bank, we could be spanning
503  * multiple chips.
504  */
505 static int flash_iterate_address_range(struct target *target,
506                 char *pad_reason, uint32_t addr, uint32_t length,
507                 int (*callback)(struct flash_bank *bank, int first, int last))
508 {
509         struct flash_bank *c;
510         int retval = ERROR_OK;
511
512         /* Danger! zero-length iterations means entire bank! */
513         do
514         {
515                 retval = get_flash_bank_by_addr(target, addr, true, &c);
516                 if (retval != ERROR_OK)
517                         return retval;
518
519                 uint32_t cur_length = length;
520                 /* check whether it all fits in this bank */
521                 if (addr + length - 1 > c->base + c->size - 1)
522                 {
523                         LOG_DEBUG("iterating over more than one flash bank.");
524                         cur_length = c->base + c->size - addr;
525                 }
526                 retval = flash_iterate_address_range_inner(target,
527                                 pad_reason, addr, cur_length,
528                                 callback);
529                 if (retval != ERROR_OK)
530                         break;
531
532                 length -= cur_length;
533                 addr += cur_length;
534         } while (length > 0);
535
536         return retval;
537 }
538
539 int flash_erase_address_range(struct target *target,
540                 bool pad, uint32_t addr, uint32_t length)
541 {
542         return flash_iterate_address_range(target, pad ? "erase" : NULL,
543                         addr, length, &flash_driver_erase);
544 }
545
546 static int flash_driver_unprotect(struct flash_bank *bank, int first, int last)
547 {
548         return flash_driver_protect(bank, 0, first, last);
549 }
550
551 int flash_unlock_address_range(struct target *target, uint32_t addr, uint32_t length)
552 {
553         /* By default, pad to sector boundaries ... the real issue here
554          * is that our (only) caller *permanently* removes protection,
555          * and doesn't restore it.
556          */
557         return flash_iterate_address_range(target, "unprotect",
558                         addr, length, &flash_driver_unprotect);
559 }
560
561 static int compare_section (const void * a, const void * b)
562 {
563         struct imagesection *b1, *b2;
564         b1=*((struct imagesection **)a);
565         b2=*((struct imagesection **)b);
566
567         if (b1->base_address == b2->base_address)
568         {
569                 return 0;
570         } else if (b1->base_address > b2->base_address)
571         {
572                 return 1;
573         } else
574         {
575                 return -1;
576         }
577 }
578
579
580 int flash_write_unlock(struct target *target, struct image *image,
581                 uint32_t *written, int erase, bool unlock)
582 {
583         int retval = ERROR_OK;
584
585         int section;
586         uint32_t section_offset;
587         struct flash_bank *c;
588         int *padding;
589
590         section = 0;
591         section_offset = 0;
592
593         if (written)
594                 *written = 0;
595
596         if (erase)
597         {
598                 /* assume all sectors need erasing - stops any problems
599                  * when flash_write is called multiple times */
600
601                 flash_set_dirty();
602         }
603
604         /* allocate padding array */
605         padding = calloc(image->num_sections, sizeof(*padding));
606
607         /* This fn requires all sections to be in ascending order of addresses,
608          * whereas an image can have sections out of order. */
609         struct imagesection **sections = malloc(sizeof(struct imagesection *) *
610                         image->num_sections);
611         int i;
612         for (i = 0; i < image->num_sections; i++)
613         {
614                 sections[i] = &image->sections[i];
615         }
616
617         qsort(sections, image->num_sections, sizeof(struct imagesection *),
618                         compare_section);
619
620         /* loop until we reach end of the image */
621         while (section < image->num_sections)
622         {
623                 uint32_t buffer_size;
624                 uint8_t *buffer;
625                 int section_last;
626                 uint32_t run_address = sections[section]->base_address + section_offset;
627                 uint32_t run_size = sections[section]->size - section_offset;
628                 int pad_bytes = 0;
629
630                 if (sections[section]->size ==  0)
631                 {
632                         LOG_WARNING("empty section %d", section);
633                         section++;
634                         section_offset = 0;
635                         continue;
636                 }
637
638                 /* find the corresponding flash bank */
639                 retval = get_flash_bank_by_addr(target, run_address, false, &c);
640                 if (retval != ERROR_OK)
641                 {
642                         goto done;
643                 }
644                 if (c == NULL)
645                 {
646                         section++; /* and skip it */
647                         section_offset = 0;
648                         continue;
649                 }
650
651                 /* collect consecutive sections which fall into the same bank */
652                 section_last = section;
653                 padding[section] = 0;
654                 while ((run_address + run_size - 1 < c->base + c->size - 1)
655                                 && (section_last + 1 < image->num_sections))
656                 {
657                         /* sections are sorted */
658                         assert(sections[section_last + 1]->base_address >= c->base);
659                         if (sections[section_last + 1]->base_address >= (c->base + c->size))
660                         {
661                           /* Done with this bank */
662                           break;
663                         }
664
665                         /* FIXME This needlessly touches sectors BETWEEN the
666                          * sections it's writing.  Without auto erase, it just
667                          * writes ones.  That WILL INVALIDATE data in cases
668                          * like Stellaris Tempest chips, corrupting internal
669                          * ECC codes; and at least FreeScale suggests issues
670                          * with that approach (in HC11 documentation).
671                          *
672                          * With auto erase enabled, data in those sectors will
673                          * be needlessly destroyed; and some of the limited
674                          * number of flash erase cycles will be wasted...
675                          *
676                          * In both cases, the extra writes slow things down.
677                          */
678
679                         /* if we have multiple sections within our image,
680                          * flash programming could fail due to alignment issues
681                          * attempt to rebuild a consecutive buffer for the flash loader */
682                         pad_bytes = (sections[section_last + 1]->base_address) - (run_address + run_size);
683                         padding[section_last] = pad_bytes;
684                         run_size += sections[++section_last]->size;
685                         run_size += pad_bytes;
686
687                         if (pad_bytes > 0)
688                                 LOG_INFO("Padding image section %d with %d bytes", section_last-1, pad_bytes);
689                 }
690
691                 if (run_address + run_size - 1 > c->base + c->size - 1)
692                 {
693                         /* If we have more than one flash chip back to back, then we limit
694                          * the current write operation to the current chip.
695                          */
696                         LOG_DEBUG("Truncate flash run size to the current flash chip.");
697
698                         run_size = c->base + c->size - run_address;
699                         assert(run_size > 0);
700                 }
701
702                 /* If we're applying any sector automagic, then pad this
703                  * (maybe-combined) segment to the end of its last sector.
704                  */
705                 if (unlock || erase) {
706                         int sector;
707                         uint32_t offset_start = run_address - c->base;
708                         uint32_t offset_end = offset_start + run_size;
709                         uint32_t end = offset_end, delta;
710
711                         for (sector = 0; sector < c->num_sectors; sector++) {
712                                 end = c->sectors[sector].offset
713                                                 + c->sectors[sector].size;
714                                 if (offset_end <= end)
715                                         break;
716                         }
717
718                         delta = end - offset_end;
719                         padding[section_last] += delta;
720                         run_size += delta;
721                 }
722
723                 /* allocate buffer */
724                 buffer = malloc(run_size);
725                 if (buffer == NULL)
726                 {
727                         LOG_ERROR("Out of memory for flash bank buffer");
728                         retval = ERROR_FAIL;
729                         goto done;
730                 }
731                 buffer_size = 0;
732
733                 /* read sections to the buffer */
734                 while (buffer_size < run_size)
735                 {
736                         size_t size_read;
737
738                         size_read = run_size - buffer_size;
739                         if (size_read > sections[section]->size - section_offset)
740                             size_read = sections[section]->size - section_offset;
741
742                         /* KLUDGE!
743                          *
744                          * #¤%#"%¤% we have to figure out the section # from the sorted
745                          * list of pointers to sections to invoke image_read_section()...
746                          */
747                         intptr_t diff = (intptr_t)sections[section] - (intptr_t)image->sections;
748                         int t_section_num = diff / sizeof(struct imagesection);
749
750                         LOG_DEBUG("image_read_section: section = %d, t_section_num = %d, section_offset = %d, buffer_size = %d, size_read = %d",
751                                  (int)section,
752 (int)t_section_num, (int)section_offset, (int)buffer_size, (int)size_read);
753                         if ((retval = image_read_section(image, t_section_num, section_offset,
754                                         size_read, buffer + buffer_size, &size_read)) != ERROR_OK || size_read == 0)
755                         {
756                                 free(buffer);
757                                 goto done;
758                         }
759
760                         /* see if we need to pad the section */
761                         while (padding[section]--)
762                                  (buffer + buffer_size)[size_read++] = 0xff;
763
764                         buffer_size += size_read;
765                         section_offset += size_read;
766
767                         if (section_offset >= sections[section]->size)
768                         {
769                                 section++;
770                                 section_offset = 0;
771                         }
772                 }
773
774                 retval = ERROR_OK;
775
776                 if (unlock)
777                 {
778                         retval = flash_unlock_address_range(target, run_address, run_size);
779                 }
780                 if (retval == ERROR_OK)
781                 {
782                         if (erase)
783                         {
784                                 /* calculate and erase sectors */
785                                 retval = flash_erase_address_range(target,
786                                                 true, run_address, run_size);
787                         }
788                 }
789
790                 if (retval == ERROR_OK)
791                 {
792                         /* write flash sectors */
793                         retval = flash_driver_write(c, buffer, run_address - c->base, run_size);
794                 }
795
796                 free(buffer);
797
798                 if (retval != ERROR_OK)
799                 {
800                         /* abort operation */
801                         goto done;
802                 }
803
804                 if (written != NULL)
805                         *written += run_size; /* add run size to total written counter */
806         }
807
808
809 done:
810         free(sections);
811         free(padding);
812
813         return retval;
814 }
815
816 int flash_write(struct target *target, struct image *image,
817                 uint32_t *written, int erase)
818 {
819         return flash_write_unlock(target, image, written, erase, false);
820 }