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

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)