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, see <http://www.gnu.org/licenses/>. *
19 ***************************************************************************/
24 #include <helper/time_support.h>
25 #include <target/image.h>
29 * Implements Tcl commands used to access NOR flash facilities.
32 COMMAND_HELPER(flash_command_get_bank_maybe_probe
, unsigned name_index
,
33 struct flash_bank
**bank
, bool do_probe
)
35 const char *name
= CMD_ARGV
[name_index
];
38 retval
= get_flash_bank_by_name(name
, bank
);
40 *bank
= get_flash_bank_by_name_noprobe(name
);
44 if (retval
!= ERROR_OK
)
50 COMMAND_PARSE_NUMBER(uint
, name
, bank_num
);
53 return get_flash_bank_by_num(bank_num
, bank
);
55 *bank
= get_flash_bank_by_num_noprobe(bank_num
);
56 retval
= (bank
) ? ERROR_OK
: ERROR_FAIL
;
61 COMMAND_HELPER(flash_command_get_bank
, unsigned name_index
,
62 struct flash_bank
**bank
)
64 return CALL_COMMAND_HANDLER(flash_command_get_bank_maybe_probe
,
65 name_index
, bank
, true);
68 COMMAND_HANDLER(handle_flash_info_command
)
75 return ERROR_COMMAND_SYNTAX_ERROR
;
77 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &p
);
78 if (retval
!= ERROR_OK
)
84 /* attempt auto probe */
85 retval
= p
->driver
->auto_probe(p
);
86 if (retval
!= ERROR_OK
)
89 /* We must query the hardware to avoid printing stale information! */
90 retval
= p
->driver
->protect_check(p
);
91 if (retval
!= ERROR_OK
)
94 command_print(CMD_CTX
,
95 "#%d : %s at 0x%8.8" PRIx32
", size 0x%8.8" PRIx32
96 ", buswidth %i, chipwidth %i",
103 for (j
= 0; j
< p
->num_sectors
; j
++) {
106 if (p
->sectors
[j
].is_protected
== 0)
107 protect_state
= "not protected";
108 else if (p
->sectors
[j
].is_protected
== 1)
109 protect_state
= "protected";
111 protect_state
= "protection state unknown";
113 command_print(CMD_CTX
,
114 "\t#%3i: 0x%8.8" PRIx32
" (0x%" PRIx32
" %" PRIi32
"kB) %s",
116 p
->sectors
[j
].offset
,
118 p
->sectors
[j
].size
>> 10,
122 if (p
->driver
->info
!= NULL
) {
123 retval
= p
->driver
->info(p
, buf
, sizeof(buf
));
124 if (retval
== ERROR_OK
)
125 command_print(CMD_CTX
, "%s", buf
);
127 LOG_ERROR("error retrieving flash info");
134 COMMAND_HANDLER(handle_flash_probe_command
)
136 struct flash_bank
*p
;
140 return ERROR_COMMAND_SYNTAX_ERROR
;
142 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank_maybe_probe
, 0, &p
, false);
143 if (retval
!= ERROR_OK
)
147 retval
= p
->driver
->probe(p
);
148 if (retval
== ERROR_OK
)
149 command_print(CMD_CTX
,
150 "flash '%s' found at 0x%8.8" PRIx32
,
154 command_print(CMD_CTX
, "flash bank '#%s' is out of bounds", CMD_ARGV
[0]);
161 COMMAND_HANDLER(handle_flash_erase_check_command
)
165 return ERROR_COMMAND_SYNTAX_ERROR
;
167 struct flash_bank
*p
;
168 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &p
);
169 if (ERROR_OK
!= retval
)
173 retval
= p
->driver
->erase_check(p
);
174 if (retval
== ERROR_OK
)
175 command_print(CMD_CTX
, "successfully checked erase state");
177 command_print(CMD_CTX
,
178 "unknown error when checking erase state of flash bank #%s at 0x%8.8" PRIx32
,
183 for (j
= 0; j
< p
->num_sectors
; j
++) {
186 if (p
->sectors
[j
].is_erased
== 0)
187 erase_state
= "not erased";
188 else if (p
->sectors
[j
].is_erased
== 1)
191 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,
204 command_print(CMD_CTX
, "\tBank is erased");
208 COMMAND_HANDLER(handle_flash_erase_address_command
)
210 struct flash_bank
*p
;
211 int retval
= ERROR_OK
;
215 bool do_unlock
= false;
216 struct target
*target
= get_current_target(CMD_CTX
);
218 while (CMD_ARGC
>= 3) {
219 /* Optionally pad out the address range to block/sector
220 * boundaries. We can't know if there's data in that part
221 * of the flash; only do padding if we're told to.
223 if (strcmp("pad", CMD_ARGV
[0]) == 0)
225 else if (strcmp("unlock", CMD_ARGV
[0]) == 0)
228 return ERROR_COMMAND_SYNTAX_ERROR
;
233 return ERROR_COMMAND_SYNTAX_ERROR
;
235 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
236 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], length
);
239 command_print(CMD_CTX
, "Length must be >0");
240 return ERROR_COMMAND_SYNTAX_ERROR
;
243 retval
= get_flash_bank_by_addr(target
, address
, true, &p
);
244 if (retval
!= ERROR_OK
)
247 /* We can't know if we did a resume + halt, in which case we no longer know the erased state
251 struct duration bench
;
252 duration_start(&bench
);
255 retval
= flash_unlock_address_range(target
, address
, length
);
257 if (retval
== ERROR_OK
)
258 retval
= flash_erase_address_range(target
, do_pad
, address
, length
);
260 if ((ERROR_OK
== retval
) && (duration_measure(&bench
) == ERROR_OK
)) {
261 command_print(CMD_CTX
, "erased address 0x%8.8" PRIx32
" (length %" PRIi32
")"
262 " in %fs (%0.3f KiB/s)", address
, length
,
263 duration_elapsed(&bench
), duration_kbps(&bench
, length
));
269 static int flash_check_sector_parameters(struct command_context
*cmd_ctx
,
270 uint32_t first
, uint32_t last
, uint32_t num_sectors
)
272 if (!(first
<= last
)) {
273 command_print(cmd_ctx
, "ERROR: "
274 "first sector must be <= last sector");
278 if (!(last
<= (num_sectors
- 1))) {
279 command_print(cmd_ctx
, "ERROR: last sector must be <= %d",
280 (int) num_sectors
- 1);
287 COMMAND_HANDLER(handle_flash_erase_command
)
290 return ERROR_COMMAND_SYNTAX_ERROR
;
295 struct flash_bank
*p
;
298 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &p
);
299 if (retval
!= ERROR_OK
)
302 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], first
);
303 if (strcmp(CMD_ARGV
[2], "last") == 0)
304 last
= p
->num_sectors
- 1;
306 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], last
);
308 retval
= flash_check_sector_parameters(CMD_CTX
, first
, last
, p
->num_sectors
);
309 if (retval
!= ERROR_OK
)
312 struct duration bench
;
313 duration_start(&bench
);
315 retval
= flash_driver_erase(p
, first
, last
);
317 if ((ERROR_OK
== retval
) && (duration_measure(&bench
) == ERROR_OK
)) {
318 command_print(CMD_CTX
, "erased sectors %" PRIu32
" "
319 "through %" PRIu32
" on flash bank %d "
320 "in %fs", first
, last
, p
->bank_number
, duration_elapsed(&bench
));
326 COMMAND_HANDLER(handle_flash_protect_command
)
329 return ERROR_COMMAND_SYNTAX_ERROR
;
334 struct flash_bank
*p
;
337 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &p
);
338 if (retval
!= ERROR_OK
)
341 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], first
);
342 if (strcmp(CMD_ARGV
[2], "last") == 0)
343 last
= p
->num_sectors
- 1;
345 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], last
);
348 COMMAND_PARSE_ON_OFF(CMD_ARGV
[3], set
);
350 retval
= flash_check_sector_parameters(CMD_CTX
, first
, last
, p
->num_sectors
);
351 if (retval
!= ERROR_OK
)
354 retval
= flash_driver_protect(p
, set
, first
, last
);
355 if (retval
== ERROR_OK
) {
356 command_print(CMD_CTX
, "%s protection for sectors %i "
357 "through %i on flash bank %d",
358 (set
) ? "set" : "cleared", (int) first
,
359 (int) last
, p
->bank_number
);
365 COMMAND_HANDLER(handle_flash_write_image_command
)
367 struct target
*target
= get_current_target(CMD_CTX
);
374 /* flash auto-erase is disabled by default*/
376 bool auto_unlock
= false;
379 if (strcmp(CMD_ARGV
[0], "erase") == 0) {
383 command_print(CMD_CTX
, "auto erase enabled");
384 } else if (strcmp(CMD_ARGV
[0], "unlock") == 0) {
388 command_print(CMD_CTX
, "auto unlock enabled");
394 return ERROR_COMMAND_SYNTAX_ERROR
;
397 LOG_ERROR("no target selected");
401 struct duration bench
;
402 duration_start(&bench
);
405 image
.base_address_set
= 1;
406 COMMAND_PARSE_NUMBER(llong
, CMD_ARGV
[1], image
.base_address
);
408 image
.base_address_set
= 0;
409 image
.base_address
= 0x0;
412 image
.start_address_set
= 0;
414 retval
= image_open(&image
, CMD_ARGV
[0], (CMD_ARGC
== 3) ? CMD_ARGV
[2] : NULL
);
415 if (retval
!= ERROR_OK
)
418 retval
= flash_write_unlock(target
, &image
, &written
, auto_erase
, auto_unlock
);
419 if (retval
!= ERROR_OK
) {
424 if ((ERROR_OK
== retval
) && (duration_measure(&bench
) == ERROR_OK
)) {
425 command_print(CMD_CTX
, "wrote %" PRIu32
" bytes from file %s "
426 "in %fs (%0.3f KiB/s)", written
, CMD_ARGV
[0],
427 duration_elapsed(&bench
), duration_kbps(&bench
, written
));
435 COMMAND_HANDLER(handle_flash_fill_command
)
442 uint32_t cur_size
= 0;
443 uint32_t chunk_count
;
444 struct target
*target
= get_current_target(CMD_CTX
);
447 int retval
= ERROR_OK
;
449 static size_t const chunksize
= 1024;
450 uint8_t *chunk
= NULL
, *readback
= NULL
;
453 retval
= ERROR_COMMAND_SYNTAX_ERROR
;
457 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
458 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], pattern
);
459 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], count
);
461 chunk
= malloc(chunksize
);
465 readback
= malloc(chunksize
);
466 if (readback
== NULL
) {
474 switch (CMD_NAME
[4]) {
485 retval
= ERROR_COMMAND_SYNTAX_ERROR
;
489 chunk_count
= MIN(count
, (chunksize
/ wordsize
));
492 for (i
= 0; i
< chunk_count
; i
++)
493 target_buffer_set_u32(target
, chunk
+ i
* wordsize
, pattern
);
496 for (i
= 0; i
< chunk_count
; i
++)
497 target_buffer_set_u16(target
, chunk
+ i
* wordsize
, pattern
);
500 memset(chunk
, pattern
, chunk_count
);
503 LOG_ERROR("BUG: can't happen");
507 struct duration bench
;
508 duration_start(&bench
);
510 for (wrote
= 0; wrote
< (count
*wordsize
); wrote
+= cur_size
) {
511 struct flash_bank
*bank
;
513 retval
= get_flash_bank_by_addr(target
, address
, true, &bank
);
514 if (retval
!= ERROR_OK
)
517 cur_size
= MIN((count
* wordsize
- wrote
), chunksize
);
518 err
= flash_driver_write(bank
, chunk
, address
- bank
->base
+ wrote
, cur_size
);
519 if (err
!= ERROR_OK
) {
524 err
= flash_driver_read(bank
, readback
, address
- bank
->base
+ wrote
, cur_size
);
525 if (err
!= ERROR_OK
) {
530 for (i
= 0; i
< cur_size
; i
++) {
531 if (readback
[i
] != chunk
[i
]) {
533 "Verification error address 0x%08" PRIx32
", read back 0x%02x, expected 0x%02x",
543 if ((retval
== ERROR_OK
) && (duration_measure(&bench
) == ERROR_OK
)) {
544 command_print(CMD_CTX
, "wrote %" PRIu32
" bytes to 0x%8.8" PRIx32
545 " in %fs (%0.3f KiB/s)", wrote
, address
,
546 duration_elapsed(&bench
), duration_kbps(&bench
, wrote
));
556 COMMAND_HANDLER(handle_flash_write_bank_command
)
560 struct fileio
*fileio
;
563 return ERROR_COMMAND_SYNTAX_ERROR
;
565 struct duration bench
;
566 duration_start(&bench
);
568 struct flash_bank
*p
;
569 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &p
);
570 if (ERROR_OK
!= retval
)
573 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], offset
);
575 if (fileio_open(&fileio
, CMD_ARGV
[1], FILEIO_READ
, FILEIO_BINARY
) != ERROR_OK
)
579 retval
= fileio_size(fileio
, &filesize
);
580 if (retval
!= ERROR_OK
) {
581 fileio_close(fileio
);
585 buffer
= malloc(filesize
);
586 if (buffer
== NULL
) {
587 fileio_close(fileio
);
588 LOG_ERROR("Out of memory");
592 if (fileio_read(fileio
, filesize
, buffer
, &buf_cnt
) != ERROR_OK
) {
594 fileio_close(fileio
);
598 retval
= flash_driver_write(p
, buffer
, offset
, buf_cnt
);
603 if ((ERROR_OK
== retval
) && (duration_measure(&bench
) == ERROR_OK
)) {
604 command_print(CMD_CTX
, "wrote %zu bytes from file %s to flash bank %u"
605 " at offset 0x%8.8" PRIx32
" in %fs (%0.3f KiB/s)",
606 filesize
, CMD_ARGV
[1], p
->bank_number
, offset
,
607 duration_elapsed(&bench
), duration_kbps(&bench
, filesize
));
610 fileio_close(fileio
);
615 COMMAND_HANDLER(handle_flash_read_bank_command
)
619 struct fileio
*fileio
;
624 return ERROR_COMMAND_SYNTAX_ERROR
;
626 struct duration bench
;
627 duration_start(&bench
);
629 struct flash_bank
*p
;
630 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &p
);
631 if (ERROR_OK
!= retval
)
634 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], offset
);
635 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[3], length
);
637 buffer
= malloc(length
);
638 if (buffer
== NULL
) {
639 LOG_ERROR("Out of memory");
643 retval
= flash_driver_read(p
, buffer
, offset
, length
);
644 if (retval
!= ERROR_OK
) {
645 LOG_ERROR("Read error");
650 retval
= fileio_open(&fileio
, CMD_ARGV
[1], FILEIO_WRITE
, FILEIO_BINARY
);
651 if (retval
!= ERROR_OK
) {
652 LOG_ERROR("Could not open file");
657 retval
= fileio_write(fileio
, length
, buffer
, &written
);
658 fileio_close(fileio
);
660 if (retval
!= ERROR_OK
) {
661 LOG_ERROR("Could not write file");
665 if (duration_measure(&bench
) == ERROR_OK
)
666 command_print(CMD_CTX
, "wrote %ld bytes to file %s from flash bank %u"
667 " at offset 0x%8.8" PRIx32
" in %fs (%0.3f KiB/s)",
668 (long)written
, CMD_ARGV
[1], p
->bank_number
, offset
,
669 duration_elapsed(&bench
), duration_kbps(&bench
, written
));
675 COMMAND_HANDLER(handle_flash_verify_bank_command
)
678 uint8_t *buffer_file
, *buffer_flash
;
679 struct fileio
*fileio
;
685 return ERROR_COMMAND_SYNTAX_ERROR
;
687 struct duration bench
;
688 duration_start(&bench
);
690 struct flash_bank
*p
;
691 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &p
);
692 if (ERROR_OK
!= retval
)
695 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], offset
);
697 retval
= fileio_open(&fileio
, CMD_ARGV
[1], FILEIO_READ
, FILEIO_BINARY
);
698 if (retval
!= ERROR_OK
) {
699 LOG_ERROR("Could not open file");
703 retval
= fileio_size(fileio
, &filesize
);
704 if (retval
!= ERROR_OK
) {
705 fileio_close(fileio
);
709 buffer_file
= malloc(filesize
);
710 if (buffer_file
== NULL
) {
711 LOG_ERROR("Out of memory");
712 fileio_close(fileio
);
716 retval
= fileio_read(fileio
, filesize
, buffer_file
, &read_cnt
);
717 fileio_close(fileio
);
718 if (retval
!= ERROR_OK
) {
719 LOG_ERROR("File read failure");
724 if (read_cnt
!= filesize
) {
725 LOG_ERROR("Short read");
730 buffer_flash
= malloc(filesize
);
731 if (buffer_flash
== NULL
) {
732 LOG_ERROR("Out of memory");
737 retval
= flash_driver_read(p
, buffer_flash
, offset
, read_cnt
);
738 if (retval
!= ERROR_OK
) {
739 LOG_ERROR("Flash read error");
745 if (duration_measure(&bench
) == ERROR_OK
)
746 command_print(CMD_CTX
, "read %ld bytes from file %s and flash bank %u"
747 " at offset 0x%8.8" PRIx32
" in %fs (%0.3f KiB/s)",
748 (long)read_cnt
, CMD_ARGV
[1], p
->bank_number
, offset
,
749 duration_elapsed(&bench
), duration_kbps(&bench
, read_cnt
));
751 differ
= memcmp(buffer_file
, buffer_flash
, read_cnt
);
752 command_print(CMD_CTX
, "contents %s", differ
? "differ" : "match");
756 for (t
= 0; t
< read_cnt
; t
++) {
757 if (buffer_flash
[t
] == buffer_file
[t
])
759 command_print(CMD_CTX
, "diff %d address 0x%08x. Was 0x%02x instead of 0x%02x",
760 diffs
, t
+ offset
, buffer_flash
[t
], buffer_file
[t
]);
761 if (diffs
++ >= 127) {
762 command_print(CMD_CTX
, "More than 128 errors, the rest are not printed.");
771 return differ
? ERROR_FAIL
: ERROR_OK
;
774 void flash_set_dirty(void)
776 struct flash_bank
*c
;
779 /* set all flash to require erasing */
780 for (c
= flash_bank_list(); c
; c
= c
->next
) {
781 for (i
= 0; i
< c
->num_sectors
; i
++)
782 c
->sectors
[i
].is_erased
= 0;
786 COMMAND_HANDLER(handle_flash_padded_value_command
)
789 return ERROR_COMMAND_SYNTAX_ERROR
;
791 struct flash_bank
*p
;
792 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &p
);
793 if (ERROR_OK
!= retval
)
796 COMMAND_PARSE_NUMBER(u8
, CMD_ARGV
[1], p
->default_padded_value
);
798 command_print(CMD_CTX
, "Default padded value set to 0x%" PRIx8
" for flash bank %u", \
799 p
->default_padded_value
, p
->bank_number
);
804 static const struct command_registration flash_exec_command_handlers
[] = {
807 .handler
= handle_flash_probe_command
,
808 .mode
= COMMAND_EXEC
,
810 .help
= "Identify a flash bank.",
814 .handler
= handle_flash_info_command
,
815 .mode
= COMMAND_EXEC
,
817 .help
= "Print information about a flash bank.",
820 .name
= "erase_check",
821 .handler
= handle_flash_erase_check_command
,
822 .mode
= COMMAND_EXEC
,
824 .help
= "Check erase state of all blocks in a "
828 .name
= "erase_sector",
829 .handler
= handle_flash_erase_command
,
830 .mode
= COMMAND_EXEC
,
831 .usage
= "bank_id first_sector_num last_sector_num",
832 .help
= "Erase a range of sectors in a flash bank.",
835 .name
= "erase_address",
836 .handler
= handle_flash_erase_address_command
,
837 .mode
= COMMAND_EXEC
,
838 .usage
= "['pad'] ['unlock'] address length",
839 .help
= "Erase flash sectors starting at address and "
840 "continuing for length bytes. If 'pad' is specified, "
841 "data outside that range may also be erased: the start "
842 "address may be decreased, and length increased, so "
843 "that all of the first and last sectors are erased. "
844 "If 'unlock' is specified, then the flash is unprotected "
850 .handler
= handle_flash_fill_command
,
851 .mode
= COMMAND_EXEC
,
852 .usage
= "address value n",
853 .help
= "Fill n words with 32-bit value, starting at "
854 "word address. (No autoerase.)",
858 .handler
= handle_flash_fill_command
,
859 .mode
= COMMAND_EXEC
,
860 .usage
= "address value n",
861 .help
= "Fill n halfwords with 16-bit value, starting at "
862 "word address. (No autoerase.)",
866 .handler
= handle_flash_fill_command
,
867 .mode
= COMMAND_EXEC
,
868 .usage
= "address value n",
869 .help
= "Fill n bytes with 8-bit value, starting at "
870 "word address. (No autoerase.)",
873 .name
= "write_bank",
874 .handler
= handle_flash_write_bank_command
,
875 .mode
= COMMAND_EXEC
,
876 .usage
= "bank_id filename offset",
877 .help
= "Write binary data from file to flash bank, "
878 "starting at specified byte offset from the "
879 "beginning of the bank.",
882 .name
= "write_image",
883 .handler
= handle_flash_write_image_command
,
884 .mode
= COMMAND_EXEC
,
885 .usage
= "[erase] [unlock] filename [offset [file_type]]",
886 .help
= "Write an image to flash. Optionally first unprotect "
887 "and/or erase the region to be used. Allow optional "
888 "offset from beginning of bank (defaults to zero)",
892 .handler
= handle_flash_read_bank_command
,
893 .mode
= COMMAND_EXEC
,
894 .usage
= "bank_id filename offset length",
895 .help
= "Read binary data from flash bank to file, "
896 "starting at specified byte offset from the "
897 "beginning of the bank.",
900 .name
= "verify_bank",
901 .handler
= handle_flash_verify_bank_command
,
902 .mode
= COMMAND_EXEC
,
903 .usage
= "bank_id filename offset",
904 .help
= "Read binary data from flash bank and file, "
905 "starting at specified byte offset from the "
906 "beginning of the bank. Compare the contents.",
910 .handler
= handle_flash_protect_command
,
911 .mode
= COMMAND_EXEC
,
912 .usage
= "bank_id first_sector [last_sector|'last'] "
914 .help
= "Turn protection on or off for a range of sectors "
915 "in a given flash bank.",
918 .name
= "padded_value",
919 .handler
= handle_flash_padded_value_command
,
920 .mode
= COMMAND_EXEC
,
921 .usage
= "bank_id value",
922 .help
= "Set default flash padded value",
924 COMMAND_REGISTRATION_DONE
927 static int flash_init_drivers(struct command_context
*cmd_ctx
)
929 if (!flash_bank_list())
932 struct command
*parent
= command_find_in_context(cmd_ctx
, "flash");
933 return register_commands(cmd_ctx
, parent
, flash_exec_command_handlers
);
936 COMMAND_HANDLER(handle_flash_bank_command
)
939 LOG_ERROR("usage: flash bank <name> <driver> "
940 "<base> <size> <chip_width> <bus_width> <target>");
941 return ERROR_COMMAND_SYNTAX_ERROR
;
943 /* save bank name and advance arguments for compatibility */
944 const char *bank_name
= *CMD_ARGV
++;
947 struct target
*target
= get_target(CMD_ARGV
[5]);
948 if (target
== NULL
) {
949 LOG_ERROR("target '%s' not defined", CMD_ARGV
[5]);
953 const char *driver_name
= CMD_ARGV
[0];
954 struct flash_driver
*driver
= flash_driver_find_by_name(driver_name
);
955 if (NULL
== driver
) {
956 /* no matching flash driver found */
957 LOG_ERROR("flash driver '%s' not found", driver_name
);
961 /* check the flash bank name is unique */
962 if (get_flash_bank_by_name_noprobe(bank_name
) != NULL
) {
963 /* flash bank name already exists */
964 LOG_ERROR("flash bank name '%s' already exists", bank_name
);
968 /* register flash specific commands */
969 if (NULL
!= driver
->commands
) {
970 int retval
= register_commands(CMD_CTX
, NULL
,
972 if (ERROR_OK
!= retval
) {
973 LOG_ERROR("couldn't register '%s' commands",
979 struct flash_bank
*c
= malloc(sizeof(*c
));
980 c
->name
= strdup(bank_name
);
983 c
->driver_priv
= NULL
;
984 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], c
->base
);
985 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], c
->size
);
986 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[3], c
->chip_width
);
987 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[4], c
->bus_width
);
988 c
->default_padded_value
= 0xff;
994 retval
= CALL_COMMAND_HANDLER(driver
->flash_bank_command
, c
);
995 if (ERROR_OK
!= retval
) {
996 LOG_ERROR("'%s' driver rejected flash bank at 0x%8.8" PRIx32
"; usage: %s",
997 driver_name
, c
->base
, driver
->usage
);
1002 if (driver
->usage
== NULL
)
1003 LOG_DEBUG("'%s' driver usage field missing", driver_name
);
1010 COMMAND_HANDLER(handle_flash_banks_command
)
1013 return ERROR_COMMAND_SYNTAX_ERROR
;
1016 for (struct flash_bank
*p
= flash_bank_list(); p
; p
= p
->next
, n
++) {
1017 LOG_USER("#%d : %s (%s) at 0x%8.8" PRIx32
", size 0x%8.8" PRIx32
", "
1018 "buswidth %u, chipwidth %u", p
->bank_number
,
1019 p
->name
, p
->driver
->name
, p
->base
, p
->size
,
1020 p
->bus_width
, p
->chip_width
);
1025 static int jim_flash_list(Jim_Interp
*interp
, int argc
, Jim_Obj
* const *argv
)
1028 Jim_WrongNumArgs(interp
, 1, argv
,
1029 "no arguments to 'flash list' command");
1033 Jim_Obj
*list
= Jim_NewListObj(interp
, NULL
, 0);
1035 for (struct flash_bank
*p
= flash_bank_list(); p
; p
= p
->next
) {
1036 Jim_Obj
*elem
= Jim_NewListObj(interp
, NULL
, 0);
1038 Jim_ListAppendElement(interp
, elem
, Jim_NewStringObj(interp
, "name", -1));
1039 Jim_ListAppendElement(interp
, elem
, Jim_NewStringObj(interp
, p
->driver
->name
, -1));
1040 Jim_ListAppendElement(interp
, elem
, Jim_NewStringObj(interp
, "base", -1));
1041 Jim_ListAppendElement(interp
, elem
, Jim_NewIntObj(interp
, p
->base
));
1042 Jim_ListAppendElement(interp
, elem
, Jim_NewStringObj(interp
, "size", -1));
1043 Jim_ListAppendElement(interp
, elem
, Jim_NewIntObj(interp
, p
->size
));
1044 Jim_ListAppendElement(interp
, elem
, Jim_NewStringObj(interp
, "bus_width", -1));
1045 Jim_ListAppendElement(interp
, elem
, Jim_NewIntObj(interp
, p
->bus_width
));
1046 Jim_ListAppendElement(interp
, elem
, Jim_NewStringObj(interp
, "chip_width", -1));
1047 Jim_ListAppendElement(interp
, elem
, Jim_NewIntObj(interp
, p
->chip_width
));
1049 Jim_ListAppendElement(interp
, list
, elem
);
1052 Jim_SetResult(interp
, list
);
1057 COMMAND_HANDLER(handle_flash_init_command
)
1060 return ERROR_COMMAND_SYNTAX_ERROR
;
1062 static bool flash_initialized
;
1063 if (flash_initialized
) {
1064 LOG_INFO("'flash init' has already been called");
1067 flash_initialized
= true;
1069 LOG_DEBUG("Initializing flash devices...");
1070 return flash_init_drivers(CMD_CTX
);
1073 static const struct command_registration flash_config_command_handlers
[] = {
1076 .handler
= handle_flash_bank_command
,
1077 .mode
= COMMAND_CONFIG
,
1078 .usage
= "bank_id driver_name base_address size_bytes "
1079 "chip_width_bytes bus_width_bytes target "
1080 "[driver_options ...]",
1081 .help
= "Define a new bank with the given name, "
1082 "using the specified NOR flash driver.",
1086 .mode
= COMMAND_CONFIG
,
1087 .handler
= handle_flash_init_command
,
1088 .help
= "Initialize flash devices.",
1092 .mode
= COMMAND_ANY
,
1093 .handler
= handle_flash_banks_command
,
1094 .help
= "Display table with information about flash banks.",
1098 .mode
= COMMAND_ANY
,
1099 .jim_handler
= jim_flash_list
,
1100 .help
= "Returns a list of details about the flash banks.",
1102 COMMAND_REGISTRATION_DONE
1104 static const struct command_registration flash_command_handlers
[] = {
1107 .mode
= COMMAND_ANY
,
1108 .help
= "NOR flash command group",
1109 .chain
= flash_config_command_handlers
,
1111 COMMAND_REGISTRATION_DONE
1114 int flash_register_commands(struct command_context
*cmd_ctx
)
1116 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)