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> *
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. *
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. *
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 ***************************************************************************/
26 #include <flash/common.h>
27 #include <flash/nor/core.h>
28 #include <flash/nor/imp.h>
29 #include <target/image.h>
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.
38 static struct flash_bank
*flash_banks
;
40 int flash_driver_erase(struct flash_bank
*bank
, unsigned int first
,
45 retval
= bank
->driver
->erase(bank
, first
, last
);
46 if (retval
!= ERROR_OK
)
47 LOG_ERROR("failed erasing sectors %u to %u", first
, last
);
52 int flash_driver_protect(struct flash_bank
*bank
, int set
, unsigned int first
,
56 unsigned int num_blocks
;
58 if (bank
->num_prot_blocks
)
59 num_blocks
= bank
->num_prot_blocks
;
61 num_blocks
= bank
->num_sectors
;
64 /* callers may not supply illegal parameters ... */
65 if (first
> last
|| last
>= num_blocks
) {
66 LOG_ERROR("illegal protection block range");
70 /* force "set" to 0/1 */
73 if (!bank
->driver
->protect
) {
74 LOG_ERROR("Flash protection is not supported.");
75 return ERROR_FLASH_OPER_UNSUPPORTED
;
80 * We must not use any cached information about protection state!!!!
82 * There are a million things that could change the protect state:
84 * the target could have reset, power cycled, been hot plugged,
85 * the application could have run, etc.
87 * Drivers only receive valid protection block range.
89 retval
= bank
->driver
->protect(bank
, set
, first
, last
);
90 if (retval
!= ERROR_OK
)
91 LOG_ERROR("failed setting protection for blocks %u to %u", first
, last
);
96 int flash_driver_write(struct flash_bank
*bank
,
97 const uint8_t *buffer
, uint32_t offset
, uint32_t count
)
101 retval
= bank
->driver
->write(bank
, buffer
, offset
, count
);
102 if (retval
!= ERROR_OK
) {
104 "error writing to flash at address " TARGET_ADDR_FMT
105 " at offset 0x%8.8" PRIx32
,
113 int flash_driver_read(struct flash_bank
*bank
,
114 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
118 LOG_DEBUG("call flash_driver_read()");
120 retval
= bank
->driver
->read(bank
, buffer
, offset
, count
);
121 if (retval
!= ERROR_OK
) {
123 "error reading to flash at address " TARGET_ADDR_FMT
124 " at offset 0x%8.8" PRIx32
,
132 int default_flash_read(struct flash_bank
*bank
,
133 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
135 return target_read_buffer(bank
->target
, offset
+ bank
->base
, count
, buffer
);
138 int flash_driver_verify(struct flash_bank
*bank
,
139 const uint8_t *buffer
, uint32_t offset
, uint32_t count
)
143 retval
= bank
->driver
->verify
? bank
->driver
->verify(bank
, buffer
, offset
, count
) :
144 default_flash_verify(bank
, buffer
, offset
, count
);
145 if (retval
!= ERROR_OK
) {
146 LOG_ERROR("verify failed in bank at " TARGET_ADDR_FMT
" starting at 0x%8.8" PRIx32
,
153 int default_flash_verify(struct flash_bank
*bank
,
154 const uint8_t *buffer
, uint32_t offset
, uint32_t count
)
156 uint32_t target_crc
, image_crc
;
159 retval
= image_calculate_checksum(buffer
, count
, &image_crc
);
160 if (retval
!= ERROR_OK
)
163 retval
= target_checksum_memory(bank
->target
, offset
+ bank
->base
, count
, &target_crc
);
164 if (retval
!= ERROR_OK
)
167 LOG_DEBUG("addr " TARGET_ADDR_FMT
", len 0x%08" PRIx32
", crc 0x%08" PRIx32
" 0x%08" PRIx32
,
168 offset
+ bank
->base
, count
, ~image_crc
, ~target_crc
);
169 if (target_crc
== image_crc
)
175 void flash_bank_add(struct flash_bank
*bank
)
177 /* put flash bank in linked list */
178 unsigned bank_num
= 0;
180 /* find last flash bank */
181 struct flash_bank
*p
= flash_banks
;
191 bank
->bank_number
= bank_num
;
194 struct flash_bank
*flash_bank_list(void)
199 struct flash_bank
*get_flash_bank_by_num_noprobe(unsigned int num
)
201 struct flash_bank
*p
;
204 for (p
= flash_banks
; p
; p
= p
->next
) {
208 LOG_ERROR("flash bank %d does not exist", num
);
212 unsigned int flash_get_bank_count(void)
214 struct flash_bank
*p
;
216 for (p
= flash_banks
; p
; p
= p
->next
)
221 void default_flash_free_driver_priv(struct flash_bank
*bank
)
223 free(bank
->driver_priv
);
224 bank
->driver_priv
= NULL
;
227 void flash_free_all_banks(void)
229 struct flash_bank
*bank
= flash_banks
;
231 struct flash_bank
*next
= bank
->next
;
232 if (bank
->driver
->free_driver_priv
)
233 bank
->driver
->free_driver_priv(bank
);
235 LOG_WARNING("Flash driver of %s does not support free_driver_priv()", bank
->name
);
237 /* For 'virtual' flash driver bank->sectors and bank->prot_blocks pointers are copied from
238 * master flash_bank structure. They point to memory locations allocated by master flash driver
239 * so master driver is responsible for releasing them.
240 * Avoid UB caused by double-free memory corruption if flash bank is 'virtual'. */
242 if (strcmp(bank
->driver
->name
, "virtual") != 0) {
244 free(bank
->prot_blocks
);
254 struct flash_bank
*get_flash_bank_by_name_noprobe(const char *name
)
256 unsigned requested
= get_flash_name_index(name
);
259 struct flash_bank
*bank
;
260 for (bank
= flash_banks
; bank
; bank
= bank
->next
) {
261 if (strcmp(bank
->name
, name
) == 0)
263 if (!flash_driver_name_matches(bank
->driver
->name
, name
))
265 if (++found
< requested
)
272 int get_flash_bank_by_name(const char *name
, struct flash_bank
**bank_result
)
274 struct flash_bank
*bank
;
277 bank
= get_flash_bank_by_name_noprobe(name
);
279 retval
= bank
->driver
->auto_probe(bank
);
281 if (retval
!= ERROR_OK
) {
282 LOG_ERROR("auto_probe failed");
291 int get_flash_bank_by_num(unsigned int num
, struct flash_bank
**bank
)
293 struct flash_bank
*p
= get_flash_bank_by_num_noprobe(num
);
299 retval
= p
->driver
->auto_probe(p
);
301 if (retval
!= ERROR_OK
) {
302 LOG_ERROR("auto_probe failed");
309 /* lookup flash bank by address, bank not found is success, but
310 * result_bank is set to NULL. */
311 int get_flash_bank_by_addr(struct target
*target
,
314 struct flash_bank
**result_bank
)
316 struct flash_bank
*c
;
318 /* cycle through bank list */
319 for (c
= flash_banks
; c
; c
= c
->next
) {
320 if (c
->target
!= target
)
324 retval
= c
->driver
->auto_probe(c
);
326 if (retval
!= ERROR_OK
) {
327 LOG_ERROR("auto_probe failed");
330 /* check whether address belongs to this flash bank */
331 if ((addr
>= c
->base
) && (addr
<= c
->base
+ (c
->size
- 1))) {
338 LOG_ERROR("No flash at address " TARGET_ADDR_FMT
, addr
);
344 static int default_flash_mem_blank_check(struct flash_bank
*bank
)
346 struct target
*target
= bank
->target
;
347 const int buffer_size
= 1024;
349 int retval
= ERROR_OK
;
351 if (bank
->target
->state
!= TARGET_HALTED
) {
352 LOG_ERROR("Target not halted");
353 return ERROR_TARGET_NOT_HALTED
;
356 uint8_t *buffer
= malloc(buffer_size
);
358 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++) {
360 bank
->sectors
[i
].is_erased
= 1;
362 for (j
= 0; j
< bank
->sectors
[i
].size
; j
+= buffer_size
) {
365 if (chunk
> (bank
->sectors
[i
].size
- j
))
366 chunk
= (bank
->sectors
[i
].size
- j
);
368 retval
= target_read_memory(target
,
369 bank
->base
+ bank
->sectors
[i
].offset
+ j
,
373 if (retval
!= ERROR_OK
)
376 for (n_bytes
= 0; n_bytes
< chunk
; n_bytes
++) {
377 if (buffer
[n_bytes
] != bank
->erased_value
) {
378 bank
->sectors
[i
].is_erased
= 0;
391 int default_flash_blank_check(struct flash_bank
*bank
)
393 struct target
*target
= bank
->target
;
396 if (bank
->target
->state
!= TARGET_HALTED
) {
397 LOG_ERROR("Target not halted");
398 return ERROR_TARGET_NOT_HALTED
;
401 struct target_memory_check_block
*block_array
;
402 block_array
= malloc(bank
->num_sectors
* sizeof(struct target_memory_check_block
));
404 return default_flash_mem_blank_check(bank
);
406 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++) {
407 block_array
[i
].address
= bank
->base
+ bank
->sectors
[i
].offset
;
408 block_array
[i
].size
= bank
->sectors
[i
].size
;
409 block_array
[i
].result
= UINT32_MAX
; /* erase state unknown */
412 bool fast_check
= true;
413 for (unsigned int i
= 0; i
< bank
->num_sectors
; ) {
414 retval
= target_blank_check_memory(target
,
415 block_array
+ i
, bank
->num_sectors
- i
,
418 /* Run slow fallback if the first run gives no result
419 * otherwise use possibly incomplete results */
424 i
+= retval
; /* add number of blocks done this round */
428 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++)
429 bank
->sectors
[i
].is_erased
= block_array
[i
].result
;
432 LOG_USER("Running slow fallback erase check - add working memory");
433 retval
= default_flash_mem_blank_check(bank
);
440 /* Manipulate given flash region, selecting the bank according to target
441 * and address. Maps an address range to a set of sectors, and issues
442 * the callback() on that set ... e.g. to erase or unprotect its members.
444 * Parameter iterate_protect_blocks switches iteration of protect block
445 * instead of erase sectors. If there is no protect blocks array, sectors
446 * are used in iteration, so compatibility for old flash drivers is retained.
448 * The "pad_reason" parameter is a kind of boolean: when it's NULL, the
449 * range must fit those sectors exactly. This is clearly safe; it can't
450 * erase data which the caller said to leave alone, for example. If it's
451 * non-NULL, rather than failing, extra data in the first and/or last
452 * sectors will be added to the range, and that reason string is used when
453 * warning about those additions.
455 static int flash_iterate_address_range_inner(struct target
*target
,
456 char *pad_reason
, target_addr_t addr
, uint32_t length
,
457 bool iterate_protect_blocks
,
458 int (*callback
)(struct flash_bank
*bank
, unsigned int first
,
461 struct flash_bank
*c
;
462 struct flash_sector
*block_array
;
463 target_addr_t last_addr
= addr
+ length
- 1; /* the last address of range */
469 int retval
= get_flash_bank_by_addr(target
, addr
, true, &c
);
470 if (retval
!= ERROR_OK
)
473 if (c
->size
== 0 || c
->num_sectors
== 0) {
474 LOG_ERROR("Bank is invalid");
475 return ERROR_FLASH_BANK_INVALID
;
479 /* special case, erase whole bank when length is zero */
480 if (addr
!= c
->base
) {
481 LOG_ERROR("Whole bank access must start at beginning of bank.");
482 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
485 return callback(c
, 0, c
->num_sectors
- 1);
488 /* check whether it all fits in this bank */
489 if (last_addr
> c
->base
+ c
->size
- 1) {
490 LOG_ERROR("Flash access does not fit into bank.");
491 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
494 if (!c
->prot_blocks
|| c
->num_prot_blocks
== 0) {
495 /* flash driver does not define protect blocks, use sectors instead */
496 iterate_protect_blocks
= false;
499 if (iterate_protect_blocks
) {
500 block_array
= c
->prot_blocks
;
501 num_blocks
= c
->num_prot_blocks
;
503 block_array
= c
->sectors
;
504 num_blocks
= c
->num_sectors
;
507 for (i
= 0; i
< num_blocks
; i
++) {
508 struct flash_sector
*f
= &block_array
[i
];
509 target_addr_t sector_addr
= c
->base
+ f
->offset
;
510 target_addr_t sector_last_addr
= sector_addr
+ f
->size
- 1;
512 /* start only on a sector boundary */
514 /* scanned past the first sector? */
515 if (addr
< sector_addr
)
518 /* is this the first sector? */
519 if (addr
== sector_addr
)
522 /* Does this need head-padding? If so, pad and warn;
523 * or else force an error.
525 * Such padding can make trouble, since *WE* can't
526 * ever know if that data was in use. The warning
527 * should help users sort out messes later.
529 else if (addr
<= sector_last_addr
&& pad_reason
) {
530 /* FIXME say how many bytes (e.g. 80 KB) */
531 LOG_WARNING("Adding extra %s range, "
532 TARGET_ADDR_FMT
" .. " TARGET_ADDR_FMT
,
541 /* is this (also?) the last sector? */
542 if (last_addr
== sector_last_addr
) {
547 /* Does this need tail-padding? If so, pad and warn;
548 * or else force an error.
550 if (last_addr
< sector_last_addr
&& pad_reason
) {
551 /* FIXME say how many bytes (e.g. 80 KB) */
552 LOG_WARNING("Adding extra %s range, "
553 TARGET_ADDR_FMT
" .. " TARGET_ADDR_FMT
,
561 /* MUST finish on a sector boundary */
562 if (last_addr
< sector_addr
)
566 /* invalid start or end address? */
567 if (first
== -1 || last
== -1) {
568 LOG_ERROR("address range " TARGET_ADDR_FMT
" .. " TARGET_ADDR_FMT
569 " is not sector-aligned",
572 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
575 /* The NOR driver may trim this range down, based on what
576 * sectors are already erased/unprotected. GDB currently
577 * blocks such optimizations.
579 return callback(c
, first
, last
);
582 /* The inner fn only handles a single bank, we could be spanning
585 static int flash_iterate_address_range(struct target
*target
,
586 char *pad_reason
, target_addr_t addr
, uint32_t length
,
587 bool iterate_protect_blocks
,
588 int (*callback
)(struct flash_bank
*bank
, unsigned int first
,
591 struct flash_bank
*c
;
592 int retval
= ERROR_OK
;
594 /* Danger! zero-length iterations means entire bank! */
596 retval
= get_flash_bank_by_addr(target
, addr
, true, &c
);
597 if (retval
!= ERROR_OK
)
600 uint32_t cur_length
= length
;
601 /* check whether it all fits in this bank */
602 if (addr
+ length
- 1 > c
->base
+ c
->size
- 1) {
603 LOG_DEBUG("iterating over more than one flash bank.");
604 cur_length
= c
->base
+ c
->size
- addr
;
606 retval
= flash_iterate_address_range_inner(target
,
607 pad_reason
, addr
, cur_length
,
608 iterate_protect_blocks
,
610 if (retval
!= ERROR_OK
)
613 length
-= cur_length
;
615 } while (length
> 0);
620 int flash_erase_address_range(struct target
*target
,
621 bool pad
, target_addr_t addr
, uint32_t length
)
623 return flash_iterate_address_range(target
, pad
? "erase" : NULL
,
624 addr
, length
, false, &flash_driver_erase
);
627 static int flash_driver_unprotect(struct flash_bank
*bank
, unsigned int first
,
630 return flash_driver_protect(bank
, 0, first
, last
);
633 int flash_unlock_address_range(struct target
*target
, target_addr_t addr
,
636 /* By default, pad to sector boundaries ... the real issue here
637 * is that our (only) caller *permanently* removes protection,
638 * and doesn't restore it.
640 return flash_iterate_address_range(target
, "unprotect",
641 addr
, length
, true, &flash_driver_unprotect
);
644 static int compare_section(const void *a
, const void *b
)
646 struct imagesection
*b1
, *b2
;
647 b1
= *((struct imagesection
**)a
);
648 b2
= *((struct imagesection
**)b
);
650 if (b1
->base_address
== b2
->base_address
)
652 else if (b1
->base_address
> b2
->base_address
)
659 * Get aligned start address of a flash write region
661 target_addr_t
flash_write_align_start(struct flash_bank
*bank
, target_addr_t addr
)
663 if (addr
< bank
->base
|| addr
>= bank
->base
+ bank
->size
664 || bank
->write_start_alignment
<= 1)
667 if (bank
->write_start_alignment
== FLASH_WRITE_ALIGN_SECTOR
) {
668 uint32_t offset
= addr
- bank
->base
;
669 uint32_t aligned
= 0;
670 for (unsigned int sect
= 0; sect
< bank
->num_sectors
; sect
++) {
671 if (bank
->sectors
[sect
].offset
> offset
)
674 aligned
= bank
->sectors
[sect
].offset
;
676 return bank
->base
+ aligned
;
679 return addr
& ~(bank
->write_start_alignment
- 1);
683 * Get aligned end address of a flash write region
685 target_addr_t
flash_write_align_end(struct flash_bank
*bank
, target_addr_t addr
)
687 if (addr
< bank
->base
|| addr
>= bank
->base
+ bank
->size
688 || bank
->write_end_alignment
<= 1)
691 if (bank
->write_end_alignment
== FLASH_WRITE_ALIGN_SECTOR
) {
692 uint32_t offset
= addr
- bank
->base
;
693 uint32_t aligned
= 0;
694 for (unsigned int sect
= 0; sect
< bank
->num_sectors
; sect
++) {
695 aligned
= bank
->sectors
[sect
].offset
+ bank
->sectors
[sect
].size
- 1;
696 if (aligned
>= offset
)
699 return bank
->base
+ aligned
;
702 return addr
| (bank
->write_end_alignment
- 1);
706 * Check if gap between sections is bigger than minimum required to discontinue flash write
708 static bool flash_write_check_gap(struct flash_bank
*bank
,
709 target_addr_t addr1
, target_addr_t addr2
)
711 if (bank
->minimal_write_gap
== FLASH_WRITE_CONTINUOUS
712 || addr1
< bank
->base
|| addr1
>= bank
->base
+ bank
->size
713 || addr2
< bank
->base
|| addr2
>= bank
->base
+ bank
->size
)
716 if (bank
->minimal_write_gap
== FLASH_WRITE_GAP_SECTOR
) {
718 uint32_t offset1
= addr1
- bank
->base
;
719 /* find the sector following the one containing addr1 */
720 for (sect
= 0; sect
< bank
->num_sectors
; sect
++) {
721 if (bank
->sectors
[sect
].offset
> offset1
)
724 if (sect
>= bank
->num_sectors
)
727 uint32_t offset2
= addr2
- bank
->base
;
728 return bank
->sectors
[sect
].offset
+ bank
->sectors
[sect
].size
<= offset2
;
731 target_addr_t aligned1
= flash_write_align_end(bank
, addr1
);
732 target_addr_t aligned2
= flash_write_align_start(bank
, addr2
);
733 return aligned1
+ bank
->minimal_write_gap
< aligned2
;
737 int flash_write_unlock_verify(struct target
*target
, struct image
*image
,
738 uint32_t *written
, bool erase
, bool unlock
, bool write
, bool verify
)
740 int retval
= ERROR_OK
;
742 unsigned int section
;
743 uint32_t section_offset
;
744 struct flash_bank
*c
;
754 /* assume all sectors need erasing - stops any problems
755 * when flash_write is called multiple times */
760 /* allocate padding array */
761 padding
= calloc(image
->num_sections
, sizeof(*padding
));
763 /* This fn requires all sections to be in ascending order of addresses,
764 * whereas an image can have sections out of order. */
765 struct imagesection
**sections
= malloc(sizeof(struct imagesection
*) *
766 image
->num_sections
);
768 for (unsigned int i
= 0; i
< image
->num_sections
; i
++)
769 sections
[i
] = &image
->sections
[i
];
771 qsort(sections
, image
->num_sections
, sizeof(struct imagesection
*),
774 /* loop until we reach end of the image */
775 while (section
< image
->num_sections
) {
778 unsigned int section_last
;
779 target_addr_t run_address
= sections
[section
]->base_address
+ section_offset
;
780 uint32_t run_size
= sections
[section
]->size
- section_offset
;
783 if (sections
[section
]->size
== 0) {
784 LOG_WARNING("empty section %d", section
);
790 /* find the corresponding flash bank */
791 retval
= get_flash_bank_by_addr(target
, run_address
, false, &c
);
792 if (retval
!= ERROR_OK
)
795 LOG_WARNING("no flash bank found for address " TARGET_ADDR_FMT
, run_address
);
796 section
++; /* and skip it */
801 /* collect consecutive sections which fall into the same bank */
802 section_last
= section
;
803 padding
[section
] = 0;
804 while ((run_address
+ run_size
- 1 < c
->base
+ c
->size
- 1) &&
805 (section_last
+ 1 < image
->num_sections
)) {
806 /* sections are sorted */
807 assert(sections
[section_last
+ 1]->base_address
>= c
->base
);
808 if (sections
[section_last
+ 1]->base_address
>= (c
->base
+ c
->size
)) {
809 /* Done with this bank */
813 /* if we have multiple sections within our image,
814 * flash programming could fail due to alignment issues
815 * attempt to rebuild a consecutive buffer for the flash loader */
816 target_addr_t run_next_addr
= run_address
+ run_size
;
817 target_addr_t next_section_base
= sections
[section_last
+ 1]->base_address
;
818 if (next_section_base
< run_next_addr
) {
819 LOG_ERROR("Section at " TARGET_ADDR_FMT
820 " overlaps section ending at " TARGET_ADDR_FMT
,
821 next_section_base
, run_next_addr
);
822 LOG_ERROR("Flash write aborted.");
827 pad_bytes
= next_section_base
- run_next_addr
;
829 if (flash_write_check_gap(c
, run_next_addr
- 1, next_section_base
)) {
830 LOG_INFO("Flash write discontinued at " TARGET_ADDR_FMT
831 ", next section at " TARGET_ADDR_FMT
,
832 run_next_addr
, next_section_base
);
837 LOG_INFO("Padding image section %d at " TARGET_ADDR_FMT
839 section_last
, run_next_addr
, pad_bytes
);
841 padding
[section_last
] = pad_bytes
;
842 run_size
+= pad_bytes
;
843 run_size
+= sections
[++section_last
]->size
;
846 if (run_address
+ run_size
- 1 > c
->base
+ c
->size
- 1) {
847 /* If we have more than one flash chip back to back, then we limit
848 * the current write operation to the current chip.
850 LOG_DEBUG("Truncate flash run size to the current flash chip.");
852 run_size
= c
->base
+ c
->size
- run_address
;
853 assert(run_size
> 0);
856 uint32_t padding_at_start
= 0;
857 if (c
->write_start_alignment
|| c
->write_end_alignment
) {
858 /* align write region according to bank requirements */
859 target_addr_t aligned_start
= flash_write_align_start(c
, run_address
);
860 padding_at_start
= run_address
- aligned_start
;
861 if (padding_at_start
> 0) {
862 LOG_WARNING("Section start address " TARGET_ADDR_FMT
863 " breaks the required alignment of flash bank %s",
864 run_address
, c
->name
);
865 LOG_WARNING("Padding %" PRIu32
" bytes from " TARGET_ADDR_FMT
,
866 padding_at_start
, aligned_start
);
868 run_address
-= padding_at_start
;
869 run_size
+= padding_at_start
;
872 target_addr_t run_end
= run_address
+ run_size
- 1;
873 target_addr_t aligned_end
= flash_write_align_end(c
, run_end
);
874 pad_bytes
= aligned_end
- run_end
;
876 LOG_INFO("Padding image section %d at " TARGET_ADDR_FMT
877 " with %d bytes (bank write end alignment)",
878 section_last
, run_end
+ 1, pad_bytes
);
880 padding
[section_last
] += pad_bytes
;
881 run_size
+= pad_bytes
;
884 } else if (unlock
|| erase
) {
885 /* If we're applying any sector automagic, then pad this
886 * (maybe-combined) segment to the end of its last sector.
888 uint32_t offset_start
= run_address
- c
->base
;
889 uint32_t offset_end
= offset_start
+ run_size
;
890 uint32_t end
= offset_end
, delta
;
892 for (unsigned int sector
= 0; sector
< c
->num_sectors
; sector
++) {
893 end
= c
->sectors
[sector
].offset
894 + c
->sectors
[sector
].size
;
895 if (offset_end
<= end
)
899 delta
= end
- offset_end
;
900 padding
[section_last
] += delta
;
904 /* allocate buffer */
905 buffer
= malloc(run_size
);
907 LOG_ERROR("Out of memory for flash bank buffer");
912 if (padding_at_start
)
913 memset(buffer
, c
->default_padded_value
, padding_at_start
);
915 buffer_idx
= padding_at_start
;
917 /* read sections to the buffer */
918 while (buffer_idx
< run_size
) {
921 size_read
= run_size
- buffer_idx
;
922 if (size_read
> sections
[section
]->size
- section_offset
)
923 size_read
= sections
[section
]->size
- section_offset
;
927 * #¤%#"%¤% we have to figure out the section # from the sorted
928 * list of pointers to sections to invoke image_read_section()...
930 intptr_t diff
= (intptr_t)sections
[section
] - (intptr_t)image
->sections
;
931 int t_section_num
= diff
/ sizeof(struct imagesection
);
933 LOG_DEBUG("image_read_section: section = %d, t_section_num = %d, "
934 "section_offset = %"PRIu32
", buffer_idx = %"PRIu32
", size_read = %zu",
935 section
, t_section_num
, section_offset
,
936 buffer_idx
, size_read
);
937 retval
= image_read_section(image
, t_section_num
, section_offset
,
938 size_read
, buffer
+ buffer_idx
, &size_read
);
939 if (retval
!= ERROR_OK
|| size_read
== 0) {
944 buffer_idx
+= size_read
;
945 section_offset
+= size_read
;
947 /* see if we need to pad the section */
948 if (padding
[section
]) {
949 memset(buffer
+ buffer_idx
, c
->default_padded_value
, padding
[section
]);
950 buffer_idx
+= padding
[section
];
953 if (section_offset
>= sections
[section
]->size
) {
962 retval
= flash_unlock_address_range(target
, run_address
, run_size
);
963 if (retval
== ERROR_OK
) {
965 /* calculate and erase sectors */
966 retval
= flash_erase_address_range(target
,
967 true, run_address
, run_size
);
971 if (retval
== ERROR_OK
) {
973 /* write flash sectors */
974 retval
= flash_driver_write(c
, buffer
, run_address
- c
->base
, run_size
);
978 if (retval
== ERROR_OK
) {
980 /* verify flash sectors */
981 retval
= flash_driver_verify(c
, buffer
, run_address
- c
->base
, run_size
);
987 if (retval
!= ERROR_OK
) {
988 /* abort operation */
993 *written
+= run_size
; /* add run size to total written counter */
1003 int flash_write(struct target
*target
, struct image
*image
,
1004 uint32_t *written
, bool erase
)
1006 return flash_write_unlock_verify(target
, image
, written
, erase
, false, true, false);
1009 struct flash_sector
*alloc_block_array(uint32_t offset
, uint32_t size
,
1010 unsigned int num_blocks
)
1012 struct flash_sector
*array
= calloc(num_blocks
, sizeof(struct flash_sector
));
1016 for (unsigned int i
= 0; i
< num_blocks
; i
++) {
1017 array
[i
].offset
= offset
;
1018 array
[i
].size
= size
;
1019 array
[i
].is_erased
= -1;
1020 array
[i
].is_protected
= -1;
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)