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

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)