flash/nor: handle flash write alignment/padding in the infrastructure
[openocd.git] / 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 * Copyright (C) 2017-2018 Tomas Vanek <vanekt@fbl.cz> *
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 * This program is distributed in the hope that it will be useful, *
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17 * GNU General Public License for more details. *
18 * *
19 * You should have received a copy of the GNU General Public License *
20 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
21 ***************************************************************************/
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 #include <flash/common.h>
27 #include <flash/nor/core.h>
28 #include <flash/nor/imp.h>
29 #include <target/image.h>
30
31 /**
32 * @file
33 * Upper level of NOR flash framework.
34 * The lower level interfaces are to drivers. These upper level ones
35 * primarily support access from Tcl scripts or from GDB.
36 */
37
38 static struct flash_bank *flash_banks;
39
40 int flash_driver_erase(struct flash_bank *bank, int first, int last)
41 {
42 int retval;
43
44 retval = bank->driver->erase(bank, first, last);
45 if (retval != ERROR_OK)
46 LOG_ERROR("failed erasing sectors %d to %d", first, last);
47
48 return retval;
49 }
50
51 int flash_driver_protect(struct flash_bank *bank, int set, int first, int last)
52 {
53 int retval;
54 int num_blocks;
55
56 if (bank->num_prot_blocks)
57 num_blocks = bank->num_prot_blocks;
58 else
59 num_blocks = bank->num_sectors;
60
61
62 /* callers may not supply illegal parameters ... */
63 if (first < 0 || first > last || last >= num_blocks) {
64 LOG_ERROR("illegal protection block range");
65 return ERROR_FAIL;
66 }
67
68 /* force "set" to 0/1 */
69 set = !!set;
70
71 /* DANGER!
72 *
73 * We must not use any cached information about protection state!!!!
74 *
75 * There are a million things that could change the protect state:
76 *
77 * the target could have reset, power cycled, been hot plugged,
78 * the application could have run, etc.
79 *
80 * Drivers only receive valid protection block range.
81 */
82 retval = bank->driver->protect(bank, set, first, last);
83 if (retval != ERROR_OK)
84 LOG_ERROR("failed setting protection for blocks %d to %d", first, last);
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 LOG_ERROR(
97 "error writing to flash at address 0x%08" PRIx32 " at offset 0x%8.8" PRIx32,
98 bank->base,
99 offset);
100 }
101
102 return retval;
103 }
104
105 int flash_driver_read(struct flash_bank *bank,
106 uint8_t *buffer, uint32_t offset, uint32_t count)
107 {
108 int retval;
109
110 LOG_DEBUG("call flash_driver_read()");
111
112 retval = bank->driver->read(bank, buffer, offset, count);
113 if (retval != ERROR_OK) {
114 LOG_ERROR(
115 "error reading to flash at address 0x%08" PRIx32 " at offset 0x%8.8" PRIx32,
116 bank->base,
117 offset);
118 }
119
120 return retval;
121 }
122
123 int default_flash_read(struct flash_bank *bank,
124 uint8_t *buffer, uint32_t offset, uint32_t count)
125 {
126 return target_read_buffer(bank->target, offset + bank->base, count, buffer);
127 }
128
129 void flash_bank_add(struct flash_bank *bank)
130 {
131 /* put flash bank in linked list */
132 unsigned bank_num = 0;
133 if (flash_banks) {
134 /* find last flash bank */
135 struct flash_bank *p = flash_banks;
136 while (NULL != p->next) {
137 bank_num += 1;
138 p = p->next;
139 }
140 p->next = bank;
141 bank_num += 1;
142 } else
143 flash_banks = bank;
144
145 bank->bank_number = bank_num;
146 }
147
148 struct flash_bank *flash_bank_list(void)
149 {
150 return flash_banks;
151 }
152
153 struct flash_bank *get_flash_bank_by_num_noprobe(int num)
154 {
155 struct flash_bank *p;
156 int i = 0;
157
158 for (p = flash_banks; p; p = p->next) {
159 if (i++ == num)
160 return p;
161 }
162 LOG_ERROR("flash bank %d does not exist", num);
163 return NULL;
164 }
165
166 int flash_get_bank_count(void)
167 {
168 struct flash_bank *p;
169 int i = 0;
170 for (p = flash_banks; p; p = p->next)
171 i++;
172 return i;
173 }
174
175 void default_flash_free_driver_priv(struct flash_bank *bank)
176 {
177 free(bank->driver_priv);
178 bank->driver_priv = NULL;
179 }
180
181 void flash_free_all_banks(void)
182 {
183 struct flash_bank *bank = flash_banks;
184 while (bank) {
185 struct flash_bank *next = bank->next;
186 if (bank->driver->free_driver_priv)
187 bank->driver->free_driver_priv(bank);
188 else
189 LOG_WARNING("Flash driver of %s does not support free_driver_priv()", bank->name);
190
191 free(bank->name);
192 free(bank->sectors);
193 free(bank->prot_blocks);
194 free(bank);
195 bank = next;
196 }
197 flash_banks = NULL;
198 }
199
200 struct flash_bank *get_flash_bank_by_name_noprobe(const char *name)
201 {
202 unsigned requested = get_flash_name_index(name);
203 unsigned found = 0;
204
205 struct flash_bank *bank;
206 for (bank = flash_banks; NULL != bank; bank = bank->next) {
207 if (strcmp(bank->name, name) == 0)
208 return bank;
209 if (!flash_driver_name_matches(bank->driver->name, name))
210 continue;
211 if (++found < requested)
212 continue;
213 return bank;
214 }
215 return NULL;
216 }
217
218 int get_flash_bank_by_name(const char *name, struct flash_bank **bank_result)
219 {
220 struct flash_bank *bank;
221 int retval;
222
223 bank = get_flash_bank_by_name_noprobe(name);
224 if (bank != NULL) {
225 retval = bank->driver->auto_probe(bank);
226
227 if (retval != ERROR_OK) {
228 LOG_ERROR("auto_probe failed");
229 return retval;
230 }
231 }
232
233 *bank_result = bank;
234 return ERROR_OK;
235 }
236
237 int get_flash_bank_by_num(int num, struct flash_bank **bank)
238 {
239 struct flash_bank *p = get_flash_bank_by_num_noprobe(num);
240 int retval;
241
242 if (p == NULL)
243 return ERROR_FAIL;
244
245 retval = p->driver->auto_probe(p);
246
247 if (retval != ERROR_OK) {
248 LOG_ERROR("auto_probe failed");
249 return retval;
250 }
251 *bank = p;
252 return ERROR_OK;
253 }
254
255 /* lookup flash bank by address, bank not found is success, but
256 * result_bank is set to NULL. */
257 int get_flash_bank_by_addr(struct target *target,
258 uint32_t addr,
259 bool check,
260 struct flash_bank **result_bank)
261 {
262 struct flash_bank *c;
263
264 /* cycle through bank list */
265 for (c = flash_banks; c; c = c->next) {
266 if (c->target != target)
267 continue;
268
269 int retval;
270 retval = c->driver->auto_probe(c);
271
272 if (retval != ERROR_OK) {
273 LOG_ERROR("auto_probe failed");
274 return retval;
275 }
276 /* check whether address belongs to this flash bank */
277 if ((addr >= c->base) && (addr <= c->base + (c->size - 1))) {
278 *result_bank = c;
279 return ERROR_OK;
280 }
281 }
282 *result_bank = NULL;
283 if (check) {
284 LOG_ERROR("No flash at address 0x%08" PRIx32, addr);
285 return ERROR_FAIL;
286 }
287 return ERROR_OK;
288 }
289
290 static int default_flash_mem_blank_check(struct flash_bank *bank)
291 {
292 struct target *target = bank->target;
293 const int buffer_size = 1024;
294 int i;
295 uint32_t nBytes;
296 int retval = ERROR_OK;
297
298 if (bank->target->state != TARGET_HALTED) {
299 LOG_ERROR("Target not halted");
300 return ERROR_TARGET_NOT_HALTED;
301 }
302
303 uint8_t *buffer = malloc(buffer_size);
304
305 for (i = 0; i < bank->num_sectors; i++) {
306 uint32_t j;
307 bank->sectors[i].is_erased = 1;
308
309 for (j = 0; j < bank->sectors[i].size; j += buffer_size) {
310 uint32_t chunk;
311 chunk = buffer_size;
312 if (chunk > (j - bank->sectors[i].size))
313 chunk = (j - bank->sectors[i].size);
314
315 retval = target_read_memory(target,
316 bank->base + bank->sectors[i].offset + j,
317 4,
318 chunk/4,
319 buffer);
320 if (retval != ERROR_OK)
321 goto done;
322
323 for (nBytes = 0; nBytes < chunk; nBytes++) {
324 if (buffer[nBytes] != bank->erased_value) {
325 bank->sectors[i].is_erased = 0;
326 break;
327 }
328 }
329 }
330 }
331
332 done:
333 free(buffer);
334
335 return retval;
336 }
337
338 int default_flash_blank_check(struct flash_bank *bank)
339 {
340 struct target *target = bank->target;
341 int i;
342 int retval;
343
344 if (bank->target->state != TARGET_HALTED) {
345 LOG_ERROR("Target not halted");
346 return ERROR_TARGET_NOT_HALTED;
347 }
348
349 struct target_memory_check_block *block_array;
350 block_array = malloc(bank->num_sectors * sizeof(struct target_memory_check_block));
351 if (block_array == NULL)
352 return default_flash_mem_blank_check(bank);
353
354 for (i = 0; i < bank->num_sectors; i++) {
355 block_array[i].address = bank->base + bank->sectors[i].offset;
356 block_array[i].size = bank->sectors[i].size;
357 block_array[i].result = UINT32_MAX; /* erase state unknown */
358 }
359
360 bool fast_check = true;
361 for (i = 0; i < bank->num_sectors; ) {
362 retval = target_blank_check_memory(target,
363 block_array + i, bank->num_sectors - i,
364 bank->erased_value);
365 if (retval < 1) {
366 /* Run slow fallback if the first run gives no result
367 * otherwise use possibly incomplete results */
368 if (i == 0)
369 fast_check = false;
370 break;
371 }
372 i += retval; /* add number of blocks done this round */
373 }
374
375 if (fast_check) {
376 for (i = 0; i < bank->num_sectors; i++)
377 bank->sectors[i].is_erased = block_array[i].result;
378 retval = ERROR_OK;
379 } else {
380 LOG_USER("Running slow fallback erase check - add working memory");
381 retval = default_flash_mem_blank_check(bank);
382 }
383 free(block_array);
384
385 return retval;
386 }
387
388 /* Manipulate given flash region, selecting the bank according to target
389 * and address. Maps an address range to a set of sectors, and issues
390 * the callback() on that set ... e.g. to erase or unprotect its members.
391 *
392 * Parameter iterate_protect_blocks switches iteration of protect block
393 * instead of erase sectors. If there is no protect blocks array, sectors
394 * are used in iteration, so compatibility for old flash drivers is retained.
395 *
396 * The "pad_reason" parameter is a kind of boolean: when it's NULL, the
397 * range must fit those sectors exactly. This is clearly safe; it can't
398 * erase data which the caller said to leave alone, for example. If it's
399 * non-NULL, rather than failing, extra data in the first and/or last
400 * sectors will be added to the range, and that reason string is used when
401 * warning about those additions.
402 */
403 static int flash_iterate_address_range_inner(struct target *target,
404 char *pad_reason, uint32_t addr, uint32_t length,
405 bool iterate_protect_blocks,
406 int (*callback)(struct flash_bank *bank, int first, int last))
407 {
408 struct flash_bank *c;
409 struct flash_sector *block_array;
410 uint32_t last_addr = addr + length; /* first address AFTER end */
411 int first = -1;
412 int last = -1;
413 int i;
414 int num_blocks;
415
416 int retval = get_flash_bank_by_addr(target, addr, true, &c);
417 if (retval != ERROR_OK)
418 return retval;
419
420 if (c->size == 0 || c->num_sectors == 0) {
421 LOG_ERROR("Bank is invalid");
422 return ERROR_FLASH_BANK_INVALID;
423 }
424
425 if (length == 0) {
426 /* special case, erase whole bank when length is zero */
427 if (addr != c->base) {
428 LOG_ERROR("Whole bank access must start at beginning of bank.");
429 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
430 }
431
432 return callback(c, 0, c->num_sectors - 1);
433 }
434
435 /* check whether it all fits in this bank */
436 if (addr + length - 1 > c->base + c->size - 1) {
437 LOG_ERROR("Flash access does not fit into bank.");
438 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
439 }
440
441 if (c->prot_blocks == NULL || c->num_prot_blocks == 0) {
442 /* flash driver does not define protect blocks, use sectors instead */
443 iterate_protect_blocks = false;
444 }
445
446 if (iterate_protect_blocks) {
447 block_array = c->prot_blocks;
448 num_blocks = c->num_prot_blocks;
449 } else {
450 block_array = c->sectors;
451 num_blocks = c->num_sectors;
452 }
453
454 addr -= c->base;
455 last_addr -= c->base;
456
457 for (i = 0; i < num_blocks; i++) {
458 struct flash_sector *f = &block_array[i];
459 uint32_t end = f->offset + f->size;
460
461 /* start only on a sector boundary */
462 if (first < 0) {
463 /* scanned past the first sector? */
464 if (addr < f->offset)
465 break;
466
467 /* is this the first sector? */
468 if (addr == f->offset)
469 first = i;
470
471 /* Does this need head-padding? If so, pad and warn;
472 * or else force an error.
473 *
474 * Such padding can make trouble, since *WE* can't
475 * ever know if that data was in use. The warning
476 * should help users sort out messes later.
477 */
478 else if (addr < end && pad_reason) {
479 /* FIXME say how many bytes (e.g. 80 KB) */
480 LOG_WARNING("Adding extra %s range, "
481 "%#8.8x to %#8.8x",
482 pad_reason,
483 (unsigned) f->offset,
484 (unsigned) addr - 1);
485 first = i;
486 } else
487 continue;
488 }
489
490 /* is this (also?) the last sector? */
491 if (last_addr == end) {
492 last = i;
493 break;
494 }
495
496 /* Does this need tail-padding? If so, pad and warn;
497 * or else force an error.
498 */
499 if (last_addr < end && pad_reason) {
500 /* FIXME say how many bytes (e.g. 80 KB) */
501 LOG_WARNING("Adding extra %s range, "
502 "%#8.8x to %#8.8x",
503 pad_reason,
504 (unsigned) last_addr,
505 (unsigned) end - 1);
506 last = i;
507 break;
508 }
509
510 /* MUST finish on a sector boundary */
511 if (last_addr <= f->offset)
512 break;
513 }
514
515 /* invalid start or end address? */
516 if (first == -1 || last == -1) {
517 LOG_ERROR("address range 0x%8.8x .. 0x%8.8x "
518 "is not sector-aligned",
519 (unsigned) (c->base + addr),
520 (unsigned) (c->base + last_addr - 1));
521 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
522 }
523
524 /* The NOR driver may trim this range down, based on what
525 * sectors are already erased/unprotected. GDB currently
526 * blocks such optimizations.
527 */
528 return callback(c, first, last);
529 }
530
531 /* The inner fn only handles a single bank, we could be spanning
532 * multiple chips.
533 */
534 static int flash_iterate_address_range(struct target *target,
535 char *pad_reason, uint32_t addr, uint32_t length,
536 bool iterate_protect_blocks,
537 int (*callback)(struct flash_bank *bank, int first, int last))
538 {
539 struct flash_bank *c;
540 int retval = ERROR_OK;
541
542 /* Danger! zero-length iterations means entire bank! */
543 do {
544 retval = get_flash_bank_by_addr(target, addr, true, &c);
545 if (retval != ERROR_OK)
546 return retval;
547
548 uint32_t cur_length = length;
549 /* check whether it all fits in this bank */
550 if (addr + length - 1 > c->base + c->size - 1) {
551 LOG_DEBUG("iterating over more than one flash bank.");
552 cur_length = c->base + c->size - addr;
553 }
554 retval = flash_iterate_address_range_inner(target,
555 pad_reason, addr, cur_length,
556 iterate_protect_blocks,
557 callback);
558 if (retval != ERROR_OK)
559 break;
560
561 length -= cur_length;
562 addr += cur_length;
563 } while (length > 0);
564
565 return retval;
566 }
567
568 int flash_erase_address_range(struct target *target,
569 bool pad, uint32_t addr, uint32_t length)
570 {
571 return flash_iterate_address_range(target, pad ? "erase" : NULL,
572 addr, length, false, &flash_driver_erase);
573 }
574
575 static int flash_driver_unprotect(struct flash_bank *bank, int first, int last)
576 {
577 return flash_driver_protect(bank, 0, first, last);
578 }
579
580 int flash_unlock_address_range(struct target *target, uint32_t addr, uint32_t length)
581 {
582 /* By default, pad to sector boundaries ... the real issue here
583 * is that our (only) caller *permanently* removes protection,
584 * and doesn't restore it.
585 */
586 return flash_iterate_address_range(target, "unprotect",
587 addr, length, true, &flash_driver_unprotect);
588 }
589
590 static int compare_section(const void *a, const void *b)
591 {
592 struct imagesection *b1, *b2;
593 b1 = *((struct imagesection **)a);
594 b2 = *((struct imagesection **)b);
595
596 if (b1->base_address == b2->base_address)
597 return 0;
598 else if (b1->base_address > b2->base_address)
599 return 1;
600 else
601 return -1;
602 }
603
604 /**
605 * Get aligned start address of a flash write region
606 */
607 target_addr_t flash_write_align_start(struct flash_bank *bank, target_addr_t addr)
608 {
609 if (addr < bank->base || addr >= bank->base + bank->size
610 || bank->write_start_alignment <= 1)
611 return addr;
612
613 if (bank->write_start_alignment == FLASH_WRITE_ALIGN_SECTOR) {
614 uint32_t offset = addr - bank->base;
615 uint32_t aligned = 0;
616 int sect;
617 for (sect = 0; sect < bank->num_sectors; sect++) {
618 if (bank->sectors[sect].offset > offset)
619 break;
620
621 aligned = bank->sectors[sect].offset;
622 }
623 return bank->base + aligned;
624 }
625
626 return addr & ~(bank->write_start_alignment - 1);
627 }
628
629 /**
630 * Get aligned end address of a flash write region
631 */
632 target_addr_t flash_write_align_end(struct flash_bank *bank, target_addr_t addr)
633 {
634 if (addr < bank->base || addr >= bank->base + bank->size
635 || bank->write_end_alignment <= 1)
636 return addr;
637
638 if (bank->write_end_alignment == FLASH_WRITE_ALIGN_SECTOR) {
639 uint32_t offset = addr - bank->base;
640 uint32_t aligned = 0;
641 int sect;
642 for (sect = 0; sect < bank->num_sectors; sect++) {
643 aligned = bank->sectors[sect].offset + bank->sectors[sect].size - 1;
644 if (aligned >= offset)
645 break;
646 }
647 return bank->base + aligned;
648 }
649
650 return addr | (bank->write_end_alignment - 1);
651 }
652
653 /**
654 * Check if gap between sections is bigger than minimum required to discontinue flash write
655 */
656 static bool flash_write_check_gap(struct flash_bank *bank,
657 target_addr_t addr1, target_addr_t addr2)
658 {
659 if (bank->minimal_write_gap == FLASH_WRITE_CONTINUOUS
660 || addr1 < bank->base || addr1 >= bank->base + bank->size
661 || addr2 < bank->base || addr2 >= bank->base + bank->size)
662 return false;
663
664 if (bank->minimal_write_gap == FLASH_WRITE_GAP_SECTOR) {
665 int sect;
666 uint32_t offset1 = addr1 - bank->base;
667 /* find the sector following the one containing addr1 */
668 for (sect = 0; sect < bank->num_sectors; sect++) {
669 if (bank->sectors[sect].offset > offset1)
670 break;
671 }
672 if (sect >= bank->num_sectors)
673 return false;
674
675 uint32_t offset2 = addr2 - bank->base;
676 return bank->sectors[sect].offset + bank->sectors[sect].size <= offset2;
677 }
678
679 target_addr_t aligned1 = flash_write_align_end(bank, addr1);
680 target_addr_t aligned2 = flash_write_align_start(bank, addr2);
681 return aligned1 + bank->minimal_write_gap < aligned2;
682 }
683
684
685 int flash_write_unlock(struct target *target, struct image *image,
686 uint32_t *written, int erase, bool unlock)
687 {
688 int retval = ERROR_OK;
689
690 int section;
691 uint32_t section_offset;
692 struct flash_bank *c;
693 int *padding;
694
695 section = 0;
696 section_offset = 0;
697
698 if (written)
699 *written = 0;
700
701 if (erase) {
702 /* assume all sectors need erasing - stops any problems
703 * when flash_write is called multiple times */
704
705 flash_set_dirty();
706 }
707
708 /* allocate padding array */
709 padding = calloc(image->num_sections, sizeof(*padding));
710
711 /* This fn requires all sections to be in ascending order of addresses,
712 * whereas an image can have sections out of order. */
713 struct imagesection **sections = malloc(sizeof(struct imagesection *) *
714 image->num_sections);
715 int i;
716 for (i = 0; i < image->num_sections; i++)
717 sections[i] = &image->sections[i];
718
719 qsort(sections, image->num_sections, sizeof(struct imagesection *),
720 compare_section);
721
722 /* loop until we reach end of the image */
723 while (section < image->num_sections) {
724 uint32_t buffer_idx;
725 uint8_t *buffer;
726 int section_last;
727 target_addr_t run_address = sections[section]->base_address + section_offset;
728 uint32_t run_size = sections[section]->size - section_offset;
729 int pad_bytes = 0;
730
731 if (sections[section]->size == 0) {
732 LOG_WARNING("empty section %d", section);
733 section++;
734 section_offset = 0;
735 continue;
736 }
737
738 /* find the corresponding flash bank */
739 retval = get_flash_bank_by_addr(target, run_address, false, &c);
740 if (retval != ERROR_OK)
741 goto done;
742 if (c == NULL) {
743 LOG_WARNING("no flash bank found for address " TARGET_ADDR_FMT, run_address);
744 section++; /* and skip it */
745 section_offset = 0;
746 continue;
747 }
748
749 /* collect consecutive sections which fall into the same bank */
750 section_last = section;
751 padding[section] = 0;
752 while ((run_address + run_size - 1 < c->base + c->size - 1) &&
753 (section_last + 1 < image->num_sections)) {
754 /* sections are sorted */
755 assert(sections[section_last + 1]->base_address >= c->base);
756 if (sections[section_last + 1]->base_address >= (c->base + c->size)) {
757 /* Done with this bank */
758 break;
759 }
760
761 /* if we have multiple sections within our image,
762 * flash programming could fail due to alignment issues
763 * attempt to rebuild a consecutive buffer for the flash loader */
764 target_addr_t run_next_addr = run_address + run_size;
765 target_addr_t next_section_base = sections[section_last + 1]->base_address;
766 if (next_section_base < run_next_addr) {
767 LOG_ERROR("Section at " TARGET_ADDR_FMT
768 " overlaps section ending at " TARGET_ADDR_FMT,
769 next_section_base, run_next_addr);
770 LOG_ERROR("Flash write aborted.");
771 retval = ERROR_FAIL;
772 goto done;
773 }
774
775 pad_bytes = next_section_base - run_next_addr;
776 if (pad_bytes) {
777 if (flash_write_check_gap(c, run_next_addr - 1, next_section_base)) {
778 LOG_INFO("Flash write discontinued at " TARGET_ADDR_FMT
779 ", next section at " TARGET_ADDR_FMT,
780 run_next_addr, next_section_base);
781 break;
782 }
783 }
784 if (pad_bytes > 0)
785 LOG_INFO("Padding image section %d at " TARGET_ADDR_FMT
786 " with %d bytes",
787 section_last, run_next_addr, pad_bytes);
788
789 padding[section_last] = pad_bytes;
790 run_size += pad_bytes;
791 run_size += sections[++section_last]->size;
792 }
793
794 if (run_address + run_size - 1 > c->base + c->size - 1) {
795 /* If we have more than one flash chip back to back, then we limit
796 * the current write operation to the current chip.
797 */
798 LOG_DEBUG("Truncate flash run size to the current flash chip.");
799
800 run_size = c->base + c->size - run_address;
801 assert(run_size > 0);
802 }
803
804 uint32_t padding_at_start = 0;
805 if (c->write_start_alignment || c->write_end_alignment) {
806 /* align write region according to bank requirements */
807 target_addr_t aligned_start = flash_write_align_start(c, run_address);
808 padding_at_start = run_address - aligned_start;
809 if (padding_at_start > 0) {
810 LOG_WARNING("Section start address " TARGET_ADDR_FMT
811 " breaks the required alignment of flash bank %s",
812 run_address, c->name);
813 LOG_WARNING("Padding %d bytes from " TARGET_ADDR_FMT,
814 padding_at_start, aligned_start);
815
816 run_address -= padding_at_start;
817 run_size += padding_at_start;
818 }
819
820 target_addr_t run_end = run_address + run_size - 1;
821 target_addr_t aligned_end = flash_write_align_end(c, run_end);
822 pad_bytes = aligned_end - run_end;
823 if (pad_bytes > 0) {
824 LOG_INFO("Padding image section %d at " TARGET_ADDR_FMT
825 " with %d bytes (bank write end alignment)",
826 section_last, run_end + 1, pad_bytes);
827
828 padding[section_last] += pad_bytes;
829 run_size += pad_bytes;
830 }
831
832 } else if (unlock || erase) {
833 /* If we're applying any sector automagic, then pad this
834 * (maybe-combined) segment to the end of its last sector.
835 */
836 int sector;
837 uint32_t offset_start = run_address - c->base;
838 uint32_t offset_end = offset_start + run_size;
839 uint32_t end = offset_end, delta;
840
841 for (sector = 0; sector < c->num_sectors; sector++) {
842 end = c->sectors[sector].offset
843 + c->sectors[sector].size;
844 if (offset_end <= end)
845 break;
846 }
847
848 delta = end - offset_end;
849 padding[section_last] += delta;
850 run_size += delta;
851 }
852
853 /* allocate buffer */
854 buffer = malloc(run_size);
855 if (buffer == NULL) {
856 LOG_ERROR("Out of memory for flash bank buffer");
857 retval = ERROR_FAIL;
858 goto done;
859 }
860
861 if (padding_at_start)
862 memset(buffer, c->default_padded_value, padding_at_start);
863
864 buffer_idx = padding_at_start;
865
866 /* read sections to the buffer */
867 while (buffer_idx < run_size) {
868 size_t size_read;
869
870 size_read = run_size - buffer_idx;
871 if (size_read > sections[section]->size - section_offset)
872 size_read = sections[section]->size - section_offset;
873
874 /* KLUDGE!
875 *
876 * #¤%#"%¤% we have to figure out the section # from the sorted
877 * list of pointers to sections to invoke image_read_section()...
878 */
879 intptr_t diff = (intptr_t)sections[section] - (intptr_t)image->sections;
880 int t_section_num = diff / sizeof(struct imagesection);
881
882 LOG_DEBUG("image_read_section: section = %d, t_section_num = %d, "
883 "section_offset = %"PRIu32", buffer_idx = %"PRIu32", size_read = %zu",
884 section, t_section_num, section_offset,
885 buffer_idx, size_read);
886 retval = image_read_section(image, t_section_num, section_offset,
887 size_read, buffer + buffer_idx, &size_read);
888 if (retval != ERROR_OK || size_read == 0) {
889 free(buffer);
890 goto done;
891 }
892
893 buffer_idx += size_read;
894 section_offset += size_read;
895
896 /* see if we need to pad the section */
897 if (padding[section]) {
898 memset(buffer + buffer_idx, c->default_padded_value, padding[section]);
899 buffer_idx += padding[section];
900 }
901
902 if (section_offset >= sections[section]->size) {
903 section++;
904 section_offset = 0;
905 }
906 }
907
908 retval = ERROR_OK;
909
910 if (unlock)
911 retval = flash_unlock_address_range(target, run_address, run_size);
912 if (retval == ERROR_OK) {
913 if (erase) {
914 /* calculate and erase sectors */
915 retval = flash_erase_address_range(target,
916 true, run_address, run_size);
917 }
918 }
919
920 if (retval == ERROR_OK) {
921 /* write flash sectors */
922 retval = flash_driver_write(c, buffer, run_address - c->base, run_size);
923 }
924
925 free(buffer);
926
927 if (retval != ERROR_OK) {
928 /* abort operation */
929 goto done;
930 }
931
932 if (written != NULL)
933 *written += run_size; /* add run size to total written counter */
934 }
935
936 done:
937 free(sections);
938 free(padding);
939
940 return retval;
941 }
942
943 int flash_write(struct target *target, struct image *image,
944 uint32_t *written, int erase)
945 {
946 return flash_write_unlock(target, image, written, erase, false);
947 }
948
949 struct flash_sector *alloc_block_array(uint32_t offset, uint32_t size, int num_blocks)
950 {
951 int i;
952
953 struct flash_sector *array = calloc(num_blocks, sizeof(struct flash_sector));
954 if (array == NULL)
955 return NULL;
956
957 for (i = 0; i < num_blocks; i++) {
958 array[i].offset = offset;
959 array[i].size = size;
960 array[i].is_erased = -1;
961 array[i].is_protected = -1;
962 offset += size;
963 }
964
965 return array;
966 }

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)