flash/nor/virtual: copy missing fields from master flash_bank structure
[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 static int flash_check_sector_parameters(struct command_context *cmd_ctx,
292 uint32_t first, uint32_t last, uint32_t num_sectors)
293 {
294 if (!(first <= last)) {
295 command_print(cmd_ctx, "ERROR: "
296 "first sector must be <= last sector");
297 return ERROR_FAIL;
298 }
299
300 if (!(last <= (num_sectors - 1))) {
301 command_print(cmd_ctx, "ERROR: last sector must be <= %" PRIu32,
302 num_sectors - 1);
303 return ERROR_FAIL;
304 }
305
306 return ERROR_OK;
307 }
308
309 COMMAND_HANDLER(handle_flash_erase_command)
310 {
311 if (CMD_ARGC != 3)
312 return ERROR_COMMAND_SYNTAX_ERROR;
313
314 uint32_t first;
315 uint32_t last;
316
317 struct flash_bank *p;
318 int retval;
319
320 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
321 if (retval != ERROR_OK)
322 return retval;
323
324 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], first);
325 if (strcmp(CMD_ARGV[2], "last") == 0)
326 last = p->num_sectors - 1;
327 else
328 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], last);
329
330 retval = flash_check_sector_parameters(CMD_CTX, first, last, p->num_sectors);
331 if (retval != ERROR_OK)
332 return retval;
333
334 struct duration bench;
335 duration_start(&bench);
336
337 retval = flash_driver_erase(p, first, last);
338
339 if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) {
340 command_print(CMD_CTX, "erased sectors %" PRIu32 " "
341 "through %" PRIu32 " on flash bank %d "
342 "in %fs", first, last, p->bank_number, duration_elapsed(&bench));
343 }
344
345 return retval;
346 }
347
348 COMMAND_HANDLER(handle_flash_protect_command)
349 {
350 if (CMD_ARGC != 4)
351 return ERROR_COMMAND_SYNTAX_ERROR;
352
353 uint32_t first;
354 uint32_t last;
355
356 struct flash_bank *p;
357 int retval;
358 int num_blocks;
359
360 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
361 if (retval != ERROR_OK)
362 return retval;
363
364 if (p->num_prot_blocks)
365 num_blocks = p->num_prot_blocks;
366 else
367 num_blocks = p->num_sectors;
368
369 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], first);
370 if (strcmp(CMD_ARGV[2], "last") == 0)
371 last = num_blocks - 1;
372 else
373 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], last);
374
375 bool set;
376 COMMAND_PARSE_ON_OFF(CMD_ARGV[3], set);
377
378 retval = flash_check_sector_parameters(CMD_CTX, first, last, num_blocks);
379 if (retval != ERROR_OK)
380 return retval;
381
382 retval = flash_driver_protect(p, set, first, last);
383 if (retval == ERROR_OK) {
384 command_print(CMD_CTX, "%s protection for sectors %" PRIu32
385 " through %" PRIu32 " on flash bank %d",
386 (set) ? "set" : "cleared", first, 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 target_addr_t address;
465 uint32_t pattern;
466 uint32_t count;
467 struct target *target = get_current_target(CMD_CTX);
468 unsigned i;
469 uint32_t wordsize;
470 int retval;
471
472 if (CMD_ARGC != 3)
473 return ERROR_COMMAND_SYNTAX_ERROR;
474
475 #if BUILD_TARGET64
476 COMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], address);
477 #else
478 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
479 #endif
480 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], pattern);
481 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], count);
482
483 struct flash_bank *bank;
484 retval = get_flash_bank_by_addr(target, address, true, &bank);
485 if (retval != ERROR_OK)
486 return retval;
487
488 switch (CMD_NAME[4]) {
489 case 'w':
490 wordsize = 4;
491 break;
492 case 'h':
493 wordsize = 2;
494 break;
495 case 'b':
496 wordsize = 1;
497 break;
498 default:
499 return ERROR_COMMAND_SYNTAX_ERROR;
500 }
501
502 if (count == 0)
503 return ERROR_OK;
504
505 if (address + count >= bank->base + bank->size) {
506 LOG_ERROR("Cannot cross flash bank borders");
507 return ERROR_FAIL;
508 }
509
510 uint32_t size_bytes = count * wordsize;
511 target_addr_t aligned_start = flash_write_align_start(bank, address);
512 target_addr_t end_addr = address + size_bytes - 1;
513 target_addr_t aligned_end = flash_write_align_end(bank, end_addr);
514 uint32_t aligned_size = aligned_end + 1 - aligned_start;
515 uint32_t padding_at_start = address - aligned_start;
516 uint32_t padding_at_end = aligned_end - end_addr;
517
518 uint8_t *buffer = malloc(aligned_size);
519 if (buffer == NULL)
520 return ERROR_FAIL;
521
522 if (padding_at_start) {
523 memset(buffer, bank->default_padded_value, padding_at_start);
524 LOG_WARNING("Start address " TARGET_ADDR_FMT
525 " breaks the required alignment of flash bank %s",
526 address, bank->name);
527 LOG_WARNING("Padding %" PRId32 " bytes from " TARGET_ADDR_FMT,
528 padding_at_start, aligned_start);
529 }
530
531 uint8_t *ptr = buffer + padding_at_start;
532
533 switch (wordsize) {
534 case 4:
535 for (i = 0; i < count; i++, ptr += wordsize)
536 target_buffer_set_u32(target, ptr, pattern);
537 break;
538 case 2:
539 for (i = 0; i < count; i++, ptr += wordsize)
540 target_buffer_set_u16(target, ptr, pattern);
541 break;
542 case 1:
543 memset(ptr, pattern, count);
544 ptr += count;
545 break;
546 default:
547 LOG_ERROR("BUG: can't happen");
548 exit(-1);
549 }
550
551 if (padding_at_end) {
552 memset(ptr, bank->default_padded_value, padding_at_end);
553 LOG_INFO("Padding at " TARGET_ADDR_FMT " with %" PRId32
554 " bytes (bank write end alignment)",
555 end_addr + 1, padding_at_end);
556 }
557
558 struct duration bench;
559 duration_start(&bench);
560
561 retval = flash_driver_write(bank, buffer, aligned_start - bank->base, aligned_size);
562 if (retval != ERROR_OK)
563 goto done;
564
565 retval = flash_driver_read(bank, buffer, address - bank->base, size_bytes);
566 if (retval != ERROR_OK)
567 goto done;
568
569 for (i = 0, ptr = buffer; i < count; i++) {
570 uint32_t readback = 0;
571
572 switch (wordsize) {
573 case 4:
574 readback = target_buffer_get_u32(target, ptr);
575 break;
576 case 2:
577 readback = target_buffer_get_u16(target, ptr);
578 break;
579 case 1:
580 readback = *ptr;
581 break;
582 }
583 if (readback != pattern) {
584 LOG_ERROR(
585 "Verification error address " TARGET_ADDR_FMT
586 ", read back 0x%02" PRIx32 ", expected 0x%02" PRIx32,
587 address + i * wordsize, readback, pattern);
588 retval = ERROR_FAIL;
589 goto done;
590 }
591 ptr += wordsize;
592 }
593
594 if ((retval == ERROR_OK) && (duration_measure(&bench) == ERROR_OK)) {
595 command_print(CMD_CTX, "wrote %" PRIu32 " bytes to " TARGET_ADDR_FMT
596 " in %fs (%0.3f KiB/s)", size_bytes, address,
597 duration_elapsed(&bench), duration_kbps(&bench, size_bytes));
598 }
599
600 done:
601 free(buffer);
602
603 return retval;
604 }
605
606 COMMAND_HANDLER(handle_flash_write_bank_command)
607 {
608 uint32_t offset;
609 uint8_t *buffer;
610 size_t length;
611 struct fileio *fileio;
612
613 if (CMD_ARGC < 2 || CMD_ARGC > 3)
614 return ERROR_COMMAND_SYNTAX_ERROR;
615
616 struct duration bench;
617 duration_start(&bench);
618
619 struct flash_bank *bank;
620 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
621 if (ERROR_OK != retval)
622 return retval;
623
624 offset = 0;
625
626 if (CMD_ARGC > 2)
627 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], offset);
628
629 if (offset > bank->size) {
630 LOG_ERROR("Offset 0x%8.8" PRIx32 " is out of range of the flash bank",
631 offset);
632 return ERROR_COMMAND_ARGUMENT_INVALID;
633 }
634
635 if (fileio_open(&fileio, CMD_ARGV[1], FILEIO_READ, FILEIO_BINARY) != ERROR_OK)
636 return ERROR_FAIL;
637
638 size_t filesize;
639 retval = fileio_size(fileio, &filesize);
640 if (retval != ERROR_OK) {
641 fileio_close(fileio);
642 return retval;
643 }
644
645 length = MIN(filesize, bank->size - offset);
646
647 if (!length) {
648 LOG_INFO("Nothing to write to flash bank");
649 fileio_close(fileio);
650 return ERROR_OK;
651 }
652
653 if (length != filesize)
654 LOG_INFO("File content exceeds flash bank size. Only writing the "
655 "first %zu bytes of the file", length);
656
657 target_addr_t start_addr = bank->base + offset;
658 target_addr_t aligned_start = flash_write_align_start(bank, start_addr);
659 target_addr_t end_addr = start_addr + length - 1;
660 target_addr_t aligned_end = flash_write_align_end(bank, end_addr);
661 uint32_t aligned_size = aligned_end + 1 - aligned_start;
662 uint32_t padding_at_start = start_addr - aligned_start;
663 uint32_t padding_at_end = aligned_end - end_addr;
664
665 buffer = malloc(aligned_size);
666 if (buffer == NULL) {
667 fileio_close(fileio);
668 LOG_ERROR("Out of memory");
669 return ERROR_FAIL;
670 }
671
672 if (padding_at_start) {
673 memset(buffer, bank->default_padded_value, padding_at_start);
674 LOG_WARNING("Start offset 0x%08" PRIx32
675 " breaks the required alignment of flash bank %s",
676 offset, bank->name);
677 LOG_WARNING("Padding %" PRId32 " bytes from " TARGET_ADDR_FMT,
678 padding_at_start, aligned_start);
679 }
680
681 uint8_t *ptr = buffer + padding_at_start;
682 size_t buf_cnt;
683 if (fileio_read(fileio, length, ptr, &buf_cnt) != ERROR_OK) {
684 free(buffer);
685 fileio_close(fileio);
686 return ERROR_FAIL;
687 }
688
689 if (buf_cnt != length) {
690 LOG_ERROR("Short read");
691 free(buffer);
692 return ERROR_FAIL;
693 }
694
695 ptr += length;
696
697 if (padding_at_end) {
698 memset(ptr, bank->default_padded_value, padding_at_end);
699 LOG_INFO("Padding at " TARGET_ADDR_FMT " with %" PRId32
700 " bytes (bank write end alignment)",
701 end_addr + 1, padding_at_end);
702 }
703
704 retval = flash_driver_write(bank, buffer, aligned_start - bank->base, aligned_size);
705
706 free(buffer);
707
708 if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) {
709 command_print(CMD_CTX, "wrote %zu bytes from file %s to flash bank %u"
710 " at offset 0x%8.8" PRIx32 " in %fs (%0.3f KiB/s)",
711 length, CMD_ARGV[1], bank->bank_number, offset,
712 duration_elapsed(&bench), duration_kbps(&bench, length));
713 }
714
715 fileio_close(fileio);
716
717 return retval;
718 }
719
720 COMMAND_HANDLER(handle_flash_read_bank_command)
721 {
722 uint32_t offset;
723 uint8_t *buffer;
724 struct fileio *fileio;
725 uint32_t length;
726 size_t written;
727
728 if (CMD_ARGC < 2 || CMD_ARGC > 4)
729 return ERROR_COMMAND_SYNTAX_ERROR;
730
731 struct duration bench;
732 duration_start(&bench);
733
734 struct flash_bank *p;
735 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
736
737 if (ERROR_OK != retval)
738 return retval;
739
740 offset = 0;
741
742 if (CMD_ARGC > 2)
743 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], offset);
744
745 if (offset > p->size) {
746 LOG_ERROR("Offset 0x%8.8" PRIx32 " is out of range of the flash bank",
747 offset);
748 return ERROR_COMMAND_ARGUMENT_INVALID;
749 }
750
751 length = p->size - offset;
752
753 if (CMD_ARGC > 3)
754 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], length);
755
756 if (offset + length > p->size) {
757 LOG_ERROR("Length of %" PRIu32 " bytes with offset 0x%8.8" PRIx32
758 " is out of range of the flash bank", length, offset);
759 return ERROR_COMMAND_ARGUMENT_INVALID;
760 }
761
762 buffer = malloc(length);
763 if (buffer == NULL) {
764 LOG_ERROR("Out of memory");
765 return ERROR_FAIL;
766 }
767
768 retval = flash_driver_read(p, buffer, offset, length);
769 if (retval != ERROR_OK) {
770 LOG_ERROR("Read error");
771 free(buffer);
772 return retval;
773 }
774
775 retval = fileio_open(&fileio, CMD_ARGV[1], FILEIO_WRITE, FILEIO_BINARY);
776 if (retval != ERROR_OK) {
777 LOG_ERROR("Could not open file");
778 free(buffer);
779 return retval;
780 }
781
782 retval = fileio_write(fileio, length, buffer, &written);
783 fileio_close(fileio);
784 free(buffer);
785 if (retval != ERROR_OK) {
786 LOG_ERROR("Could not write file");
787 return ERROR_FAIL;
788 }
789
790 if (duration_measure(&bench) == ERROR_OK)
791 command_print(CMD_CTX, "wrote %zd bytes to file %s from flash bank %u"
792 " at offset 0x%8.8" PRIx32 " in %fs (%0.3f KiB/s)",
793 written, CMD_ARGV[1], p->bank_number, offset,
794 duration_elapsed(&bench), duration_kbps(&bench, written));
795
796 return retval;
797 }
798
799
800 COMMAND_HANDLER(handle_flash_verify_bank_command)
801 {
802 uint32_t offset;
803 uint8_t *buffer_file, *buffer_flash;
804 struct fileio *fileio;
805 size_t read_cnt;
806 size_t filesize;
807 size_t length;
808 int differ;
809
810 if (CMD_ARGC < 2 || CMD_ARGC > 3)
811 return ERROR_COMMAND_SYNTAX_ERROR;
812
813 struct duration bench;
814 duration_start(&bench);
815
816 struct flash_bank *p;
817 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
818 if (ERROR_OK != retval)
819 return retval;
820
821 offset = 0;
822
823 if (CMD_ARGC > 2)
824 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], offset);
825
826 if (offset > p->size) {
827 LOG_ERROR("Offset 0x%8.8" PRIx32 " is out of range of the flash bank",
828 offset);
829 return ERROR_COMMAND_ARGUMENT_INVALID;
830 }
831
832 retval = fileio_open(&fileio, CMD_ARGV[1], FILEIO_READ, FILEIO_BINARY);
833 if (retval != ERROR_OK) {
834 LOG_ERROR("Could not open file");
835 return retval;
836 }
837
838 retval = fileio_size(fileio, &filesize);
839 if (retval != ERROR_OK) {
840 fileio_close(fileio);
841 return retval;
842 }
843
844 length = MIN(filesize, p->size - offset);
845
846 if (!length) {
847 LOG_INFO("Nothing to compare with flash bank");
848 fileio_close(fileio);
849 return ERROR_OK;
850 }
851
852 if (length != filesize)
853 LOG_INFO("File content exceeds flash bank size. Only comparing the "
854 "first %zu bytes of the file", length);
855
856 buffer_file = malloc(length);
857 if (buffer_file == NULL) {
858 LOG_ERROR("Out of memory");
859 fileio_close(fileio);
860 return ERROR_FAIL;
861 }
862
863 retval = fileio_read(fileio, length, buffer_file, &read_cnt);
864 fileio_close(fileio);
865 if (retval != ERROR_OK) {
866 LOG_ERROR("File read failure");
867 free(buffer_file);
868 return retval;
869 }
870
871 if (read_cnt != length) {
872 LOG_ERROR("Short read");
873 free(buffer_file);
874 return ERROR_FAIL;
875 }
876
877 buffer_flash = malloc(length);
878 if (buffer_flash == NULL) {
879 LOG_ERROR("Out of memory");
880 free(buffer_file);
881 return ERROR_FAIL;
882 }
883
884 retval = flash_driver_read(p, buffer_flash, offset, length);
885 if (retval != ERROR_OK) {
886 LOG_ERROR("Flash read error");
887 free(buffer_flash);
888 free(buffer_file);
889 return retval;
890 }
891
892 if (duration_measure(&bench) == ERROR_OK)
893 command_print(CMD_CTX, "read %zd bytes from file %s and flash bank %u"
894 " at offset 0x%8.8" PRIx32 " in %fs (%0.3f KiB/s)",
895 length, CMD_ARGV[1], p->bank_number, offset,
896 duration_elapsed(&bench), duration_kbps(&bench, length));
897
898 differ = memcmp(buffer_file, buffer_flash, length);
899 command_print(CMD_CTX, "contents %s", differ ? "differ" : "match");
900 if (differ) {
901 uint32_t t;
902 int diffs = 0;
903 for (t = 0; t < length; t++) {
904 if (buffer_flash[t] == buffer_file[t])
905 continue;
906 command_print(CMD_CTX, "diff %d address 0x%08x. Was 0x%02x instead of 0x%02x",
907 diffs, t + offset, buffer_flash[t], buffer_file[t]);
908 if (diffs++ >= 127) {
909 command_print(CMD_CTX, "More than 128 errors, the rest are not printed.");
910 break;
911 }
912 keep_alive();
913 }
914 }
915 free(buffer_flash);
916 free(buffer_file);
917
918 return differ ? ERROR_FAIL : ERROR_OK;
919 }
920
921 void flash_set_dirty(void)
922 {
923 struct flash_bank *c;
924 int i;
925
926 /* set all flash to require erasing */
927 for (c = flash_bank_list(); c; c = c->next) {
928 for (i = 0; i < c->num_sectors; i++)
929 c->sectors[i].is_erased = 0;
930 }
931 }
932
933 COMMAND_HANDLER(handle_flash_padded_value_command)
934 {
935 if (CMD_ARGC != 2)
936 return ERROR_COMMAND_SYNTAX_ERROR;
937
938 struct flash_bank *p;
939 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
940 if (ERROR_OK != retval)
941 return retval;
942
943 COMMAND_PARSE_NUMBER(u8, CMD_ARGV[1], p->default_padded_value);
944
945 command_print(CMD_CTX, "Default padded value set to 0x%" PRIx8 " for flash bank %u", \
946 p->default_padded_value, p->bank_number);
947
948 return retval;
949 }
950
951 static const struct command_registration flash_exec_command_handlers[] = {
952 {
953 .name = "probe",
954 .handler = handle_flash_probe_command,
955 .mode = COMMAND_EXEC,
956 .usage = "bank_id",
957 .help = "Identify a flash bank.",
958 },
959 {
960 .name = "info",
961 .handler = handle_flash_info_command,
962 .mode = COMMAND_EXEC,
963 .usage = "bank_id ['sectors']",
964 .help = "Print information about a flash bank.",
965 },
966 {
967 .name = "erase_check",
968 .handler = handle_flash_erase_check_command,
969 .mode = COMMAND_EXEC,
970 .usage = "bank_id",
971 .help = "Check erase state of all blocks in a "
972 "flash bank.",
973 },
974 {
975 .name = "erase_sector",
976 .handler = handle_flash_erase_command,
977 .mode = COMMAND_EXEC,
978 .usage = "bank_id first_sector_num last_sector_num",
979 .help = "Erase a range of sectors in a flash bank.",
980 },
981 {
982 .name = "erase_address",
983 .handler = handle_flash_erase_address_command,
984 .mode = COMMAND_EXEC,
985 .usage = "['pad'] ['unlock'] address length",
986 .help = "Erase flash sectors starting at address and "
987 "continuing for length bytes. If 'pad' is specified, "
988 "data outside that range may also be erased: the start "
989 "address may be decreased, and length increased, so "
990 "that all of the first and last sectors are erased. "
991 "If 'unlock' is specified, then the flash is unprotected "
992 "before erasing.",
993
994 },
995 {
996 .name = "fillw",
997 .handler = handle_flash_fill_command,
998 .mode = COMMAND_EXEC,
999 .usage = "address value n",
1000 .help = "Fill n words with 32-bit value, starting at "
1001 "word address. (No autoerase.)",
1002 },
1003 {
1004 .name = "fillh",
1005 .handler = handle_flash_fill_command,
1006 .mode = COMMAND_EXEC,
1007 .usage = "address value n",
1008 .help = "Fill n halfwords with 16-bit value, starting at "
1009 "word address. (No autoerase.)",
1010 },
1011 {
1012 .name = "fillb",
1013 .handler = handle_flash_fill_command,
1014 .mode = COMMAND_EXEC,
1015 .usage = "address value n",
1016 .help = "Fill n bytes with 8-bit value, starting at "
1017 "word address. (No autoerase.)",
1018 },
1019 {
1020 .name = "write_bank",
1021 .handler = handle_flash_write_bank_command,
1022 .mode = COMMAND_EXEC,
1023 .usage = "bank_id filename [offset]",
1024 .help = "Write binary data from file to flash bank. Allow optional "
1025 "offset from beginning of the bank (defaults to zero).",
1026 },
1027 {
1028 .name = "write_image",
1029 .handler = handle_flash_write_image_command,
1030 .mode = COMMAND_EXEC,
1031 .usage = "[erase] [unlock] filename [offset [file_type]]",
1032 .help = "Write an image to flash. Optionally first unprotect "
1033 "and/or erase the region to be used. Allow optional "
1034 "offset from beginning of bank (defaults to zero)",
1035 },
1036 {
1037 .name = "read_bank",
1038 .handler = handle_flash_read_bank_command,
1039 .mode = COMMAND_EXEC,
1040 .usage = "bank_id filename [offset [length]]",
1041 .help = "Read binary data from flash bank to file. Allow optional "
1042 "offset from beginning of the bank (defaults to zero).",
1043 },
1044 {
1045 .name = "verify_bank",
1046 .handler = handle_flash_verify_bank_command,
1047 .mode = COMMAND_EXEC,
1048 .usage = "bank_id filename [offset]",
1049 .help = "Compare the contents of a file with the contents of the "
1050 "flash bank. Allow optional offset from beginning of the bank "
1051 "(defaults to zero).",
1052 },
1053 {
1054 .name = "protect",
1055 .handler = handle_flash_protect_command,
1056 .mode = COMMAND_EXEC,
1057 .usage = "bank_id first_block [last_block|'last'] "
1058 "('on'|'off')",
1059 .help = "Turn protection on or off for a range of protection "
1060 "blocks or sectors in a given flash bank. "
1061 "See 'flash info' output for a list of blocks.",
1062 },
1063 {
1064 .name = "padded_value",
1065 .handler = handle_flash_padded_value_command,
1066 .mode = COMMAND_EXEC,
1067 .usage = "bank_id value",
1068 .help = "Set default flash padded value",
1069 },
1070 COMMAND_REGISTRATION_DONE
1071 };
1072
1073 static int flash_init_drivers(struct command_context *cmd_ctx)
1074 {
1075 if (!flash_bank_list())
1076 return ERROR_OK;
1077
1078 struct command *parent = command_find_in_context(cmd_ctx, "flash");
1079 return register_commands(cmd_ctx, parent, flash_exec_command_handlers);
1080 }
1081
1082 COMMAND_HANDLER(handle_flash_bank_command)
1083 {
1084 if (CMD_ARGC < 7) {
1085 LOG_ERROR("usage: flash bank <name> <driver> "
1086 "<base> <size> <chip_width> <bus_width> <target>");
1087 return ERROR_COMMAND_SYNTAX_ERROR;
1088 }
1089 /* save bank name and advance arguments for compatibility */
1090 const char *bank_name = *CMD_ARGV++;
1091 CMD_ARGC--;
1092
1093 struct target *target = get_target(CMD_ARGV[5]);
1094 if (target == NULL) {
1095 LOG_ERROR("target '%s' not defined", CMD_ARGV[5]);
1096 return ERROR_FAIL;
1097 }
1098
1099 const char *driver_name = CMD_ARGV[0];
1100 struct flash_driver *driver = flash_driver_find_by_name(driver_name);
1101 if (NULL == driver) {
1102 /* no matching flash driver found */
1103 LOG_ERROR("flash driver '%s' not found", driver_name);
1104 return ERROR_FAIL;
1105 }
1106
1107 /* check the flash bank name is unique */
1108 if (get_flash_bank_by_name_noprobe(bank_name) != NULL) {
1109 /* flash bank name already exists */
1110 LOG_ERROR("flash bank name '%s' already exists", bank_name);
1111 return ERROR_FAIL;
1112 }
1113
1114 /* register flash specific commands */
1115 if (NULL != driver->commands) {
1116 int retval = register_commands(CMD_CTX, NULL,
1117 driver->commands);
1118 if (ERROR_OK != retval) {
1119 LOG_ERROR("couldn't register '%s' commands",
1120 driver_name);
1121 return ERROR_FAIL;
1122 }
1123 }
1124
1125 struct flash_bank *c = calloc(1, sizeof(*c));
1126 c->name = strdup(bank_name);
1127 c->target = target;
1128 c->driver = driver;
1129 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], c->base);
1130 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], c->size);
1131 COMMAND_PARSE_NUMBER(int, CMD_ARGV[3], c->chip_width);
1132 COMMAND_PARSE_NUMBER(int, CMD_ARGV[4], c->bus_width);
1133 c->default_padded_value = c->erased_value = 0xff;
1134 c->minimal_write_gap = FLASH_WRITE_GAP_SECTOR;
1135
1136 int retval;
1137 retval = CALL_COMMAND_HANDLER(driver->flash_bank_command, c);
1138 if (ERROR_OK != retval) {
1139 LOG_ERROR("'%s' driver rejected flash bank at 0x%8.8" PRIx32 "; usage: %s",
1140 driver_name, c->base, driver->usage);
1141 free(c);
1142 return retval;
1143 }
1144
1145 if (driver->usage == NULL)
1146 LOG_DEBUG("'%s' driver usage field missing", driver_name);
1147
1148 flash_bank_add(c);
1149
1150 return ERROR_OK;
1151 }
1152
1153 COMMAND_HANDLER(handle_flash_banks_command)
1154 {
1155 if (CMD_ARGC != 0)
1156 return ERROR_COMMAND_SYNTAX_ERROR;
1157
1158 unsigned n = 0;
1159 for (struct flash_bank *p = flash_bank_list(); p; p = p->next, n++) {
1160 LOG_USER("#%d : %s (%s) at 0x%8.8" PRIx32 ", size 0x%8.8" PRIx32 ", "
1161 "buswidth %u, chipwidth %u", p->bank_number,
1162 p->name, p->driver->name, p->base, p->size,
1163 p->bus_width, p->chip_width);
1164 }
1165 return ERROR_OK;
1166 }
1167
1168 static int jim_flash_list(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
1169 {
1170 if (argc != 1) {
1171 Jim_WrongNumArgs(interp, 1, argv,
1172 "no arguments to 'flash list' command");
1173 return JIM_ERR;
1174 }
1175
1176 Jim_Obj *list = Jim_NewListObj(interp, NULL, 0);
1177
1178 for (struct flash_bank *p = flash_bank_list(); p; p = p->next) {
1179 Jim_Obj *elem = Jim_NewListObj(interp, NULL, 0);
1180
1181 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "name", -1));
1182 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, p->driver->name, -1));
1183 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "base", -1));
1184 Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->base));
1185 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "size", -1));
1186 Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->size));
1187 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "bus_width", -1));
1188 Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->bus_width));
1189 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "chip_width", -1));
1190 Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->chip_width));
1191
1192 Jim_ListAppendElement(interp, list, elem);
1193 }
1194
1195 Jim_SetResult(interp, list);
1196
1197 return JIM_OK;
1198 }
1199
1200 COMMAND_HANDLER(handle_flash_init_command)
1201 {
1202 if (CMD_ARGC != 0)
1203 return ERROR_COMMAND_SYNTAX_ERROR;
1204
1205 static bool flash_initialized;
1206 if (flash_initialized) {
1207 LOG_INFO("'flash init' has already been called");
1208 return ERROR_OK;
1209 }
1210 flash_initialized = true;
1211
1212 LOG_DEBUG("Initializing flash devices...");
1213 return flash_init_drivers(CMD_CTX);
1214 }
1215
1216 static const struct command_registration flash_config_command_handlers[] = {
1217 {
1218 .name = "bank",
1219 .handler = handle_flash_bank_command,
1220 .mode = COMMAND_CONFIG,
1221 .usage = "bank_id driver_name base_address size_bytes "
1222 "chip_width_bytes bus_width_bytes target "
1223 "[driver_options ...]",
1224 .help = "Define a new bank with the given name, "
1225 "using the specified NOR flash driver.",
1226 },
1227 {
1228 .name = "init",
1229 .mode = COMMAND_CONFIG,
1230 .handler = handle_flash_init_command,
1231 .help = "Initialize flash devices.",
1232 },
1233 {
1234 .name = "banks",
1235 .mode = COMMAND_ANY,
1236 .handler = handle_flash_banks_command,
1237 .help = "Display table with information about flash banks.",
1238 },
1239 {
1240 .name = "list",
1241 .mode = COMMAND_ANY,
1242 .jim_handler = jim_flash_list,
1243 .help = "Returns a list of details about the flash banks.",
1244 },
1245 COMMAND_REGISTRATION_DONE
1246 };
1247 static const struct command_registration flash_command_handlers[] = {
1248 {
1249 .name = "flash",
1250 .mode = COMMAND_ANY,
1251 .help = "NOR flash command group",
1252 .chain = flash_config_command_handlers,
1253 },
1254 COMMAND_REGISTRATION_DONE
1255 };
1256
1257 int flash_register_commands(struct command_context *cmd_ctx)
1258 {
1259 return register_commands(cmd_ctx, NULL, flash_command_handlers);
1260 }

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)