1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
27 #include "time_support.h"
35 #include <sys/types.h>
40 /* command handlers */
41 int handle_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
42 int handle_flash_banks_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
43 int handle_flash_info_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
44 int handle_flash_probe_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
45 int handle_flash_erase_check_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
46 int handle_flash_erase_address_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
47 int handle_flash_protect_check_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
48 int handle_flash_erase_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
49 int handle_flash_write_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
50 int handle_flash_write_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
51 int handle_flash_write_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
52 int handle_flash_fill_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
53 int handle_flash_protect_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
54 int handle_flash_auto_erase_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
55 flash_bank_t
*get_flash_bank_by_addr(target_t
*target
, u32 addr
);
59 extern flash_driver_t lpc2000_flash
;
60 extern flash_driver_t cfi_flash
;
61 extern flash_driver_t at91sam7_flash
;
62 extern flash_driver_t str7x_flash
;
63 extern flash_driver_t str9x_flash
;
64 extern flash_driver_t stellaris_flash
;
65 extern flash_driver_t str9xpec_flash
;
66 extern flash_driver_t stm32x_flash
;
67 extern flash_driver_t tms470_flash
;
68 extern flash_driver_t ecosflash_flash
;
70 flash_driver_t
*flash_drivers
[] =
85 flash_bank_t
*flash_banks
;
86 static command_t
*flash_cmd
;
87 static int auto_erase
= 0;
89 /* wafer thin wrapper for invoking the flash driver */
90 static int flash_driver_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
94 retval
=bank
->driver
->write(bank
, buffer
, offset
, count
);
97 LOG_ERROR("error writing to flash at address 0x%08x at offset 0x%8.8x (%d)", bank
->base
, offset
, retval
);
103 static int flash_driver_erase(struct flash_bank_s
*bank
, int first
, int last
)
107 retval
=bank
->driver
->erase(bank
, first
, last
);
108 if (retval
!=ERROR_OK
)
110 LOG_ERROR("failed erasing sectors %d to %d (%d)", first
, last
, retval
);
116 int flash_driver_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
120 retval
=bank
->driver
->protect(bank
, set
, first
, last
);
121 if (retval
!=ERROR_OK
)
123 LOG_ERROR("failed setting protection for areas %d to %d (%d)", first
, last
, retval
);
130 int flash_register_commands(struct command_context_s
*cmd_ctx
)
132 flash_cmd
= register_command(cmd_ctx
, NULL
, "flash", NULL
, COMMAND_ANY
, NULL
);
134 register_command(cmd_ctx
, flash_cmd
, "bank", handle_flash_bank_command
, COMMAND_CONFIG
, "flash_bank <driver> <base> <size> <chip_width> <bus_width> <target> [driver_options ...]");
135 register_command(cmd_ctx
, flash_cmd
, "auto_erase", handle_flash_auto_erase_command
, COMMAND_ANY
,
136 "auto erase flash sectors <on|off>");
140 int flash_init_drivers(struct command_context_s
*cmd_ctx
)
144 register_command(cmd_ctx
, flash_cmd
, "banks", handle_flash_banks_command
, COMMAND_EXEC
,
145 "list configured flash banks ");
146 register_command(cmd_ctx
, flash_cmd
, "info", handle_flash_info_command
, COMMAND_EXEC
,
147 "print info about flash bank <num>");
148 register_command(cmd_ctx
, flash_cmd
, "probe", handle_flash_probe_command
, COMMAND_EXEC
,
149 "identify flash bank <num>");
150 register_command(cmd_ctx
, flash_cmd
, "erase_check", handle_flash_erase_check_command
, COMMAND_EXEC
,
151 "check erase state of sectors in flash bank <num>");
152 register_command(cmd_ctx
, flash_cmd
, "protect_check", handle_flash_protect_check_command
, COMMAND_EXEC
,
153 "check protection state of sectors in flash bank <num>");
154 register_command(cmd_ctx
, flash_cmd
, "erase_sector", handle_flash_erase_command
, COMMAND_EXEC
,
155 "erase sectors at <bank> <first> <last>");
156 register_command(cmd_ctx
, flash_cmd
, "erase_address", handle_flash_erase_address_command
, COMMAND_EXEC
,
157 "erase address range <address> <length>");
159 register_command(cmd_ctx
, flash_cmd
, "fillw", handle_flash_fill_command
, COMMAND_EXEC
,
160 "fill with pattern <address> <word_pattern> <count>");
161 register_command(cmd_ctx
, flash_cmd
, "fillh", handle_flash_fill_command
, COMMAND_EXEC
,
162 "fill with pattern <address> <halfword_pattern> <count>");
163 register_command(cmd_ctx
, flash_cmd
, "fillb", handle_flash_fill_command
, COMMAND_EXEC
,
164 "fill with pattern <address> <byte_pattern> <count>");
166 register_command(cmd_ctx
, flash_cmd
, "write_bank", handle_flash_write_bank_command
, COMMAND_EXEC
,
167 "write binary data to <bank> <file> <offset>");
168 register_command(cmd_ctx
, flash_cmd
, "write_image", handle_flash_write_image_command
, COMMAND_EXEC
,
169 "write_image <file> [offset] [type]");
170 register_command(cmd_ctx
, flash_cmd
, "protect", handle_flash_protect_command
, COMMAND_EXEC
,
171 "set protection of sectors at <bank> <first> <last> <on|off>");
177 flash_bank_t
*get_flash_bank_by_num_noprobe(int num
)
182 for (p
= flash_banks
; p
; p
= p
->next
)
189 LOG_ERROR("flash bank %d does not exist", num
);
193 int flash_get_bank_count()
197 for (p
= flash_banks
; p
; p
= p
->next
)
204 flash_bank_t
*get_flash_bank_by_num(int num
)
206 flash_bank_t
*p
= get_flash_bank_by_num_noprobe(num
);
212 retval
= p
->driver
->auto_probe(p
);
214 if (retval
!= ERROR_OK
)
216 LOG_ERROR("auto_probe failed %d\n", retval
);
222 int handle_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
230 return ERROR_COMMAND_SYNTAX_ERROR
;
233 if ((target
= get_target_by_num(strtoul(args
[5], NULL
, 0))) == NULL
)
235 LOG_ERROR("target %lu not defined", strtoul(args
[5], NULL
, 0));
239 for (i
= 0; flash_drivers
[i
]; i
++)
241 if (strcmp(args
[0], flash_drivers
[i
]->name
) == 0)
245 /* register flash specific commands */
246 if (flash_drivers
[i
]->register_commands(cmd_ctx
) != ERROR_OK
)
248 LOG_ERROR("couldn't register '%s' commands", args
[0]);
252 c
= malloc(sizeof(flash_bank_t
));
254 c
->driver
= flash_drivers
[i
];
255 c
->driver_priv
= NULL
;
256 c
->base
= strtoul(args
[1], NULL
, 0);
257 c
->size
= strtoul(args
[2], NULL
, 0);
258 c
->chip_width
= strtoul(args
[3], NULL
, 0);
259 c
->bus_width
= strtoul(args
[4], NULL
, 0);
264 if (flash_drivers
[i
]->flash_bank_command(cmd_ctx
, cmd
, args
, argc
, c
) != ERROR_OK
)
266 LOG_ERROR("'%s' driver rejected flash bank at 0x%8.8x", args
[0], c
->base
);
271 /* put flash bank in linked list */
274 /* find last flash bank */
275 for (p
= flash_banks
; p
&& p
->next
; p
= p
->next
);
288 /* no matching flash driver found */
291 LOG_ERROR("flash driver '%s' not found", args
[0]);
298 int handle_flash_banks_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
305 command_print(cmd_ctx
, "no flash banks configured");
309 for (p
= flash_banks
; p
; p
= p
->next
)
311 command_print(cmd_ctx
, "#%i: %s at 0x%8.8x, size 0x%8.8x, buswidth %i, chipwidth %i",
312 i
++, p
->driver
->name
, p
->base
, p
->size
, p
->bus_width
, p
->chip_width
);
318 int handle_flash_info_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
327 return ERROR_COMMAND_SYNTAX_ERROR
;
330 for (p
= flash_banks
; p
; p
= p
->next
, i
++)
332 if (i
== strtoul(args
[0], NULL
, 0))
336 /* attempt auto probe */
337 p
->driver
->auto_probe(p
);
339 command_print(cmd_ctx
, "#%i: %s at 0x%8.8x, size 0x%8.8x, buswidth %i, chipwidth %i",
340 i
, p
->driver
->name
, p
->base
, p
->size
, p
->bus_width
, p
->chip_width
);
341 for (j
= 0; j
< p
->num_sectors
; j
++)
343 char *erase_state
, *protect_state
;
345 if (p
->sectors
[j
].is_erased
== 0)
346 erase_state
= "not erased";
347 else if (p
->sectors
[j
].is_erased
== 1)
348 erase_state
= "erased";
350 erase_state
= "erase state unknown";
352 if (p
->sectors
[j
].is_protected
== 0)
353 protect_state
= "not protected";
354 else if (p
->sectors
[j
].is_protected
== 1)
355 protect_state
= "protected";
357 protect_state
= "protection state unknown";
359 command_print(cmd_ctx
, "\t#%i: 0x%8.8x (0x%x %ikB) %s, %s",
360 j
, p
->sectors
[j
].offset
, p
->sectors
[j
].size
, p
->sectors
[j
].size
>>10,
361 erase_state
, protect_state
);
364 *buf
= '\0'; /* initialize buffer, otherwise it migh contain garbage if driver function fails */
365 retval
= p
->driver
->info(p
, buf
, sizeof(buf
));
366 command_print(cmd_ctx
, "%s", buf
);
367 if (retval
!= ERROR_OK
)
368 LOG_ERROR("error retrieving flash info (%d)", retval
);
375 int handle_flash_probe_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
382 return ERROR_COMMAND_SYNTAX_ERROR
;
385 p
= get_flash_bank_by_num_noprobe(strtoul(args
[0], NULL
, 0));
388 if ((retval
= p
->driver
->probe(p
)) == ERROR_OK
)
390 command_print(cmd_ctx
, "flash '%s' found at 0x%8.8x", p
->driver
->name
, p
->base
);
392 else if (retval
== ERROR_FLASH_BANK_INVALID
)
394 command_print(cmd_ctx
, "probing failed for flash bank '#%s' at 0x%8.8x",
399 command_print(cmd_ctx
, "unknown error when probing flash bank '#%s' at 0x%8.8x",
405 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
411 int handle_flash_erase_check_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
418 return ERROR_COMMAND_SYNTAX_ERROR
;
421 p
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
424 if ((retval
= p
->driver
->erase_check(p
)) == ERROR_OK
)
426 command_print(cmd_ctx
, "successfully checked erase state", p
->driver
->name
, p
->base
);
430 command_print(cmd_ctx
, "unknown error when checking erase state of flash bank #%s at 0x%8.8x",
438 int handle_flash_erase_address_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
447 target_t
*target
= get_current_target(cmd_ctx
);
451 return ERROR_COMMAND_SYNTAX_ERROR
;
454 address
= strtoul(args
[0], NULL
, 0);
455 length
= strtoul(args
[1], NULL
, 0);
458 command_print(cmd_ctx
, "Length must be >0");
459 return ERROR_COMMAND_SYNTAX_ERROR
;
462 p
= get_flash_bank_by_addr(target
, address
);
465 return ERROR_COMMAND_SYNTAX_ERROR
;
468 /* We can't know if we did a resume + halt, in which case we no longer know the erased state */
471 duration_start_measure(&duration
);
473 if ((retval
= flash_erase_address_range(target
, address
, length
)) == ERROR_OK
)
475 duration_stop_measure(&duration
, &duration_text
);
476 command_print(cmd_ctx
, "erased address 0x%8.8x length %i in %s", address
, length
, duration_text
);
483 int handle_flash_protect_check_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
490 return ERROR_COMMAND_SYNTAX_ERROR
;
493 p
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
496 if ((retval
= p
->driver
->protect_check(p
)) == ERROR_OK
)
498 command_print(cmd_ctx
, "successfully checked protect state");
500 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
502 command_print(cmd_ctx
, "checking protection state failed (possibly unsupported) by flash #%s at 0x%8.8x", args
[0], p
->base
);
506 command_print(cmd_ctx
, "unknown error when checking protection state of flash bank '#%s' at 0x%8.8x", args
[0], p
->base
);
511 return ERROR_COMMAND_SYNTAX_ERROR
;
517 int handle_flash_erase_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
521 int first
= strtoul(args
[1], NULL
, 0);
522 int last
= strtoul(args
[2], NULL
, 0);
524 flash_bank_t
*p
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
528 duration_start_measure(&duration
);
532 return ERROR_COMMAND_SYNTAX_ERROR
;
535 if ((retval
= flash_driver_erase(p
, first
, last
)) == ERROR_OK
)
537 duration_stop_measure(&duration
, &duration_text
);
539 command_print(cmd_ctx
, "erased sectors %i through %i on flash bank %i in %s", first
, last
, strtoul(args
[0], 0, 0), duration_text
);
545 return ERROR_COMMAND_SYNTAX_ERROR
;
551 int handle_flash_protect_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
555 int first
= strtoul(args
[1], NULL
, 0);
556 int last
= strtoul(args
[2], NULL
, 0);
559 flash_bank_t
*p
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
562 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
566 if (strcmp(args
[3], "on") == 0)
568 else if (strcmp(args
[3], "off") == 0)
572 return ERROR_COMMAND_SYNTAX_ERROR
;
575 retval
= flash_driver_protect(p
, set
, first
, last
);
576 if (retval
== ERROR_OK
)
578 command_print(cmd_ctx
, "%s protection for sectors %i through %i on flash bank %i", (set
) ? "set" : "cleared", first
, last
, strtoul(args
[0], 0, 0));
583 return ERROR_COMMAND_SYNTAX_ERROR
;
590 int handle_flash_write_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
592 target_t
*target
= get_current_target(cmd_ctx
);
604 return ERROR_COMMAND_SYNTAX_ERROR
;
610 LOG_ERROR("no target selected");
614 duration_start_measure(&duration
);
618 image
.base_address_set
= 1;
619 image
.base_address
= strtoul(args
[1], NULL
, 0);
623 image
.base_address_set
= 0;
624 image
.base_address
= 0x0;
627 image
.start_address_set
= 0;
629 retval
= image_open(&image
, args
[0], (argc
== 3) ? args
[2] : NULL
);
630 if (retval
!= ERROR_OK
)
635 retval
= flash_write(target
, &image
, &written
, auto_erase
);
637 if (retval
!= ERROR_OK
)
643 duration_stop_measure(&duration
, &duration_text
);
644 if (retval
== ERROR_OK
)
646 command_print(cmd_ctx
, "wrote %u byte from file %s in %s (%f kb/s)",
647 written
, args
[0], duration_text
,
648 (float)written
/ 1024.0 / ((float)duration
.duration
.tv_sec
+ ((float)duration
.duration
.tv_usec
/ 1000000.0)));
657 int handle_flash_fill_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
668 target_t
*target
= get_current_target(cmd_ctx
);
674 return ERROR_COMMAND_SYNTAX_ERROR
;
677 address
= strtoul(args
[0], NULL
, 0);
678 pattern
= strtoul(args
[1], NULL
, 0);
679 count
= strtoul(args
[2], NULL
, 0);
697 return ERROR_COMMAND_SYNTAX_ERROR
;
700 chunk_count
= MIN(count
, (1024 / wordsize
));
704 for(i
= 0; i
< chunk_count
; i
++)
706 target_buffer_set_u32(target
, chunk
+ i
* wordsize
, pattern
);
710 for(i
= 0; i
< chunk_count
; i
++)
712 target_buffer_set_u16(target
, chunk
+ i
* wordsize
, pattern
);
716 memset(chunk
, pattern
, chunk_count
);
719 LOG_ERROR("BUG: can't happen");
723 duration_start_measure(&duration
);
726 err
= flash_erase_address_range( target
, address
, count
*wordsize
);
729 for (wrote
=0; wrote
<(count
*wordsize
); wrote
+=sizeof(chunk
))
731 int cur_size
= MIN( (count
*wordsize
- wrote
) , 1024 );
735 bank
= get_flash_bank_by_addr(target
, address
);
741 err
= flash_driver_write(bank
, chunk
, address
- bank
->base
+ wrote
, cur_size
);
749 duration_stop_measure(&duration
, &duration_text
);
754 speed
=wrote
/ 1024.0;
755 speed
/=((float)duration
.duration
.tv_sec
+ ((float)duration
.duration
.tv_usec
/ 1000000.0));
756 command_print(cmd_ctx
, "wrote %d bytes to 0x%8.8x in %s (%f kb/s)",
757 count
*wordsize
, address
, duration_text
,
764 int handle_flash_write_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
780 return ERROR_COMMAND_SYNTAX_ERROR
;
783 duration_start_measure(&duration
);
785 offset
= strtoul(args
[2], NULL
, 0);
786 p
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
789 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
793 if (fileio_open(&fileio
, args
[1], FILEIO_READ
, FILEIO_BINARY
) != ERROR_OK
)
798 buffer
= malloc(fileio
.size
);
799 if (fileio_read(&fileio
, fileio
.size
, buffer
, &buf_cnt
) != ERROR_OK
)
804 retval
= flash_driver_write(p
, buffer
, offset
, buf_cnt
);
808 duration_stop_measure(&duration
, &duration_text
);
809 if (retval
!=ERROR_OK
)
811 command_print(cmd_ctx
, "wrote %"PRIi64
" byte from file %s to flash bank %i at offset 0x%8.8x in %s (%f kb/s)",
812 fileio
.size
, args
[1], strtoul(args
[0], NULL
, 0), offset
, duration_text
,
813 (float)fileio
.size
/ 1024.0 / ((float)duration
.duration
.tv_sec
+ ((float)duration
.duration
.tv_usec
/ 1000000.0)));
817 fileio_close(&fileio
);
822 void flash_set_dirty(void)
827 /* set all flash to require erasing */
828 for (c
= flash_banks
; c
; c
= c
->next
)
830 for (i
= 0; i
< c
->num_sectors
; i
++)
832 c
->sectors
[i
].is_erased
= 0;
837 /* lookup flash bank by address */
838 flash_bank_t
*get_flash_bank_by_addr(target_t
*target
, u32 addr
)
842 /* cycle through bank list */
843 for (c
= flash_banks
; c
; c
= c
->next
)
846 retval
= c
->driver
->auto_probe(c
);
848 if (retval
!= ERROR_OK
)
850 LOG_ERROR("auto_probe failed %d\n", retval
);
853 /* check whether address belongs to this flash bank */
854 if ((addr
>= c
->base
) && (addr
< c
->base
+ c
->size
) && target
== c
->target
)
857 LOG_ERROR("No flash at address 0x%08x\n", addr
);
861 /* erase given flash region, selects proper bank according to target and address */
862 int flash_erase_address_range(target_t
*target
, u32 addr
, u32 length
)
869 if ((c
= get_flash_bank_by_addr(target
, addr
)) == NULL
)
870 return ERROR_FLASH_DST_OUT_OF_BANK
; /* no corresponding bank found */
872 if (c
->size
== 0 || c
->num_sectors
== 0)
873 return ERROR_FLASH_BANK_INVALID
;
877 /* special case, erase whole bank when length is zero */
879 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
881 return flash_driver_erase(c
, 0, c
->num_sectors
- 1);
884 /* check whether it fits */
885 if (addr
+ length
> c
->base
+ c
->size
)
886 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
890 for (i
= 0; i
< c
->num_sectors
; i
++)
892 /* check whether sector overlaps with the given range and is not yet erased */
893 if (addr
< c
->sectors
[i
].offset
+ c
->sectors
[i
].size
&& addr
+ length
> c
->sectors
[i
].offset
&& c
->sectors
[i
].is_erased
!= 1) {
894 /* if first is not set yet then this is the first sector */
897 last
= i
; /* and it is the last one so far in any case */
901 if( first
== -1 || last
== -1 )
904 return flash_driver_erase(c
, first
, last
);
907 /* write (optional verify) an image to flash memory of the given target */
908 int flash_write(target_t
*target
, image_t
*image
, u32
*written
, int erase
)
924 /* assume all sectors need erasing - stops any problems
925 * when flash_write is called multiple times */
930 /* loop until we reach end of the image */
931 while (section
< image
->num_sections
)
937 u32 run_address
= image
->sections
[section
].base_address
+ section_offset
;
938 u32 run_size
= image
->sections
[section
].size
- section_offset
;
940 if (image
->sections
[section
].size
== 0)
942 LOG_WARNING("empty section %d", section
);
948 /* find the corresponding flash bank */
949 if ((c
= get_flash_bank_by_addr(target
, run_address
)) == NULL
)
951 section
++; /* and skip it */
956 /* collect consecutive sections which fall into the same bank */
957 section_first
= section
;
958 section_last
= section
;
959 while ((run_address
+ run_size
< c
->base
+ c
->size
)
960 && (section_last
+ 1 < image
->num_sections
))
962 if (image
->sections
[section_last
+ 1].base_address
< (run_address
+ run_size
))
964 LOG_DEBUG("section %d out of order(very slightly surprising, but supported)", section_last
+ 1);
967 if (image
->sections
[section_last
+ 1].base_address
!= (run_address
+ run_size
))
969 run_size
+= image
->sections
[++section_last
].size
;
972 /* fit the run into bank constraints */
973 if (run_address
+ run_size
> c
->base
+ c
->size
)
974 run_size
= c
->base
+ c
->size
- run_address
;
976 /* allocate buffer */
977 buffer
= malloc(run_size
);
980 /* read sections to the buffer */
981 while (buffer_size
< run_size
)
985 if (buffer_size
- run_size
<= image
->sections
[section
].size
- section_offset
)
986 size_read
= buffer_size
- run_size
;
988 size_read
= image
->sections
[section
].size
- section_offset
;
990 if ((retval
= image_read_section(image
, section
, section_offset
,
991 size_read
, buffer
+ buffer_size
, &size_read
)) != ERROR_OK
|| size_read
== 0)
998 buffer_size
+= size_read
;
999 section_offset
+= size_read
;
1001 if (section_offset
>= image
->sections
[section
].size
)
1012 /* calculate and erase sectors */
1013 retval
= flash_erase_address_range( target
, run_address
, run_size
);
1016 if (retval
== ERROR_OK
)
1018 /* write flash sectors */
1019 retval
= flash_driver_write(c
, buffer
, run_address
- c
->base
, run_size
);
1024 if (retval
!= ERROR_OK
)
1026 return retval
; /* abort operation */
1029 if (written
!= NULL
)
1030 *written
+= run_size
; /* add run size to total written counter */
1036 int handle_flash_auto_erase_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1040 return ERROR_COMMAND_SYNTAX_ERROR
;
1043 if (strcmp(args
[0], "on") == 0)
1045 else if (strcmp(args
[0], "off") == 0)
1048 return ERROR_COMMAND_SYNTAX_ERROR
;
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)