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

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)