0b72a1232d5246b5fc54dcb39b006b40fae516f0
[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 <= %d",
301 (int) 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 %i "
384 "through %i on flash bank %d",
385 (set) ? "set" : "cleared", (int) first,
386 (int) last, p->bank_number);
387 }
388
389 return retval;
390 }
391
392 COMMAND_HANDLER(handle_flash_write_image_command)
393 {
394 struct target *target = get_current_target(CMD_CTX);
395
396 struct image image;
397 uint32_t written;
398
399 int retval;
400
401 /* flash auto-erase is disabled by default*/
402 int auto_erase = 0;
403 bool auto_unlock = false;
404
405 while (CMD_ARGC) {
406 if (strcmp(CMD_ARGV[0], "erase") == 0) {
407 auto_erase = 1;
408 CMD_ARGV++;
409 CMD_ARGC--;
410 command_print(CMD_CTX, "auto erase enabled");
411 } else if (strcmp(CMD_ARGV[0], "unlock") == 0) {
412 auto_unlock = true;
413 CMD_ARGV++;
414 CMD_ARGC--;
415 command_print(CMD_CTX, "auto unlock enabled");
416 } else
417 break;
418 }
419
420 if (CMD_ARGC < 1)
421 return ERROR_COMMAND_SYNTAX_ERROR;
422
423 if (!target) {
424 LOG_ERROR("no target selected");
425 return ERROR_FAIL;
426 }
427
428 struct duration bench;
429 duration_start(&bench);
430
431 if (CMD_ARGC >= 2) {
432 image.base_address_set = 1;
433 COMMAND_PARSE_NUMBER(llong, CMD_ARGV[1], image.base_address);
434 } else {
435 image.base_address_set = 0;
436 image.base_address = 0x0;
437 }
438
439 image.start_address_set = 0;
440
441 retval = image_open(&image, CMD_ARGV[0], (CMD_ARGC == 3) ? CMD_ARGV[2] : NULL);
442 if (retval != ERROR_OK)
443 return retval;
444
445 retval = flash_write_unlock(target, &image, &written, auto_erase, auto_unlock);
446 if (retval != ERROR_OK) {
447 image_close(&image);
448 return retval;
449 }
450
451 if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) {
452 command_print(CMD_CTX, "wrote %" PRIu32 " bytes from file %s "
453 "in %fs (%0.3f KiB/s)", written, CMD_ARGV[0],
454 duration_elapsed(&bench), duration_kbps(&bench, written));
455 }
456
457 image_close(&image);
458
459 return retval;
460 }
461
462 COMMAND_HANDLER(handle_flash_fill_command)
463 {
464 int err = ERROR_OK;
465 uint32_t address;
466 uint32_t pattern;
467 uint32_t count;
468 uint32_t wrote = 0;
469 uint32_t cur_size = 0;
470 uint32_t chunk_count;
471 struct target *target = get_current_target(CMD_CTX);
472 unsigned i;
473 uint32_t wordsize;
474 int retval = ERROR_OK;
475
476 static size_t const chunksize = 1024;
477 uint8_t *chunk = NULL, *readback = NULL;
478
479 if (CMD_ARGC != 3) {
480 retval = ERROR_COMMAND_SYNTAX_ERROR;
481 goto done;
482 }
483
484 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
485 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], pattern);
486 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], count);
487
488 chunk = malloc(chunksize);
489 if (chunk == NULL)
490 return ERROR_FAIL;
491
492 readback = malloc(chunksize);
493 if (readback == NULL) {
494 free(chunk);
495 return ERROR_FAIL;
496 }
497
498 if (count == 0)
499 goto done;
500
501 switch (CMD_NAME[4]) {
502 case 'w':
503 wordsize = 4;
504 break;
505 case 'h':
506 wordsize = 2;
507 break;
508 case 'b':
509 wordsize = 1;
510 break;
511 default:
512 retval = ERROR_COMMAND_SYNTAX_ERROR;
513 goto done;
514 }
515
516 chunk_count = MIN(count, (chunksize / wordsize));
517 switch (wordsize) {
518 case 4:
519 for (i = 0; i < chunk_count; i++)
520 target_buffer_set_u32(target, chunk + i * wordsize, pattern);
521 break;
522 case 2:
523 for (i = 0; i < chunk_count; i++)
524 target_buffer_set_u16(target, chunk + i * wordsize, pattern);
525 break;
526 case 1:
527 memset(chunk, pattern, chunk_count);
528 break;
529 default:
530 LOG_ERROR("BUG: can't happen");
531 exit(-1);
532 }
533
534 struct duration bench;
535 duration_start(&bench);
536
537 for (wrote = 0; wrote < (count*wordsize); wrote += cur_size) {
538 struct flash_bank *bank;
539
540 retval = get_flash_bank_by_addr(target, address, true, &bank);
541 if (retval != ERROR_OK)
542 goto done;
543
544 cur_size = MIN((count * wordsize - wrote), chunksize);
545 err = flash_driver_write(bank, chunk, address - bank->base + wrote, cur_size);
546 if (err != ERROR_OK) {
547 retval = err;
548 goto done;
549 }
550
551 err = flash_driver_read(bank, readback, address - bank->base + wrote, cur_size);
552 if (err != ERROR_OK) {
553 retval = err;
554 goto done;
555 }
556
557 for (i = 0; i < cur_size; i++) {
558 if (readback[i] != chunk[i]) {
559 LOG_ERROR(
560 "Verification error address 0x%08" PRIx32 ", read back 0x%02x, expected 0x%02x",
561 address + wrote + i,
562 readback[i],
563 chunk[i]);
564 retval = ERROR_FAIL;
565 goto done;
566 }
567 }
568 }
569
570 if ((retval == ERROR_OK) && (duration_measure(&bench) == ERROR_OK)) {
571 command_print(CMD_CTX, "wrote %" PRIu32 " bytes to 0x%8.8" PRIx32
572 " in %fs (%0.3f KiB/s)", wrote, address,
573 duration_elapsed(&bench), duration_kbps(&bench, wrote));
574 }
575
576 done:
577 free(readback);
578 free(chunk);
579
580 return retval;
581 }
582
583 COMMAND_HANDLER(handle_flash_write_bank_command)
584 {
585 uint32_t offset;
586 uint8_t *buffer;
587 struct fileio *fileio;
588
589 if (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 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], offset);
601
602 if (fileio_open(&fileio, CMD_ARGV[1], FILEIO_READ, FILEIO_BINARY) != ERROR_OK)
603 return ERROR_FAIL;
604
605 size_t filesize;
606 retval = fileio_size(fileio, &filesize);
607 if (retval != ERROR_OK) {
608 fileio_close(fileio);
609 return retval;
610 }
611
612 buffer = malloc(filesize);
613 if (buffer == NULL) {
614 fileio_close(fileio);
615 LOG_ERROR("Out of memory");
616 return ERROR_FAIL;
617 }
618 size_t buf_cnt;
619 if (fileio_read(fileio, filesize, buffer, &buf_cnt) != ERROR_OK) {
620 free(buffer);
621 fileio_close(fileio);
622 return ERROR_FAIL;
623 }
624
625 retval = flash_driver_write(p, buffer, offset, buf_cnt);
626
627 free(buffer);
628 buffer = NULL;
629
630 if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) {
631 command_print(CMD_CTX, "wrote %zu bytes from file %s to flash bank %u"
632 " at offset 0x%8.8" PRIx32 " in %fs (%0.3f KiB/s)",
633 filesize, CMD_ARGV[1], p->bank_number, offset,
634 duration_elapsed(&bench), duration_kbps(&bench, filesize));
635 }
636
637 fileio_close(fileio);
638
639 return retval;
640 }
641
642 COMMAND_HANDLER(handle_flash_read_bank_command)
643 {
644 uint32_t offset;
645 uint8_t *buffer;
646 struct fileio *fileio;
647 uint32_t length;
648 size_t written;
649
650 if (CMD_ARGC != 4)
651 return ERROR_COMMAND_SYNTAX_ERROR;
652
653 struct duration bench;
654 duration_start(&bench);
655
656 struct flash_bank *p;
657 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
658 if (ERROR_OK != retval)
659 return retval;
660
661 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], offset);
662 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], length);
663
664 buffer = malloc(length);
665 if (buffer == NULL) {
666 LOG_ERROR("Out of memory");
667 return ERROR_FAIL;
668 }
669
670 retval = flash_driver_read(p, buffer, offset, length);
671 if (retval != ERROR_OK) {
672 LOG_ERROR("Read error");
673 free(buffer);
674 return retval;
675 }
676
677 retval = fileio_open(&fileio, CMD_ARGV[1], FILEIO_WRITE, FILEIO_BINARY);
678 if (retval != ERROR_OK) {
679 LOG_ERROR("Could not open file");
680 free(buffer);
681 return retval;
682 }
683
684 retval = fileio_write(fileio, length, buffer, &written);
685 fileio_close(fileio);
686 free(buffer);
687 if (retval != ERROR_OK) {
688 LOG_ERROR("Could not write file");
689 return ERROR_FAIL;
690 }
691
692 if (duration_measure(&bench) == ERROR_OK)
693 command_print(CMD_CTX, "wrote %ld bytes to file %s from flash bank %u"
694 " at offset 0x%8.8" PRIx32 " in %fs (%0.3f KiB/s)",
695 (long)written, CMD_ARGV[1], p->bank_number, offset,
696 duration_elapsed(&bench), duration_kbps(&bench, written));
697
698 return retval;
699 }
700
701
702 COMMAND_HANDLER(handle_flash_verify_bank_command)
703 {
704 uint32_t offset;
705 uint8_t *buffer_file, *buffer_flash;
706 struct fileio *fileio;
707 size_t read_cnt;
708 size_t filesize;
709 int differ;
710
711 if (CMD_ARGC != 3)
712 return ERROR_COMMAND_SYNTAX_ERROR;
713
714 struct duration bench;
715 duration_start(&bench);
716
717 struct flash_bank *p;
718 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
719 if (ERROR_OK != retval)
720 return retval;
721
722 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], offset);
723
724 retval = fileio_open(&fileio, CMD_ARGV[1], FILEIO_READ, FILEIO_BINARY);
725 if (retval != ERROR_OK) {
726 LOG_ERROR("Could not open file");
727 return retval;
728 }
729
730 retval = fileio_size(fileio, &filesize);
731 if (retval != ERROR_OK) {
732 fileio_close(fileio);
733 return retval;
734 }
735
736 buffer_file = malloc(filesize);
737 if (buffer_file == NULL) {
738 LOG_ERROR("Out of memory");
739 fileio_close(fileio);
740 return ERROR_FAIL;
741 }
742
743 retval = fileio_read(fileio, filesize, buffer_file, &read_cnt);
744 fileio_close(fileio);
745 if (retval != ERROR_OK) {
746 LOG_ERROR("File read failure");
747 free(buffer_file);
748 return retval;
749 }
750
751 if (read_cnt != filesize) {
752 LOG_ERROR("Short read");
753 free(buffer_file);
754 return ERROR_FAIL;
755 }
756
757 buffer_flash = malloc(filesize);
758 if (buffer_flash == NULL) {
759 LOG_ERROR("Out of memory");
760 free(buffer_file);
761 return ERROR_FAIL;
762 }
763
764 retval = flash_driver_read(p, buffer_flash, offset, read_cnt);
765 if (retval != ERROR_OK) {
766 LOG_ERROR("Flash read error");
767 free(buffer_flash);
768 free(buffer_file);
769 return retval;
770 }
771
772 if (duration_measure(&bench) == ERROR_OK)
773 command_print(CMD_CTX, "read %ld bytes from file %s and flash bank %u"
774 " at offset 0x%8.8" PRIx32 " in %fs (%0.3f KiB/s)",
775 (long)read_cnt, CMD_ARGV[1], p->bank_number, offset,
776 duration_elapsed(&bench), duration_kbps(&bench, read_cnt));
777
778 differ = memcmp(buffer_file, buffer_flash, read_cnt);
779 command_print(CMD_CTX, "contents %s", differ ? "differ" : "match");
780 if (differ) {
781 uint32_t t;
782 int diffs = 0;
783 for (t = 0; t < read_cnt; t++) {
784 if (buffer_flash[t] == buffer_file[t])
785 continue;
786 command_print(CMD_CTX, "diff %d address 0x%08x. Was 0x%02x instead of 0x%02x",
787 diffs, t + offset, buffer_flash[t], buffer_file[t]);
788 if (diffs++ >= 127) {
789 command_print(CMD_CTX, "More than 128 errors, the rest are not printed.");
790 break;
791 }
792 keep_alive();
793 }
794 }
795 free(buffer_flash);
796 free(buffer_file);
797
798 return differ ? ERROR_FAIL : ERROR_OK;
799 }
800
801 void flash_set_dirty(void)
802 {
803 struct flash_bank *c;
804 int i;
805
806 /* set all flash to require erasing */
807 for (c = flash_bank_list(); c; c = c->next) {
808 for (i = 0; i < c->num_sectors; i++)
809 c->sectors[i].is_erased = 0;
810 }
811 }
812
813 COMMAND_HANDLER(handle_flash_padded_value_command)
814 {
815 if (CMD_ARGC != 2)
816 return ERROR_COMMAND_SYNTAX_ERROR;
817
818 struct flash_bank *p;
819 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
820 if (ERROR_OK != retval)
821 return retval;
822
823 COMMAND_PARSE_NUMBER(u8, CMD_ARGV[1], p->default_padded_value);
824
825 command_print(CMD_CTX, "Default padded value set to 0x%" PRIx8 " for flash bank %u", \
826 p->default_padded_value, p->bank_number);
827
828 return retval;
829 }
830
831 static const struct command_registration flash_exec_command_handlers[] = {
832 {
833 .name = "probe",
834 .handler = handle_flash_probe_command,
835 .mode = COMMAND_EXEC,
836 .usage = "bank_id",
837 .help = "Identify a flash bank.",
838 },
839 {
840 .name = "info",
841 .handler = handle_flash_info_command,
842 .mode = COMMAND_EXEC,
843 .usage = "bank_id ['sectors']",
844 .help = "Print information about a flash bank.",
845 },
846 {
847 .name = "erase_check",
848 .handler = handle_flash_erase_check_command,
849 .mode = COMMAND_EXEC,
850 .usage = "bank_id",
851 .help = "Check erase state of all blocks in a "
852 "flash bank.",
853 },
854 {
855 .name = "erase_sector",
856 .handler = handle_flash_erase_command,
857 .mode = COMMAND_EXEC,
858 .usage = "bank_id first_sector_num last_sector_num",
859 .help = "Erase a range of sectors in a flash bank.",
860 },
861 {
862 .name = "erase_address",
863 .handler = handle_flash_erase_address_command,
864 .mode = COMMAND_EXEC,
865 .usage = "['pad'] ['unlock'] address length",
866 .help = "Erase flash sectors starting at address and "
867 "continuing for length bytes. If 'pad' is specified, "
868 "data outside that range may also be erased: the start "
869 "address may be decreased, and length increased, so "
870 "that all of the first and last sectors are erased. "
871 "If 'unlock' is specified, then the flash is unprotected "
872 "before erasing.",
873
874 },
875 {
876 .name = "fillw",
877 .handler = handle_flash_fill_command,
878 .mode = COMMAND_EXEC,
879 .usage = "address value n",
880 .help = "Fill n words with 32-bit value, starting at "
881 "word address. (No autoerase.)",
882 },
883 {
884 .name = "fillh",
885 .handler = handle_flash_fill_command,
886 .mode = COMMAND_EXEC,
887 .usage = "address value n",
888 .help = "Fill n halfwords with 16-bit value, starting at "
889 "word address. (No autoerase.)",
890 },
891 {
892 .name = "fillb",
893 .handler = handle_flash_fill_command,
894 .mode = COMMAND_EXEC,
895 .usage = "address value n",
896 .help = "Fill n bytes with 8-bit value, starting at "
897 "word address. (No autoerase.)",
898 },
899 {
900 .name = "write_bank",
901 .handler = handle_flash_write_bank_command,
902 .mode = COMMAND_EXEC,
903 .usage = "bank_id filename offset",
904 .help = "Write binary data from file to flash bank, "
905 "starting at specified byte offset from the "
906 "beginning of the bank.",
907 },
908 {
909 .name = "write_image",
910 .handler = handle_flash_write_image_command,
911 .mode = COMMAND_EXEC,
912 .usage = "[erase] [unlock] filename [offset [file_type]]",
913 .help = "Write an image to flash. Optionally first unprotect "
914 "and/or erase the region to be used. Allow optional "
915 "offset from beginning of bank (defaults to zero)",
916 },
917 {
918 .name = "read_bank",
919 .handler = handle_flash_read_bank_command,
920 .mode = COMMAND_EXEC,
921 .usage = "bank_id filename offset length",
922 .help = "Read binary data from flash bank to file, "
923 "starting at specified byte offset from the "
924 "beginning of the bank.",
925 },
926 {
927 .name = "verify_bank",
928 .handler = handle_flash_verify_bank_command,
929 .mode = COMMAND_EXEC,
930 .usage = "bank_id filename offset",
931 .help = "Read binary data from flash bank and file, "
932 "starting at specified byte offset from the "
933 "beginning of the bank. Compare the contents.",
934 },
935 {
936 .name = "protect",
937 .handler = handle_flash_protect_command,
938 .mode = COMMAND_EXEC,
939 .usage = "bank_id first_block [last_block|'last'] "
940 "('on'|'off')",
941 .help = "Turn protection on or off for a range of protection "
942 "blocks or sectors in a given flash bank. "
943 "See 'flash info' output for a list of blocks.",
944 },
945 {
946 .name = "padded_value",
947 .handler = handle_flash_padded_value_command,
948 .mode = COMMAND_EXEC,
949 .usage = "bank_id value",
950 .help = "Set default flash padded value",
951 },
952 COMMAND_REGISTRATION_DONE
953 };
954
955 static int flash_init_drivers(struct command_context *cmd_ctx)
956 {
957 if (!flash_bank_list())
958 return ERROR_OK;
959
960 struct command *parent = command_find_in_context(cmd_ctx, "flash");
961 return register_commands(cmd_ctx, parent, flash_exec_command_handlers);
962 }
963
964 COMMAND_HANDLER(handle_flash_bank_command)
965 {
966 if (CMD_ARGC < 7) {
967 LOG_ERROR("usage: flash bank <name> <driver> "
968 "<base> <size> <chip_width> <bus_width> <target>");
969 return ERROR_COMMAND_SYNTAX_ERROR;
970 }
971 /* save bank name and advance arguments for compatibility */
972 const char *bank_name = *CMD_ARGV++;
973 CMD_ARGC--;
974
975 struct target *target = get_target(CMD_ARGV[5]);
976 if (target == NULL) {
977 LOG_ERROR("target '%s' not defined", CMD_ARGV[5]);
978 return ERROR_FAIL;
979 }
980
981 const char *driver_name = CMD_ARGV[0];
982 struct flash_driver *driver = flash_driver_find_by_name(driver_name);
983 if (NULL == driver) {
984 /* no matching flash driver found */
985 LOG_ERROR("flash driver '%s' not found", driver_name);
986 return ERROR_FAIL;
987 }
988
989 /* check the flash bank name is unique */
990 if (get_flash_bank_by_name_noprobe(bank_name) != NULL) {
991 /* flash bank name already exists */
992 LOG_ERROR("flash bank name '%s' already exists", bank_name);
993 return ERROR_FAIL;
994 }
995
996 /* register flash specific commands */
997 if (NULL != driver->commands) {
998 int retval = register_commands(CMD_CTX, NULL,
999 driver->commands);
1000 if (ERROR_OK != retval) {
1001 LOG_ERROR("couldn't register '%s' commands",
1002 driver_name);
1003 return ERROR_FAIL;
1004 }
1005 }
1006
1007 struct flash_bank *c = malloc(sizeof(*c));
1008 c->name = strdup(bank_name);
1009 c->target = target;
1010 c->driver = driver;
1011 c->driver_priv = NULL;
1012 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], c->base);
1013 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], c->size);
1014 COMMAND_PARSE_NUMBER(int, CMD_ARGV[3], c->chip_width);
1015 COMMAND_PARSE_NUMBER(int, CMD_ARGV[4], c->bus_width);
1016 c->default_padded_value = c->erased_value = 0xff;
1017 c->num_sectors = 0;
1018 c->sectors = NULL;
1019 c->num_prot_blocks = 0;
1020 c->prot_blocks = NULL;
1021 c->next = NULL;
1022
1023 int retval;
1024 retval = CALL_COMMAND_HANDLER(driver->flash_bank_command, c);
1025 if (ERROR_OK != retval) {
1026 LOG_ERROR("'%s' driver rejected flash bank at 0x%8.8" PRIx32 "; usage: %s",
1027 driver_name, c->base, driver->usage);
1028 free(c);
1029 return retval;
1030 }
1031
1032 if (driver->usage == NULL)
1033 LOG_DEBUG("'%s' driver usage field missing", driver_name);
1034
1035 flash_bank_add(c);
1036
1037 return ERROR_OK;
1038 }
1039
1040 COMMAND_HANDLER(handle_flash_banks_command)
1041 {
1042 if (CMD_ARGC != 0)
1043 return ERROR_COMMAND_SYNTAX_ERROR;
1044
1045 unsigned n = 0;
1046 for (struct flash_bank *p = flash_bank_list(); p; p = p->next, n++) {
1047 LOG_USER("#%d : %s (%s) at 0x%8.8" PRIx32 ", size 0x%8.8" PRIx32 ", "
1048 "buswidth %u, chipwidth %u", p->bank_number,
1049 p->name, p->driver->name, p->base, p->size,
1050 p->bus_width, p->chip_width);
1051 }
1052 return ERROR_OK;
1053 }
1054
1055 static int jim_flash_list(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
1056 {
1057 if (argc != 1) {
1058 Jim_WrongNumArgs(interp, 1, argv,
1059 "no arguments to 'flash list' command");
1060 return JIM_ERR;
1061 }
1062
1063 Jim_Obj *list = Jim_NewListObj(interp, NULL, 0);
1064
1065 for (struct flash_bank *p = flash_bank_list(); p; p = p->next) {
1066 Jim_Obj *elem = Jim_NewListObj(interp, NULL, 0);
1067
1068 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "name", -1));
1069 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, p->driver->name, -1));
1070 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "base", -1));
1071 Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->base));
1072 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "size", -1));
1073 Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->size));
1074 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "bus_width", -1));
1075 Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->bus_width));
1076 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "chip_width", -1));
1077 Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->chip_width));
1078
1079 Jim_ListAppendElement(interp, list, elem);
1080 }
1081
1082 Jim_SetResult(interp, list);
1083
1084 return JIM_OK;
1085 }
1086
1087 COMMAND_HANDLER(handle_flash_init_command)
1088 {
1089 if (CMD_ARGC != 0)
1090 return ERROR_COMMAND_SYNTAX_ERROR;
1091
1092 static bool flash_initialized;
1093 if (flash_initialized) {
1094 LOG_INFO("'flash init' has already been called");
1095 return ERROR_OK;
1096 }
1097 flash_initialized = true;
1098
1099 LOG_DEBUG("Initializing flash devices...");
1100 return flash_init_drivers(CMD_CTX);
1101 }
1102
1103 static const struct command_registration flash_config_command_handlers[] = {
1104 {
1105 .name = "bank",
1106 .handler = handle_flash_bank_command,
1107 .mode = COMMAND_CONFIG,
1108 .usage = "bank_id driver_name base_address size_bytes "
1109 "chip_width_bytes bus_width_bytes target "
1110 "[driver_options ...]",
1111 .help = "Define a new bank with the given name, "
1112 "using the specified NOR flash driver.",
1113 },
1114 {
1115 .name = "init",
1116 .mode = COMMAND_CONFIG,
1117 .handler = handle_flash_init_command,
1118 .help = "Initialize flash devices.",
1119 },
1120 {
1121 .name = "banks",
1122 .mode = COMMAND_ANY,
1123 .handler = handle_flash_banks_command,
1124 .help = "Display table with information about flash banks.",
1125 },
1126 {
1127 .name = "list",
1128 .mode = COMMAND_ANY,
1129 .jim_handler = jim_flash_list,
1130 .help = "Returns a list of details about the flash banks.",
1131 },
1132 COMMAND_REGISTRATION_DONE
1133 };
1134 static const struct command_registration flash_command_handlers[] = {
1135 {
1136 .name = "flash",
1137 .mode = COMMAND_ANY,
1138 .help = "NOR flash command group",
1139 .chain = flash_config_command_handlers,
1140 },
1141 COMMAND_REGISTRATION_DONE
1142 };
1143
1144 int flash_register_commands(struct command_context *cmd_ctx)
1145 {
1146 return register_commands(cmd_ctx, NULL, flash_command_handlers);
1147 }

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)