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

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)