1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de> *
3 * Copyright (C) 2007,2008 Ø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> *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 ***************************************************************************/
26 #include <flash/common.h>
27 #include <flash/nor/core.h>
28 #include <flash/nor/imp.h>
29 #include <target/image.h>
32 struct flash_bank
*flash_banks
;
34 int flash_driver_erase(struct flash_bank
*bank
, int first
, int last
)
38 retval
= bank
->driver
->erase(bank
, first
, last
);
39 if (retval
!= ERROR_OK
)
41 LOG_ERROR("failed erasing sectors %d to %d (%d)", first
, last
, retval
);
47 int flash_driver_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
51 retval
= bank
->driver
->protect(bank
, set
, first
, last
);
52 if (retval
!= ERROR_OK
)
54 LOG_ERROR("failed setting protection for areas %d to %d (%d)", first
, last
, retval
);
60 int flash_driver_write(struct flash_bank
*bank
,
61 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
65 retval
= bank
->driver
->write(bank
, buffer
, offset
, count
);
66 if (retval
!= ERROR_OK
)
68 LOG_ERROR("error writing to flash at address 0x%08" PRIx32
" at offset 0x%8.8" PRIx32
" (%d)",
69 bank
->base
, offset
, retval
);
75 void flash_bank_add(struct flash_bank
*bank
)
77 /* put flash bank in linked list */
78 unsigned bank_num
= 0;
81 /* find last flash bank */
82 struct flash_bank
*p
= flash_banks
;
83 while (NULL
!= p
->next
)
94 bank
->bank_number
= bank_num
;
97 struct flash_bank
*flash_bank_list(void)
102 struct flash_bank
*get_flash_bank_by_num_noprobe(int num
)
104 struct flash_bank
*p
;
107 for (p
= flash_banks
; p
; p
= p
->next
)
114 LOG_ERROR("flash bank %d does not exist", num
);
118 int flash_get_bank_count(void)
120 struct flash_bank
*p
;
122 for (p
= flash_banks
; p
; p
= p
->next
)
129 struct flash_bank
*get_flash_bank_by_name(const char *name
)
131 unsigned requested
= get_flash_name_index(name
);
134 struct flash_bank
*bank
;
135 for (bank
= flash_banks
; NULL
!= bank
; bank
= bank
->next
)
137 if (strcmp(bank
->name
, name
) == 0)
139 if (!flash_driver_name_matches(bank
->driver
->name
, name
))
141 if (++found
< requested
)
148 struct flash_bank
*get_flash_bank_by_num(int num
)
150 struct flash_bank
*p
= get_flash_bank_by_num_noprobe(num
);
156 retval
= p
->driver
->auto_probe(p
);
158 if (retval
!= ERROR_OK
)
160 LOG_ERROR("auto_probe failed %d\n", retval
);
166 /* lookup flash bank by address */
167 struct flash_bank
*get_flash_bank_by_addr(struct target
*target
, uint32_t addr
)
169 struct flash_bank
*c
;
171 /* cycle through bank list */
172 for (c
= flash_banks
; c
; c
= c
->next
)
175 retval
= c
->driver
->auto_probe(c
);
177 if (retval
!= ERROR_OK
)
179 LOG_ERROR("auto_probe failed %d\n", retval
);
182 /* check whether address belongs to this flash bank */
183 if ((addr
>= c
->base
) && (addr
<= c
->base
+ (c
->size
- 1)) && target
== c
->target
)
186 LOG_ERROR("No flash at address 0x%08" PRIx32
"\n", addr
);
190 int default_flash_mem_blank_check(struct flash_bank
*bank
)
192 struct target
*target
= bank
->target
;
193 const int buffer_size
= 1024;
196 int retval
= ERROR_OK
;
198 if (bank
->target
->state
!= TARGET_HALTED
)
200 LOG_ERROR("Target not halted");
201 return ERROR_TARGET_NOT_HALTED
;
204 uint8_t *buffer
= malloc(buffer_size
);
206 for (i
= 0; i
< bank
->num_sectors
; i
++)
209 bank
->sectors
[i
].is_erased
= 1;
211 for (j
= 0; j
< bank
->sectors
[i
].size
; j
+= buffer_size
)
215 if (chunk
> (j
- bank
->sectors
[i
].size
))
217 chunk
= (j
- bank
->sectors
[i
].size
);
220 retval
= target_read_memory(target
, bank
->base
+ bank
->sectors
[i
].offset
+ j
, 4, chunk
/4, buffer
);
221 if (retval
!= ERROR_OK
)
226 for (nBytes
= 0; nBytes
< chunk
; nBytes
++)
228 if (buffer
[nBytes
] != 0xFF)
230 bank
->sectors
[i
].is_erased
= 0;
243 int default_flash_blank_check(struct flash_bank
*bank
)
245 struct target
*target
= bank
->target
;
251 if (bank
->target
->state
!= TARGET_HALTED
)
253 LOG_ERROR("Target not halted");
254 return ERROR_TARGET_NOT_HALTED
;
257 for (i
= 0; i
< bank
->num_sectors
; i
++)
259 uint32_t address
= bank
->base
+ bank
->sectors
[i
].offset
;
260 uint32_t size
= bank
->sectors
[i
].size
;
262 if ((retval
= target_blank_check_memory(target
, address
, size
, &blank
)) != ERROR_OK
)
268 bank
->sectors
[i
].is_erased
= 1;
270 bank
->sectors
[i
].is_erased
= 0;
276 LOG_USER("Running slow fallback erase check - add working memory");
277 return default_flash_mem_blank_check(bank
);
283 /* erase given flash region, selects proper bank according to target and address */
284 static int flash_iterate_address_range(struct target
*target
,
285 uint32_t addr
, uint32_t length
,
286 int (*callback
)(struct flash_bank
*bank
, int first
, int last
))
288 struct flash_bank
*c
;
289 uint32_t last_addr
= addr
+ length
; /* first address AFTER end */
294 if ((c
= get_flash_bank_by_addr(target
, addr
)) == NULL
)
295 return ERROR_FLASH_DST_OUT_OF_BANK
; /* no corresponding bank found */
297 if (c
->size
== 0 || c
->num_sectors
== 0)
299 LOG_ERROR("Bank is invalid");
300 return ERROR_FLASH_BANK_INVALID
;
305 /* special case, erase whole bank when length is zero */
307 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
309 return callback(c
, 0, c
->num_sectors
- 1);
312 /* check whether it all fits in this bank */
313 if (addr
+ length
- 1 > c
->base
+ c
->size
- 1)
314 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
316 /** @todo: handle erasures that cross into adjacent banks */
319 last_addr
-= c
->base
;
321 for (i
= 0; i
< c
->num_sectors
; i
++)
323 struct flash_sector
*f
= c
->sectors
+ i
;
325 /* start only on a sector boundary */
327 /* is this the first sector? */
328 if (addr
== f
->offset
)
330 else if (addr
< f
->offset
)
334 /* is this (also?) the last sector? */
335 if (last_addr
== f
->offset
+ f
->size
) {
340 /* MUST finish on a sector boundary */
341 if (last_addr
<= f
->offset
)
345 /* invalid start or end address? */
346 if (first
== -1 || last
== -1) {
347 LOG_ERROR("address range 0x%8.8x .. 0x%8.8x "
348 "is not sector-aligned",
349 (unsigned) (c
->base
+ addr
),
350 (unsigned) (last_addr
- 1));
351 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
354 /* The NOR driver may trim this range down, based on
355 * whether or not a given sector is already erased.
357 * REVISIT should *we* trim it... ?
359 return callback(c
, first
, last
);
362 int flash_erase_address_range(struct target
*target
,
363 uint32_t addr
, uint32_t length
)
365 return flash_iterate_address_range(target
,
366 addr
, length
, &flash_driver_erase
);
369 static int flash_driver_unprotect(struct flash_bank
*bank
, int first
, int last
)
371 return flash_driver_protect(bank
, 0, first
, last
);
374 static int flash_unlock_address_range(struct target
*target
, uint32_t addr
, uint32_t length
)
376 return flash_iterate_address_range(target
,
377 addr
, length
, &flash_driver_unprotect
);
380 int flash_write_unlock(struct target
*target
, struct image
*image
,
381 uint32_t *written
, int erase
, bool unlock
)
383 int retval
= ERROR_OK
;
386 uint32_t section_offset
;
387 struct flash_bank
*c
;
398 /* assume all sectors need erasing - stops any problems
399 * when flash_write is called multiple times */
404 /* allocate padding array */
405 padding
= calloc(image
->num_sections
, sizeof(*padding
));
407 /* loop until we reach end of the image */
408 while (section
< image
->num_sections
)
410 uint32_t buffer_size
;
414 uint32_t run_address
= image
->sections
[section
].base_address
+ section_offset
;
415 uint32_t run_size
= image
->sections
[section
].size
- section_offset
;
418 if (image
->sections
[section
].size
== 0)
420 LOG_WARNING("empty section %d", section
);
426 /* find the corresponding flash bank */
427 if ((c
= get_flash_bank_by_addr(target
, run_address
)) == NULL
)
429 section
++; /* and skip it */
434 /* collect consecutive sections which fall into the same bank */
435 section_first
= section
;
436 section_last
= section
;
437 padding
[section
] = 0;
438 while ((run_address
+ run_size
- 1 < c
->base
+ c
->size
- 1)
439 && (section_last
+ 1 < image
->num_sections
))
441 if (image
->sections
[section_last
+ 1].base_address
< (run_address
+ run_size
))
443 LOG_DEBUG("section %d out of order "
444 "(surprising, but supported)",
446 /* REVISIT this can break with autoerase ...
447 * clobbering data after it's written.
452 /* REVISIT This needlessly touches sectors BETWEEN the
453 * sections it's writing. Without auto erase, it just
454 * writes ones; unlikely to destroy data.
456 * With auto erase enabled, data in those sectors will
457 * be needlessly destroyed; and some of the limited
458 * number of flash erase cycles will be wasted...
460 * In both cases, the extra writes slow things down.
463 /* if we have multiple sections within our image, flash programming could fail due to alignment issues
464 * attempt to rebuild a consecutive buffer for the flash loader */
465 pad_bytes
= (image
->sections
[section_last
+ 1].base_address
) - (run_address
+ run_size
);
466 if ((run_address
+ run_size
+ pad_bytes
) > (c
->base
+ c
->size
))
468 padding
[section_last
] = pad_bytes
;
469 run_size
+= image
->sections
[++section_last
].size
;
470 run_size
+= pad_bytes
;
472 LOG_INFO("Padding image section %d with %d bytes", section_last
-1, pad_bytes
);
475 /* fit the run into bank constraints */
476 if (run_address
+ run_size
- 1 > c
->base
+ c
->size
- 1)
478 /* REVISIT isn't this superfluous, given the while()
479 * loop conditions above??
481 LOG_WARNING("writing %d bytes only - as image section is %d bytes and bank is only %d bytes", \
482 (int)(c
->base
+ c
->size
- run_address
), (int)(run_size
), (int)(c
->size
));
483 run_size
= c
->base
+ c
->size
- run_address
;
486 /* If we're applying any sector automagic, then pad this
487 * (maybe-combined) segment to the end of its last sector.
489 if (unlock
|| erase
) {
491 uint32_t offset_start
= run_address
- c
->base
;
492 uint32_t offset_end
= offset_start
+ run_size
;
493 uint32_t end
= offset_end
, delta
;
495 for (sector
= 0; sector
< c
->num_sectors
; sector
++) {
496 end
= c
->sectors
[sector
].offset
497 + c
->sectors
[sector
].size
;
498 if (offset_end
<= end
)
502 delta
= end
- offset_end
;
503 padding
[section_last
] += delta
;
507 /* allocate buffer */
508 buffer
= malloc(run_size
);
511 /* read sections to the buffer */
512 while (buffer_size
< run_size
)
516 size_read
= run_size
- buffer_size
;
517 if (size_read
> image
->sections
[section
].size
- section_offset
)
518 size_read
= image
->sections
[section
].size
- section_offset
;
520 if ((retval
= image_read_section(image
, section
, section_offset
,
521 size_read
, buffer
+ buffer_size
, &size_read
)) != ERROR_OK
|| size_read
== 0)
528 /* see if we need to pad the section */
529 while (padding
[section
]--)
530 (buffer
+ buffer_size
)[size_read
++] = 0xff;
532 buffer_size
+= size_read
;
533 section_offset
+= size_read
;
535 if (section_offset
>= image
->sections
[section
].size
)
546 retval
= flash_unlock_address_range(target
, run_address
, run_size
);
548 if (retval
== ERROR_OK
)
552 /* calculate and erase sectors */
553 retval
= flash_erase_address_range(target
, run_address
, run_size
);
557 if (retval
== ERROR_OK
)
559 /* write flash sectors */
560 retval
= flash_driver_write(c
, buffer
, run_address
- c
->base
, run_size
);
565 if (retval
!= ERROR_OK
)
568 return retval
; /* abort operation */
572 *written
+= run_size
; /* add run size to total written counter */
580 int flash_write(struct target
*target
, struct image
*image
,
581 uint32_t *written
, int erase
)
583 return flash_write_unlock(target
, image
, written
, erase
, false);
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)