fda2c91a12e2a025b2a33ced2cbef4a5c47405c2
[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 #include "armv4_5.h"
32 #include "algorithm.h"
33 #include "binarybuffer.h"
34 #include "armv7m.h"
35
36 #include <string.h>
37 #include <unistd.h>
38 #include <stdlib.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #include <errno.h>
42 #include <inttypes.h>
43
44 /* command handlers */
45 int handle_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
46 int handle_flash_banks_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
47 int handle_flash_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
48 int handle_flash_probe_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
49 int handle_flash_erase_check_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
50 int handle_flash_erase_address_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
51 int handle_flash_protect_check_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
52 int handle_flash_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
53 int handle_flash_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
54 int handle_flash_write_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
55 int handle_flash_write_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
56 int handle_flash_fill_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
57 int handle_flash_protect_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
58 flash_bank_t *get_flash_bank_by_addr(target_t *target, u32 addr);
59
60 /* flash drivers
61 */
62 extern flash_driver_t lpc2000_flash;
63 extern flash_driver_t cfi_flash;
64 extern flash_driver_t at91sam7_flash;
65 extern flash_driver_t str7x_flash;
66 extern flash_driver_t str9x_flash;
67 extern flash_driver_t stellaris_flash;
68 extern flash_driver_t str9xpec_flash;
69 extern flash_driver_t stm32x_flash;
70 extern flash_driver_t tms470_flash;
71 extern flash_driver_t ecosflash_flash;
72 extern flash_driver_t lpc288x_flash;
73
74 flash_driver_t *flash_drivers[] =
75 {
76 &lpc2000_flash,
77 &cfi_flash,
78 &at91sam7_flash,
79 &str7x_flash,
80 &str9x_flash,
81 &stellaris_flash,
82 &str9xpec_flash,
83 &stm32x_flash,
84 &tms470_flash,
85 &ecosflash_flash,
86 &lpc288x_flash,
87 NULL,
88 };
89
90 flash_bank_t *flash_banks;
91 static command_t *flash_cmd;
92
93 /* wafer thin wrapper for invoking the flash driver */
94 static int flash_driver_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
95 {
96 int retval;
97
98 retval=bank->driver->write(bank, buffer, offset, count);
99 if (retval!=ERROR_OK)
100 {
101 LOG_ERROR("error writing to flash at address 0x%08x at offset 0x%8.8x (%d)", bank->base, offset, retval);
102 }
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;
110
111 retval=bank->driver->erase(bank, first, last);
112 if (retval!=ERROR_OK)
113 {
114 LOG_ERROR("failed erasing sectors %d to %d (%d)", first, last, retval);
115 }
116
117 return retval;
118 }
119
120 int flash_driver_protect(struct flash_bank_s *bank, int set, int first, int last)
121 {
122 int retval;
123
124 retval=bank->driver->protect(bank, set, first, last);
125 if (retval!=ERROR_OK)
126 {
127 LOG_ERROR("failed setting protection for areas %d to %d (%d)", first, last, retval);
128 }
129
130 return retval;
131 }
132
133
134 int flash_register_commands(struct command_context_s *cmd_ctx)
135 {
136 flash_cmd = register_command(cmd_ctx, NULL, "flash", NULL, COMMAND_ANY, NULL);
137
138 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 ...]");
139 return ERROR_OK;
140 }
141
142 int flash_init_drivers(struct command_context_s *cmd_ctx)
143 {
144 if (flash_banks)
145 {
146 register_command(cmd_ctx, flash_cmd, "banks", handle_flash_banks_command, COMMAND_EXEC,
147 "list configured flash banks ");
148 register_command(cmd_ctx, flash_cmd, "info", handle_flash_info_command, COMMAND_EXEC,
149 "print info about flash bank <num>");
150 register_command(cmd_ctx, flash_cmd, "probe", handle_flash_probe_command, COMMAND_EXEC,
151 "identify flash bank <num>");
152 register_command(cmd_ctx, flash_cmd, "erase_check", handle_flash_erase_check_command, COMMAND_EXEC,
153 "check erase state of sectors in flash bank <num>");
154 register_command(cmd_ctx, flash_cmd, "protect_check", handle_flash_protect_check_command, COMMAND_EXEC,
155 "check protection state of sectors in flash bank <num>");
156 register_command(cmd_ctx, flash_cmd, "erase_sector", handle_flash_erase_command, COMMAND_EXEC,
157 "erase sectors at <bank> <first> <last>");
158 register_command(cmd_ctx, flash_cmd, "erase_address", handle_flash_erase_address_command, COMMAND_EXEC,
159 "erase address range <address> <length>");
160
161 register_command(cmd_ctx, flash_cmd, "fillw", handle_flash_fill_command, COMMAND_EXEC,
162 "fill with pattern <address> <word_pattern> <count>");
163 register_command(cmd_ctx, flash_cmd, "fillh", handle_flash_fill_command, COMMAND_EXEC,
164 "fill with pattern <address> <halfword_pattern> <count>");
165 register_command(cmd_ctx, flash_cmd, "fillb", handle_flash_fill_command, COMMAND_EXEC,
166 "fill with pattern <address> <byte_pattern> <count>");
167
168 register_command(cmd_ctx, flash_cmd, "write_bank", handle_flash_write_bank_command, COMMAND_EXEC,
169 "write binary data to <bank> <file> <offset>");
170 register_command(cmd_ctx, flash_cmd, "write_image", handle_flash_write_image_command, COMMAND_EXEC,
171 "write_image [erase] <file> [offset] [type]");
172 register_command(cmd_ctx, flash_cmd, "protect", handle_flash_protect_command, COMMAND_EXEC,
173 "set protection of sectors at <bank> <first> <last> <on|off>");
174 }
175
176 return ERROR_OK;
177 }
178
179 flash_bank_t *get_flash_bank_by_num_noprobe(int num)
180 {
181 flash_bank_t *p;
182 int i = 0;
183
184 for (p = flash_banks; p; p = p->next)
185 {
186 if (i++ == num)
187 {
188 return p;
189 }
190 }
191 LOG_ERROR("flash bank %d does not exist", num);
192 return NULL;
193 }
194
195 int flash_get_bank_count()
196 {
197 flash_bank_t *p;
198 int i = 0;
199 for (p = flash_banks; p; p = p->next)
200 {
201 i++;
202 }
203 return i;
204 }
205
206 flash_bank_t *get_flash_bank_by_num(int num)
207 {
208 flash_bank_t *p = get_flash_bank_by_num_noprobe(num);
209 int retval;
210
211 if (p == NULL)
212 return NULL;
213
214 retval = p->driver->auto_probe(p);
215
216 if (retval != ERROR_OK)
217 {
218 LOG_ERROR("auto_probe failed %d\n", retval);
219 return NULL;
220 }
221 return p;
222 }
223
224 int handle_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
225 {
226 int i;
227 int found = 0;
228 target_t *target;
229
230 if (argc < 6)
231 {
232 return ERROR_COMMAND_SYNTAX_ERROR;
233 }
234
235 if ((target = get_target_by_num(strtoul(args[5], NULL, 0))) == NULL)
236 {
237 LOG_ERROR("target %lu not defined", strtoul(args[5], NULL, 0));
238 return ERROR_OK;
239 }
240
241 for (i = 0; flash_drivers[i]; i++)
242 {
243 if (strcmp(args[0], flash_drivers[i]->name) == 0)
244 {
245 flash_bank_t *p, *c;
246
247 /* register flash specific commands */
248 if (flash_drivers[i]->register_commands(cmd_ctx) != ERROR_OK)
249 {
250 LOG_ERROR("couldn't register '%s' commands", args[0]);
251 exit(-1);
252 }
253
254 c = malloc(sizeof(flash_bank_t));
255 c->target = target;
256 c->driver = flash_drivers[i];
257 c->driver_priv = NULL;
258 c->base = strtoul(args[1], NULL, 0);
259 c->size = strtoul(args[2], NULL, 0);
260 c->chip_width = strtoul(args[3], NULL, 0);
261 c->bus_width = strtoul(args[4], NULL, 0);
262 c->num_sectors = 0;
263 c->sectors = NULL;
264 c->next = NULL;
265
266 if (flash_drivers[i]->flash_bank_command(cmd_ctx, cmd, args, argc, c) != ERROR_OK)
267 {
268 LOG_ERROR("'%s' driver rejected flash bank at 0x%8.8x", args[0], c->base);
269 free(c);
270 return ERROR_OK;
271 }
272
273 /* put flash bank in linked list */
274 if (flash_banks)
275 {
276 /* find last flash bank */
277 for (p = flash_banks; p && p->next; p = p->next);
278 if (p)
279 p->next = c;
280 }
281 else
282 {
283 flash_banks = c;
284 }
285
286 found = 1;
287 }
288 }
289
290 /* no matching flash driver found */
291 if (!found)
292 {
293 LOG_ERROR("flash driver '%s' not found", args[0]);
294 exit(-1);
295 }
296
297 return ERROR_OK;
298 }
299
300 int handle_flash_banks_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
301 {
302 flash_bank_t *p;
303 int i = 0;
304
305 if (!flash_banks)
306 {
307 command_print(cmd_ctx, "no flash banks configured");
308 return ERROR_OK;
309 }
310
311 for (p = flash_banks; p; p = p->next)
312 {
313 command_print(cmd_ctx, "#%i: %s at 0x%8.8x, size 0x%8.8x, buswidth %i, chipwidth %i",
314 i++, p->driver->name, p->base, p->size, p->bus_width, p->chip_width);
315 }
316
317 return ERROR_OK;
318 }
319
320 int handle_flash_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
321 {
322 flash_bank_t *p;
323 int i = 0;
324 int j = 0;
325 int retval;
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 if ((retval = p->driver->auto_probe(p)) != ERROR_OK)
340 return retval;
341
342 command_print(cmd_ctx, "#%i: %s at 0x%8.8x, size 0x%8.8x, buswidth %i, chipwidth %i",
343 i, p->driver->name, p->base, p->size, p->bus_width, p->chip_width);
344 for (j = 0; j < p->num_sectors; j++)
345 {
346 char *protect_state;
347
348 if (p->sectors[j].is_protected == 0)
349 protect_state = "not protected";
350 else if (p->sectors[j].is_protected == 1)
351 protect_state = "protected";
352 else
353 protect_state = "protection state unknown";
354
355 command_print(cmd_ctx, "\t#%i: 0x%8.8x (0x%x %ikB) %s",
356 j, p->sectors[j].offset, p->sectors[j].size, p->sectors[j].size>>10,
357 protect_state);
358 }
359
360 *buf = '\0'; /* initialize buffer, otherwise it migh contain garbage if driver function fails */
361 retval = p->driver->info(p, buf, sizeof(buf));
362 command_print(cmd_ctx, "%s", buf);
363 if (retval != ERROR_OK)
364 LOG_ERROR("error retrieving flash info (%d)", retval);
365 }
366 }
367
368 return ERROR_OK;
369 }
370
371 int handle_flash_probe_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
372 {
373 flash_bank_t *p;
374 int retval;
375
376 if (argc != 1)
377 {
378 return ERROR_COMMAND_SYNTAX_ERROR;
379 }
380
381 p = get_flash_bank_by_num_noprobe(strtoul(args[0], NULL, 0));
382 if (p)
383 {
384 if ((retval = p->driver->probe(p)) == ERROR_OK)
385 {
386 command_print(cmd_ctx, "flash '%s' found at 0x%8.8x", p->driver->name, p->base);
387 }
388 else if (retval == ERROR_FLASH_BANK_INVALID)
389 {
390 command_print(cmd_ctx, "probing failed for flash bank '#%s' at 0x%8.8x",
391 args[0], p->base);
392 }
393 else
394 {
395 command_print(cmd_ctx, "unknown error when probing flash bank '#%s' at 0x%8.8x",
396 args[0], p->base);
397 }
398 }
399 else
400 {
401 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
402 }
403
404 return ERROR_OK;
405 }
406
407 int handle_flash_erase_check_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
408 {
409 flash_bank_t *p;
410 int retval;
411
412 if (argc != 1)
413 {
414 return ERROR_COMMAND_SYNTAX_ERROR;
415 }
416
417 p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
418 if (p)
419 {
420 int j;
421 if ((retval = p->driver->erase_check(p)) == ERROR_OK)
422 {
423 command_print(cmd_ctx, "successfully checked erase state", p->driver->name, p->base);
424 }
425 else
426 {
427 command_print(cmd_ctx, "unknown error when checking erase state of flash bank #%s at 0x%8.8x",
428 args[0], p->base);
429 }
430
431 for (j = 0; j < p->num_sectors; j++)
432 {
433 char *erase_state;
434
435 if (p->sectors[j].is_erased == 0)
436 erase_state = "not erased";
437 else if (p->sectors[j].is_erased == 1)
438 erase_state = "erased";
439 else
440 erase_state = "erase state unknown";
441
442 command_print(cmd_ctx, "\t#%i: 0x%8.8x (0x%x %ikB) %s",
443 j, p->sectors[j].offset, p->sectors[j].size, p->sectors[j].size>>10,
444 erase_state);
445 }
446
447 }
448
449 return ERROR_OK;
450 }
451
452 int handle_flash_erase_address_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
453 {
454 flash_bank_t *p;
455 int retval;
456 int address;
457 int length;
458 duration_t duration;
459 char *duration_text;
460
461 target_t *target = get_current_target(cmd_ctx);
462
463 if (argc != 2)
464 {
465 return ERROR_COMMAND_SYNTAX_ERROR;
466 }
467
468 address = strtoul(args[0], NULL, 0);
469 length = strtoul(args[1], NULL, 0);
470 if (length <= 0)
471 {
472 command_print(cmd_ctx, "Length must be >0");
473 return ERROR_COMMAND_SYNTAX_ERROR;
474 }
475
476 p = get_flash_bank_by_addr(target, address);
477 if (p == NULL)
478 {
479 return ERROR_COMMAND_SYNTAX_ERROR;
480 }
481
482 /* We can't know if we did a resume + halt, in which case we no longer know the erased state */
483 flash_set_dirty();
484
485 duration_start_measure(&duration);
486
487 if ((retval = flash_erase_address_range(target, address, length)) == ERROR_OK)
488 {
489 duration_stop_measure(&duration, &duration_text);
490 command_print(cmd_ctx, "erased address 0x%8.8x length %i in %s", address, length, duration_text);
491 free(duration_text);
492 }
493
494 return retval;
495 }
496
497 int handle_flash_protect_check_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
498 {
499 flash_bank_t *p;
500 int retval;
501
502 if (argc != 1)
503 {
504 return ERROR_COMMAND_SYNTAX_ERROR;
505 }
506
507 p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
508 if (p)
509 {
510 if ((retval = p->driver->protect_check(p)) == ERROR_OK)
511 {
512 command_print(cmd_ctx, "successfully checked protect state");
513 }
514 else if (retval == ERROR_FLASH_OPERATION_FAILED)
515 {
516 command_print(cmd_ctx, "checking protection state failed (possibly unsupported) by flash #%s at 0x%8.8x", args[0], p->base);
517 }
518 else
519 {
520 command_print(cmd_ctx, "unknown error when checking protection state of flash bank '#%s' at 0x%8.8x", args[0], p->base);
521 }
522 }
523 else
524 {
525 return ERROR_COMMAND_SYNTAX_ERROR;
526 }
527
528 return ERROR_OK;
529 }
530
531 int handle_flash_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
532 {
533 if (argc > 2)
534 {
535 int first = strtoul(args[1], NULL, 0);
536 int last = strtoul(args[2], NULL, 0);
537 int retval;
538 flash_bank_t *p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
539 duration_t duration;
540 char *duration_text;
541
542 duration_start_measure(&duration);
543
544 if (!p)
545 {
546 return ERROR_COMMAND_SYNTAX_ERROR;
547 }
548
549 if ((retval = flash_driver_erase(p, first, last)) == ERROR_OK)
550 {
551 duration_stop_measure(&duration, &duration_text);
552
553 command_print(cmd_ctx, "erased sectors %i through %i on flash bank %i in %s", first, last, strtoul(args[0], 0, 0), duration_text);
554 free(duration_text);
555 }
556 }
557 else
558 {
559 return ERROR_COMMAND_SYNTAX_ERROR;
560 }
561
562 return ERROR_OK;
563 }
564
565 int handle_flash_protect_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
566 {
567 if (argc > 3)
568 {
569 int first = strtoul(args[1], NULL, 0);
570 int last = strtoul(args[2], NULL, 0);
571 int set;
572 int retval;
573 flash_bank_t *p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
574 if (!p)
575 {
576 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
577 return ERROR_OK;
578 }
579
580 if (strcmp(args[3], "on") == 0)
581 set = 1;
582 else if (strcmp(args[3], "off") == 0)
583 set = 0;
584 else
585 {
586 return ERROR_COMMAND_SYNTAX_ERROR;
587 }
588
589 retval = flash_driver_protect(p, set, first, last);
590 if (retval == ERROR_OK)
591 {
592 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));
593 }
594 }
595 else
596 {
597 return ERROR_COMMAND_SYNTAX_ERROR;
598
599 }
600
601 return ERROR_OK;
602 }
603
604 int handle_flash_write_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
605 {
606 target_t *target = get_current_target(cmd_ctx);
607
608 image_t image;
609 u32 written;
610
611 duration_t duration;
612 char *duration_text;
613
614 int retval;
615
616 if (argc < 1)
617 {
618 return ERROR_COMMAND_SYNTAX_ERROR;
619 }
620
621 /* flash auto-erase is disabled by default*/
622 int auto_erase = 0;
623
624 if (strcmp(args[0], "erase")==0)
625 {
626 auto_erase = 1;
627 args++;
628 argc--;
629 command_print(cmd_ctx, "auto erase enabled");
630 }
631
632
633 if (argc < 1)
634 {
635 return ERROR_COMMAND_SYNTAX_ERROR;
636 }
637
638 if (!target)
639 {
640 LOG_ERROR("no target selected");
641 return ERROR_FAIL;
642 }
643
644 duration_start_measure(&duration);
645
646 if (argc >= 2)
647 {
648 image.base_address_set = 1;
649 image.base_address = strtoul(args[1], NULL, 0);
650 }
651 else
652 {
653 image.base_address_set = 0;
654 image.base_address = 0x0;
655 }
656
657 image.start_address_set = 0;
658
659 retval = image_open(&image, args[0], (argc == 3) ? args[2] : NULL);
660 if (retval != ERROR_OK)
661 {
662 return retval;
663 }
664
665 retval = flash_write(target, &image, &written, auto_erase);
666 if (retval != ERROR_OK)
667 {
668 image_close(&image);
669 return retval;
670 }
671
672 duration_stop_measure(&duration, &duration_text);
673 if (retval == ERROR_OK)
674 {
675 command_print(cmd_ctx, "wrote %u byte from file %s in %s (%f kb/s)",
676 written, args[0], duration_text,
677 (float)written / 1024.0 / ((float)duration.duration.tv_sec + ((float)duration.duration.tv_usec / 1000000.0)));
678 }
679 free(duration_text);
680
681 image_close(&image);
682
683 return retval;
684 }
685
686 int handle_flash_fill_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
687 {
688 int err = ERROR_OK;
689 u32 address;
690 u32 pattern;
691 u32 count;
692 u8 chunk[1024];
693 u32 wrote = 0;
694 int chunk_count;
695 char *duration_text;
696 duration_t duration;
697 target_t *target = get_current_target(cmd_ctx);
698 u32 i;
699 int wordsize;
700
701 if (argc != 3)
702 {
703 return ERROR_COMMAND_SYNTAX_ERROR;
704 }
705
706 address = strtoul(args[0], NULL, 0);
707 pattern = strtoul(args[1], NULL, 0);
708 count = strtoul(args[2], NULL, 0);
709
710 if(count == 0)
711 return ERROR_OK;
712
713
714 switch(cmd[4])
715 {
716 case 'w':
717 wordsize=4;
718 break;
719 case 'h':
720 wordsize=2;
721 break;
722 case 'b':
723 wordsize=1;
724 break;
725 default:
726 return ERROR_COMMAND_SYNTAX_ERROR;
727 }
728
729 chunk_count = MIN(count, (1024 / wordsize));
730 switch(wordsize)
731 {
732 case 4:
733 for(i = 0; i < chunk_count; i++)
734 {
735 target_buffer_set_u32(target, chunk + i * wordsize, pattern);
736 }
737 break;
738 case 2:
739 for(i = 0; i < chunk_count; i++)
740 {
741 target_buffer_set_u16(target, chunk + i * wordsize, pattern);
742 }
743 break;
744 case 1:
745 memset(chunk, pattern, chunk_count);
746 break;
747 default:
748 LOG_ERROR("BUG: can't happen");
749 exit(-1);
750 }
751
752 duration_start_measure(&duration);
753
754 flash_set_dirty();
755 err = flash_erase_address_range( target, address, count*wordsize );
756 if (err == ERROR_OK)
757 {
758 for (wrote=0; wrote<(count*wordsize); wrote+=sizeof(chunk))
759 {
760 int cur_size = MIN( (count*wordsize - wrote) , 1024 );
761 if (err == ERROR_OK)
762 {
763 flash_bank_t *bank;
764 bank = get_flash_bank_by_addr(target, address);
765 if(bank == NULL)
766 {
767 err = ERROR_FAIL;
768 break;
769 }
770 err = flash_driver_write(bank, chunk, address - bank->base + wrote, cur_size);
771 wrote += cur_size;
772 }
773 if (err!=ERROR_OK)
774 break;
775 }
776 }
777
778 duration_stop_measure(&duration, &duration_text);
779
780 if(err == ERROR_OK)
781 {
782 float speed;
783 speed=wrote / 1024.0;
784 speed/=((float)duration.duration.tv_sec + ((float)duration.duration.tv_usec / 1000000.0));
785 command_print(cmd_ctx, "wrote %d bytes to 0x%8.8x in %s (%f kb/s)",
786 count*wordsize, address, duration_text,
787 speed);
788 }
789 free(duration_text);
790 return ERROR_OK;
791 }
792
793 int handle_flash_write_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
794 {
795 u32 offset;
796 u8 *buffer;
797 u32 buf_cnt;
798
799 fileio_t fileio;
800
801 duration_t duration;
802 char *duration_text;
803
804 int retval;
805 flash_bank_t *p;
806
807 if (argc != 3)
808 {
809 return ERROR_COMMAND_SYNTAX_ERROR;
810 }
811
812 duration_start_measure(&duration);
813
814 offset = strtoul(args[2], NULL, 0);
815 p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
816 if (!p)
817 {
818 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
819 return ERROR_OK;
820 }
821
822 if (fileio_open(&fileio, args[1], FILEIO_READ, FILEIO_BINARY) != ERROR_OK)
823 {
824 return ERROR_OK;
825 }
826
827 buffer = malloc(fileio.size);
828 if (fileio_read(&fileio, fileio.size, buffer, &buf_cnt) != ERROR_OK)
829 {
830 return ERROR_OK;
831 }
832
833 retval = flash_driver_write(p, buffer, offset, buf_cnt);
834
835 free(buffer);
836
837 duration_stop_measure(&duration, &duration_text);
838 if (retval!=ERROR_OK)
839 {
840 command_print(cmd_ctx, "wrote %"PRIi64" byte from file %s to flash bank %i at offset 0x%8.8x in %s (%f kb/s)",
841 fileio.size, args[1], strtoul(args[0], NULL, 0), offset, duration_text,
842 (float)fileio.size / 1024.0 / ((float)duration.duration.tv_sec + ((float)duration.duration.tv_usec / 1000000.0)));
843 }
844 free(duration_text);
845
846 fileio_close(&fileio);
847
848 return retval;
849 }
850
851 void flash_set_dirty(void)
852 {
853 flash_bank_t *c;
854 int i;
855
856 /* set all flash to require erasing */
857 for (c = flash_banks; c; c = c->next)
858 {
859 for (i = 0; i < c->num_sectors; i++)
860 {
861 c->sectors[i].is_erased = 0;
862 }
863 }
864 }
865
866 /* lookup flash bank by address */
867 flash_bank_t *get_flash_bank_by_addr(target_t *target, u32 addr)
868 {
869 flash_bank_t *c;
870
871 /* cycle through bank list */
872 for (c = flash_banks; c; c = c->next)
873 {
874 int retval;
875 retval = c->driver->auto_probe(c);
876
877 if (retval != ERROR_OK)
878 {
879 LOG_ERROR("auto_probe failed %d\n", retval);
880 return NULL;
881 }
882 /* check whether address belongs to this flash bank */
883 if ((addr >= c->base) && (addr < c->base + c->size) && target == c->target)
884 return c;
885 }
886 LOG_ERROR("No flash at address 0x%08x\n", addr);
887 return NULL;
888 }
889
890 /* erase given flash region, selects proper bank according to target and address */
891 int flash_erase_address_range(target_t *target, u32 addr, u32 length)
892 {
893 flash_bank_t *c;
894 int first = -1;
895 int last = -1;
896 int i;
897
898 if ((c = get_flash_bank_by_addr(target, addr)) == NULL)
899 return ERROR_FLASH_DST_OUT_OF_BANK; /* no corresponding bank found */
900
901 if (c->size == 0 || c->num_sectors == 0)
902 {
903 LOG_ERROR("Bank is invalid");
904 return ERROR_FLASH_BANK_INVALID;
905 }
906
907 if (length == 0)
908 {
909 /* special case, erase whole bank when length is zero */
910 if (addr != c->base)
911 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
912
913 return flash_driver_erase(c, 0, c->num_sectors - 1);
914 }
915
916 /* check whether it fits */
917 if (addr + length > c->base + c->size)
918 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
919
920 addr -= c->base;
921
922 for (i = 0; i < c->num_sectors; i++)
923 {
924 /* check whether sector overlaps with the given range and is not yet erased */
925 if (addr < c->sectors[i].offset + c->sectors[i].size && addr + length > c->sectors[i].offset && c->sectors[i].is_erased != 1) {
926 /* if first is not set yet then this is the first sector */
927 if (first == -1)
928 first = i;
929 last = i; /* and it is the last one so far in any case */
930 }
931 }
932
933 if( first == -1 || last == -1 )
934 return ERROR_OK;
935
936 return flash_driver_erase(c, first, last);
937 }
938
939 /* write (optional verify) an image to flash memory of the given target */
940 int flash_write(target_t *target, image_t *image, u32 *written, int erase)
941 {
942 int retval=ERROR_OK;
943
944 int section;
945 u32 section_offset;
946 flash_bank_t *c;
947
948 section = 0;
949 section_offset = 0;
950
951 if (written)
952 *written = 0;
953
954 if (erase)
955 {
956 /* assume all sectors need erasing - stops any problems
957 * when flash_write is called multiple times */
958
959 flash_set_dirty();
960 }
961
962 /* loop until we reach end of the image */
963 while (section < image->num_sections)
964 {
965 u32 buffer_size;
966 u8 *buffer;
967 int section_first;
968 int section_last;
969 u32 run_address = image->sections[section].base_address + section_offset;
970 u32 run_size = image->sections[section].size - section_offset;
971
972 if (image->sections[section].size == 0)
973 {
974 LOG_WARNING("empty section %d", section);
975 section++;
976 section_offset = 0;
977 continue;
978 }
979
980 /* find the corresponding flash bank */
981 if ((c = get_flash_bank_by_addr(target, run_address)) == NULL)
982 {
983 section++; /* and skip it */
984 section_offset = 0;
985 continue;
986 }
987
988 /* collect consecutive sections which fall into the same bank */
989 section_first = section;
990 section_last = section;
991 while ((run_address + run_size < c->base + c->size)
992 && (section_last + 1 < image->num_sections))
993 {
994 if (image->sections[section_last + 1].base_address < (run_address + run_size))
995 {
996 LOG_DEBUG("section %d out of order(very slightly surprising, but supported)", section_last + 1);
997 break;
998 }
999 if (image->sections[section_last + 1].base_address != (run_address + run_size))
1000 break;
1001 run_size += image->sections[++section_last].size;
1002 }
1003
1004 /* fit the run into bank constraints */
1005 if (run_address + run_size > c->base + c->size)
1006 run_size = c->base + c->size - run_address;
1007
1008 /* allocate buffer */
1009 buffer = malloc(run_size);
1010 buffer_size = 0;
1011
1012 /* read sections to the buffer */
1013 while (buffer_size < run_size)
1014 {
1015 u32 size_read;
1016
1017 if (buffer_size - run_size <= image->sections[section].size - section_offset)
1018 size_read = buffer_size - run_size;
1019 else
1020 size_read = image->sections[section].size - section_offset;
1021
1022 if ((retval = image_read_section(image, section, section_offset,
1023 size_read, buffer + buffer_size, &size_read)) != ERROR_OK || size_read == 0)
1024 {
1025 free(buffer);
1026
1027 return retval;
1028 }
1029
1030 buffer_size += size_read;
1031 section_offset += size_read;
1032
1033 if (section_offset >= image->sections[section].size)
1034 {
1035 section++;
1036 section_offset = 0;
1037 }
1038 }
1039
1040 retval = ERROR_OK;
1041
1042 if (erase)
1043 {
1044 /* calculate and erase sectors */
1045 retval = flash_erase_address_range( target, run_address, run_size );
1046 }
1047
1048 if (retval == ERROR_OK)
1049 {
1050 /* write flash sectors */
1051 retval = flash_driver_write(c, buffer, run_address - c->base, run_size);
1052 }
1053
1054 free(buffer);
1055
1056 if (retval != ERROR_OK)
1057 {
1058 return retval; /* abort operation */
1059 }
1060
1061 if (written != NULL)
1062 *written += run_size; /* add run size to total written counter */
1063 }
1064
1065 return retval;
1066 }
1067
1068 int default_flash_blank_check(struct flash_bank_s *bank)
1069 {
1070 target_t *target = bank->target;
1071 u8 buffer[1024];
1072 int buffer_size=sizeof(buffer);
1073 int i;
1074 int nBytes;
1075
1076 if (bank->target->state != TARGET_HALTED)
1077 {
1078 return ERROR_TARGET_NOT_HALTED;
1079 }
1080
1081 int retval;
1082 int fast_check=0;
1083 working_area_t *erase_check_algorithm;
1084 #if 0
1085 /* FIX! doesn't work yet... */
1086 /*
1087 char test(char *a, int len, char t)
1088 {
1089 int i=0;
1090
1091 for (i=0; i<len; i++)
1092 {
1093 t&=a[i];
1094
1095 }
1096 }
1097
1098 $ arm-elf-gcc -c -mthumb -O3 test.c
1099
1100 $ arm-elf-objdump --disassemble test.o
1101
1102 test.o: file format elf32-littlearm
1103
1104 Disassembly of section .text:
1105
1106 00000000 <test>:
1107 0: b510 push {r4, lr}
1108 2: 0612 lsl r2, r2, #24
1109 4: 1c04 mov r4, r0 (add r4, r0, #0)
1110 6: 0e10 lsr r0, r2, #24
1111 8: 2200 mov r2, #0
1112 a: 2900 cmp r1, #0
1113 c: dd04 ble 18 <test+0x18>
1114 e: 5ca3 ldrb r3, [r4, r2]
1115 10: 3201 add r2, #1
1116 12: 4018 and r0, r3
1117 14: 428a cmp r2, r1
1118 16: dbfa blt e <test+0xe>
1119 18: bd10 pop {r4, pc}
1120 1a: 46c0 nop (mov r8, r8)
1121
1122
1123 */
1124 u16 erase_check_code[] =
1125 {
1126 0x0612,// lsl r2, r2, #24
1127 0x1c04,// mov r4, r0 (add r4, r0, #0)
1128 0x0e10,// lsr r0, r2, #24
1129 0x2200,// mov r2, #0
1130 0x2900,// cmp r1, #0
1131 0xdd04,// ble 18 <test+0x18>
1132 0x5ca3,// ldrb r3, [r4, r2]
1133 0x3201,// add r2, #1
1134 0x4018,// and r0, r3
1135 0x428a,// cmp r2, r1
1136 0xdbfa,// blt e <test+0xe>
1137 0x46c0,// nop (mov r8, r8)
1138
1139 };
1140
1141
1142
1143 /* make sure we have a working area */
1144 if (target_alloc_working_area(target, ((sizeof(erase_check_code)+3)/4)*4, &erase_check_algorithm) != ERROR_OK)
1145 {
1146 erase_check_algorithm = NULL;
1147 }
1148
1149 if (erase_check_algorithm)
1150 {
1151 u8 erase_check_code_buf[((sizeof(erase_check_code)+3)/4)*4];
1152 LOG_DEBUG("Running fast flash erase check");
1153
1154 for (i = 0; i < sizeof(erase_check_code)/sizeof(*erase_check_code); i++)
1155 target_buffer_set_u16(target, erase_check_code_buf + (i*2), erase_check_code[i]);
1156
1157 /* write algorithm code to working area */
1158 if ((retval=target->type->write_memory(target, erase_check_algorithm->address, 2, sizeof(erase_check_code)/sizeof(*erase_check_code), erase_check_code_buf))==ERROR_OK)
1159 {
1160 for (i = 0; i < bank->num_sectors; i++)
1161 {
1162 u32 address = bank->base + bank->sectors[i].offset;
1163 u32 size = bank->sectors[i].size;
1164
1165 reg_param_t reg_params[3];
1166 armv7m_algorithm_t arm_info;
1167
1168 arm_info.common_magic = ARMV7M_COMMON_MAGIC;
1169 arm_info.core_mode = ARMV7M_MODE_ANY;
1170 arm_info.core_state = ARMV7M_STATE_THUMB;
1171
1172 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
1173 buf_set_u32(reg_params[0].value, 0, 32, address);
1174
1175 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
1176 buf_set_u32(reg_params[1].value, 0, 32, size);
1177
1178 init_reg_param(&reg_params[2], "r2", 32, PARAM_IN_OUT);
1179 buf_set_u32(reg_params[2].value, 0, 32, 0xff);
1180
1181 if ((retval = target->type->run_algorithm(target, 0, NULL, 3, reg_params, erase_check_algorithm->address,
1182 erase_check_algorithm->address + sizeof(erase_check_code) - 2, 10000, &arm_info)) != ERROR_OK)
1183 break;
1184
1185 if (buf_get_u32(reg_params[2].value, 0, 32) == 0xff)
1186 bank->sectors[i].is_erased = 1;
1187 else
1188 bank->sectors[i].is_erased = 0;
1189
1190 destroy_reg_param(&reg_params[0]);
1191 destroy_reg_param(&reg_params[1]);
1192 destroy_reg_param(&reg_params[2]);
1193 }
1194 if (i == bank->num_sectors)
1195 {
1196 fast_check = 1;
1197 }
1198 }
1199 target_free_working_area(target, erase_check_algorithm);
1200 }
1201 #endif
1202 if (!fast_check)
1203 {
1204 /* try ARM7 instead */
1205
1206 u32 erase_check_code[] =
1207 {
1208 0xe4d03001, /* ldrb r3, [r0], #1 */
1209 0xe0022003, /* and r2, r2, r3 */
1210 0xe2511001, /* subs r1, r1, #1 */
1211 0x1afffffb, /* b -4 */
1212 0xeafffffe /* b 0 */
1213 };
1214
1215 /* make sure we have a working area */
1216 if (target_alloc_working_area(target, 20, &erase_check_algorithm) == ERROR_OK)
1217 {
1218 u8 erase_check_code_buf[5 * 4];
1219
1220 for (i = 0; i < 5; i++)
1221 target_buffer_set_u32(target, erase_check_code_buf + (i*4), erase_check_code[i]);
1222
1223 /* write algorithm code to working area */
1224 if ((retval=target->type->write_memory(target, erase_check_algorithm->address, 4, 5, erase_check_code_buf))==ERROR_OK)
1225 {
1226 for (i = 0; i < bank->num_sectors; i++)
1227 {
1228 u32 address = bank->base + bank->sectors[i].offset;
1229 u32 size = bank->sectors[i].size;
1230
1231 reg_param_t reg_params[3];
1232 armv4_5_algorithm_t armv4_5_info;
1233
1234 armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
1235 armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
1236 armv4_5_info.core_state = ARMV4_5_STATE_ARM;
1237
1238 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
1239 buf_set_u32(reg_params[0].value, 0, 32, address);
1240
1241 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
1242 buf_set_u32(reg_params[1].value, 0, 32, size);
1243
1244 init_reg_param(&reg_params[2], "r2", 32, PARAM_IN_OUT);
1245 buf_set_u32(reg_params[2].value, 0, 32, 0xff);
1246
1247 if ((retval = target->type->run_algorithm(target, 0, NULL, 3, reg_params,
1248 erase_check_algorithm->address, erase_check_algorithm->address + 0x10, 10000, &armv4_5_info)) != ERROR_OK)
1249 break;
1250
1251 if (buf_get_u32(reg_params[2].value, 0, 32) == 0xff)
1252 bank->sectors[i].is_erased = 1;
1253 else
1254 bank->sectors[i].is_erased = 0;
1255
1256 destroy_reg_param(&reg_params[0]);
1257 destroy_reg_param(&reg_params[1]);
1258 destroy_reg_param(&reg_params[2]);
1259 }
1260 if (i == bank->num_sectors)
1261 {
1262 fast_check = 1;
1263 }
1264 }
1265 target_free_working_area(target, erase_check_algorithm);
1266 }
1267 }
1268
1269
1270 if (!fast_check)
1271 {
1272 LOG_USER("Running slow fallback erase check - add working memory");
1273 for (i = 0; i < bank->num_sectors; i++)
1274 {
1275 int j;
1276 bank->sectors[i].is_erased = 1;
1277
1278 for (j=0; j<bank->sectors[i].size; j+=buffer_size)
1279 {
1280 int chunk;
1281 int retval;
1282 chunk=buffer_size;
1283 if (chunk>(j-bank->sectors[i].size))
1284 {
1285 chunk=(j-bank->sectors[i].size);
1286 }
1287
1288 retval=target->type->read_memory(target, bank->base + bank->sectors[i].offset + j, 4, chunk/4, buffer);
1289 if (retval!=ERROR_OK)
1290 return retval;
1291
1292 for (nBytes = 0; nBytes < chunk; nBytes++)
1293 {
1294 if (buffer[nBytes] != 0xFF)
1295 {
1296 bank->sectors[i].is_erased = 0;
1297 break;
1298 }
1299 }
1300 }
1301 }
1302 }
1303
1304 return ERROR_OK;
1305 }

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)