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

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)