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
, int first
, int last
)
44 retval
= bank
->driver
->erase(bank
, first
, last
);
45 if (retval
!= ERROR_OK
)
46 LOG_ERROR("failed erasing sectors %d to %d", first
, last
);
51 int flash_driver_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
56 if (bank
->num_prot_blocks
)
57 num_blocks
= bank
->num_prot_blocks
;
59 num_blocks
= bank
->num_sectors
;
62 /* callers may not supply illegal parameters ... */
63 if (first
< 0 || first
> last
|| last
>= num_blocks
) {
64 LOG_ERROR("illegal protection block range");
68 /* force "set" to 0/1 */
71 if (bank
->driver
->protect
== NULL
) {
72 LOG_ERROR("Flash protection is not supported.");
73 return ERROR_FLASH_OPER_UNSUPPORTED
;
78 * We must not use any cached information about protection state!!!!
80 * There are a million things that could change the protect state:
82 * the target could have reset, power cycled, been hot plugged,
83 * the application could have run, etc.
85 * Drivers only receive valid protection block range.
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
);
94 int flash_driver_write(struct flash_bank
*bank
,
95 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
99 retval
= bank
->driver
->write(bank
, buffer
, offset
, count
);
100 if (retval
!= ERROR_OK
) {
102 "error writing to flash at address 0x%08" PRIx32
" at offset 0x%8.8" PRIx32
,
110 int flash_driver_read(struct flash_bank
*bank
,
111 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
115 LOG_DEBUG("call flash_driver_read()");
117 retval
= bank
->driver
->read(bank
, buffer
, offset
, count
);
118 if (retval
!= ERROR_OK
) {
120 "error reading to flash at address 0x%08" PRIx32
" at offset 0x%8.8" PRIx32
,
128 int default_flash_read(struct flash_bank
*bank
,
129 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
131 return target_read_buffer(bank
->target
, offset
+ bank
->base
, count
, buffer
);
134 void flash_bank_add(struct flash_bank
*bank
)
136 /* put flash bank in linked list */
137 unsigned bank_num
= 0;
139 /* find last flash bank */
140 struct flash_bank
*p
= flash_banks
;
141 while (NULL
!= p
->next
) {
150 bank
->bank_number
= bank_num
;
153 struct flash_bank
*flash_bank_list(void)
158 struct flash_bank
*get_flash_bank_by_num_noprobe(int num
)
160 struct flash_bank
*p
;
163 for (p
= flash_banks
; p
; p
= p
->next
) {
167 LOG_ERROR("flash bank %d does not exist", num
);
171 int flash_get_bank_count(void)
173 struct flash_bank
*p
;
175 for (p
= flash_banks
; p
; p
= p
->next
)
180 void default_flash_free_driver_priv(struct flash_bank
*bank
)
182 free(bank
->driver_priv
);
183 bank
->driver_priv
= NULL
;
186 void flash_free_all_banks(void)
188 struct flash_bank
*bank
= flash_banks
;
190 struct flash_bank
*next
= bank
->next
;
191 if (bank
->driver
->free_driver_priv
)
192 bank
->driver
->free_driver_priv(bank
);
194 LOG_WARNING("Flash driver of %s does not support free_driver_priv()", bank
->name
);
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'. */
201 if (strcmp(bank
->driver
->name
, "virtual") != 0) {
203 free(bank
->prot_blocks
);
213 struct flash_bank
*get_flash_bank_by_name_noprobe(const char *name
)
215 unsigned requested
= get_flash_name_index(name
);
218 struct flash_bank
*bank
;
219 for (bank
= flash_banks
; NULL
!= bank
; bank
= bank
->next
) {
220 if (strcmp(bank
->name
, name
) == 0)
222 if (!flash_driver_name_matches(bank
->driver
->name
, name
))
224 if (++found
< requested
)
231 int get_flash_bank_by_name(const char *name
, struct flash_bank
**bank_result
)
233 struct flash_bank
*bank
;
236 bank
= get_flash_bank_by_name_noprobe(name
);
238 retval
= bank
->driver
->auto_probe(bank
);
240 if (retval
!= ERROR_OK
) {
241 LOG_ERROR("auto_probe failed");
250 int get_flash_bank_by_num(int num
, struct flash_bank
**bank
)
252 struct flash_bank
*p
= get_flash_bank_by_num_noprobe(num
);
258 retval
= p
->driver
->auto_probe(p
);
260 if (retval
!= ERROR_OK
) {
261 LOG_ERROR("auto_probe failed");
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
,
273 struct flash_bank
**result_bank
)
275 struct flash_bank
*c
;
277 /* cycle through bank list */
278 for (c
= flash_banks
; c
; c
= c
->next
) {
279 if (c
->target
!= target
)
283 retval
= c
->driver
->auto_probe(c
);
285 if (retval
!= ERROR_OK
) {
286 LOG_ERROR("auto_probe failed");
289 /* check whether address belongs to this flash bank */
290 if ((addr
>= c
->base
) && (addr
<= c
->base
+ (c
->size
- 1))) {
297 LOG_ERROR("No flash at address 0x%08" PRIx32
, addr
);
303 static int default_flash_mem_blank_check(struct flash_bank
*bank
)
305 struct target
*target
= bank
->target
;
306 const int buffer_size
= 1024;
309 int retval
= ERROR_OK
;
311 if (bank
->target
->state
!= TARGET_HALTED
) {
312 LOG_ERROR("Target not halted");
313 return ERROR_TARGET_NOT_HALTED
;
316 uint8_t *buffer
= malloc(buffer_size
);
318 for (i
= 0; i
< bank
->num_sectors
; i
++) {
320 bank
->sectors
[i
].is_erased
= 1;
322 for (j
= 0; j
< bank
->sectors
[i
].size
; j
+= buffer_size
) {
325 if (chunk
> (bank
->sectors
[i
].size
- j
))
326 chunk
= (bank
->sectors
[i
].size
- j
);
328 retval
= target_read_memory(target
,
329 bank
->base
+ bank
->sectors
[i
].offset
+ j
,
333 if (retval
!= ERROR_OK
)
336 for (nBytes
= 0; nBytes
< chunk
; nBytes
++) {
337 if (buffer
[nBytes
] != bank
->erased_value
) {
338 bank
->sectors
[i
].is_erased
= 0;
351 int default_flash_blank_check(struct flash_bank
*bank
)
353 struct target
*target
= bank
->target
;
357 if (bank
->target
->state
!= TARGET_HALTED
) {
358 LOG_ERROR("Target not halted");
359 return ERROR_TARGET_NOT_HALTED
;
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
);
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 */
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
,
379 /* Run slow fallback if the first run gives no result
380 * otherwise use possibly incomplete results */
385 i
+= retval
; /* add number of blocks done this round */
389 for (i
= 0; i
< bank
->num_sectors
; i
++)
390 bank
->sectors
[i
].is_erased
= block_array
[i
].result
;
393 LOG_USER("Running slow fallback erase check - add working memory");
394 retval
= default_flash_mem_blank_check(bank
);
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.
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.
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.
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
))
421 struct flash_bank
*c
;
422 struct flash_sector
*block_array
;
423 uint32_t last_addr
= addr
+ length
; /* first address AFTER end */
429 int retval
= get_flash_bank_by_addr(target
, addr
, true, &c
);
430 if (retval
!= ERROR_OK
)
433 if (c
->size
== 0 || c
->num_sectors
== 0) {
434 LOG_ERROR("Bank is invalid");
435 return ERROR_FLASH_BANK_INVALID
;
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
;
445 return callback(c
, 0, c
->num_sectors
- 1);
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
;
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;
459 if (iterate_protect_blocks
) {
460 block_array
= c
->prot_blocks
;
461 num_blocks
= c
->num_prot_blocks
;
463 block_array
= c
->sectors
;
464 num_blocks
= c
->num_sectors
;
468 last_addr
-= c
->base
;
470 for (i
= 0; i
< num_blocks
; i
++) {
471 struct flash_sector
*f
= &block_array
[i
];
472 uint32_t end
= f
->offset
+ f
->size
;
474 /* start only on a sector boundary */
476 /* scanned past the first sector? */
477 if (addr
< f
->offset
)
480 /* is this the first sector? */
481 if (addr
== f
->offset
)
484 /* Does this need head-padding? If so, pad and warn;
485 * or else force an error.
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.
491 else if (addr
< end
&& pad_reason
) {
492 /* FIXME say how many bytes (e.g. 80 KB) */
493 LOG_WARNING("Adding extra %s range, "
496 (unsigned) f
->offset
,
497 (unsigned) addr
- 1);
503 /* is this (also?) the last sector? */
504 if (last_addr
== end
) {
509 /* Does this need tail-padding? If so, pad and warn;
510 * or else force an error.
512 if (last_addr
< end
&& pad_reason
) {
513 /* FIXME say how many bytes (e.g. 80 KB) */
514 LOG_WARNING("Adding extra %s range, "
517 (unsigned) last_addr
,
523 /* MUST finish on a sector boundary */
524 if (last_addr
<= f
->offset
)
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
;
537 /* The NOR driver may trim this range down, based on what
538 * sectors are already erased/unprotected. GDB currently
539 * blocks such optimizations.
541 return callback(c
, first
, last
);
544 /* The inner fn only handles a single bank, we could be spanning
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
))
552 struct flash_bank
*c
;
553 int retval
= ERROR_OK
;
555 /* Danger! zero-length iterations means entire bank! */
557 retval
= get_flash_bank_by_addr(target
, addr
, true, &c
);
558 if (retval
!= ERROR_OK
)
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
;
567 retval
= flash_iterate_address_range_inner(target
,
568 pad_reason
, addr
, cur_length
,
569 iterate_protect_blocks
,
571 if (retval
!= ERROR_OK
)
574 length
-= cur_length
;
576 } while (length
> 0);
581 int flash_erase_address_range(struct target
*target
,
582 bool pad
, uint32_t addr
, uint32_t length
)
584 return flash_iterate_address_range(target
, pad
? "erase" : NULL
,
585 addr
, length
, false, &flash_driver_erase
);
588 static int flash_driver_unprotect(struct flash_bank
*bank
, int first
, int last
)
590 return flash_driver_protect(bank
, 0, first
, last
);
593 int flash_unlock_address_range(struct target
*target
, uint32_t addr
, uint32_t length
)
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.
599 return flash_iterate_address_range(target
, "unprotect",
600 addr
, length
, true, &flash_driver_unprotect
);
603 static int compare_section(const void *a
, const void *b
)
605 struct imagesection
*b1
, *b2
;
606 b1
= *((struct imagesection
**)a
);
607 b2
= *((struct imagesection
**)b
);
609 if (b1
->base_address
== b2
->base_address
)
611 else if (b1
->base_address
> b2
->base_address
)
618 * Get aligned start address of a flash write region
620 target_addr_t
flash_write_align_start(struct flash_bank
*bank
, target_addr_t addr
)
622 if (addr
< bank
->base
|| addr
>= bank
->base
+ bank
->size
623 || bank
->write_start_alignment
<= 1)
626 if (bank
->write_start_alignment
== FLASH_WRITE_ALIGN_SECTOR
) {
627 uint32_t offset
= addr
- bank
->base
;
628 uint32_t aligned
= 0;
630 for (sect
= 0; sect
< bank
->num_sectors
; sect
++) {
631 if (bank
->sectors
[sect
].offset
> offset
)
634 aligned
= bank
->sectors
[sect
].offset
;
636 return bank
->base
+ aligned
;
639 return addr
& ~(bank
->write_start_alignment
- 1);
643 * Get aligned end address of a flash write region
645 target_addr_t
flash_write_align_end(struct flash_bank
*bank
, target_addr_t addr
)
647 if (addr
< bank
->base
|| addr
>= bank
->base
+ bank
->size
648 || bank
->write_end_alignment
<= 1)
651 if (bank
->write_end_alignment
== FLASH_WRITE_ALIGN_SECTOR
) {
652 uint32_t offset
= addr
- bank
->base
;
653 uint32_t aligned
= 0;
655 for (sect
= 0; sect
< bank
->num_sectors
; sect
++) {
656 aligned
= bank
->sectors
[sect
].offset
+ bank
->sectors
[sect
].size
- 1;
657 if (aligned
>= offset
)
660 return bank
->base
+ aligned
;
663 return addr
| (bank
->write_end_alignment
- 1);
667 * Check if gap between sections is bigger than minimum required to discontinue flash write
669 static bool flash_write_check_gap(struct flash_bank
*bank
,
670 target_addr_t addr1
, target_addr_t addr2
)
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
)
677 if (bank
->minimal_write_gap
== FLASH_WRITE_GAP_SECTOR
) {
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
)
685 if (sect
>= bank
->num_sectors
)
688 uint32_t offset2
= addr2
- bank
->base
;
689 return bank
->sectors
[sect
].offset
+ bank
->sectors
[sect
].size
<= offset2
;
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
;
698 int flash_write_unlock(struct target
*target
, struct image
*image
,
699 uint32_t *written
, int erase
, bool unlock
)
701 int retval
= ERROR_OK
;
704 uint32_t section_offset
;
705 struct flash_bank
*c
;
715 /* assume all sectors need erasing - stops any problems
716 * when flash_write is called multiple times */
721 /* allocate padding array */
722 padding
= calloc(image
->num_sections
, sizeof(*padding
));
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
);
729 for (i
= 0; i
< image
->num_sections
; i
++)
730 sections
[i
] = &image
->sections
[i
];
732 qsort(sections
, image
->num_sections
, sizeof(struct imagesection
*),
735 /* loop until we reach end of the image */
736 while (section
< image
->num_sections
) {
740 target_addr_t run_address
= sections
[section
]->base_address
+ section_offset
;
741 uint32_t run_size
= sections
[section
]->size
- section_offset
;
744 if (sections
[section
]->size
== 0) {
745 LOG_WARNING("empty section %d", section
);
751 /* find the corresponding flash bank */
752 retval
= get_flash_bank_by_addr(target
, run_address
, false, &c
);
753 if (retval
!= ERROR_OK
)
756 LOG_WARNING("no flash bank found for address " TARGET_ADDR_FMT
, run_address
);
757 section
++; /* and skip it */
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 */
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.");
788 pad_bytes
= next_section_base
- run_next_addr
;
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
);
798 LOG_INFO("Padding image section %d at " TARGET_ADDR_FMT
800 section_last
, run_next_addr
, pad_bytes
);
802 padding
[section_last
] = pad_bytes
;
803 run_size
+= pad_bytes
;
804 run_size
+= sections
[++section_last
]->size
;
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.
811 LOG_DEBUG("Truncate flash run size to the current flash chip.");
813 run_size
= c
->base
+ c
->size
- run_address
;
814 assert(run_size
> 0);
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
);
829 run_address
-= padding_at_start
;
830 run_size
+= padding_at_start
;
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
;
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
);
841 padding
[section_last
] += pad_bytes
;
842 run_size
+= pad_bytes
;
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.
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
;
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
)
861 delta
= end
- offset_end
;
862 padding
[section_last
] += delta
;
866 /* allocate buffer */
867 buffer
= malloc(run_size
);
868 if (buffer
== NULL
) {
869 LOG_ERROR("Out of memory for flash bank buffer");
874 if (padding_at_start
)
875 memset(buffer
, c
->default_padded_value
, padding_at_start
);
877 buffer_idx
= padding_at_start
;
879 /* read sections to the buffer */
880 while (buffer_idx
< run_size
) {
883 size_read
= run_size
- buffer_idx
;
884 if (size_read
> sections
[section
]->size
- section_offset
)
885 size_read
= sections
[section
]->size
- section_offset
;
889 * #¤%#"%¤% we have to figure out the section # from the sorted
890 * list of pointers to sections to invoke image_read_section()...
892 intptr_t diff
= (intptr_t)sections
[section
] - (intptr_t)image
->sections
;
893 int t_section_num
= diff
/ sizeof(struct imagesection
);
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) {
906 buffer_idx
+= size_read
;
907 section_offset
+= size_read
;
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
];
915 if (section_offset
>= sections
[section
]->size
) {
924 retval
= flash_unlock_address_range(target
, run_address
, run_size
);
925 if (retval
== ERROR_OK
) {
927 /* calculate and erase sectors */
928 retval
= flash_erase_address_range(target
,
929 true, run_address
, run_size
);
933 if (retval
== ERROR_OK
) {
934 /* write flash sectors */
935 retval
= flash_driver_write(c
, buffer
, run_address
- c
->base
, run_size
);
940 if (retval
!= ERROR_OK
) {
941 /* abort operation */
946 *written
+= run_size
; /* add run size to total written counter */
956 int flash_write(struct target
*target
, struct image
*image
,
957 uint32_t *written
, int erase
)
959 return flash_write_unlock(target
, image
, written
, erase
, false);
962 struct flash_sector
*alloc_block_array(uint32_t offset
, uint32_t size
, int num_blocks
)
966 struct flash_sector
*array
= calloc(num_blocks
, sizeof(struct flash_sector
));
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;
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)