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> *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
20 ***************************************************************************/
25 #include <flash/common.h>
26 #include <flash/nor/core.h>
27 #include <flash/nor/imp.h>
28 #include <target/image.h>
32 * Upper level of NOR flash framework.
33 * The lower level interfaces are to drivers. These upper level ones
34 * primarily support access from Tcl scripts or from GDB.
37 static struct flash_bank
*flash_banks
;
39 int flash_driver_erase(struct flash_bank
*bank
, int first
, int last
)
43 retval
= bank
->driver
->erase(bank
, first
, last
);
44 if (retval
!= ERROR_OK
)
45 LOG_ERROR("failed erasing sectors %d to %d", first
, last
);
50 int flash_driver_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
55 if (bank
->num_prot_blocks
)
56 num_blocks
= bank
->num_prot_blocks
;
58 num_blocks
= bank
->num_sectors
;
61 /* callers may not supply illegal parameters ... */
62 if (first
< 0 || first
> last
|| last
>= num_blocks
) {
63 LOG_ERROR("illegal protection block range");
67 /* force "set" to 0/1 */
72 * We must not use any cached information about protection state!!!!
74 * There are a million things that could change the protect state:
76 * the target could have reset, power cycled, been hot plugged,
77 * the application could have run, etc.
79 * Drivers only receive valid protection block range.
81 retval
= bank
->driver
->protect(bank
, set
, first
, last
);
82 if (retval
!= ERROR_OK
)
83 LOG_ERROR("failed setting protection for blocks %d to %d", first
, last
);
88 int flash_driver_write(struct flash_bank
*bank
,
89 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
93 retval
= bank
->driver
->write(bank
, buffer
, offset
, count
);
94 if (retval
!= ERROR_OK
) {
96 "error writing to flash at address 0x%08" PRIx32
" at offset 0x%8.8" PRIx32
,
104 int flash_driver_read(struct flash_bank
*bank
,
105 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
109 LOG_DEBUG("call flash_driver_read()");
111 retval
= bank
->driver
->read(bank
, buffer
, offset
, count
);
112 if (retval
!= ERROR_OK
) {
114 "error reading to flash at address 0x%08" PRIx32
" at offset 0x%8.8" PRIx32
,
122 int default_flash_read(struct flash_bank
*bank
,
123 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
125 return target_read_buffer(bank
->target
, offset
+ bank
->base
, count
, buffer
);
128 void flash_bank_add(struct flash_bank
*bank
)
130 /* put flash bank in linked list */
131 unsigned bank_num
= 0;
133 /* find last flash bank */
134 struct flash_bank
*p
= flash_banks
;
135 while (NULL
!= p
->next
) {
144 bank
->bank_number
= bank_num
;
147 struct flash_bank
*flash_bank_list(void)
152 struct flash_bank
*get_flash_bank_by_num_noprobe(int num
)
154 struct flash_bank
*p
;
157 for (p
= flash_banks
; p
; p
= p
->next
) {
161 LOG_ERROR("flash bank %d does not exist", num
);
165 int flash_get_bank_count(void)
167 struct flash_bank
*p
;
169 for (p
= flash_banks
; p
; p
= p
->next
)
174 struct flash_bank
*get_flash_bank_by_name_noprobe(const char *name
)
176 unsigned requested
= get_flash_name_index(name
);
179 struct flash_bank
*bank
;
180 for (bank
= flash_banks
; NULL
!= bank
; bank
= bank
->next
) {
181 if (strcmp(bank
->name
, name
) == 0)
183 if (!flash_driver_name_matches(bank
->driver
->name
, name
))
185 if (++found
< requested
)
192 int get_flash_bank_by_name(const char *name
, struct flash_bank
**bank_result
)
194 struct flash_bank
*bank
;
197 bank
= get_flash_bank_by_name_noprobe(name
);
199 retval
= bank
->driver
->auto_probe(bank
);
201 if (retval
!= ERROR_OK
) {
202 LOG_ERROR("auto_probe failed");
211 int get_flash_bank_by_num(int num
, struct flash_bank
**bank
)
213 struct flash_bank
*p
= get_flash_bank_by_num_noprobe(num
);
219 retval
= p
->driver
->auto_probe(p
);
221 if (retval
!= ERROR_OK
) {
222 LOG_ERROR("auto_probe failed");
229 /* lookup flash bank by address, bank not found is success, but
230 * result_bank is set to NULL. */
231 int get_flash_bank_by_addr(struct target
*target
,
234 struct flash_bank
**result_bank
)
236 struct flash_bank
*c
;
238 /* cycle through bank list */
239 for (c
= flash_banks
; c
; c
= c
->next
) {
240 if (c
->target
!= target
)
244 retval
= c
->driver
->auto_probe(c
);
246 if (retval
!= ERROR_OK
) {
247 LOG_ERROR("auto_probe failed");
250 /* check whether address belongs to this flash bank */
251 if ((addr
>= c
->base
) && (addr
<= c
->base
+ (c
->size
- 1))) {
258 LOG_ERROR("No flash at address 0x%08" PRIx32
, addr
);
264 static int default_flash_mem_blank_check(struct flash_bank
*bank
)
266 struct target
*target
= bank
->target
;
267 const int buffer_size
= 1024;
270 int retval
= ERROR_OK
;
272 if (bank
->target
->state
!= TARGET_HALTED
) {
273 LOG_ERROR("Target not halted");
274 return ERROR_TARGET_NOT_HALTED
;
277 uint8_t *buffer
= malloc(buffer_size
);
279 for (i
= 0; i
< bank
->num_sectors
; i
++) {
281 bank
->sectors
[i
].is_erased
= 1;
283 for (j
= 0; j
< bank
->sectors
[i
].size
; j
+= buffer_size
) {
286 if (chunk
> (j
- bank
->sectors
[i
].size
))
287 chunk
= (j
- bank
->sectors
[i
].size
);
289 retval
= target_read_memory(target
,
290 bank
->base
+ bank
->sectors
[i
].offset
+ j
,
294 if (retval
!= ERROR_OK
)
297 for (nBytes
= 0; nBytes
< chunk
; nBytes
++) {
298 if (buffer
[nBytes
] != bank
->erased_value
) {
299 bank
->sectors
[i
].is_erased
= 0;
312 int default_flash_blank_check(struct flash_bank
*bank
)
314 struct target
*target
= bank
->target
;
320 if (bank
->target
->state
!= TARGET_HALTED
) {
321 LOG_ERROR("Target not halted");
322 return ERROR_TARGET_NOT_HALTED
;
325 for (i
= 0; i
< bank
->num_sectors
; i
++) {
326 uint32_t address
= bank
->base
+ bank
->sectors
[i
].offset
;
327 uint32_t size
= bank
->sectors
[i
].size
;
329 retval
= target_blank_check_memory(target
, address
, size
, &blank
, bank
->erased_value
);
330 if (retval
!= ERROR_OK
) {
334 if (blank
== bank
->erased_value
)
335 bank
->sectors
[i
].is_erased
= 1;
337 bank
->sectors
[i
].is_erased
= 0;
342 LOG_USER("Running slow fallback erase check - add working memory");
343 return default_flash_mem_blank_check(bank
);
349 /* Manipulate given flash region, selecting the bank according to target
350 * and address. Maps an address range to a set of sectors, and issues
351 * the callback() on that set ... e.g. to erase or unprotect its members.
353 * Parameter iterate_protect_blocks switches iteration of protect block
354 * instead of erase sectors. If there is no protect blocks array, sectors
355 * are used in iteration, so compatibility for old flash drivers is retained.
357 * The "pad_reason" parameter is a kind of boolean: when it's NULL, the
358 * range must fit those sectors exactly. This is clearly safe; it can't
359 * erase data which the caller said to leave alone, for example. If it's
360 * non-NULL, rather than failing, extra data in the first and/or last
361 * sectors will be added to the range, and that reason string is used when
362 * warning about those additions.
364 static int flash_iterate_address_range_inner(struct target
*target
,
365 char *pad_reason
, uint32_t addr
, uint32_t length
,
366 bool iterate_protect_blocks
,
367 int (*callback
)(struct flash_bank
*bank
, int first
, int last
))
369 struct flash_bank
*c
;
370 struct flash_sector
*block_array
;
371 uint32_t last_addr
= addr
+ length
; /* first address AFTER end */
377 int retval
= get_flash_bank_by_addr(target
, addr
, true, &c
);
378 if (retval
!= ERROR_OK
)
381 if (c
->size
== 0 || c
->num_sectors
== 0) {
382 LOG_ERROR("Bank is invalid");
383 return ERROR_FLASH_BANK_INVALID
;
387 /* special case, erase whole bank when length is zero */
388 if (addr
!= c
->base
) {
389 LOG_ERROR("Whole bank access must start at beginning of bank.");
390 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
393 return callback(c
, 0, c
->num_sectors
- 1);
396 /* check whether it all fits in this bank */
397 if (addr
+ length
- 1 > c
->base
+ c
->size
- 1) {
398 LOG_ERROR("Flash access does not fit into bank.");
399 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
402 if (c
->prot_blocks
== NULL
|| c
->num_prot_blocks
== 0) {
403 /* flash driver does not define protect blocks, use sectors instead */
404 iterate_protect_blocks
= false;
407 if (iterate_protect_blocks
) {
408 block_array
= c
->prot_blocks
;
409 num_blocks
= c
->num_prot_blocks
;
411 block_array
= c
->sectors
;
412 num_blocks
= c
->num_sectors
;
416 last_addr
-= c
->base
;
418 for (i
= 0; i
< num_blocks
; i
++) {
419 struct flash_sector
*f
= &block_array
[i
];
420 uint32_t end
= f
->offset
+ f
->size
;
422 /* start only on a sector boundary */
424 /* scanned past the first sector? */
425 if (addr
< f
->offset
)
428 /* is this the first sector? */
429 if (addr
== f
->offset
)
432 /* Does this need head-padding? If so, pad and warn;
433 * or else force an error.
435 * Such padding can make trouble, since *WE* can't
436 * ever know if that data was in use. The warning
437 * should help users sort out messes later.
439 else if (addr
< end
&& pad_reason
) {
440 /* FIXME say how many bytes (e.g. 80 KB) */
441 LOG_WARNING("Adding extra %s range, "
444 (unsigned) f
->offset
,
445 (unsigned) addr
- 1);
451 /* is this (also?) the last sector? */
452 if (last_addr
== end
) {
457 /* Does this need tail-padding? If so, pad and warn;
458 * or else force an error.
460 if (last_addr
< end
&& pad_reason
) {
461 /* FIXME say how many bytes (e.g. 80 KB) */
462 LOG_WARNING("Adding extra %s range, "
465 (unsigned) last_addr
,
471 /* MUST finish on a sector boundary */
472 if (last_addr
<= f
->offset
)
476 /* invalid start or end address? */
477 if (first
== -1 || last
== -1) {
478 LOG_ERROR("address range 0x%8.8x .. 0x%8.8x "
479 "is not sector-aligned",
480 (unsigned) (c
->base
+ addr
),
481 (unsigned) (c
->base
+ last_addr
- 1));
482 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
485 /* The NOR driver may trim this range down, based on what
486 * sectors are already erased/unprotected. GDB currently
487 * blocks such optimizations.
489 return callback(c
, first
, last
);
492 /* The inner fn only handles a single bank, we could be spanning
495 static int flash_iterate_address_range(struct target
*target
,
496 char *pad_reason
, uint32_t addr
, uint32_t length
,
497 bool iterate_protect_blocks
,
498 int (*callback
)(struct flash_bank
*bank
, int first
, int last
))
500 struct flash_bank
*c
;
501 int retval
= ERROR_OK
;
503 /* Danger! zero-length iterations means entire bank! */
505 retval
= get_flash_bank_by_addr(target
, addr
, true, &c
);
506 if (retval
!= ERROR_OK
)
509 uint32_t cur_length
= length
;
510 /* check whether it all fits in this bank */
511 if (addr
+ length
- 1 > c
->base
+ c
->size
- 1) {
512 LOG_DEBUG("iterating over more than one flash bank.");
513 cur_length
= c
->base
+ c
->size
- addr
;
515 retval
= flash_iterate_address_range_inner(target
,
516 pad_reason
, addr
, cur_length
,
517 iterate_protect_blocks
,
519 if (retval
!= ERROR_OK
)
522 length
-= cur_length
;
524 } while (length
> 0);
529 int flash_erase_address_range(struct target
*target
,
530 bool pad
, uint32_t addr
, uint32_t length
)
532 return flash_iterate_address_range(target
, pad
? "erase" : NULL
,
533 addr
, length
, false, &flash_driver_erase
);
536 static int flash_driver_unprotect(struct flash_bank
*bank
, int first
, int last
)
538 return flash_driver_protect(bank
, 0, first
, last
);
541 int flash_unlock_address_range(struct target
*target
, uint32_t addr
, uint32_t length
)
543 /* By default, pad to sector boundaries ... the real issue here
544 * is that our (only) caller *permanently* removes protection,
545 * and doesn't restore it.
547 return flash_iterate_address_range(target
, "unprotect",
548 addr
, length
, true, &flash_driver_unprotect
);
551 static int compare_section(const void *a
, const void *b
)
553 struct imagesection
*b1
, *b2
;
554 b1
= *((struct imagesection
**)a
);
555 b2
= *((struct imagesection
**)b
);
557 if (b1
->base_address
== b2
->base_address
)
559 else if (b1
->base_address
> b2
->base_address
)
565 int flash_write_unlock(struct target
*target
, struct image
*image
,
566 uint32_t *written
, int erase
, bool unlock
)
568 int retval
= ERROR_OK
;
571 uint32_t section_offset
;
572 struct flash_bank
*c
;
582 /* assume all sectors need erasing - stops any problems
583 * when flash_write is called multiple times */
588 /* allocate padding array */
589 padding
= calloc(image
->num_sections
, sizeof(*padding
));
591 /* This fn requires all sections to be in ascending order of addresses,
592 * whereas an image can have sections out of order. */
593 struct imagesection
**sections
= malloc(sizeof(struct imagesection
*) *
594 image
->num_sections
);
596 for (i
= 0; i
< image
->num_sections
; i
++)
597 sections
[i
] = &image
->sections
[i
];
599 qsort(sections
, image
->num_sections
, sizeof(struct imagesection
*),
602 /* loop until we reach end of the image */
603 while (section
< image
->num_sections
) {
604 uint32_t buffer_size
;
607 target_addr_t run_address
= sections
[section
]->base_address
+ section_offset
;
608 uint32_t run_size
= sections
[section
]->size
- section_offset
;
611 if (sections
[section
]->size
== 0) {
612 LOG_WARNING("empty section %d", section
);
618 /* find the corresponding flash bank */
619 retval
= get_flash_bank_by_addr(target
, run_address
, false, &c
);
620 if (retval
!= ERROR_OK
)
623 LOG_WARNING("no flash bank found for address " TARGET_ADDR_FMT
, run_address
);
624 section
++; /* and skip it */
629 /* collect consecutive sections which fall into the same bank */
630 section_last
= section
;
631 padding
[section
] = 0;
632 while ((run_address
+ run_size
- 1 < c
->base
+ c
->size
- 1) &&
633 (section_last
+ 1 < image
->num_sections
)) {
634 /* sections are sorted */
635 assert(sections
[section_last
+ 1]->base_address
>= c
->base
);
636 if (sections
[section_last
+ 1]->base_address
>= (c
->base
+ c
->size
)) {
637 /* Done with this bank */
641 /* FIXME This needlessly touches sectors BETWEEN the
642 * sections it's writing. Without auto erase, it just
643 * writes ones. That WILL INVALIDATE data in cases
644 * like Stellaris Tempest chips, corrupting internal
645 * ECC codes; and at least FreeScale suggests issues
646 * with that approach (in HC11 documentation).
648 * With auto erase enabled, data in those sectors will
649 * be needlessly destroyed; and some of the limited
650 * number of flash erase cycles will be wasted...
652 * In both cases, the extra writes slow things down.
655 /* if we have multiple sections within our image,
656 * flash programming could fail due to alignment issues
657 * attempt to rebuild a consecutive buffer for the flash loader */
658 target_addr_t run_next_addr
= run_address
+ run_size
;
659 if (sections
[section_last
+ 1]->base_address
< run_next_addr
) {
660 LOG_ERROR("Section at " TARGET_ADDR_FMT
661 " overlaps section ending at " TARGET_ADDR_FMT
,
662 sections
[section_last
+ 1]->base_address
,
664 LOG_ERROR("Flash write aborted.");
669 pad_bytes
= sections
[section_last
+ 1]->base_address
- run_next_addr
;
670 padding
[section_last
] = pad_bytes
;
671 run_size
+= sections
[++section_last
]->size
;
672 run_size
+= pad_bytes
;
675 LOG_INFO("Padding image section %d with %d bytes",
680 if (run_address
+ run_size
- 1 > c
->base
+ c
->size
- 1) {
681 /* If we have more than one flash chip back to back, then we limit
682 * the current write operation to the current chip.
684 LOG_DEBUG("Truncate flash run size to the current flash chip.");
686 run_size
= c
->base
+ c
->size
- run_address
;
687 assert(run_size
> 0);
690 /* If we're applying any sector automagic, then pad this
691 * (maybe-combined) segment to the end of its last sector.
693 if (unlock
|| erase
) {
695 uint32_t offset_start
= run_address
- c
->base
;
696 uint32_t offset_end
= offset_start
+ run_size
;
697 uint32_t end
= offset_end
, delta
;
699 for (sector
= 0; sector
< c
->num_sectors
; sector
++) {
700 end
= c
->sectors
[sector
].offset
701 + c
->sectors
[sector
].size
;
702 if (offset_end
<= end
)
706 delta
= end
- offset_end
;
707 padding
[section_last
] += delta
;
711 /* allocate buffer */
712 buffer
= malloc(run_size
);
713 if (buffer
== NULL
) {
714 LOG_ERROR("Out of memory for flash bank buffer");
720 /* read sections to the buffer */
721 while (buffer_size
< run_size
) {
724 size_read
= run_size
- buffer_size
;
725 if (size_read
> sections
[section
]->size
- section_offset
)
726 size_read
= sections
[section
]->size
- section_offset
;
730 * #¤%#"%¤% we have to figure out the section # from the sorted
731 * list of pointers to sections to invoke image_read_section()...
733 intptr_t diff
= (intptr_t)sections
[section
] - (intptr_t)image
->sections
;
734 int t_section_num
= diff
/ sizeof(struct imagesection
);
736 LOG_DEBUG("image_read_section: section = %d, t_section_num = %d, "
737 "section_offset = %d, buffer_size = %d, size_read = %d",
738 (int)section
, (int)t_section_num
, (int)section_offset
,
739 (int)buffer_size
, (int)size_read
);
740 retval
= image_read_section(image
, t_section_num
, section_offset
,
741 size_read
, buffer
+ buffer_size
, &size_read
);
742 if (retval
!= ERROR_OK
|| size_read
== 0) {
747 /* see if we need to pad the section */
748 while (padding
[section
]--)
749 (buffer
+ buffer_size
)[size_read
++] = c
->default_padded_value
;
751 buffer_size
+= size_read
;
752 section_offset
+= size_read
;
754 if (section_offset
>= sections
[section
]->size
) {
763 retval
= flash_unlock_address_range(target
, run_address
, run_size
);
764 if (retval
== ERROR_OK
) {
766 /* calculate and erase sectors */
767 retval
= flash_erase_address_range(target
,
768 true, run_address
, run_size
);
772 if (retval
== ERROR_OK
) {
773 /* write flash sectors */
774 retval
= flash_driver_write(c
, buffer
, run_address
- c
->base
, run_size
);
779 if (retval
!= ERROR_OK
) {
780 /* abort operation */
785 *written
+= run_size
; /* add run size to total written counter */
795 int flash_write(struct target
*target
, struct image
*image
,
796 uint32_t *written
, int erase
)
798 return flash_write_unlock(target
, image
, written
, erase
, false);
801 struct flash_sector
*alloc_block_array(uint32_t offset
, uint32_t size
, int num_blocks
)
805 struct flash_sector
*array
= calloc(num_blocks
, sizeof(struct flash_sector
));
809 for (i
= 0; i
< num_blocks
; i
++) {
810 array
[i
].offset
= offset
;
811 array
[i
].size
= size
;
812 array
[i
].is_erased
= -1;
813 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)