Remove FSF address from GPL notices
[openocd.git] / src / flash / nor / tcl.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de> *
3 * Copyright (C) 2007,2008 Øyvind Harboe <oyvind.harboe@zylin.com> *
4 * Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk> *
5 * Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
19 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23 #include "imp.h"
24 #include <helper/time_support.h>
25 #include <target/image.h>
26
27 /**
28 * @file
29 * Implements Tcl commands used to access NOR flash facilities.
30 */
31
32 COMMAND_HELPER(flash_command_get_bank_maybe_probe, unsigned name_index,
33 struct flash_bank **bank, bool do_probe)
34 {
35 const char *name = CMD_ARGV[name_index];
36 int retval;
37 if (do_probe) {
38 retval = get_flash_bank_by_name(name, bank);
39 } else {
40 *bank = get_flash_bank_by_name_noprobe(name);
41 retval = ERROR_OK;
42 }
43
44 if (retval != ERROR_OK)
45 return retval;
46 if (*bank)
47 return ERROR_OK;
48
49 unsigned bank_num;
50 COMMAND_PARSE_NUMBER(uint, name, bank_num);
51
52 if (do_probe) {
53 return get_flash_bank_by_num(bank_num, bank);
54 } else {
55 *bank = get_flash_bank_by_num_noprobe(bank_num);
56 retval = (bank) ? ERROR_OK : ERROR_FAIL;
57 return retval;
58 }
59 }
60
61 COMMAND_HELPER(flash_command_get_bank, unsigned name_index,
62 struct flash_bank **bank)
63 {
64 return CALL_COMMAND_HANDLER(flash_command_get_bank_maybe_probe,
65 name_index, bank, true);
66 }
67
68 COMMAND_HANDLER(handle_flash_info_command)
69 {
70 struct flash_bank *p;
71 int j = 0;
72 int retval;
73
74 if (CMD_ARGC != 1)
75 return ERROR_COMMAND_SYNTAX_ERROR;
76
77 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
78 if (retval != ERROR_OK)
79 return retval;
80
81 if (p != NULL) {
82 char buf[1024];
83
84 /* attempt auto probe */
85 retval = p->driver->auto_probe(p);
86 if (retval != ERROR_OK)
87 return retval;
88
89 /* We must query the hardware to avoid printing stale information! */
90 retval = p->driver->protect_check(p);
91 if (retval != ERROR_OK)
92 return retval;
93
94 command_print(CMD_CTX,
95 "#%d : %s at 0x%8.8" PRIx32 ", size 0x%8.8" PRIx32
96 ", buswidth %i, chipwidth %i",
97 p->bank_number,
98 p->driver->name,
99 p->base,
100 p->size,
101 p->bus_width,
102 p->chip_width);
103 for (j = 0; j < p->num_sectors; j++) {
104 char *protect_state;
105
106 if (p->sectors[j].is_protected == 0)
107 protect_state = "not protected";
108 else if (p->sectors[j].is_protected == 1)
109 protect_state = "protected";
110 else
111 protect_state = "protection state unknown";
112
113 command_print(CMD_CTX,
114 "\t#%3i: 0x%8.8" PRIx32 " (0x%" PRIx32 " %" PRIi32 "kB) %s",
115 j,
116 p->sectors[j].offset,
117 p->sectors[j].size,
118 p->sectors[j].size >> 10,
119 protect_state);
120 }
121
122 if (p->driver->info != NULL) {
123 retval = p->driver->info(p, buf, sizeof(buf));
124 if (retval == ERROR_OK)
125 command_print(CMD_CTX, "%s", buf);
126 else
127 LOG_ERROR("error retrieving flash info");
128 }
129 }
130
131 return retval;
132 }
133
134 COMMAND_HANDLER(handle_flash_probe_command)
135 {
136 struct flash_bank *p;
137 int retval;
138
139 if (CMD_ARGC != 1)
140 return ERROR_COMMAND_SYNTAX_ERROR;
141
142 retval = CALL_COMMAND_HANDLER(flash_command_get_bank_maybe_probe, 0, &p, false);
143 if (retval != ERROR_OK)
144 return retval;
145
146 if (p) {
147 retval = p->driver->probe(p);
148 if (retval == ERROR_OK)
149 command_print(CMD_CTX,
150 "flash '%s' found at 0x%8.8" PRIx32,
151 p->driver->name,
152 p->base);
153 } else {
154 command_print(CMD_CTX, "flash bank '#%s' is out of bounds", CMD_ARGV[0]);
155 retval = ERROR_FAIL;
156 }
157
158 return retval;
159 }
160
161 COMMAND_HANDLER(handle_flash_erase_check_command)
162 {
163 if (CMD_ARGC != 1)
164 return ERROR_COMMAND_SYNTAX_ERROR;
165
166 struct flash_bank *p;
167 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
168 if (ERROR_OK != retval)
169 return retval;
170
171 int j;
172 retval = p->driver->erase_check(p);
173 if (retval == ERROR_OK)
174 command_print(CMD_CTX, "successfully checked erase state");
175 else {
176 command_print(CMD_CTX,
177 "unknown error when checking erase state of flash bank #%s at 0x%8.8" PRIx32,
178 CMD_ARGV[0],
179 p->base);
180 }
181
182 for (j = 0; j < p->num_sectors; j++) {
183 char *erase_state;
184
185 if (p->sectors[j].is_erased == 0)
186 erase_state = "not erased";
187 else if (p->sectors[j].is_erased == 1)
188 erase_state = "erased";
189 else
190 erase_state = "erase state unknown";
191
192 command_print(CMD_CTX,
193 "\t#%3i: 0x%8.8" PRIx32 " (0x%" PRIx32 " %" PRIi32 "kB) %s",
194 j,
195 p->sectors[j].offset,
196 p->sectors[j].size,
197 p->sectors[j].size >> 10,
198 erase_state);
199 }
200
201 return retval;
202 }
203
204 COMMAND_HANDLER(handle_flash_erase_address_command)
205 {
206 struct flash_bank *p;
207 int retval = ERROR_OK;
208 uint32_t address;
209 uint32_t length;
210 bool do_pad = false;
211 bool do_unlock = false;
212 struct target *target = get_current_target(CMD_CTX);
213
214 while (CMD_ARGC >= 3) {
215 /* Optionally pad out the address range to block/sector
216 * boundaries. We can't know if there's data in that part
217 * of the flash; only do padding if we're told to.
218 */
219 if (strcmp("pad", CMD_ARGV[0]) == 0)
220 do_pad = true;
221 else if (strcmp("unlock", CMD_ARGV[0]) == 0)
222 do_unlock = true;
223 else
224 return ERROR_COMMAND_SYNTAX_ERROR;
225 CMD_ARGC--;
226 CMD_ARGV++;
227 }
228 if (CMD_ARGC != 2)
229 return ERROR_COMMAND_SYNTAX_ERROR;
230
231 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
232 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], length);
233
234 if (length <= 0) {
235 command_print(CMD_CTX, "Length must be >0");
236 return ERROR_COMMAND_SYNTAX_ERROR;
237 }
238
239 retval = get_flash_bank_by_addr(target, address, true, &p);
240 if (retval != ERROR_OK)
241 return retval;
242
243 /* We can't know if we did a resume + halt, in which case we no longer know the erased state
244 **/
245 flash_set_dirty();
246
247 struct duration bench;
248 duration_start(&bench);
249
250 if (do_unlock)
251 retval = flash_unlock_address_range(target, address, length);
252
253 if (retval == ERROR_OK)
254 retval = flash_erase_address_range(target, do_pad, address, length);
255
256 if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) {
257 command_print(CMD_CTX, "erased address 0x%8.8" PRIx32 " (length %" PRIi32 ")"
258 " in %fs (%0.3f KiB/s)", address, length,
259 duration_elapsed(&bench), duration_kbps(&bench, length));
260 }
261
262 return retval;
263 }
264
265 static int flash_check_sector_parameters(struct command_context *cmd_ctx,
266 uint32_t first, uint32_t last, uint32_t num_sectors)
267 {
268 if (!(first <= last)) {
269 command_print(cmd_ctx, "ERROR: "
270 "first sector must be <= last sector");
271 return ERROR_FAIL;
272 }
273
274 if (!(last <= (num_sectors - 1))) {
275 command_print(cmd_ctx, "ERROR: last sector must be <= %d",
276 (int) num_sectors - 1);
277 return ERROR_FAIL;
278 }
279
280 return ERROR_OK;
281 }
282
283 COMMAND_HANDLER(handle_flash_erase_command)
284 {
285 if (CMD_ARGC != 3)
286 return ERROR_COMMAND_SYNTAX_ERROR;
287
288 uint32_t first;
289 uint32_t last;
290
291 struct flash_bank *p;
292 int retval;
293
294 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
295 if (retval != ERROR_OK)
296 return retval;
297
298 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], first);
299 if (strcmp(CMD_ARGV[2], "last") == 0)
300 last = p->num_sectors - 1;
301 else
302 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], last);
303
304 retval = flash_check_sector_parameters(CMD_CTX, first, last, p->num_sectors);
305 if (retval != ERROR_OK)
306 return retval;
307
308 struct duration bench;
309 duration_start(&bench);
310
311 retval = flash_driver_erase(p, first, last);
312
313 if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) {
314 command_print(CMD_CTX, "erased sectors %" PRIu32 " "
315 "through %" PRIu32 " on flash bank %d "
316 "in %fs", first, last, p->bank_number, duration_elapsed(&bench));
317 }
318
319 return ERROR_OK;
320 }
321
322 COMMAND_HANDLER(handle_flash_protect_command)
323 {
324 if (CMD_ARGC != 4)
325 return ERROR_COMMAND_SYNTAX_ERROR;
326
327 uint32_t first;
328 uint32_t last;
329
330 struct flash_bank *p;
331 int retval;
332
333 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
334 if (retval != ERROR_OK)
335 return retval;
336
337 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], first);
338 if (strcmp(CMD_ARGV[2], "last") == 0)
339 last = p->num_sectors - 1;
340 else
341 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], last);
342
343 bool set;
344 COMMAND_PARSE_ON_OFF(CMD_ARGV[3], set);
345
346 retval = flash_check_sector_parameters(CMD_CTX, first, last, p->num_sectors);
347 if (retval != ERROR_OK)
348 return retval;
349
350 retval = flash_driver_protect(p, set, first, last);
351 if (retval == ERROR_OK) {
352 command_print(CMD_CTX, "%s protection for sectors %i "
353 "through %i on flash bank %d",
354 (set) ? "set" : "cleared", (int) first,
355 (int) last, p->bank_number);
356 }
357
358 return retval;
359 }
360
361 COMMAND_HANDLER(handle_flash_write_image_command)
362 {
363 struct target *target = get_current_target(CMD_CTX);
364
365 struct image image;
366 uint32_t written;
367
368 int retval;
369
370 /* flash auto-erase is disabled by default*/
371 int auto_erase = 0;
372 bool auto_unlock = false;
373
374 while (CMD_ARGC) {
375 if (strcmp(CMD_ARGV[0], "erase") == 0) {
376 auto_erase = 1;
377 CMD_ARGV++;
378 CMD_ARGC--;
379 command_print(CMD_CTX, "auto erase enabled");
380 } else if (strcmp(CMD_ARGV[0], "unlock") == 0) {
381 auto_unlock = true;
382 CMD_ARGV++;
383 CMD_ARGC--;
384 command_print(CMD_CTX, "auto unlock enabled");
385 } else
386 break;
387 }
388
389 if (CMD_ARGC < 1)
390 return ERROR_COMMAND_SYNTAX_ERROR;
391
392 if (!target) {
393 LOG_ERROR("no target selected");
394 return ERROR_FAIL;
395 }
396
397 struct duration bench;
398 duration_start(&bench);
399
400 if (CMD_ARGC >= 2) {
401 image.base_address_set = 1;
402 COMMAND_PARSE_NUMBER(llong, CMD_ARGV[1], image.base_address);
403 } else {
404 image.base_address_set = 0;
405 image.base_address = 0x0;
406 }
407
408 image.start_address_set = 0;
409
410 retval = image_open(&image, CMD_ARGV[0], (CMD_ARGC == 3) ? CMD_ARGV[2] : NULL);
411 if (retval != ERROR_OK)
412 return retval;
413
414 retval = flash_write_unlock(target, &image, &written, auto_erase, auto_unlock);
415 if (retval != ERROR_OK) {
416 image_close(&image);
417 return retval;
418 }
419
420 if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) {
421 command_print(CMD_CTX, "wrote %" PRIu32 " bytes from file %s "
422 "in %fs (%0.3f KiB/s)", written, CMD_ARGV[0],
423 duration_elapsed(&bench), duration_kbps(&bench, written));
424 }
425
426 image_close(&image);
427
428 return retval;
429 }
430
431 COMMAND_HANDLER(handle_flash_fill_command)
432 {
433 int err = ERROR_OK;
434 uint32_t address;
435 uint32_t pattern;
436 uint32_t count;
437 uint32_t wrote = 0;
438 uint32_t cur_size = 0;
439 uint32_t chunk_count;
440 struct target *target = get_current_target(CMD_CTX);
441 unsigned i;
442 uint32_t wordsize;
443 int retval = ERROR_OK;
444
445 static size_t const chunksize = 1024;
446 uint8_t *chunk = NULL, *readback = NULL;
447
448 if (CMD_ARGC != 3) {
449 retval = ERROR_COMMAND_SYNTAX_ERROR;
450 goto done;
451 }
452
453 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
454 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], pattern);
455 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], count);
456
457 chunk = malloc(chunksize);
458 if (chunk == NULL)
459 return ERROR_FAIL;
460
461 readback = malloc(chunksize);
462 if (readback == NULL) {
463 free(chunk);
464 return ERROR_FAIL;
465 }
466
467 if (count == 0)
468 goto done;
469
470 switch (CMD_NAME[4]) {
471 case 'w':
472 wordsize = 4;
473 break;
474 case 'h':
475 wordsize = 2;
476 break;
477 case 'b':
478 wordsize = 1;
479 break;
480 default:
481 retval = ERROR_COMMAND_SYNTAX_ERROR;
482 goto done;
483 }
484
485 chunk_count = MIN(count, (chunksize / wordsize));
486 switch (wordsize) {
487 case 4:
488 for (i = 0; i < chunk_count; i++)
489 target_buffer_set_u32(target, chunk + i * wordsize, pattern);
490 break;
491 case 2:
492 for (i = 0; i < chunk_count; i++)
493 target_buffer_set_u16(target, chunk + i * wordsize, pattern);
494 break;
495 case 1:
496 memset(chunk, pattern, chunk_count);
497 break;
498 default:
499 LOG_ERROR("BUG: can't happen");
500 exit(-1);
501 }
502
503 struct duration bench;
504 duration_start(&bench);
505
506 for (wrote = 0; wrote < (count*wordsize); wrote += cur_size) {
507 struct flash_bank *bank;
508
509 retval = get_flash_bank_by_addr(target, address, true, &bank);
510 if (retval != ERROR_OK)
511 goto done;
512
513 cur_size = MIN((count * wordsize - wrote), chunksize);
514 err = flash_driver_write(bank, chunk, address - bank->base + wrote, cur_size);
515 if (err != ERROR_OK) {
516 retval = err;
517 goto done;
518 }
519
520 err = flash_driver_read(bank, readback, address - bank->base + wrote, cur_size);
521 if (err != ERROR_OK) {
522 retval = err;
523 goto done;
524 }
525
526 for (i = 0; i < cur_size; i++) {
527 if (readback[i] != chunk[i]) {
528 LOG_ERROR(
529 "Verification error address 0x%08" PRIx32 ", read back 0x%02x, expected 0x%02x",
530 address + wrote + i,
531 readback[i],
532 chunk[i]);
533 retval = ERROR_FAIL;
534 goto done;
535 }
536 }
537 }
538
539 if ((retval == ERROR_OK) && (duration_measure(&bench) == ERROR_OK)) {
540 command_print(CMD_CTX, "wrote %" PRIu32 " bytes to 0x%8.8" PRIx32
541 " in %fs (%0.3f KiB/s)", wrote, address,
542 duration_elapsed(&bench), duration_kbps(&bench, wrote));
543 }
544
545 done:
546 free(readback);
547 free(chunk);
548
549 return retval;
550 }
551
552 COMMAND_HANDLER(handle_flash_write_bank_command)
553 {
554 uint32_t offset;
555 uint8_t *buffer;
556 struct fileio *fileio;
557
558 if (CMD_ARGC != 3)
559 return ERROR_COMMAND_SYNTAX_ERROR;
560
561 struct duration bench;
562 duration_start(&bench);
563
564 struct flash_bank *p;
565 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
566 if (ERROR_OK != retval)
567 return retval;
568
569 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], offset);
570
571 if (fileio_open(&fileio, CMD_ARGV[1], FILEIO_READ, FILEIO_BINARY) != ERROR_OK)
572 return ERROR_OK;
573
574 size_t filesize;
575 retval = fileio_size(fileio, &filesize);
576 if (retval != ERROR_OK) {
577 fileio_close(fileio);
578 return retval;
579 }
580
581 buffer = malloc(filesize);
582 if (buffer == NULL) {
583 fileio_close(fileio);
584 LOG_ERROR("Out of memory");
585 return ERROR_FAIL;
586 }
587 size_t buf_cnt;
588 if (fileio_read(fileio, filesize, buffer, &buf_cnt) != ERROR_OK) {
589 free(buffer);
590 fileio_close(fileio);
591 return ERROR_OK;
592 }
593
594 retval = flash_driver_write(p, buffer, offset, buf_cnt);
595
596 free(buffer);
597 buffer = NULL;
598
599 if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) {
600 command_print(CMD_CTX, "wrote %zu bytes from file %s to flash bank %u"
601 " at offset 0x%8.8" PRIx32 " in %fs (%0.3f KiB/s)",
602 filesize, CMD_ARGV[1], p->bank_number, offset,
603 duration_elapsed(&bench), duration_kbps(&bench, filesize));
604 }
605
606 fileio_close(fileio);
607
608 return retval;
609 }
610
611 COMMAND_HANDLER(handle_flash_read_bank_command)
612 {
613 uint32_t offset;
614 uint8_t *buffer;
615 struct fileio *fileio;
616 uint32_t length;
617 size_t written;
618
619 if (CMD_ARGC != 4)
620 return ERROR_COMMAND_SYNTAX_ERROR;
621
622 struct duration bench;
623 duration_start(&bench);
624
625 struct flash_bank *p;
626 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
627 if (ERROR_OK != retval)
628 return retval;
629
630 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], offset);
631 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], length);
632
633 buffer = malloc(length);
634 if (buffer == NULL) {
635 LOG_ERROR("Out of memory");
636 return ERROR_FAIL;
637 }
638
639 retval = flash_driver_read(p, buffer, offset, length);
640 if (retval != ERROR_OK) {
641 LOG_ERROR("Read error");
642 free(buffer);
643 return retval;
644 }
645
646 retval = fileio_open(&fileio, CMD_ARGV[1], FILEIO_WRITE, FILEIO_BINARY);
647 if (retval != ERROR_OK) {
648 LOG_ERROR("Could not open file");
649 free(buffer);
650 return retval;
651 }
652
653 retval = fileio_write(fileio, length, buffer, &written);
654 fileio_close(fileio);
655 free(buffer);
656 if (retval != ERROR_OK) {
657 LOG_ERROR("Could not write file");
658 return ERROR_FAIL;
659 }
660
661 if (duration_measure(&bench) == ERROR_OK)
662 command_print(CMD_CTX, "wrote %ld bytes to file %s from flash bank %u"
663 " at offset 0x%8.8" PRIx32 " in %fs (%0.3f KiB/s)",
664 (long)written, CMD_ARGV[1], p->bank_number, offset,
665 duration_elapsed(&bench), duration_kbps(&bench, written));
666
667 return retval;
668 }
669
670
671 COMMAND_HANDLER(handle_flash_verify_bank_command)
672 {
673 uint32_t offset;
674 uint8_t *buffer_file, *buffer_flash;
675 struct fileio *fileio;
676 size_t read_cnt;
677 size_t filesize;
678 int differ;
679
680 if (CMD_ARGC != 3)
681 return ERROR_COMMAND_SYNTAX_ERROR;
682
683 struct duration bench;
684 duration_start(&bench);
685
686 struct flash_bank *p;
687 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
688 if (ERROR_OK != retval)
689 return retval;
690
691 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], offset);
692
693 retval = fileio_open(&fileio, CMD_ARGV[1], FILEIO_READ, FILEIO_BINARY);
694 if (retval != ERROR_OK) {
695 LOG_ERROR("Could not open file");
696 return retval;
697 }
698
699 retval = fileio_size(fileio, &filesize);
700 if (retval != ERROR_OK) {
701 fileio_close(fileio);
702 return retval;
703 }
704
705 buffer_file = malloc(filesize);
706 if (buffer_file == NULL) {
707 LOG_ERROR("Out of memory");
708 fileio_close(fileio);
709 return ERROR_FAIL;
710 }
711
712 retval = fileio_read(fileio, filesize, buffer_file, &read_cnt);
713 fileio_close(fileio);
714 if (retval != ERROR_OK) {
715 LOG_ERROR("File read failure");
716 free(buffer_file);
717 return retval;
718 }
719
720 if (read_cnt != filesize) {
721 LOG_ERROR("Short read");
722 free(buffer_file);
723 return ERROR_FAIL;
724 }
725
726 buffer_flash = malloc(filesize);
727 if (buffer_flash == NULL) {
728 LOG_ERROR("Out of memory");
729 free(buffer_file);
730 return ERROR_FAIL;
731 }
732
733 retval = flash_driver_read(p, buffer_flash, offset, read_cnt);
734 if (retval != ERROR_OK) {
735 LOG_ERROR("Flash read error");
736 free(buffer_flash);
737 free(buffer_file);
738 return retval;
739 }
740
741 if (duration_measure(&bench) == ERROR_OK)
742 command_print(CMD_CTX, "read %ld bytes from file %s and flash bank %u"
743 " at offset 0x%8.8" PRIx32 " in %fs (%0.3f KiB/s)",
744 (long)read_cnt, CMD_ARGV[1], p->bank_number, offset,
745 duration_elapsed(&bench), duration_kbps(&bench, read_cnt));
746
747 differ = memcmp(buffer_file, buffer_flash, read_cnt);
748 command_print(CMD_CTX, "contents %s", differ ? "differ" : "match");
749 if (differ) {
750 uint32_t t;
751 int diffs = 0;
752 for (t = 0; t < read_cnt; t++) {
753 if (buffer_flash[t] == buffer_file[t])
754 continue;
755 command_print(CMD_CTX, "diff %d address 0x%08x. Was 0x%02x instead of 0x%02x",
756 diffs, t + offset, buffer_flash[t], buffer_file[t]);
757 if (diffs++ >= 127) {
758 command_print(CMD_CTX, "More than 128 errors, the rest are not printed.");
759 break;
760 }
761 keep_alive();
762 }
763 }
764 free(buffer_flash);
765 free(buffer_file);
766
767 return differ ? ERROR_FAIL : ERROR_OK;
768 }
769
770 void flash_set_dirty(void)
771 {
772 struct flash_bank *c;
773 int i;
774
775 /* set all flash to require erasing */
776 for (c = flash_bank_list(); c; c = c->next) {
777 for (i = 0; i < c->num_sectors; i++)
778 c->sectors[i].is_erased = 0;
779 }
780 }
781
782 COMMAND_HANDLER(handle_flash_padded_value_command)
783 {
784 if (CMD_ARGC != 2)
785 return ERROR_COMMAND_SYNTAX_ERROR;
786
787 struct flash_bank *p;
788 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
789 if (ERROR_OK != retval)
790 return retval;
791
792 COMMAND_PARSE_NUMBER(u8, CMD_ARGV[1], p->default_padded_value);
793
794 command_print(CMD_CTX, "Default padded value set to 0x%" PRIx8 " for flash bank %u", \
795 p->default_padded_value, p->bank_number);
796
797 return retval;
798 }
799
800 static const struct command_registration flash_exec_command_handlers[] = {
801 {
802 .name = "probe",
803 .handler = handle_flash_probe_command,
804 .mode = COMMAND_EXEC,
805 .usage = "bank_id",
806 .help = "Identify a flash bank.",
807 },
808 {
809 .name = "info",
810 .handler = handle_flash_info_command,
811 .mode = COMMAND_EXEC,
812 .usage = "bank_id",
813 .help = "Print information about a flash bank.",
814 },
815 {
816 .name = "erase_check",
817 .handler = handle_flash_erase_check_command,
818 .mode = COMMAND_EXEC,
819 .usage = "bank_id",
820 .help = "Check erase state of all blocks in a "
821 "flash bank.",
822 },
823 {
824 .name = "erase_sector",
825 .handler = handle_flash_erase_command,
826 .mode = COMMAND_EXEC,
827 .usage = "bank_id first_sector_num last_sector_num",
828 .help = "Erase a range of sectors in a flash bank.",
829 },
830 {
831 .name = "erase_address",
832 .handler = handle_flash_erase_address_command,
833 .mode = COMMAND_EXEC,
834 .usage = "['pad'] ['unlock'] address length",
835 .help = "Erase flash sectors starting at address and "
836 "continuing for length bytes. If 'pad' is specified, "
837 "data outside that range may also be erased: the start "
838 "address may be decreased, and length increased, so "
839 "that all of the first and last sectors are erased. "
840 "If 'unlock' is specified, then the flash is unprotected "
841 "before erasing.",
842
843 },
844 {
845 .name = "fillw",
846 .handler = handle_flash_fill_command,
847 .mode = COMMAND_EXEC,
848 .usage = "address value n",
849 .help = "Fill n words with 32-bit value, starting at "
850 "word address. (No autoerase.)",
851 },
852 {
853 .name = "fillh",
854 .handler = handle_flash_fill_command,
855 .mode = COMMAND_EXEC,
856 .usage = "address value n",
857 .help = "Fill n halfwords with 16-bit value, starting at "
858 "word address. (No autoerase.)",
859 },
860 {
861 .name = "fillb",
862 .handler = handle_flash_fill_command,
863 .mode = COMMAND_EXEC,
864 .usage = "address value n",
865 .help = "Fill n bytes with 8-bit value, starting at "
866 "word address. (No autoerase.)",
867 },
868 {
869 .name = "write_bank",
870 .handler = handle_flash_write_bank_command,
871 .mode = COMMAND_EXEC,
872 .usage = "bank_id filename offset",
873 .help = "Write binary data from file to flash bank, "
874 "starting at specified byte offset from the "
875 "beginning of the bank.",
876 },
877 {
878 .name = "write_image",
879 .handler = handle_flash_write_image_command,
880 .mode = COMMAND_EXEC,
881 .usage = "[erase] [unlock] filename [offset [file_type]]",
882 .help = "Write an image to flash. Optionally first unprotect "
883 "and/or erase the region to be used. Allow optional "
884 "offset from beginning of bank (defaults to zero)",
885 },
886 {
887 .name = "read_bank",
888 .handler = handle_flash_read_bank_command,
889 .mode = COMMAND_EXEC,
890 .usage = "bank_id filename offset length",
891 .help = "Read binary data from flash bank to file, "
892 "starting at specified byte offset from the "
893 "beginning of the bank.",
894 },
895 {
896 .name = "verify_bank",
897 .handler = handle_flash_verify_bank_command,
898 .mode = COMMAND_EXEC,
899 .usage = "bank_id filename offset",
900 .help = "Read binary data from flash bank and file, "
901 "starting at specified byte offset from the "
902 "beginning of the bank. Compare the contents.",
903 },
904 {
905 .name = "protect",
906 .handler = handle_flash_protect_command,
907 .mode = COMMAND_EXEC,
908 .usage = "bank_id first_sector [last_sector|'last'] "
909 "('on'|'off')",
910 .help = "Turn protection on or off for a range of sectors "
911 "in a given flash bank.",
912 },
913 {
914 .name = "padded_value",
915 .handler = handle_flash_padded_value_command,
916 .mode = COMMAND_EXEC,
917 .usage = "bank_id value",
918 .help = "Set default flash padded value",
919 },
920 COMMAND_REGISTRATION_DONE
921 };
922
923 static int flash_init_drivers(struct command_context *cmd_ctx)
924 {
925 if (!flash_bank_list())
926 return ERROR_OK;
927
928 struct command *parent = command_find_in_context(cmd_ctx, "flash");
929 return register_commands(cmd_ctx, parent, flash_exec_command_handlers);
930 }
931
932 COMMAND_HANDLER(handle_flash_bank_command)
933 {
934 if (CMD_ARGC < 7) {
935 LOG_ERROR("usage: flash bank <name> <driver> "
936 "<base> <size> <chip_width> <bus_width> <target>");
937 return ERROR_COMMAND_SYNTAX_ERROR;
938 }
939 /* save bank name and advance arguments for compatibility */
940 const char *bank_name = *CMD_ARGV++;
941 CMD_ARGC--;
942
943 struct target *target = get_target(CMD_ARGV[5]);
944 if (target == NULL) {
945 LOG_ERROR("target '%s' not defined", CMD_ARGV[5]);
946 return ERROR_FAIL;
947 }
948
949 const char *driver_name = CMD_ARGV[0];
950 struct flash_driver *driver = flash_driver_find_by_name(driver_name);
951 if (NULL == driver) {
952 /* no matching flash driver found */
953 LOG_ERROR("flash driver '%s' not found", driver_name);
954 return ERROR_FAIL;
955 }
956
957 /* check the flash bank name is unique */
958 if (get_flash_bank_by_name_noprobe(bank_name) != NULL) {
959 /* flash bank name already exists */
960 LOG_ERROR("flash bank name '%s' already exists", bank_name);
961 return ERROR_FAIL;
962 }
963
964 /* register flash specific commands */
965 if (NULL != driver->commands) {
966 int retval = register_commands(CMD_CTX, NULL,
967 driver->commands);
968 if (ERROR_OK != retval) {
969 LOG_ERROR("couldn't register '%s' commands",
970 driver_name);
971 return ERROR_FAIL;
972 }
973 }
974
975 struct flash_bank *c = malloc(sizeof(*c));
976 c->name = strdup(bank_name);
977 c->target = target;
978 c->driver = driver;
979 c->driver_priv = NULL;
980 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], c->base);
981 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], c->size);
982 COMMAND_PARSE_NUMBER(int, CMD_ARGV[3], c->chip_width);
983 COMMAND_PARSE_NUMBER(int, CMD_ARGV[4], c->bus_width);
984 c->default_padded_value = 0xff;
985 c->num_sectors = 0;
986 c->sectors = NULL;
987 c->next = NULL;
988
989 int retval;
990 retval = CALL_COMMAND_HANDLER(driver->flash_bank_command, c);
991 if (ERROR_OK != retval) {
992 LOG_ERROR("'%s' driver rejected flash bank at 0x%8.8" PRIx32 "; usage: %s",
993 driver_name, c->base, driver->usage);
994 free(c);
995 return retval;
996 }
997
998 if (driver->usage == NULL)
999 LOG_DEBUG("'%s' driver usage field missing", driver_name);
1000
1001 flash_bank_add(c);
1002
1003 return ERROR_OK;
1004 }
1005
1006 COMMAND_HANDLER(handle_flash_banks_command)
1007 {
1008 if (CMD_ARGC != 0)
1009 return ERROR_COMMAND_SYNTAX_ERROR;
1010
1011 unsigned n = 0;
1012 for (struct flash_bank *p = flash_bank_list(); p; p = p->next, n++) {
1013 LOG_USER("#%d : %s (%s) at 0x%8.8" PRIx32 ", size 0x%8.8" PRIx32 ", "
1014 "buswidth %u, chipwidth %u", p->bank_number,
1015 p->name, p->driver->name, p->base, p->size,
1016 p->bus_width, p->chip_width);
1017 }
1018 return ERROR_OK;
1019 }
1020
1021 static int jim_flash_list(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
1022 {
1023 if (argc != 1) {
1024 Jim_WrongNumArgs(interp, 1, argv,
1025 "no arguments to 'flash list' command");
1026 return JIM_ERR;
1027 }
1028
1029 Jim_Obj *list = Jim_NewListObj(interp, NULL, 0);
1030
1031 for (struct flash_bank *p = flash_bank_list(); p; p = p->next) {
1032 Jim_Obj *elem = Jim_NewListObj(interp, NULL, 0);
1033
1034 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "name", -1));
1035 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, p->driver->name, -1));
1036 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "base", -1));
1037 Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->base));
1038 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "size", -1));
1039 Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->size));
1040 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "bus_width", -1));
1041 Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->bus_width));
1042 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "chip_width", -1));
1043 Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->chip_width));
1044
1045 Jim_ListAppendElement(interp, list, elem);
1046 }
1047
1048 Jim_SetResult(interp, list);
1049
1050 return JIM_OK;
1051 }
1052
1053 COMMAND_HANDLER(handle_flash_init_command)
1054 {
1055 if (CMD_ARGC != 0)
1056 return ERROR_COMMAND_SYNTAX_ERROR;
1057
1058 static bool flash_initialized;
1059 if (flash_initialized) {
1060 LOG_INFO("'flash init' has already been called");
1061 return ERROR_OK;
1062 }
1063 flash_initialized = true;
1064
1065 LOG_DEBUG("Initializing flash devices...");
1066 return flash_init_drivers(CMD_CTX);
1067 }
1068
1069 static const struct command_registration flash_config_command_handlers[] = {
1070 {
1071 .name = "bank",
1072 .handler = handle_flash_bank_command,
1073 .mode = COMMAND_CONFIG,
1074 .usage = "bank_id driver_name base_address size_bytes "
1075 "chip_width_bytes bus_width_bytes target "
1076 "[driver_options ...]",
1077 .help = "Define a new bank with the given name, "
1078 "using the specified NOR flash driver.",
1079 },
1080 {
1081 .name = "init",
1082 .mode = COMMAND_CONFIG,
1083 .handler = handle_flash_init_command,
1084 .help = "Initialize flash devices.",
1085 },
1086 {
1087 .name = "banks",
1088 .mode = COMMAND_ANY,
1089 .handler = handle_flash_banks_command,
1090 .help = "Display table with information about flash banks.",
1091 },
1092 {
1093 .name = "list",
1094 .mode = COMMAND_ANY,
1095 .jim_handler = jim_flash_list,
1096 .help = "Returns a list of details about the flash banks.",
1097 },
1098 COMMAND_REGISTRATION_DONE
1099 };
1100 static const struct command_registration flash_command_handlers[] = {
1101 {
1102 .name = "flash",
1103 .mode = COMMAND_ANY,
1104 .help = "NOR flash command group",
1105 .chain = flash_config_command_handlers,
1106 },
1107 COMMAND_REGISTRATION_DONE
1108 };
1109
1110 int flash_register_commands(struct command_context *cmd_ctx)
1111 {
1112 return register_commands(cmd_ctx, NULL, flash_command_handlers);
1113 }

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)