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

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)