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> *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
21 ***************************************************************************/
26 #include <helper/time_support.h>
27 #include <target/image.h>
31 * Implements Tcl commands used to access NOR flash facilities.
34 COMMAND_HELPER(flash_command_get_bank_maybe_probe
, unsigned name_index
,
35 struct flash_bank
**bank
, bool do_probe
)
37 const char *name
= CMD_ARGV
[name_index
];
40 retval
= get_flash_bank_by_name(name
, bank
);
42 *bank
= get_flash_bank_by_name_noprobe(name
);
46 if (retval
!= ERROR_OK
)
52 COMMAND_PARSE_NUMBER(uint
, name
, bank_num
);
55 return get_flash_bank_by_num(bank_num
, bank
);
57 *bank
= get_flash_bank_by_num_noprobe(bank_num
);
58 retval
= (bank
) ? ERROR_OK
: ERROR_FAIL
;
63 COMMAND_HELPER(flash_command_get_bank
, unsigned name_index
,
64 struct flash_bank
**bank
)
66 return CALL_COMMAND_HANDLER(flash_command_get_bank_maybe_probe
,
67 name_index
, bank
, true);
70 COMMAND_HANDLER(handle_flash_info_command
)
77 return ERROR_COMMAND_SYNTAX_ERROR
;
79 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &p
);
80 if (retval
!= ERROR_OK
)
86 /* attempt auto probe */
87 retval
= p
->driver
->auto_probe(p
);
88 if (retval
!= ERROR_OK
)
91 /* We must query the hardware to avoid printing stale information! */
92 retval
= p
->driver
->protect_check(p
);
93 if (retval
!= ERROR_OK
)
96 command_print(CMD_CTX
,
97 "#%d : %s at 0x%8.8" PRIx32
", size 0x%8.8" PRIx32
98 ", buswidth %i, chipwidth %i",
105 for (j
= 0; j
< p
->num_sectors
; j
++) {
108 if (p
->sectors
[j
].is_protected
== 0)
109 protect_state
= "not protected";
110 else if (p
->sectors
[j
].is_protected
== 1)
111 protect_state
= "protected";
113 protect_state
= "protection state unknown";
115 command_print(CMD_CTX
,
116 "\t#%3i: 0x%8.8" PRIx32
" (0x%" PRIx32
" %" PRIi32
"kB) %s",
118 p
->sectors
[j
].offset
,
120 p
->sectors
[j
].size
>> 10,
124 if (p
->driver
->info
!= NULL
) {
125 retval
= p
->driver
->info(p
, buf
, sizeof(buf
));
126 if (retval
== ERROR_OK
)
127 command_print(CMD_CTX
, "%s", buf
);
129 LOG_ERROR("error retrieving flash info");
136 COMMAND_HANDLER(handle_flash_probe_command
)
138 struct flash_bank
*p
;
142 return ERROR_COMMAND_SYNTAX_ERROR
;
144 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank_maybe_probe
, 0, &p
, false);
145 if (retval
!= ERROR_OK
)
149 retval
= p
->driver
->probe(p
);
150 if (retval
== ERROR_OK
)
151 command_print(CMD_CTX
,
152 "flash '%s' found at 0x%8.8" PRIx32
,
156 command_print(CMD_CTX
, "flash bank '#%s' is out of bounds", CMD_ARGV
[0]);
163 COMMAND_HANDLER(handle_flash_erase_check_command
)
166 return ERROR_COMMAND_SYNTAX_ERROR
;
168 struct flash_bank
*p
;
169 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &p
);
170 if (ERROR_OK
!= retval
)
174 retval
= p
->driver
->erase_check(p
);
175 if (retval
== ERROR_OK
)
176 command_print(CMD_CTX
, "successfully checked erase state");
178 command_print(CMD_CTX
,
179 "unknown error when checking erase state of flash bank #%s at 0x%8.8" PRIx32
,
184 for (j
= 0; j
< p
->num_sectors
; j
++) {
187 if (p
->sectors
[j
].is_erased
== 0)
188 erase_state
= "not erased";
189 else if (p
->sectors
[j
].is_erased
== 1)
190 erase_state
= "erased";
192 erase_state
= "erase state unknown";
194 command_print(CMD_CTX
,
195 "\t#%3i: 0x%8.8" PRIx32
" (0x%" PRIx32
" %" PRIi32
"kB) %s",
197 p
->sectors
[j
].offset
,
199 p
->sectors
[j
].size
>> 10,
206 COMMAND_HANDLER(handle_flash_erase_address_command
)
208 struct flash_bank
*p
;
209 int retval
= ERROR_OK
;
213 bool do_unlock
= false;
214 struct target
*target
= get_current_target(CMD_CTX
);
216 while (CMD_ARGC
>= 3) {
217 /* Optionally pad out the address range to block/sector
218 * boundaries. We can't know if there's data in that part
219 * of the flash; only do padding if we're told to.
221 if (strcmp("pad", CMD_ARGV
[0]) == 0)
223 else if (strcmp("unlock", CMD_ARGV
[0]) == 0)
226 return ERROR_COMMAND_SYNTAX_ERROR
;
231 return ERROR_COMMAND_SYNTAX_ERROR
;
233 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
234 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], length
);
237 command_print(CMD_CTX
, "Length must be >0");
238 return ERROR_COMMAND_SYNTAX_ERROR
;
241 retval
= get_flash_bank_by_addr(target
, address
, true, &p
);
242 if (retval
!= ERROR_OK
)
245 /* We can't know if we did a resume + halt, in which case we no longer know the erased state
249 struct duration bench
;
250 duration_start(&bench
);
253 retval
= flash_unlock_address_range(target
, address
, length
);
255 if (retval
== ERROR_OK
)
256 retval
= flash_erase_address_range(target
, do_pad
, address
, length
);
258 if ((ERROR_OK
== retval
) && (duration_measure(&bench
) == ERROR_OK
)) {
259 command_print(CMD_CTX
, "erased address 0x%8.8" PRIx32
" (length %" PRIi32
")"
260 " in %fs (%0.3f KiB/s)", address
, length
,
261 duration_elapsed(&bench
), duration_kbps(&bench
, length
));
267 static int flash_check_sector_parameters(struct command_context
*cmd_ctx
,
268 uint32_t first
, uint32_t last
, uint32_t num_sectors
)
270 if (!(first
<= last
)) {
271 command_print(cmd_ctx
, "ERROR: "
272 "first sector must be <= last sector");
276 if (!(last
<= (num_sectors
- 1))) {
277 command_print(cmd_ctx
, "ERROR: last sector must be <= %d",
278 (int) num_sectors
- 1);
285 COMMAND_HANDLER(handle_flash_erase_command
)
288 return ERROR_COMMAND_SYNTAX_ERROR
;
293 struct flash_bank
*p
;
296 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &p
);
297 if (retval
!= ERROR_OK
)
300 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], first
);
301 if (strcmp(CMD_ARGV
[2], "last") == 0)
302 last
= p
->num_sectors
- 1;
304 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], last
);
306 retval
= flash_check_sector_parameters(CMD_CTX
, first
, last
, p
->num_sectors
);
307 if (retval
!= ERROR_OK
)
310 struct duration bench
;
311 duration_start(&bench
);
313 retval
= flash_driver_erase(p
, first
, last
);
315 if ((ERROR_OK
== retval
) && (duration_measure(&bench
) == ERROR_OK
)) {
316 command_print(CMD_CTX
, "erased sectors %" PRIu32
" "
317 "through %" PRIu32
" on flash bank %d "
318 "in %fs", first
, last
, p
->bank_number
, duration_elapsed(&bench
));
324 COMMAND_HANDLER(handle_flash_protect_command
)
327 return ERROR_COMMAND_SYNTAX_ERROR
;
332 struct flash_bank
*p
;
335 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &p
);
336 if (retval
!= ERROR_OK
)
339 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], first
);
340 if (strcmp(CMD_ARGV
[2], "last") == 0)
341 last
= p
->num_sectors
- 1;
343 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], last
);
346 COMMAND_PARSE_ON_OFF(CMD_ARGV
[3], set
);
348 retval
= flash_check_sector_parameters(CMD_CTX
, first
, last
, p
->num_sectors
);
349 if (retval
!= ERROR_OK
)
352 retval
= flash_driver_protect(p
, set
, first
, last
);
353 if (retval
== ERROR_OK
) {
354 command_print(CMD_CTX
, "%s protection for sectors %i "
355 "through %i on flash bank %d",
356 (set
) ? "set" : "cleared", (int) first
,
357 (int) last
, p
->bank_number
);
363 COMMAND_HANDLER(handle_flash_write_image_command
)
365 struct target
*target
= get_current_target(CMD_CTX
);
372 /* flash auto-erase is disabled by default*/
374 bool auto_unlock
= false;
377 if (strcmp(CMD_ARGV
[0], "erase") == 0) {
381 command_print(CMD_CTX
, "auto erase enabled");
382 } else if (strcmp(CMD_ARGV
[0], "unlock") == 0) {
386 command_print(CMD_CTX
, "auto unlock enabled");
392 return ERROR_COMMAND_SYNTAX_ERROR
;
395 LOG_ERROR("no target selected");
399 struct duration bench
;
400 duration_start(&bench
);
403 image
.base_address_set
= 1;
404 COMMAND_PARSE_NUMBER(llong
, CMD_ARGV
[1], image
.base_address
);
406 image
.base_address_set
= 0;
407 image
.base_address
= 0x0;
410 image
.start_address_set
= 0;
412 retval
= image_open(&image
, CMD_ARGV
[0], (CMD_ARGC
== 3) ? CMD_ARGV
[2] : NULL
);
413 if (retval
!= ERROR_OK
)
416 retval
= flash_write_unlock(target
, &image
, &written
, auto_erase
, auto_unlock
);
417 if (retval
!= ERROR_OK
) {
422 if ((ERROR_OK
== retval
) && (duration_measure(&bench
) == ERROR_OK
)) {
423 command_print(CMD_CTX
, "wrote %" PRIu32
" bytes from file %s "
424 "in %fs (%0.3f KiB/s)", written
, CMD_ARGV
[0],
425 duration_elapsed(&bench
), duration_kbps(&bench
, written
));
433 COMMAND_HANDLER(handle_flash_fill_command
)
440 uint32_t cur_size
= 0;
441 uint32_t chunk_count
;
442 struct target
*target
= get_current_target(CMD_CTX
);
445 int retval
= ERROR_OK
;
447 static size_t const chunksize
= 1024;
448 uint8_t *chunk
= NULL
, *readback
= NULL
;
451 retval
= ERROR_COMMAND_SYNTAX_ERROR
;
455 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
456 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], pattern
);
457 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], count
);
459 chunk
= malloc(chunksize
);
463 readback
= malloc(chunksize
);
464 if (readback
== NULL
) {
472 switch (CMD_NAME
[4]) {
483 retval
= ERROR_COMMAND_SYNTAX_ERROR
;
487 chunk_count
= MIN(count
, (chunksize
/ wordsize
));
490 for (i
= 0; i
< chunk_count
; i
++)
491 target_buffer_set_u32(target
, chunk
+ i
* wordsize
, pattern
);
494 for (i
= 0; i
< chunk_count
; i
++)
495 target_buffer_set_u16(target
, chunk
+ i
* wordsize
, pattern
);
498 memset(chunk
, pattern
, chunk_count
);
501 LOG_ERROR("BUG: can't happen");
505 struct duration bench
;
506 duration_start(&bench
);
508 for (wrote
= 0; wrote
< (count
*wordsize
); wrote
+= cur_size
) {
509 struct flash_bank
*bank
;
511 retval
= get_flash_bank_by_addr(target
, address
, true, &bank
);
512 if (retval
!= ERROR_OK
)
515 cur_size
= MIN((count
* wordsize
- wrote
), chunksize
);
516 err
= flash_driver_write(bank
, chunk
, address
- bank
->base
+ wrote
, cur_size
);
517 if (err
!= ERROR_OK
) {
522 err
= flash_driver_read(bank
, readback
, address
- bank
->base
+ wrote
, cur_size
);
523 if (err
!= ERROR_OK
) {
528 for (i
= 0; i
< cur_size
; i
++) {
529 if (readback
[i
] != chunk
[i
]) {
531 "Verification error address 0x%08" PRIx32
", read back 0x%02x, expected 0x%02x",
541 if ((retval
== ERROR_OK
) && (duration_measure(&bench
) == ERROR_OK
)) {
542 command_print(CMD_CTX
, "wrote %" PRIu32
" bytes to 0x%8.8" PRIx32
543 " in %fs (%0.3f KiB/s)", wrote
, address
,
544 duration_elapsed(&bench
), duration_kbps(&bench
, wrote
));
554 COMMAND_HANDLER(handle_flash_write_bank_command
)
558 struct fileio fileio
;
561 return ERROR_COMMAND_SYNTAX_ERROR
;
563 struct duration bench
;
564 duration_start(&bench
);
566 struct flash_bank
*p
;
567 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &p
);
568 if (ERROR_OK
!= retval
)
571 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], offset
);
573 if (fileio_open(&fileio
, CMD_ARGV
[1], FILEIO_READ
, FILEIO_BINARY
) != ERROR_OK
)
577 retval
= fileio_size(&fileio
, &filesize
);
578 if (retval
!= ERROR_OK
) {
579 fileio_close(&fileio
);
583 buffer
= malloc(filesize
);
584 if (buffer
== NULL
) {
585 fileio_close(&fileio
);
586 LOG_ERROR("Out of memory");
590 if (fileio_read(&fileio
, filesize
, buffer
, &buf_cnt
) != ERROR_OK
) {
592 fileio_close(&fileio
);
596 retval
= flash_driver_write(p
, buffer
, offset
, buf_cnt
);
601 if ((ERROR_OK
== retval
) && (duration_measure(&bench
) == ERROR_OK
)) {
602 command_print(CMD_CTX
, "wrote %ld bytes from file %s to flash bank %u"
603 " at offset 0x%8.8" PRIx32
" in %fs (%0.3f KiB/s)",
604 (long)filesize
, CMD_ARGV
[1], p
->bank_number
, offset
,
605 duration_elapsed(&bench
), duration_kbps(&bench
, filesize
));
608 fileio_close(&fileio
);
613 COMMAND_HANDLER(handle_flash_read_bank_command
)
617 struct fileio fileio
;
622 return ERROR_COMMAND_SYNTAX_ERROR
;
624 struct duration bench
;
625 duration_start(&bench
);
627 struct flash_bank
*p
;
628 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &p
);
629 if (ERROR_OK
!= retval
)
632 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], offset
);
633 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[3], length
);
635 buffer
= malloc(length
);
636 if (buffer
== NULL
) {
637 LOG_ERROR("Out of memory");
641 retval
= flash_driver_read(p
, buffer
, offset
, length
);
642 if (retval
!= ERROR_OK
) {
643 LOG_ERROR("Read error");
648 retval
= fileio_open(&fileio
, CMD_ARGV
[1], FILEIO_WRITE
, FILEIO_BINARY
);
649 if (retval
!= ERROR_OK
) {
650 LOG_ERROR("Could not open file");
655 retval
= fileio_write(&fileio
, length
, buffer
, &written
);
656 fileio_close(&fileio
);
658 if (retval
!= ERROR_OK
) {
659 LOG_ERROR("Could not write file");
663 if (duration_measure(&bench
) == ERROR_OK
)
664 command_print(CMD_CTX
, "wrote %ld bytes to file %s from flash bank %u"
665 " at offset 0x%8.8" PRIx32
" in %fs (%0.3f KiB/s)",
666 (long)written
, CMD_ARGV
[1], p
->bank_number
, offset
,
667 duration_elapsed(&bench
), duration_kbps(&bench
, written
));
673 COMMAND_HANDLER(handle_flash_verify_bank_command
)
676 uint8_t *buffer_file
, *buffer_flash
;
677 struct fileio fileio
;
683 return ERROR_COMMAND_SYNTAX_ERROR
;
685 struct duration bench
;
686 duration_start(&bench
);
688 struct flash_bank
*p
;
689 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &p
);
690 if (ERROR_OK
!= retval
)
693 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], offset
);
695 retval
= fileio_open(&fileio
, CMD_ARGV
[1], FILEIO_READ
, FILEIO_BINARY
);
696 if (retval
!= ERROR_OK
) {
697 LOG_ERROR("Could not open file");
701 retval
= fileio_size(&fileio
, &filesize
);
702 if (retval
!= ERROR_OK
) {
703 fileio_close(&fileio
);
707 buffer_file
= malloc(filesize
);
708 if (buffer_file
== NULL
) {
709 LOG_ERROR("Out of memory");
710 fileio_close(&fileio
);
714 retval
= fileio_read(&fileio
, filesize
, buffer_file
, &read_cnt
);
715 fileio_close(&fileio
);
716 if (retval
!= ERROR_OK
) {
717 LOG_ERROR("File read failure");
722 if (read_cnt
!= (size_t) filesize
) {
723 LOG_ERROR("Short read");
728 buffer_flash
= malloc(filesize
);
729 if (buffer_flash
== NULL
) {
730 LOG_ERROR("Out of memory");
735 retval
= flash_driver_read(p
, buffer_flash
, offset
, read_cnt
);
736 if (retval
!= ERROR_OK
) {
737 LOG_ERROR("Flash read error");
743 if (duration_measure(&bench
) == ERROR_OK
)
744 command_print(CMD_CTX
, "read %ld bytes from file %s and flash bank %u"
745 " at offset 0x%8.8" PRIx32
" in %fs (%0.3f KiB/s)",
746 (long)read_cnt
, CMD_ARGV
[1], p
->bank_number
, offset
,
747 duration_elapsed(&bench
), duration_kbps(&bench
, read_cnt
));
749 differ
= memcmp(buffer_file
, buffer_flash
, read_cnt
);
750 command_print(CMD_CTX
, "contents %s", differ
? "differ" : "match");
754 for (t
= 0; t
< read_cnt
; t
++) {
755 if (buffer_flash
[t
] == buffer_file
[t
])
757 command_print(CMD_CTX
, "diff %d address 0x%08x. Was 0x%02x instead of 0x%02x",
758 diffs
, t
+ offset
, buffer_flash
[t
], buffer_file
[t
]);
759 if (diffs
++ >= 127) {
760 command_print(CMD_CTX
, "More than 128 errors, the rest are not printed.");
769 return differ
? ERROR_FAIL
: ERROR_OK
;
772 void flash_set_dirty(void)
774 struct flash_bank
*c
;
777 /* set all flash to require erasing */
778 for (c
= flash_bank_list(); c
; c
= c
->next
) {
779 for (i
= 0; i
< c
->num_sectors
; i
++)
780 c
->sectors
[i
].is_erased
= 0;
784 COMMAND_HANDLER(handle_flash_padded_value_command
)
787 return ERROR_COMMAND_SYNTAX_ERROR
;
789 struct flash_bank
*p
;
790 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &p
);
791 if (ERROR_OK
!= retval
)
794 COMMAND_PARSE_NUMBER(u8
, CMD_ARGV
[1], p
->default_padded_value
);
796 command_print(CMD_CTX
, "Default padded value set to 0x%" PRIx8
" for flash bank %u", \
797 p
->default_padded_value
, p
->bank_number
);
802 static const struct command_registration flash_exec_command_handlers
[] = {
805 .handler
= handle_flash_probe_command
,
806 .mode
= COMMAND_EXEC
,
808 .help
= "Identify a flash bank.",
812 .handler
= handle_flash_info_command
,
813 .mode
= COMMAND_EXEC
,
815 .help
= "Print information about a flash bank.",
818 .name
= "erase_check",
819 .handler
= handle_flash_erase_check_command
,
820 .mode
= COMMAND_EXEC
,
822 .help
= "Check erase state of all blocks in a "
826 .name
= "erase_sector",
827 .handler
= handle_flash_erase_command
,
828 .mode
= COMMAND_EXEC
,
829 .usage
= "bank_id first_sector_num last_sector_num",
830 .help
= "Erase a range of sectors in a flash bank.",
833 .name
= "erase_address",
834 .handler
= handle_flash_erase_address_command
,
835 .mode
= COMMAND_EXEC
,
836 .usage
= "['pad'] ['unlock'] address length",
837 .help
= "Erase flash sectors starting at address and "
838 "continuing for length bytes. If 'pad' is specified, "
839 "data outside that range may also be erased: the start "
840 "address may be decreased, and length increased, so "
841 "that all of the first and last sectors are erased. "
842 "If 'unlock' is specified, then the flash is unprotected "
848 .handler
= handle_flash_fill_command
,
849 .mode
= COMMAND_EXEC
,
850 .usage
= "address value n",
851 .help
= "Fill n words with 32-bit value, starting at "
852 "word address. (No autoerase.)",
856 .handler
= handle_flash_fill_command
,
857 .mode
= COMMAND_EXEC
,
858 .usage
= "address value n",
859 .help
= "Fill n halfwords with 16-bit value, starting at "
860 "word address. (No autoerase.)",
864 .handler
= handle_flash_fill_command
,
865 .mode
= COMMAND_EXEC
,
866 .usage
= "address value n",
867 .help
= "Fill n bytes with 8-bit value, starting at "
868 "word address. (No autoerase.)",
871 .name
= "write_bank",
872 .handler
= handle_flash_write_bank_command
,
873 .mode
= COMMAND_EXEC
,
874 .usage
= "bank_id filename offset",
875 .help
= "Write binary data from file to flash bank, "
876 "starting at specified byte offset from the "
877 "beginning of the bank.",
880 .name
= "write_image",
881 .handler
= handle_flash_write_image_command
,
882 .mode
= COMMAND_EXEC
,
883 .usage
= "[erase] [unlock] filename [offset [file_type]]",
884 .help
= "Write an image to flash. Optionally first unprotect "
885 "and/or erase the region to be used. Allow optional "
886 "offset from beginning of bank (defaults to zero)",
890 .handler
= handle_flash_read_bank_command
,
891 .mode
= COMMAND_EXEC
,
892 .usage
= "bank_id filename offset length",
893 .help
= "Read binary data from flash bank to file, "
894 "starting at specified byte offset from the "
895 "beginning of the bank.",
898 .name
= "verify_bank",
899 .handler
= handle_flash_verify_bank_command
,
900 .mode
= COMMAND_EXEC
,
901 .usage
= "bank_id filename offset",
902 .help
= "Read binary data from flash bank and file, "
903 "starting at specified byte offset from the "
904 "beginning of the bank. Compare the contents.",
908 .handler
= handle_flash_protect_command
,
909 .mode
= COMMAND_EXEC
,
910 .usage
= "bank_id first_sector [last_sector|'last'] "
912 .help
= "Turn protection on or off for a range of sectors "
913 "in a given flash bank.",
916 .name
= "padded_value",
917 .handler
= handle_flash_padded_value_command
,
918 .mode
= COMMAND_EXEC
,
919 .usage
= "bank_id value",
920 .help
= "Set default flash padded value",
922 COMMAND_REGISTRATION_DONE
925 static int flash_init_drivers(struct command_context
*cmd_ctx
)
927 if (!flash_bank_list())
930 struct command
*parent
= command_find_in_context(cmd_ctx
, "flash");
931 return register_commands(cmd_ctx
, parent
, flash_exec_command_handlers
);
934 COMMAND_HANDLER(handle_flash_bank_command
)
937 LOG_ERROR("usage: flash bank <name> <driver> "
938 "<base> <size> <chip_width> <bus_width> <target>");
939 return ERROR_COMMAND_SYNTAX_ERROR
;
941 /* save bank name and advance arguments for compatibility */
942 const char *bank_name
= *CMD_ARGV
++;
945 struct target
*target
= get_target(CMD_ARGV
[5]);
946 if (target
== NULL
) {
947 LOG_ERROR("target '%s' not defined", CMD_ARGV
[5]);
951 const char *driver_name
= CMD_ARGV
[0];
952 struct flash_driver
*driver
= flash_driver_find_by_name(driver_name
);
953 if (NULL
== driver
) {
954 /* no matching flash driver found */
955 LOG_ERROR("flash driver '%s' not found", driver_name
);
959 /* check the flash bank name is unique */
960 if (get_flash_bank_by_name_noprobe(bank_name
) != NULL
) {
961 /* flash bank name already exists */
962 LOG_ERROR("flash bank name '%s' already exists", bank_name
);
966 /* register flash specific commands */
967 if (NULL
!= driver
->commands
) {
968 int retval
= register_commands(CMD_CTX
, NULL
,
970 if (ERROR_OK
!= retval
) {
971 LOG_ERROR("couldn't register '%s' commands",
977 struct flash_bank
*c
= malloc(sizeof(*c
));
978 c
->name
= strdup(bank_name
);
981 c
->driver_priv
= NULL
;
982 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], c
->base
);
983 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], c
->size
);
984 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[3], c
->chip_width
);
985 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[4], c
->bus_width
);
986 c
->default_padded_value
= 0xff;
992 retval
= CALL_COMMAND_HANDLER(driver
->flash_bank_command
, c
);
993 if (ERROR_OK
!= retval
) {
994 LOG_ERROR("'%s' driver rejected flash bank at 0x%8.8" PRIx32
"; usage: %s",
995 driver_name
, c
->base
, driver
->usage
);
1000 if (driver
->usage
== NULL
)
1001 LOG_DEBUG("'%s' driver usage field missing", driver_name
);
1008 COMMAND_HANDLER(handle_flash_banks_command
)
1011 return ERROR_COMMAND_SYNTAX_ERROR
;
1014 for (struct flash_bank
*p
= flash_bank_list(); p
; p
= p
->next
, n
++) {
1015 LOG_USER("#%d : %s (%s) at 0x%8.8" PRIx32
", size 0x%8.8" PRIx32
", "
1016 "buswidth %u, chipwidth %u", p
->bank_number
,
1017 p
->name
, p
->driver
->name
, p
->base
, p
->size
,
1018 p
->bus_width
, p
->chip_width
);
1023 static int jim_flash_list(Jim_Interp
*interp
, int argc
, Jim_Obj
* const *argv
)
1026 Jim_WrongNumArgs(interp
, 1, argv
,
1027 "no arguments to 'flash list' command");
1031 Jim_Obj
*list
= Jim_NewListObj(interp
, NULL
, 0);
1033 for (struct flash_bank
*p
= flash_bank_list(); p
; p
= p
->next
) {
1034 Jim_Obj
*elem
= Jim_NewListObj(interp
, NULL
, 0);
1036 Jim_ListAppendElement(interp
, elem
, Jim_NewStringObj(interp
, "name", -1));
1037 Jim_ListAppendElement(interp
, elem
, Jim_NewStringObj(interp
, p
->driver
->name
, -1));
1038 Jim_ListAppendElement(interp
, elem
, Jim_NewStringObj(interp
, "base", -1));
1039 Jim_ListAppendElement(interp
, elem
, Jim_NewIntObj(interp
, p
->base
));
1040 Jim_ListAppendElement(interp
, elem
, Jim_NewStringObj(interp
, "size", -1));
1041 Jim_ListAppendElement(interp
, elem
, Jim_NewIntObj(interp
, p
->size
));
1042 Jim_ListAppendElement(interp
, elem
, Jim_NewStringObj(interp
, "bus_width", -1));
1043 Jim_ListAppendElement(interp
, elem
, Jim_NewIntObj(interp
, p
->bus_width
));
1044 Jim_ListAppendElement(interp
, elem
, Jim_NewStringObj(interp
, "chip_width", -1));
1045 Jim_ListAppendElement(interp
, elem
, Jim_NewIntObj(interp
, p
->chip_width
));
1047 Jim_ListAppendElement(interp
, list
, elem
);
1050 Jim_SetResult(interp
, list
);
1055 COMMAND_HANDLER(handle_flash_init_command
)
1058 return ERROR_COMMAND_SYNTAX_ERROR
;
1060 static bool flash_initialized
;
1061 if (flash_initialized
) {
1062 LOG_INFO("'flash init' has already been called");
1065 flash_initialized
= true;
1067 LOG_DEBUG("Initializing flash devices...");
1068 return flash_init_drivers(CMD_CTX
);
1071 static const struct command_registration flash_config_command_handlers
[] = {
1074 .handler
= handle_flash_bank_command
,
1075 .mode
= COMMAND_CONFIG
,
1076 .usage
= "bank_id driver_name base_address size_bytes "
1077 "chip_width_bytes bus_width_bytes target "
1078 "[driver_options ...]",
1079 .help
= "Define a new bank with the given name, "
1080 "using the specified NOR flash driver.",
1084 .mode
= COMMAND_CONFIG
,
1085 .handler
= handle_flash_init_command
,
1086 .help
= "Initialize flash devices.",
1090 .mode
= COMMAND_ANY
,
1091 .handler
= handle_flash_banks_command
,
1092 .help
= "Display table with information about flash banks.",
1096 .mode
= COMMAND_ANY
,
1097 .jim_handler
= jim_flash_list
,
1098 .help
= "Returns a list of details about the flash banks.",
1100 COMMAND_REGISTRATION_DONE
1102 static const struct command_registration flash_command_handlers
[] = {
1105 .mode
= COMMAND_ANY
,
1106 .help
= "NOR flash command group",
1107 .chain
= flash_config_command_handlers
,
1109 COMMAND_REGISTRATION_DONE
1112 int flash_register_commands(struct command_context
*cmd_ctx
)
1114 return register_commands(cmd_ctx
, NULL
, flash_command_handlers
);
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)