92ac6fd6c315c1ee918fb5a2179bec0909557611
[openocd.git] / src / flash / flash.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
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. *
9 * *
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. *
14 * *
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 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "flash.h"
25 #include "command.h"
26 #include "target.h"
27 #include "time_support.h"
28 #include "fileio.h"
29 #include "image.h"
30 #include "log.h"
31
32 #include <string.h>
33 #include <unistd.h>
34 #include <stdlib.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <errno.h>
38 #include <inttypes.h>
39
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_protect_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
53 int handle_flash_auto_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
54 flash_bank_t *get_flash_bank_by_addr(target_t *target, u32 addr);
55
56 /* flash drivers
57 */
58 extern flash_driver_t lpc2000_flash;
59 extern flash_driver_t cfi_flash;
60 extern flash_driver_t at91sam7_flash;
61 extern flash_driver_t str7x_flash;
62 extern flash_driver_t str9x_flash;
63 extern flash_driver_t stellaris_flash;
64 extern flash_driver_t str9xpec_flash;
65 extern flash_driver_t stm32x_flash;
66 extern flash_driver_t tms470_flash;
67 extern flash_driver_t ecosflash_flash;
68
69 flash_driver_t *flash_drivers[] =
70 {
71 &lpc2000_flash,
72 &cfi_flash,
73 &at91sam7_flash,
74 &str7x_flash,
75 &str9x_flash,
76 &stellaris_flash,
77 &str9xpec_flash,
78 &stm32x_flash,
79 &tms470_flash,
80 &ecosflash_flash,
81 NULL,
82 };
83
84 flash_bank_t *flash_banks;
85 static command_t *flash_cmd;
86 static int auto_erase = 0;
87
88 /* wafer thin wrapper for invoking the flash driver */
89 static int flash_driver_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
90 {
91 int retval;
92
93 retval=bank->driver->write(bank, buffer, offset, count);
94 if (retval!=ERROR_OK)
95 {
96 ERROR("error writing to flash at address 0x%08x at offset 0x%8.8x", bank->base, offset);
97 }
98
99 return retval;
100 }
101
102 static int flash_driver_erase(struct flash_bank_s *bank, int first, int last)
103 {
104 int retval;
105
106 retval=bank->driver->erase(bank, first, last);
107 if (retval!=ERROR_OK)
108 {
109 ERROR("failed erasing sectors %d to %d", first, last);
110 }
111
112 return retval;
113 }
114
115 int flash_driver_protect(struct flash_bank_s *bank, int set, int first, int last)
116 {
117 int retval;
118
119 retval=bank->driver->protect(bank, set, first, last);
120 if (retval!=ERROR_OK)
121 {
122 ERROR("failed setting protection for areas %d to %d", first, last);
123 }
124
125 return retval;
126 }
127
128
129 int flash_register_commands(struct command_context_s *cmd_ctx)
130 {
131 flash_cmd = register_command(cmd_ctx, NULL, "flash", NULL, COMMAND_ANY, NULL);
132
133 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 ...]");
134 register_command(cmd_ctx, flash_cmd, "auto_erase", handle_flash_auto_erase_command, COMMAND_ANY,
135 "auto erase flash sectors <on|off>");
136 return ERROR_OK;
137 }
138
139 int flash_init_drivers(struct command_context_s *cmd_ctx)
140 {
141 if (flash_banks)
142 {
143 register_command(cmd_ctx, flash_cmd, "banks", handle_flash_banks_command, COMMAND_EXEC,
144 "list configured flash banks ");
145 register_command(cmd_ctx, flash_cmd, "info", handle_flash_info_command, COMMAND_EXEC,
146 "print info about flash bank <num>");
147 register_command(cmd_ctx, flash_cmd, "probe", handle_flash_probe_command, COMMAND_EXEC,
148 "identify flash bank <num>");
149 register_command(cmd_ctx, flash_cmd, "erase_check", handle_flash_erase_check_command, COMMAND_EXEC,
150 "check erase state of sectors in flash bank <num>");
151 register_command(cmd_ctx, flash_cmd, "protect_check", handle_flash_protect_check_command, COMMAND_EXEC,
152 "check protection state of sectors in flash bank <num>");
153 register_command(cmd_ctx, flash_cmd, "erase_sector", handle_flash_erase_command, COMMAND_EXEC,
154 "erase sectors at <bank> <first> <last>");
155 register_command(cmd_ctx, flash_cmd, "erase_address", handle_flash_erase_address_command, COMMAND_EXEC,
156 "erase address range <address> <length>");
157 register_command(cmd_ctx, flash_cmd, "write_bank", handle_flash_write_bank_command, COMMAND_EXEC,
158 "write binary data to <bank> <file> <offset>");
159 register_command(cmd_ctx, flash_cmd, "write_image", handle_flash_write_image_command, COMMAND_EXEC,
160 "write_image <file> [offset] [type]");
161 register_command(cmd_ctx, flash_cmd, "protect", handle_flash_protect_command, COMMAND_EXEC,
162 "set protection of sectors at <bank> <first> <last> <on|off>");
163 }
164
165 return ERROR_OK;
166 }
167
168 flash_bank_t *get_flash_bank_by_num_noprobe(int num)
169 {
170 flash_bank_t *p;
171 int i = 0;
172
173 for (p = flash_banks; p; p = p->next)
174 {
175 if (i++ == num)
176 {
177 return p;
178 }
179 }
180 ERROR("flash bank %d does not exist", num);
181 return NULL;
182 }
183
184 int flash_get_bank_count()
185 {
186 flash_bank_t *p;
187 int i = 0;
188 for (p = flash_banks; p; p = p->next)
189 {
190 i++;
191 }
192 return i;
193 }
194
195 flash_bank_t *get_flash_bank_by_num(int num)
196 {
197 flash_bank_t *p = get_flash_bank_by_num_noprobe(num);
198 int retval;
199
200 if (p == NULL)
201 return NULL;
202
203 retval = p->driver->auto_probe(p);
204
205 if (retval != ERROR_OK)
206 {
207 ERROR("auto_probe failed %d\n", retval);
208 return NULL;
209 }
210 return p;
211 }
212
213 int handle_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
214 {
215 int i;
216 int found = 0;
217 target_t *target;
218
219 if (argc < 6)
220 {
221 return ERROR_COMMAND_SYNTAX_ERROR;
222 }
223
224 if ((target = get_target_by_num(strtoul(args[5], NULL, 0))) == NULL)
225 {
226 ERROR("target %lu not defined", strtoul(args[5], NULL, 0));
227 return ERROR_OK;
228 }
229
230 for (i = 0; flash_drivers[i]; i++)
231 {
232 if (strcmp(args[0], flash_drivers[i]->name) == 0)
233 {
234 flash_bank_t *p, *c;
235
236 /* register flash specific commands */
237 if (flash_drivers[i]->register_commands(cmd_ctx) != ERROR_OK)
238 {
239 ERROR("couldn't register '%s' commands", args[0]);
240 exit(-1);
241 }
242
243 c = malloc(sizeof(flash_bank_t));
244 c->target = target;
245 c->driver = flash_drivers[i];
246 c->driver_priv = NULL;
247 c->base = strtoul(args[1], NULL, 0);
248 c->size = strtoul(args[2], NULL, 0);
249 c->chip_width = strtoul(args[3], NULL, 0);
250 c->bus_width = strtoul(args[4], NULL, 0);
251 c->num_sectors = 0;
252 c->sectors = NULL;
253 c->next = NULL;
254
255 if (flash_drivers[i]->flash_bank_command(cmd_ctx, cmd, args, argc, c) != ERROR_OK)
256 {
257 ERROR("'%s' driver rejected flash bank at 0x%8.8x", args[0], c->base);
258 free(c);
259 return ERROR_OK;
260 }
261
262 /* put flash bank in linked list */
263 if (flash_banks)
264 {
265 /* find last flash bank */
266 for (p = flash_banks; p && p->next; p = p->next);
267 if (p)
268 p->next = c;
269 }
270 else
271 {
272 flash_banks = c;
273 }
274
275 found = 1;
276 }
277 }
278
279 /* no matching flash driver found */
280 if (!found)
281 {
282 ERROR("flash driver '%s' not found", args[0]);
283 exit(-1);
284 }
285
286 return ERROR_OK;
287 }
288
289 int handle_flash_banks_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
290 {
291 flash_bank_t *p;
292 int i = 0;
293
294 if (!flash_banks)
295 {
296 command_print(cmd_ctx, "no flash banks configured");
297 return ERROR_OK;
298 }
299
300 for (p = flash_banks; p; p = p->next)
301 {
302 command_print(cmd_ctx, "#%i: %s at 0x%8.8x, size 0x%8.8x, buswidth %i, chipwidth %i",
303 i++, p->driver->name, p->base, p->size, p->bus_width, p->chip_width);
304 }
305
306 return ERROR_OK;
307 }
308
309 int handle_flash_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
310 {
311 flash_bank_t *p;
312 int i = 0;
313 int j = 0;
314
315 if (argc != 1)
316 {
317 return ERROR_COMMAND_SYNTAX_ERROR;
318 }
319
320 for (p = flash_banks; p; p = p->next, i++)
321 {
322 if (i == strtoul(args[0], NULL, 0))
323 {
324 char buf[1024];
325
326 /* attempt auto probe */
327 p->driver->auto_probe(p);
328
329 command_print(cmd_ctx, "#%i: %s at 0x%8.8x, size 0x%8.8x, buswidth %i, chipwidth %i",
330 i, p->driver->name, p->base, p->size, p->bus_width, p->chip_width);
331 for (j = 0; j < p->num_sectors; j++)
332 {
333 char *erase_state, *protect_state;
334
335 if (p->sectors[j].is_erased == 0)
336 erase_state = "not erased";
337 else if (p->sectors[j].is_erased == 1)
338 erase_state = "erased";
339 else
340 erase_state = "erase state unknown";
341
342 if (p->sectors[j].is_protected == 0)
343 protect_state = "not protected";
344 else if (p->sectors[j].is_protected == 1)
345 protect_state = "protected";
346 else
347 protect_state = "protection state unknown";
348
349 command_print(cmd_ctx, "\t#%i: 0x%8.8x (0x%x %ikB) %s, %s",
350 j, p->sectors[j].offset, p->sectors[j].size, p->sectors[j].size>>10,
351 erase_state, protect_state);
352 }
353
354 p->driver->info(p, buf, 1024);
355 command_print(cmd_ctx, "%s", buf);
356 }
357 }
358
359 return ERROR_OK;
360 }
361
362 int handle_flash_probe_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
363 {
364 flash_bank_t *p;
365 int retval;
366
367 if (argc != 1)
368 {
369 return ERROR_COMMAND_SYNTAX_ERROR;
370 }
371
372 p = get_flash_bank_by_num_noprobe(strtoul(args[0], NULL, 0));
373 if (p)
374 {
375 if ((retval = p->driver->probe(p)) == ERROR_OK)
376 {
377 command_print(cmd_ctx, "flash '%s' found at 0x%8.8x", p->driver->name, p->base);
378 }
379 else if (retval == ERROR_FLASH_BANK_INVALID)
380 {
381 command_print(cmd_ctx, "probing failed for flash bank '#%s' at 0x%8.8x",
382 args[0], p->base);
383 }
384 else
385 {
386 command_print(cmd_ctx, "unknown error when probing flash bank '#%s' at 0x%8.8x",
387 args[0], p->base);
388 }
389 }
390 else
391 {
392 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
393 }
394
395 return ERROR_OK;
396 }
397
398 int handle_flash_erase_check_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
399 {
400 flash_bank_t *p;
401 int retval;
402
403 if (argc != 1)
404 {
405 return ERROR_COMMAND_SYNTAX_ERROR;
406 }
407
408 p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
409 if (p)
410 {
411 if ((retval = p->driver->erase_check(p)) == ERROR_OK)
412 {
413 command_print(cmd_ctx, "successfully checked erase state", p->driver->name, p->base);
414 }
415 else
416 {
417 command_print(cmd_ctx, "unknown error when checking erase state of flash bank #%s at 0x%8.8x",
418 args[0], p->base);
419 }
420 }
421
422 return ERROR_OK;
423 }
424
425 int handle_flash_erase_address_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
426 {
427 flash_bank_t *p;
428 int retval;
429 int address;
430 int length;
431 duration_t duration;
432 char *duration_text;
433
434 target_t *target = get_current_target(cmd_ctx);
435
436 if (argc != 2)
437 {
438 return ERROR_COMMAND_SYNTAX_ERROR;
439 }
440
441 address = strtoul(args[0], NULL, 0);
442 length = strtoul(args[1], NULL, 0);
443 if (length <= 0)
444 {
445 command_print(cmd_ctx, "Length must be >0");
446 return ERROR_COMMAND_SYNTAX_ERROR;
447 }
448
449 p = get_flash_bank_by_addr(target, address);
450 if (p == NULL)
451 {
452 return ERROR_COMMAND_SYNTAX_ERROR;
453 }
454
455 /* We can't know if we did a resume + halt, in which case we no longer know the erased state */
456 flash_set_dirty();
457
458 duration_start_measure(&duration);
459
460 if ((retval = flash_erase_address_range(target, address, length)) == ERROR_OK)
461 {
462 duration_stop_measure(&duration, &duration_text);
463 command_print(cmd_ctx, "erased address 0x%8.8x length %i in %s", address, length, duration_text);
464 free(duration_text);
465 }
466
467 return retval;
468 }
469
470 int handle_flash_protect_check_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
471 {
472 flash_bank_t *p;
473 int retval;
474
475 if (argc != 1)
476 {
477 return ERROR_COMMAND_SYNTAX_ERROR;
478 }
479
480 p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
481 if (p)
482 {
483 if ((retval = p->driver->protect_check(p)) == ERROR_OK)
484 {
485 command_print(cmd_ctx, "successfully checked protect state");
486 }
487 else if (retval == ERROR_FLASH_OPERATION_FAILED)
488 {
489 command_print(cmd_ctx, "checking protection state failed (possibly unsupported) by flash #%s at 0x%8.8x", args[0], p->base);
490 }
491 else
492 {
493 command_print(cmd_ctx, "unknown error when checking protection state of flash bank '#%s' at 0x%8.8x", args[0], p->base);
494 }
495 }
496 else
497 {
498 return ERROR_COMMAND_SYNTAX_ERROR;
499 }
500
501 return ERROR_OK;
502 }
503
504 int handle_flash_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
505 {
506 if (argc > 2)
507 {
508 int first = strtoul(args[1], NULL, 0);
509 int last = strtoul(args[2], NULL, 0);
510 int retval;
511 flash_bank_t *p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
512 duration_t duration;
513 char *duration_text;
514
515 duration_start_measure(&duration);
516
517 if (!p)
518 {
519 return ERROR_COMMAND_SYNTAX_ERROR;
520 }
521
522 if ((retval = flash_driver_erase(p, first, last)) == ERROR_OK)
523 {
524 duration_stop_measure(&duration, &duration_text);
525
526 command_print(cmd_ctx, "erased sectors %i through %i on flash bank %i in %s", first, last, strtoul(args[0], 0, 0), duration_text);
527 free(duration_text);
528 }
529 }
530 else
531 {
532 return ERROR_COMMAND_SYNTAX_ERROR;
533 }
534
535 return ERROR_OK;
536 }
537
538 int handle_flash_protect_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
539 {
540 if (argc > 3)
541 {
542 int first = strtoul(args[1], NULL, 0);
543 int last = strtoul(args[2], NULL, 0);
544 int set;
545 int retval;
546 flash_bank_t *p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
547 if (!p)
548 {
549 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
550 return ERROR_OK;
551 }
552
553 if (strcmp(args[3], "on") == 0)
554 set = 1;
555 else if (strcmp(args[3], "off") == 0)
556 set = 0;
557 else
558 {
559 return ERROR_COMMAND_SYNTAX_ERROR;
560 }
561
562 retval = flash_driver_protect(p, set, first, last);
563 if (retval == ERROR_OK)
564 {
565 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));
566 }
567 }
568 else
569 {
570 return ERROR_COMMAND_SYNTAX_ERROR;
571
572 }
573
574 return ERROR_OK;
575 }
576
577 int handle_flash_write_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
578 {
579 target_t *target = get_current_target(cmd_ctx);
580
581 image_t image;
582 u32 written;
583
584 duration_t duration;
585 char *duration_text;
586
587 int retval;
588
589 if (argc < 1)
590 {
591 return ERROR_COMMAND_SYNTAX_ERROR;
592
593 }
594
595 if (!target)
596 {
597 ERROR("no target selected");
598 return ERROR_OK;
599 }
600
601 duration_start_measure(&duration);
602
603 if (argc >= 2)
604 {
605 image.base_address_set = 1;
606 image.base_address = strtoul(args[1], NULL, 0);
607 }
608 else
609 {
610 image.base_address_set = 0;
611 image.base_address = 0x0;
612 }
613
614 image.start_address_set = 0;
615
616 retval = image_open(&image, args[0], (argc == 3) ? args[2] : NULL);
617 if (retval != ERROR_OK)
618 {
619 return retval;
620 }
621
622 retval = flash_write(target, &image, &written, auto_erase);
623
624 if (retval != ERROR_OK)
625 {
626 image_close(&image);
627 return retval;
628 }
629
630 duration_stop_measure(&duration, &duration_text);
631 if (retval == ERROR_OK)
632 {
633 command_print(cmd_ctx, "wrote %u byte from file %s in %s (%f kb/s)",
634 written, args[0], duration_text,
635 (float)written / 1024.0 / ((float)duration.duration.tv_sec + ((float)duration.duration.tv_usec / 1000000.0)));
636 }
637 free(duration_text);
638
639 image_close(&image);
640
641 return retval;
642 }
643
644 int handle_flash_write_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
645 {
646 u32 offset;
647 u8 *buffer;
648 u32 buf_cnt;
649
650 fileio_t fileio;
651
652 duration_t duration;
653 char *duration_text;
654
655 int retval;
656 flash_bank_t *p;
657
658 if (argc != 3)
659 {
660 return ERROR_COMMAND_SYNTAX_ERROR;
661 }
662
663 duration_start_measure(&duration);
664
665 offset = strtoul(args[2], NULL, 0);
666 p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
667 if (!p)
668 {
669 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
670 return ERROR_OK;
671 }
672
673 if (fileio_open(&fileio, args[1], FILEIO_READ, FILEIO_BINARY) != ERROR_OK)
674 {
675 return ERROR_OK;
676 }
677
678 buffer = malloc(fileio.size);
679 if (fileio_read(&fileio, fileio.size, buffer, &buf_cnt) != ERROR_OK)
680 {
681 return ERROR_OK;
682 }
683
684 retval = flash_driver_write(p, buffer, offset, buf_cnt);
685
686 free(buffer);
687
688 duration_stop_measure(&duration, &duration_text);
689 if (retval!=ERROR_OK)
690 {
691 command_print(cmd_ctx, "wrote %"PRIi64" byte from file %s to flash bank %i at offset 0x%8.8x in %s (%f kb/s)",
692 fileio.size, args[1], strtoul(args[0], NULL, 0), offset, duration_text,
693 (float)fileio.size / 1024.0 / ((float)duration.duration.tv_sec + ((float)duration.duration.tv_usec / 1000000.0)));
694 }
695 free(duration_text);
696
697 fileio_close(&fileio);
698
699 return retval;
700 }
701
702 void flash_set_dirty(void)
703 {
704 flash_bank_t *c;
705 int i;
706
707 /* set all flash to require erasing */
708 for (c = flash_banks; c; c = c->next)
709 {
710 for (i = 0; i < c->num_sectors; i++)
711 {
712 c->sectors[i].is_erased = 0;
713 }
714 }
715 }
716
717 /* lookup flash bank by address */
718 flash_bank_t *get_flash_bank_by_addr(target_t *target, u32 addr)
719 {
720 flash_bank_t *c;
721
722 /* cycle through bank list */
723 for (c = flash_banks; c; c = c->next)
724 {
725 int retval;
726 retval = c->driver->auto_probe(c);
727
728 if (retval != ERROR_OK)
729 {
730 ERROR("auto_probe failed %d\n", retval);
731 return NULL;
732 }
733 /* check whether address belongs to this flash bank */
734 if ((addr >= c->base) && (addr < c->base + c->size) && target == c->target)
735 return c;
736 }
737 ERROR("No flash at address 0x%08x\n", addr);
738 return NULL;
739 }
740
741 /* erase given flash region, selects proper bank according to target and address */
742 int flash_erase_address_range(target_t *target, u32 addr, u32 length)
743 {
744 flash_bank_t *c;
745 int first = -1;
746 int last = -1;
747 int i;
748
749 if ((c = get_flash_bank_by_addr(target, addr)) == NULL)
750 return ERROR_FLASH_DST_OUT_OF_BANK; /* no corresponding bank found */
751
752 if (c->size == 0 || c->num_sectors == 0)
753 return ERROR_FLASH_BANK_INVALID;
754
755 if (length == 0)
756 {
757 /* special case, erase whole bank when length is zero */
758 if (addr != c->base)
759 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
760
761 return flash_driver_erase(c, 0, c->num_sectors - 1);
762 }
763
764 /* check whether it fits */
765 if (addr + length > c->base + c->size)
766 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
767
768 addr -= c->base;
769
770 for (i = 0; i < c->num_sectors; i++)
771 {
772 /* check whether sector overlaps with the given range and is not yet erased */
773 if (addr < c->sectors[i].offset + c->sectors[i].size && addr + length > c->sectors[i].offset && c->sectors[i].is_erased != 1) {
774 /* if first is not set yet then this is the first sector */
775 if (first == -1)
776 first = i;
777 last = i; /* and it is the last one so far in any case */
778 }
779 }
780
781 if( first == -1 || last == -1 )
782 return ERROR_OK;
783
784 return flash_driver_erase(c, first, last);
785 }
786
787 /* write (optional verify) an image to flash memory of the given target */
788 int flash_write(target_t *target, image_t *image, u32 *written, int erase)
789 {
790 int retval;
791
792 int section;
793 u32 section_offset;
794 flash_bank_t *c;
795
796 section = 0;
797 section_offset = 0;
798
799 if (written)
800 *written = 0;
801
802 if (erase)
803 {
804 /* assume all sectors need erasing - stops any problems
805 * when flash_write is called multiple times */
806
807 flash_set_dirty();
808 }
809
810 /* loop until we reach end of the image */
811 while (section < image->num_sections)
812 {
813 u32 buffer_size;
814 u8 *buffer;
815 int section_first;
816 int section_last;
817 u32 run_address = image->sections[section].base_address + section_offset;
818 u32 run_size = image->sections[section].size - section_offset;
819
820 if (image->sections[section].size == 0)
821 {
822 WARNING("empty section %d", section);
823 section++;
824 section_offset = 0;
825 continue;
826 }
827
828 /* find the corresponding flash bank */
829 if ((c = get_flash_bank_by_addr(target, run_address)) == NULL)
830 {
831 section++; /* and skip it */
832 section_offset = 0;
833 continue;
834 }
835
836 /* collect consecutive sections which fall into the same bank */
837 section_first = section;
838 section_last = section;
839 while ((run_address + run_size < c->base + c->size)
840 && (section_last + 1 < image->num_sections))
841 {
842 if (image->sections[section_last + 1].base_address < (run_address + run_size))
843 {
844 DEBUG("section %d out of order(very slightly surprising, but supported)", section_last + 1);
845 break;
846 }
847 if (image->sections[section_last + 1].base_address != (run_address + run_size))
848 break;
849 run_size += image->sections[++section_last].size;
850 }
851
852 /* fit the run into bank constraints */
853 if (run_address + run_size > c->base + c->size)
854 run_size = c->base + c->size - run_address;
855
856 /* allocate buffer */
857 buffer = malloc(run_size);
858 buffer_size = 0;
859
860 /* read sections to the buffer */
861 while (buffer_size < run_size)
862 {
863 u32 size_read;
864
865 if (buffer_size - run_size <= image->sections[section].size - section_offset)
866 size_read = buffer_size - run_size;
867 else
868 size_read = image->sections[section].size - section_offset;
869
870 if ((retval = image_read_section(image, section, section_offset,
871 size_read, buffer + buffer_size, &size_read)) != ERROR_OK || size_read == 0)
872 {
873 free(buffer);
874
875 return retval;
876 }
877
878 buffer_size += size_read;
879 section_offset += size_read;
880
881 if (section_offset >= image->sections[section].size)
882 {
883 section++;
884 section_offset = 0;
885 }
886 }
887
888 retval = ERROR_OK;
889
890 if (erase)
891 {
892 /* calculate and erase sectors */
893 retval = flash_erase_address_range( target, run_address, run_size );
894 }
895
896 if (retval == ERROR_OK)
897 {
898 /* write flash sectors */
899 retval = flash_driver_write(c, buffer, run_address - c->base, run_size);
900 }
901
902 free(buffer);
903
904 if (retval != ERROR_OK)
905 {
906 return retval; /* abort operation */
907 }
908
909 if (written != NULL)
910 *written += run_size; /* add run size to total written counter */
911 }
912
913 return ERROR_OK;
914 }
915
916 int handle_flash_auto_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
917 {
918 if (argc != 1)
919 {
920 return ERROR_COMMAND_SYNTAX_ERROR;
921
922 }
923
924 if (strcmp(args[0], "on") == 0)
925 auto_erase = 1;
926 else if (strcmp(args[0], "off") == 0)
927 auto_erase = 0;
928 else
929 return ERROR_COMMAND_SYNTAX_ERROR;
930
931 return ERROR_OK;
932 }

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)