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 */
73 * We must not use any cached information about protection state!!!!
75 * There are a million things that could change the protect state:
77 * the target could have reset, power cycled, been hot plugged,
78 * the application could have run, etc.
80 * Drivers only receive valid protection block range.
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
);
89 int flash_driver_write(struct flash_bank
*bank
,
90 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
94 retval
= bank
->driver
->write(bank
, buffer
, offset
, count
);
95 if (retval
!= ERROR_OK
) {
97 "error writing to flash at address 0x%08" PRIx32
" at offset 0x%8.8" PRIx32
,
105 int flash_driver_read(struct flash_bank
*bank
,
106 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
110 LOG_DEBUG("call flash_driver_read()");
112 retval
= bank
->driver
->read(bank
, buffer
, offset
, count
);
113 if (retval
!= ERROR_OK
) {
115 "error reading to flash at address 0x%08" PRIx32
" at offset 0x%8.8" PRIx32
,
123 int default_flash_read(struct flash_bank
*bank
,
124 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
126 return target_read_buffer(bank
->target
, offset
+ bank
->base
, count
, buffer
);
129 void flash_bank_add(struct flash_bank
*bank
)
131 /* put flash bank in linked list */
132 unsigned bank_num
= 0;
134 /* find last flash bank */
135 struct flash_bank
*p
= flash_banks
;
136 while (NULL
!= p
->next
) {
145 bank
->bank_number
= bank_num
;
148 struct flash_bank
*flash_bank_list(void)
153 struct flash_bank
*get_flash_bank_by_num_noprobe(int num
)
155 struct flash_bank
*p
;
158 for (p
= flash_banks
; p
; p
= p
->next
) {
162 LOG_ERROR("flash bank %d does not exist", num
);
166 int flash_get_bank_count(void)
168 struct flash_bank
*p
;
170 for (p
= flash_banks
; p
; p
= p
->next
)
175 void default_flash_free_driver_priv(struct flash_bank
*bank
)
177 free(bank
->driver_priv
);
178 bank
->driver_priv
= NULL
;
181 void flash_free_all_banks(void)
183 struct flash_bank
*bank
= flash_banks
;
185 struct flash_bank
*next
= bank
->next
;
186 if (bank
->driver
->free_driver_priv
)
187 bank
->driver
->free_driver_priv(bank
);
189 LOG_WARNING("Flash driver of %s does not support free_driver_priv()", bank
->name
);
191 /* For 'virtual' flash driver bank->sectors and bank->prot_blocks pointers are copied from
192 * master flash_bank structure. They point to memory locations allocated by master flash driver
193 * so master driver is responsible for releasing them.
194 * Avoid UB caused by double-free memory corruption if flash bank is 'virtual'. */
196 if (strcmp(bank
->driver
->name
, "virtual") != 0) {
198 free(bank
->prot_blocks
);
208 struct flash_bank
*get_flash_bank_by_name_noprobe(const char *name
)
210 unsigned requested
= get_flash_name_index(name
);
213 struct flash_bank
*bank
;
214 for (bank
= flash_banks
; NULL
!= bank
; bank
= bank
->next
) {
215 if (strcmp(bank
->name
, name
) == 0)
217 if (!flash_driver_name_matches(bank
->driver
->name
, name
))
219 if (++found
< requested
)
226 int get_flash_bank_by_name(const char *name
, struct flash_bank
**bank_result
)
228 struct flash_bank
*bank
;
231 bank
= get_flash_bank_by_name_noprobe(name
);
233 retval
= bank
->driver
->auto_probe(bank
);
235 if (retval
!= ERROR_OK
) {
236 LOG_ERROR("auto_probe failed");
245 int get_flash_bank_by_num(int num
, struct flash_bank
**bank
)
247 struct flash_bank
*p
= get_flash_bank_by_num_noprobe(num
);
253 retval
= p
->driver
->auto_probe(p
);
255 if (retval
!= ERROR_OK
) {
256 LOG_ERROR("auto_probe failed");
263 /* lookup flash bank by address, bank not found is success, but
264 * result_bank is set to NULL. */
265 int get_flash_bank_by_addr(struct target
*target
,
268 struct flash_bank
**result_bank
)
270 struct flash_bank
*c
;
272 /* cycle through bank list */
273 for (c
= flash_banks
; c
; c
= c
->next
) {
274 if (c
->target
!= target
)
278 retval
= c
->driver
->auto_probe(c
);
280 if (retval
!= ERROR_OK
) {
281 LOG_ERROR("auto_probe failed");
284 /* check whether address belongs to this flash bank */
285 if ((addr
>= c
->base
) && (addr
<= c
->base
+ (c
->size
- 1))) {
292 LOG_ERROR("No flash at address 0x%08" PRIx32
, addr
);
298 static int default_flash_mem_blank_check(struct flash_bank
*bank
)
300 struct target
*target
= bank
->target
;
301 const int buffer_size
= 1024;
304 int retval
= ERROR_OK
;
306 if (bank
->target
->state
!= TARGET_HALTED
) {
307 LOG_ERROR("Target not halted");
308 return ERROR_TARGET_NOT_HALTED
;
311 uint8_t *buffer
= malloc(buffer_size
);
313 for (i
= 0; i
< bank
->num_sectors
; i
++) {
315 bank
->sectors
[i
].is_erased
= 1;
317 for (j
= 0; j
< bank
->sectors
[i
].size
; j
+= buffer_size
) {
320 if (chunk
> (j
- bank
->sectors
[i
].size
))
321 chunk
= (j
- bank
->sectors
[i
].size
);
323 retval
= target_read_memory(target
,
324 bank
->base
+ bank
->sectors
[i
].offset
+ j
,
328 if (retval
!= ERROR_OK
)
331 for (nBytes
= 0; nBytes
< chunk
; nBytes
++) {
332 if (buffer
[nBytes
] != bank
->erased_value
) {
333 bank
->sectors
[i
].is_erased
= 0;
346 int default_flash_blank_check(struct flash_bank
*bank
)
348 struct target
*target
= bank
->target
;
352 if (bank
->target
->state
!= TARGET_HALTED
) {
353 LOG_ERROR("Target not halted");
354 return ERROR_TARGET_NOT_HALTED
;
357 struct target_memory_check_block
*block_array
;
358 block_array
= malloc(bank
->num_sectors
* sizeof(struct target_memory_check_block
));
359 if (block_array
== NULL
)
360 return default_flash_mem_blank_check(bank
);
362 for (i
= 0; i
< bank
->num_sectors
; i
++) {
363 block_array
[i
].address
= bank
->base
+ bank
->sectors
[i
].offset
;
364 block_array
[i
].size
= bank
->sectors
[i
].size
;
365 block_array
[i
].result
= UINT32_MAX
; /* erase state unknown */
368 bool fast_check
= true;
369 for (i
= 0; i
< bank
->num_sectors
; ) {
370 retval
= target_blank_check_memory(target
,
371 block_array
+ i
, bank
->num_sectors
- i
,
374 /* Run slow fallback if the first run gives no result
375 * otherwise use possibly incomplete results */
380 i
+= retval
; /* add number of blocks done this round */
384 for (i
= 0; i
< bank
->num_sectors
; i
++)
385 bank
->sectors
[i
].is_erased
= block_array
[i
].result
;
388 LOG_USER("Running slow fallback erase check - add working memory");
389 retval
= default_flash_mem_blank_check(bank
);
396 /* Manipulate given flash region, selecting the bank according to target
397 * and address. Maps an address range to a set of sectors, and issues
398 * the callback() on that set ... e.g. to erase or unprotect its members.
400 * Parameter iterate_protect_blocks switches iteration of protect block
401 * instead of erase sectors. If there is no protect blocks array, sectors
402 * are used in iteration, so compatibility for old flash drivers is retained.
404 * The "pad_reason" parameter is a kind of boolean: when it's NULL, the
405 * range must fit those sectors exactly. This is clearly safe; it can't
406 * erase data which the caller said to leave alone, for example. If it's
407 * non-NULL, rather than failing, extra data in the first and/or last
408 * sectors will be added to the range, and that reason string is used when
409 * warning about those additions.
411 static int flash_iterate_address_range_inner(struct target
*target
,
412 char *pad_reason
, uint32_t addr
, uint32_t length
,
413 bool iterate_protect_blocks
,
414 int (*callback
)(struct flash_bank
*bank
, int first
, int last
))
416 struct flash_bank
*c
;
417 struct flash_sector
*block_array
;
418 uint32_t last_addr
= addr
+ length
; /* first address AFTER end */
424 int retval
= get_flash_bank_by_addr(target
, addr
, true, &c
);
425 if (retval
!= ERROR_OK
)
428 if (c
->size
== 0 || c
->num_sectors
== 0) {
429 LOG_ERROR("Bank is invalid");
430 return ERROR_FLASH_BANK_INVALID
;
434 /* special case, erase whole bank when length is zero */
435 if (addr
!= c
->base
) {
436 LOG_ERROR("Whole bank access must start at beginning of bank.");
437 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
440 return callback(c
, 0, c
->num_sectors
- 1);
443 /* check whether it all fits in this bank */
444 if (addr
+ length
- 1 > c
->base
+ c
->size
- 1) {
445 LOG_ERROR("Flash access does not fit into bank.");
446 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
449 if (c
->prot_blocks
== NULL
|| c
->num_prot_blocks
== 0) {
450 /* flash driver does not define protect blocks, use sectors instead */
451 iterate_protect_blocks
= false;
454 if (iterate_protect_blocks
) {
455 block_array
= c
->prot_blocks
;
456 num_blocks
= c
->num_prot_blocks
;
458 block_array
= c
->sectors
;
459 num_blocks
= c
->num_sectors
;
463 last_addr
-= c
->base
;
465 for (i
= 0; i
< num_blocks
; i
++) {
466 struct flash_sector
*f
= &block_array
[i
];
467 uint32_t end
= f
->offset
+ f
->size
;
469 /* start only on a sector boundary */
471 /* scanned past the first sector? */
472 if (addr
< f
->offset
)
475 /* is this the first sector? */
476 if (addr
== f
->offset
)
479 /* Does this need head-padding? If so, pad and warn;
480 * or else force an error.
482 * Such padding can make trouble, since *WE* can't
483 * ever know if that data was in use. The warning
484 * should help users sort out messes later.
486 else if (addr
< end
&& pad_reason
) {
487 /* FIXME say how many bytes (e.g. 80 KB) */
488 LOG_WARNING("Adding extra %s range, "
491 (unsigned) f
->offset
,
492 (unsigned) addr
- 1);
498 /* is this (also?) the last sector? */
499 if (last_addr
== end
) {
504 /* Does this need tail-padding? If so, pad and warn;
505 * or else force an error.
507 if (last_addr
< end
&& pad_reason
) {
508 /* FIXME say how many bytes (e.g. 80 KB) */
509 LOG_WARNING("Adding extra %s range, "
512 (unsigned) last_addr
,
518 /* MUST finish on a sector boundary */
519 if (last_addr
<= f
->offset
)
523 /* invalid start or end address? */
524 if (first
== -1 || last
== -1) {
525 LOG_ERROR("address range 0x%8.8x .. 0x%8.8x "
526 "is not sector-aligned",
527 (unsigned) (c
->base
+ addr
),
528 (unsigned) (c
->base
+ last_addr
- 1));
529 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
532 /* The NOR driver may trim this range down, based on what
533 * sectors are already erased/unprotected. GDB currently
534 * blocks such optimizations.
536 return callback(c
, first
, last
);
539 /* The inner fn only handles a single bank, we could be spanning
542 static int flash_iterate_address_range(struct target
*target
,
543 char *pad_reason
, uint32_t addr
, uint32_t length
,
544 bool iterate_protect_blocks
,
545 int (*callback
)(struct flash_bank
*bank
, int first
, int last
))
547 struct flash_bank
*c
;
548 int retval
= ERROR_OK
;
550 /* Danger! zero-length iterations means entire bank! */
552 retval
= get_flash_bank_by_addr(target
, addr
, true, &c
);
553 if (retval
!= ERROR_OK
)
556 uint32_t cur_length
= length
;
557 /* check whether it all fits in this bank */
558 if (addr
+ length
- 1 > c
->base
+ c
->size
- 1) {
559 LOG_DEBUG("iterating over more than one flash bank.");
560 cur_length
= c
->base
+ c
->size
- addr
;
562 retval
= flash_iterate_address_range_inner(target
,
563 pad_reason
, addr
, cur_length
,
564 iterate_protect_blocks
,
566 if (retval
!= ERROR_OK
)
569 length
-= cur_length
;
571 } while (length
> 0);
576 int flash_erase_address_range(struct target
*target
,
577 bool pad
, uint32_t addr
, uint32_t length
)
579 return flash_iterate_address_range(target
, pad
? "erase" : NULL
,
580 addr
, length
, false, &flash_driver_erase
);
583 static int flash_driver_unprotect(struct flash_bank
*bank
, int first
, int last
)
585 return flash_driver_protect(bank
, 0, first
, last
);
588 int flash_unlock_address_range(struct target
*target
, uint32_t addr
, uint32_t length
)
590 /* By default, pad to sector boundaries ... the real issue here
591 * is that our (only) caller *permanently* removes protection,
592 * and doesn't restore it.
594 return flash_iterate_address_range(target
, "unprotect",
595 addr
, length
, true, &flash_driver_unprotect
);
598 static int compare_section(const void *a
, const void *b
)
600 struct imagesection
*b1
, *b2
;
601 b1
= *((struct imagesection
**)a
);
602 b2
= *((struct imagesection
**)b
);
604 if (b1
->base_address
== b2
->base_address
)
606 else if (b1
->base_address
> b2
->base_address
)
613 * Get aligned start address of a flash write region
615 target_addr_t
flash_write_align_start(struct flash_bank
*bank
, target_addr_t addr
)
617 if (addr
< bank
->base
|| addr
>= bank
->base
+ bank
->size
618 || bank
->write_start_alignment
<= 1)
621 if (bank
->write_start_alignment
== FLASH_WRITE_ALIGN_SECTOR
) {
622 uint32_t offset
= addr
- bank
->base
;
623 uint32_t aligned
= 0;
625 for (sect
= 0; sect
< bank
->num_sectors
; sect
++) {
626 if (bank
->sectors
[sect
].offset
> offset
)
629 aligned
= bank
->sectors
[sect
].offset
;
631 return bank
->base
+ aligned
;
634 return addr
& ~(bank
->write_start_alignment
- 1);
638 * Get aligned end address of a flash write region
640 target_addr_t
flash_write_align_end(struct flash_bank
*bank
, target_addr_t addr
)
642 if (addr
< bank
->base
|| addr
>= bank
->base
+ bank
->size
643 || bank
->write_end_alignment
<= 1)
646 if (bank
->write_end_alignment
== FLASH_WRITE_ALIGN_SECTOR
) {
647 uint32_t offset
= addr
- bank
->base
;
648 uint32_t aligned
= 0;
650 for (sect
= 0; sect
< bank
->num_sectors
; sect
++) {
651 aligned
= bank
->sectors
[sect
].offset
+ bank
->sectors
[sect
].size
- 1;
652 if (aligned
>= offset
)
655 return bank
->base
+ aligned
;
658 return addr
| (bank
->write_end_alignment
- 1);
662 * Check if gap between sections is bigger than minimum required to discontinue flash write
664 static bool flash_write_check_gap(struct flash_bank
*bank
,
665 target_addr_t addr1
, target_addr_t addr2
)
667 if (bank
->minimal_write_gap
== FLASH_WRITE_CONTINUOUS
668 || addr1
< bank
->base
|| addr1
>= bank
->base
+ bank
->size
669 || addr2
< bank
->base
|| addr2
>= bank
->base
+ bank
->size
)
672 if (bank
->minimal_write_gap
== FLASH_WRITE_GAP_SECTOR
) {
674 uint32_t offset1
= addr1
- bank
->base
;
675 /* find the sector following the one containing addr1 */
676 for (sect
= 0; sect
< bank
->num_sectors
; sect
++) {
677 if (bank
->sectors
[sect
].offset
> offset1
)
680 if (sect
>= bank
->num_sectors
)
683 uint32_t offset2
= addr2
- bank
->base
;
684 return bank
->sectors
[sect
].offset
+ bank
->sectors
[sect
].size
<= offset2
;
687 target_addr_t aligned1
= flash_write_align_end(bank
, addr1
);
688 target_addr_t aligned2
= flash_write_align_start(bank
, addr2
);
689 return aligned1
+ bank
->minimal_write_gap
< aligned2
;
693 int flash_write_unlock(struct target
*target
, struct image
*image
,
694 uint32_t *written
, int erase
, bool unlock
)
696 int retval
= ERROR_OK
;
699 uint32_t section_offset
;
700 struct flash_bank
*c
;
710 /* assume all sectors need erasing - stops any problems
711 * when flash_write is called multiple times */
716 /* allocate padding array */
717 padding
= calloc(image
->num_sections
, sizeof(*padding
));
719 /* This fn requires all sections to be in ascending order of addresses,
720 * whereas an image can have sections out of order. */
721 struct imagesection
**sections
= malloc(sizeof(struct imagesection
*) *
722 image
->num_sections
);
724 for (i
= 0; i
< image
->num_sections
; i
++)
725 sections
[i
] = &image
->sections
[i
];
727 qsort(sections
, image
->num_sections
, sizeof(struct imagesection
*),
730 /* loop until we reach end of the image */
731 while (section
< image
->num_sections
) {
735 target_addr_t run_address
= sections
[section
]->base_address
+ section_offset
;
736 uint32_t run_size
= sections
[section
]->size
- section_offset
;
739 if (sections
[section
]->size
== 0) {
740 LOG_WARNING("empty section %d", section
);
746 /* find the corresponding flash bank */
747 retval
= get_flash_bank_by_addr(target
, run_address
, false, &c
);
748 if (retval
!= ERROR_OK
)
751 LOG_WARNING("no flash bank found for address " TARGET_ADDR_FMT
, run_address
);
752 section
++; /* and skip it */
757 /* collect consecutive sections which fall into the same bank */
758 section_last
= section
;
759 padding
[section
] = 0;
760 while ((run_address
+ run_size
- 1 < c
->base
+ c
->size
- 1) &&
761 (section_last
+ 1 < image
->num_sections
)) {
762 /* sections are sorted */
763 assert(sections
[section_last
+ 1]->base_address
>= c
->base
);
764 if (sections
[section_last
+ 1]->base_address
>= (c
->base
+ c
->size
)) {
765 /* Done with this bank */
769 /* if we have multiple sections within our image,
770 * flash programming could fail due to alignment issues
771 * attempt to rebuild a consecutive buffer for the flash loader */
772 target_addr_t run_next_addr
= run_address
+ run_size
;
773 target_addr_t next_section_base
= sections
[section_last
+ 1]->base_address
;
774 if (next_section_base
< run_next_addr
) {
775 LOG_ERROR("Section at " TARGET_ADDR_FMT
776 " overlaps section ending at " TARGET_ADDR_FMT
,
777 next_section_base
, run_next_addr
);
778 LOG_ERROR("Flash write aborted.");
783 pad_bytes
= next_section_base
- run_next_addr
;
785 if (flash_write_check_gap(c
, run_next_addr
- 1, next_section_base
)) {
786 LOG_INFO("Flash write discontinued at " TARGET_ADDR_FMT
787 ", next section at " TARGET_ADDR_FMT
,
788 run_next_addr
, next_section_base
);
793 LOG_INFO("Padding image section %d at " TARGET_ADDR_FMT
795 section_last
, run_next_addr
, pad_bytes
);
797 padding
[section_last
] = pad_bytes
;
798 run_size
+= pad_bytes
;
799 run_size
+= sections
[++section_last
]->size
;
802 if (run_address
+ run_size
- 1 > c
->base
+ c
->size
- 1) {
803 /* If we have more than one flash chip back to back, then we limit
804 * the current write operation to the current chip.
806 LOG_DEBUG("Truncate flash run size to the current flash chip.");
808 run_size
= c
->base
+ c
->size
- run_address
;
809 assert(run_size
> 0);
812 uint32_t padding_at_start
= 0;
813 if (c
->write_start_alignment
|| c
->write_end_alignment
) {
814 /* align write region according to bank requirements */
815 target_addr_t aligned_start
= flash_write_align_start(c
, run_address
);
816 padding_at_start
= run_address
- aligned_start
;
817 if (padding_at_start
> 0) {
818 LOG_WARNING("Section start address " TARGET_ADDR_FMT
819 " breaks the required alignment of flash bank %s",
820 run_address
, c
->name
);
821 LOG_WARNING("Padding %d bytes from " TARGET_ADDR_FMT
,
822 padding_at_start
, aligned_start
);
824 run_address
-= padding_at_start
;
825 run_size
+= padding_at_start
;
828 target_addr_t run_end
= run_address
+ run_size
- 1;
829 target_addr_t aligned_end
= flash_write_align_end(c
, run_end
);
830 pad_bytes
= aligned_end
- run_end
;
832 LOG_INFO("Padding image section %d at " TARGET_ADDR_FMT
833 " with %d bytes (bank write end alignment)",
834 section_last
, run_end
+ 1, pad_bytes
);
836 padding
[section_last
] += pad_bytes
;
837 run_size
+= pad_bytes
;
840 } else if (unlock
|| erase
) {
841 /* If we're applying any sector automagic, then pad this
842 * (maybe-combined) segment to the end of its last sector.
845 uint32_t offset_start
= run_address
- c
->base
;
846 uint32_t offset_end
= offset_start
+ run_size
;
847 uint32_t end
= offset_end
, delta
;
849 for (sector
= 0; sector
< c
->num_sectors
; sector
++) {
850 end
= c
->sectors
[sector
].offset
851 + c
->sectors
[sector
].size
;
852 if (offset_end
<= end
)
856 delta
= end
- offset_end
;
857 padding
[section_last
] += delta
;
861 /* allocate buffer */
862 buffer
= malloc(run_size
);
863 if (buffer
== NULL
) {
864 LOG_ERROR("Out of memory for flash bank buffer");
869 if (padding_at_start
)
870 memset(buffer
, c
->default_padded_value
, padding_at_start
);
872 buffer_idx
= padding_at_start
;
874 /* read sections to the buffer */
875 while (buffer_idx
< run_size
) {
878 size_read
= run_size
- buffer_idx
;
879 if (size_read
> sections
[section
]->size
- section_offset
)
880 size_read
= sections
[section
]->size
- section_offset
;
884 * #¤%#"%¤% we have to figure out the section # from the sorted
885 * list of pointers to sections to invoke image_read_section()...
887 intptr_t diff
= (intptr_t)sections
[section
] - (intptr_t)image
->sections
;
888 int t_section_num
= diff
/ sizeof(struct imagesection
);
890 LOG_DEBUG("image_read_section: section = %d, t_section_num = %d, "
891 "section_offset = %"PRIu32
", buffer_idx = %"PRIu32
", size_read = %zu",
892 section
, t_section_num
, section_offset
,
893 buffer_idx
, size_read
);
894 retval
= image_read_section(image
, t_section_num
, section_offset
,
895 size_read
, buffer
+ buffer_idx
, &size_read
);
896 if (retval
!= ERROR_OK
|| size_read
== 0) {
901 buffer_idx
+= size_read
;
902 section_offset
+= size_read
;
904 /* see if we need to pad the section */
905 if (padding
[section
]) {
906 memset(buffer
+ buffer_idx
, c
->default_padded_value
, padding
[section
]);
907 buffer_idx
+= padding
[section
];
910 if (section_offset
>= sections
[section
]->size
) {
919 retval
= flash_unlock_address_range(target
, run_address
, run_size
);
920 if (retval
== ERROR_OK
) {
922 /* calculate and erase sectors */
923 retval
= flash_erase_address_range(target
,
924 true, run_address
, run_size
);
928 if (retval
== ERROR_OK
) {
929 /* write flash sectors */
930 retval
= flash_driver_write(c
, buffer
, run_address
- c
->base
, run_size
);
935 if (retval
!= ERROR_OK
) {
936 /* abort operation */
941 *written
+= run_size
; /* add run size to total written counter */
951 int flash_write(struct target
*target
, struct image
*image
,
952 uint32_t *written
, int erase
)
954 return flash_write_unlock(target
, image
, written
, erase
, false);
957 struct flash_sector
*alloc_block_array(uint32_t offset
, uint32_t size
, int num_blocks
)
961 struct flash_sector
*array
= calloc(num_blocks
, sizeof(struct flash_sector
));
965 for (i
= 0; i
< num_blocks
; i
++) {
966 array
[i
].offset
= offset
;
967 array
[i
].size
= size
;
968 array
[i
].is_erased
= -1;
969 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)