- rename log functions to stop conflicts under win32 (wingdi)
[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 LOG_ERROR("error writing to flash at address 0x%08x at offset 0x%8.8x (%d)", bank->base, offset, retval);
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 LOG_ERROR("failed erasing sectors %d to %d (%d)", first, last, retval);
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 LOG_ERROR("failed setting protection for areas %d to %d (%d)", first, last, retval);
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 LOG_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 LOG_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 LOG_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 LOG_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 LOG_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 LOG_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 int retval;
315
316 if (argc != 1)
317 {
318 return ERROR_COMMAND_SYNTAX_ERROR;
319 }
320
321 for (p = flash_banks; p; p = p->next, i++)
322 {
323 if (i == strtoul(args[0], NULL, 0))
324 {
325 char buf[1024];
326
327 /* attempt auto probe */
328 p->driver->auto_probe(p);
329
330 command_print(cmd_ctx, "#%i: %s at 0x%8.8x, size 0x%8.8x, buswidth %i, chipwidth %i",
331 i, p->driver->name, p->base, p->size, p->bus_width, p->chip_width);
332 for (j = 0; j < p->num_sectors; j++)
333 {
334 char *erase_state, *protect_state;
335
336 if (p->sectors[j].is_erased == 0)
337 erase_state = "not erased";
338 else if (p->sectors[j].is_erased == 1)
339 erase_state = "erased";
340 else
341 erase_state = "erase state unknown";
342
343 if (p->sectors[j].is_protected == 0)
344 protect_state = "not protected";
345 else if (p->sectors[j].is_protected == 1)
346 protect_state = "protected";
347 else
348 protect_state = "protection state unknown";
349
350 command_print(cmd_ctx, "\t#%i: 0x%8.8x (0x%x %ikB) %s, %s",
351 j, p->sectors[j].offset, p->sectors[j].size, p->sectors[j].size>>10,
352 erase_state, protect_state);
353 }
354
355 *buf = '\0'; /* initialize buffer, otherwise it migh contain garbage if driver function fails */
356 retval = p->driver->info(p, buf, sizeof(buf));
357 command_print(cmd_ctx, "%s", buf);
358 if (retval != ERROR_OK)
359 LOG_ERROR("error retrieving flash info (%d)", retval);
360 }
361 }
362
363 return ERROR_OK;
364 }
365
366 int handle_flash_probe_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
367 {
368 flash_bank_t *p;
369 int retval;
370
371 if (argc != 1)
372 {
373 return ERROR_COMMAND_SYNTAX_ERROR;
374 }
375
376 p = get_flash_bank_by_num_noprobe(strtoul(args[0], NULL, 0));
377 if (p)
378 {
379 if ((retval = p->driver->probe(p)) == ERROR_OK)
380 {
381 command_print(cmd_ctx, "flash '%s' found at 0x%8.8x", p->driver->name, p->base);
382 }
383 else if (retval == ERROR_FLASH_BANK_INVALID)
384 {
385 command_print(cmd_ctx, "probing failed for flash bank '#%s' at 0x%8.8x",
386 args[0], p->base);
387 }
388 else
389 {
390 command_print(cmd_ctx, "unknown error when probing flash bank '#%s' at 0x%8.8x",
391 args[0], p->base);
392 }
393 }
394 else
395 {
396 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
397 }
398
399 return ERROR_OK;
400 }
401
402 int handle_flash_erase_check_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
403 {
404 flash_bank_t *p;
405 int retval;
406
407 if (argc != 1)
408 {
409 return ERROR_COMMAND_SYNTAX_ERROR;
410 }
411
412 p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
413 if (p)
414 {
415 if ((retval = p->driver->erase_check(p)) == ERROR_OK)
416 {
417 command_print(cmd_ctx, "successfully checked erase state", p->driver->name, p->base);
418 }
419 else
420 {
421 command_print(cmd_ctx, "unknown error when checking erase state of flash bank #%s at 0x%8.8x",
422 args[0], p->base);
423 }
424 }
425
426 return ERROR_OK;
427 }
428
429 int handle_flash_erase_address_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
430 {
431 flash_bank_t *p;
432 int retval;
433 int address;
434 int length;
435 duration_t duration;
436 char *duration_text;
437
438 target_t *target = get_current_target(cmd_ctx);
439
440 if (argc != 2)
441 {
442 return ERROR_COMMAND_SYNTAX_ERROR;
443 }
444
445 address = strtoul(args[0], NULL, 0);
446 length = strtoul(args[1], NULL, 0);
447 if (length <= 0)
448 {
449 command_print(cmd_ctx, "Length must be >0");
450 return ERROR_COMMAND_SYNTAX_ERROR;
451 }
452
453 p = get_flash_bank_by_addr(target, address);
454 if (p == NULL)
455 {
456 return ERROR_COMMAND_SYNTAX_ERROR;
457 }
458
459 /* We can't know if we did a resume + halt, in which case we no longer know the erased state */
460 flash_set_dirty();
461
462 duration_start_measure(&duration);
463
464 if ((retval = flash_erase_address_range(target, address, length)) == ERROR_OK)
465 {
466 duration_stop_measure(&duration, &duration_text);
467 command_print(cmd_ctx, "erased address 0x%8.8x length %i in %s", address, length, duration_text);
468 free(duration_text);
469 }
470
471 return retval;
472 }
473
474 int handle_flash_protect_check_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
475 {
476 flash_bank_t *p;
477 int retval;
478
479 if (argc != 1)
480 {
481 return ERROR_COMMAND_SYNTAX_ERROR;
482 }
483
484 p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
485 if (p)
486 {
487 if ((retval = p->driver->protect_check(p)) == ERROR_OK)
488 {
489 command_print(cmd_ctx, "successfully checked protect state");
490 }
491 else if (retval == ERROR_FLASH_OPERATION_FAILED)
492 {
493 command_print(cmd_ctx, "checking protection state failed (possibly unsupported) by flash #%s at 0x%8.8x", args[0], p->base);
494 }
495 else
496 {
497 command_print(cmd_ctx, "unknown error when checking protection state of flash bank '#%s' at 0x%8.8x", args[0], p->base);
498 }
499 }
500 else
501 {
502 return ERROR_COMMAND_SYNTAX_ERROR;
503 }
504
505 return ERROR_OK;
506 }
507
508 int handle_flash_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
509 {
510 if (argc > 2)
511 {
512 int first = strtoul(args[1], NULL, 0);
513 int last = strtoul(args[2], NULL, 0);
514 int retval;
515 flash_bank_t *p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
516 duration_t duration;
517 char *duration_text;
518
519 duration_start_measure(&duration);
520
521 if (!p)
522 {
523 return ERROR_COMMAND_SYNTAX_ERROR;
524 }
525
526 if ((retval = flash_driver_erase(p, first, last)) == ERROR_OK)
527 {
528 duration_stop_measure(&duration, &duration_text);
529
530 command_print(cmd_ctx, "erased sectors %i through %i on flash bank %i in %s", first, last, strtoul(args[0], 0, 0), duration_text);
531 free(duration_text);
532 }
533 }
534 else
535 {
536 return ERROR_COMMAND_SYNTAX_ERROR;
537 }
538
539 return ERROR_OK;
540 }
541
542 int handle_flash_protect_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
543 {
544 if (argc > 3)
545 {
546 int first = strtoul(args[1], NULL, 0);
547 int last = strtoul(args[2], NULL, 0);
548 int set;
549 int retval;
550 flash_bank_t *p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
551 if (!p)
552 {
553 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
554 return ERROR_OK;
555 }
556
557 if (strcmp(args[3], "on") == 0)
558 set = 1;
559 else if (strcmp(args[3], "off") == 0)
560 set = 0;
561 else
562 {
563 return ERROR_COMMAND_SYNTAX_ERROR;
564 }
565
566 retval = flash_driver_protect(p, set, first, last);
567 if (retval == ERROR_OK)
568 {
569 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));
570 }
571 }
572 else
573 {
574 return ERROR_COMMAND_SYNTAX_ERROR;
575
576 }
577
578 return ERROR_OK;
579 }
580
581 int handle_flash_write_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
582 {
583 target_t *target = get_current_target(cmd_ctx);
584
585 image_t image;
586 u32 written;
587
588 duration_t duration;
589 char *duration_text;
590
591 int retval;
592
593 if (argc < 1)
594 {
595 return ERROR_COMMAND_SYNTAX_ERROR;
596
597 }
598
599 if (!target)
600 {
601 LOG_ERROR("no target selected");
602 return ERROR_OK;
603 }
604
605 duration_start_measure(&duration);
606
607 if (argc >= 2)
608 {
609 image.base_address_set = 1;
610 image.base_address = strtoul(args[1], NULL, 0);
611 }
612 else
613 {
614 image.base_address_set = 0;
615 image.base_address = 0x0;
616 }
617
618 image.start_address_set = 0;
619
620 retval = image_open(&image, args[0], (argc == 3) ? args[2] : NULL);
621 if (retval != ERROR_OK)
622 {
623 return retval;
624 }
625
626 retval = flash_write(target, &image, &written, auto_erase);
627
628 if (retval != ERROR_OK)
629 {
630 image_close(&image);
631 return retval;
632 }
633
634 duration_stop_measure(&duration, &duration_text);
635 if (retval == ERROR_OK)
636 {
637 command_print(cmd_ctx, "wrote %u byte from file %s in %s (%f kb/s)",
638 written, args[0], duration_text,
639 (float)written / 1024.0 / ((float)duration.duration.tv_sec + ((float)duration.duration.tv_usec / 1000000.0)));
640 }
641 free(duration_text);
642
643 image_close(&image);
644
645 return retval;
646 }
647
648 int handle_flash_write_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
649 {
650 u32 offset;
651 u8 *buffer;
652 u32 buf_cnt;
653
654 fileio_t fileio;
655
656 duration_t duration;
657 char *duration_text;
658
659 int retval;
660 flash_bank_t *p;
661
662 if (argc != 3)
663 {
664 return ERROR_COMMAND_SYNTAX_ERROR;
665 }
666
667 duration_start_measure(&duration);
668
669 offset = strtoul(args[2], NULL, 0);
670 p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
671 if (!p)
672 {
673 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
674 return ERROR_OK;
675 }
676
677 if (fileio_open(&fileio, args[1], FILEIO_READ, FILEIO_BINARY) != ERROR_OK)
678 {
679 return ERROR_OK;
680 }
681
682 buffer = malloc(fileio.size);
683 if (fileio_read(&fileio, fileio.size, buffer, &buf_cnt) != ERROR_OK)
684 {
685 return ERROR_OK;
686 }
687
688 retval = flash_driver_write(p, buffer, offset, buf_cnt);
689
690 free(buffer);
691
692 duration_stop_measure(&duration, &duration_text);
693 if (retval!=ERROR_OK)
694 {
695 command_print(cmd_ctx, "wrote %"PRIi64" byte from file %s to flash bank %i at offset 0x%8.8x in %s (%f kb/s)",
696 fileio.size, args[1], strtoul(args[0], NULL, 0), offset, duration_text,
697 (float)fileio.size / 1024.0 / ((float)duration.duration.tv_sec + ((float)duration.duration.tv_usec / 1000000.0)));
698 }
699 free(duration_text);
700
701 fileio_close(&fileio);
702
703 return retval;
704 }
705
706 void flash_set_dirty(void)
707 {
708 flash_bank_t *c;
709 int i;
710
711 /* set all flash to require erasing */
712 for (c = flash_banks; c; c = c->next)
713 {
714 for (i = 0; i < c->num_sectors; i++)
715 {
716 c->sectors[i].is_erased = 0;
717 }
718 }
719 }
720
721 /* lookup flash bank by address */
722 flash_bank_t *get_flash_bank_by_addr(target_t *target, u32 addr)
723 {
724 flash_bank_t *c;
725
726 /* cycle through bank list */
727 for (c = flash_banks; c; c = c->next)
728 {
729 int retval;
730 retval = c->driver->auto_probe(c);
731
732 if (retval != ERROR_OK)
733 {
734 LOG_ERROR("auto_probe failed %d\n", retval);
735 return NULL;
736 }
737 /* check whether address belongs to this flash bank */
738 if ((addr >= c->base) && (addr < c->base + c->size) && target == c->target)
739 return c;
740 }
741 LOG_ERROR("No flash at address 0x%08x\n", addr);
742 return NULL;
743 }
744
745 /* erase given flash region, selects proper bank according to target and address */
746 int flash_erase_address_range(target_t *target, u32 addr, u32 length)
747 {
748 flash_bank_t *c;
749 int first = -1;
750 int last = -1;
751 int i;
752
753 if ((c = get_flash_bank_by_addr(target, addr)) == NULL)
754 return ERROR_FLASH_DST_OUT_OF_BANK; /* no corresponding bank found */
755
756 if (c->size == 0 || c->num_sectors == 0)
757 return ERROR_FLASH_BANK_INVALID;
758
759 if (length == 0)
760 {
761 /* special case, erase whole bank when length is zero */
762 if (addr != c->base)
763 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
764
765 return flash_driver_erase(c, 0, c->num_sectors - 1);
766 }
767
768 /* check whether it fits */
769 if (addr + length > c->base + c->size)
770 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
771
772 addr -= c->base;
773
774 for (i = 0; i < c->num_sectors; i++)
775 {
776 /* check whether sector overlaps with the given range and is not yet erased */
777 if (addr < c->sectors[i].offset + c->sectors[i].size && addr + length > c->sectors[i].offset && c->sectors[i].is_erased != 1) {
778 /* if first is not set yet then this is the first sector */
779 if (first == -1)
780 first = i;
781 last = i; /* and it is the last one so far in any case */
782 }
783 }
784
785 if( first == -1 || last == -1 )
786 return ERROR_OK;
787
788 return flash_driver_erase(c, first, last);
789 }
790
791 /* write (optional verify) an image to flash memory of the given target */
792 int flash_write(target_t *target, image_t *image, u32 *written, int erase)
793 {
794 int retval;
795
796 int section;
797 u32 section_offset;
798 flash_bank_t *c;
799
800 section = 0;
801 section_offset = 0;
802
803 if (written)
804 *written = 0;
805
806 if (erase)
807 {
808 /* assume all sectors need erasing - stops any problems
809 * when flash_write is called multiple times */
810
811 flash_set_dirty();
812 }
813
814 /* loop until we reach end of the image */
815 while (section < image->num_sections)
816 {
817 u32 buffer_size;
818 u8 *buffer;
819 int section_first;
820 int section_last;
821 u32 run_address = image->sections[section].base_address + section_offset;
822 u32 run_size = image->sections[section].size - section_offset;
823
824 if (image->sections[section].size == 0)
825 {
826 LOG_WARNING("empty section %d", section);
827 section++;
828 section_offset = 0;
829 continue;
830 }
831
832 /* find the corresponding flash bank */
833 if ((c = get_flash_bank_by_addr(target, run_address)) == NULL)
834 {
835 section++; /* and skip it */
836 section_offset = 0;
837 continue;
838 }
839
840 /* collect consecutive sections which fall into the same bank */
841 section_first = section;
842 section_last = section;
843 while ((run_address + run_size < c->base + c->size)
844 && (section_last + 1 < image->num_sections))
845 {
846 if (image->sections[section_last + 1].base_address < (run_address + run_size))
847 {
848 LOG_DEBUG("section %d out of order(very slightly surprising, but supported)", section_last + 1);
849 break;
850 }
851 if (image->sections[section_last + 1].base_address != (run_address + run_size))
852 break;
853 run_size += image->sections[++section_last].size;
854 }
855
856 /* fit the run into bank constraints */
857 if (run_address + run_size > c->base + c->size)
858 run_size = c->base + c->size - run_address;
859
860 /* allocate buffer */
861 buffer = malloc(run_size);
862 buffer_size = 0;
863
864 /* read sections to the buffer */
865 while (buffer_size < run_size)
866 {
867 u32 size_read;
868
869 if (buffer_size - run_size <= image->sections[section].size - section_offset)
870 size_read = buffer_size - run_size;
871 else
872 size_read = image->sections[section].size - section_offset;
873
874 if ((retval = image_read_section(image, section, section_offset,
875 size_read, buffer + buffer_size, &size_read)) != ERROR_OK || size_read == 0)
876 {
877 free(buffer);
878
879 return retval;
880 }
881
882 buffer_size += size_read;
883 section_offset += size_read;
884
885 if (section_offset >= image->sections[section].size)
886 {
887 section++;
888 section_offset = 0;
889 }
890 }
891
892 retval = ERROR_OK;
893
894 if (erase)
895 {
896 /* calculate and erase sectors */
897 retval = flash_erase_address_range( target, run_address, run_size );
898 }
899
900 if (retval == ERROR_OK)
901 {
902 /* write flash sectors */
903 retval = flash_driver_write(c, buffer, run_address - c->base, run_size);
904 }
905
906 free(buffer);
907
908 if (retval != ERROR_OK)
909 {
910 return retval; /* abort operation */
911 }
912
913 if (written != NULL)
914 *written += run_size; /* add run size to total written counter */
915 }
916
917 return ERROR_OK;
918 }
919
920 int handle_flash_auto_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
921 {
922 if (argc != 1)
923 {
924 return ERROR_COMMAND_SYNTAX_ERROR;
925 }
926
927 if (strcmp(args[0], "on") == 0)
928 auto_erase = 1;
929 else if (strcmp(args[0], "off") == 0)
930 auto_erase = 0;
931 else
932 return ERROR_COMMAND_SYNTAX_ERROR;
933
934 return ERROR_OK;
935 }

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)