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
)
73 bool show_sectors
= false;
74 bool prot_block_available
;
76 if (CMD_ARGC
< 1 || CMD_ARGC
> 2)
77 return ERROR_COMMAND_SYNTAX_ERROR
;
80 if (strcmp("sectors", CMD_ARGV
[1]) == 0)
83 return ERROR_COMMAND_SYNTAX_ERROR
;
86 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &p
);
87 if (retval
!= ERROR_OK
)
93 struct flash_sector
*block_array
;
95 /* attempt auto probe */
96 retval
= p
->driver
->auto_probe(p
);
97 if (retval
!= ERROR_OK
)
100 /* We must query the hardware to avoid printing stale information! */
101 retval
= p
->driver
->protect_check(p
);
102 if (retval
!= ERROR_OK
)
105 command_print(CMD_CTX
,
106 "#%d : %s at 0x%8.8" PRIx32
", size 0x%8.8" PRIx32
107 ", buswidth %i, chipwidth %i",
115 prot_block_available
= p
->num_prot_blocks
&& p
->prot_blocks
;
116 if (!show_sectors
&& prot_block_available
) {
117 block_array
= p
->prot_blocks
;
118 num_blocks
= p
->num_prot_blocks
;
120 block_array
= p
->sectors
;
121 num_blocks
= p
->num_sectors
;
124 for (j
= 0; j
< num_blocks
; j
++) {
125 char *protect_state
= "";
127 if (block_array
[j
].is_protected
== 0)
128 protect_state
= "not protected";
129 else if (block_array
[j
].is_protected
== 1)
130 protect_state
= "protected";
131 else if (!show_sectors
|| !prot_block_available
)
132 protect_state
= "protection state unknown";
134 command_print(CMD_CTX
,
135 "\t#%3i: 0x%8.8" PRIx32
" (0x%" PRIx32
" %" PRIi32
"kB) %s",
137 block_array
[j
].offset
,
139 block_array
[j
].size
>> 10,
143 if (p
->driver
->info
!= NULL
) {
144 retval
= p
->driver
->info(p
, buf
, sizeof(buf
));
145 if (retval
== ERROR_OK
)
146 command_print(CMD_CTX
, "%s", buf
);
148 LOG_ERROR("error retrieving flash info");
155 COMMAND_HANDLER(handle_flash_probe_command
)
157 struct flash_bank
*p
;
161 return ERROR_COMMAND_SYNTAX_ERROR
;
163 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank_maybe_probe
, 0, &p
, false);
164 if (retval
!= ERROR_OK
)
168 retval
= p
->driver
->probe(p
);
169 if (retval
== ERROR_OK
)
170 command_print(CMD_CTX
,
171 "flash '%s' found at 0x%8.8" PRIx32
,
175 command_print(CMD_CTX
, "flash bank '#%s' is out of bounds", CMD_ARGV
[0]);
182 COMMAND_HANDLER(handle_flash_erase_check_command
)
186 return ERROR_COMMAND_SYNTAX_ERROR
;
188 struct flash_bank
*p
;
189 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &p
);
190 if (ERROR_OK
!= retval
)
194 retval
= p
->driver
->erase_check(p
);
195 if (retval
== ERROR_OK
)
196 command_print(CMD_CTX
, "successfully checked erase state");
198 command_print(CMD_CTX
,
199 "unknown error when checking erase state of flash bank #%s at 0x%8.8" PRIx32
,
204 for (j
= 0; j
< p
->num_sectors
; j
++) {
207 if (p
->sectors
[j
].is_erased
== 0)
208 erase_state
= "not erased";
209 else if (p
->sectors
[j
].is_erased
== 1)
212 erase_state
= "erase state unknown";
215 command_print(CMD_CTX
,
216 "\t#%3i: 0x%8.8" PRIx32
" (0x%" PRIx32
" %" PRIi32
"kB) %s",
218 p
->sectors
[j
].offset
,
220 p
->sectors
[j
].size
>> 10,
225 command_print(CMD_CTX
, "\tBank is erased");
229 COMMAND_HANDLER(handle_flash_erase_address_command
)
231 struct flash_bank
*p
;
232 int retval
= ERROR_OK
;
236 bool do_unlock
= false;
237 struct target
*target
= get_current_target(CMD_CTX
);
239 while (CMD_ARGC
>= 3) {
240 /* Optionally pad out the address range to block/sector
241 * boundaries. We can't know if there's data in that part
242 * of the flash; only do padding if we're told to.
244 if (strcmp("pad", CMD_ARGV
[0]) == 0)
246 else if (strcmp("unlock", CMD_ARGV
[0]) == 0)
249 return ERROR_COMMAND_SYNTAX_ERROR
;
254 return ERROR_COMMAND_SYNTAX_ERROR
;
256 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
257 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], length
);
260 command_print(CMD_CTX
, "Length must be >0");
261 return ERROR_COMMAND_SYNTAX_ERROR
;
264 retval
= get_flash_bank_by_addr(target
, address
, true, &p
);
265 if (retval
!= ERROR_OK
)
268 /* We can't know if we did a resume + halt, in which case we no longer know the erased state
272 struct duration bench
;
273 duration_start(&bench
);
276 retval
= flash_unlock_address_range(target
, address
, length
);
278 if (retval
== ERROR_OK
)
279 retval
= flash_erase_address_range(target
, do_pad
, address
, length
);
281 if ((ERROR_OK
== retval
) && (duration_measure(&bench
) == ERROR_OK
)) {
282 command_print(CMD_CTX
, "erased address 0x%8.8" PRIx32
" (length %" PRIi32
")"
283 " in %fs (%0.3f KiB/s)", address
, length
,
284 duration_elapsed(&bench
), duration_kbps(&bench
, length
));
290 static int flash_check_sector_parameters(struct command_context
*cmd_ctx
,
291 uint32_t first
, uint32_t last
, uint32_t num_sectors
)
293 if (!(first
<= last
)) {
294 command_print(cmd_ctx
, "ERROR: "
295 "first sector must be <= last sector");
299 if (!(last
<= (num_sectors
- 1))) {
300 command_print(cmd_ctx
, "ERROR: last sector must be <= %" PRIu32
,
308 COMMAND_HANDLER(handle_flash_erase_command
)
311 return ERROR_COMMAND_SYNTAX_ERROR
;
316 struct flash_bank
*p
;
319 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &p
);
320 if (retval
!= ERROR_OK
)
323 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], first
);
324 if (strcmp(CMD_ARGV
[2], "last") == 0)
325 last
= p
->num_sectors
- 1;
327 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], last
);
329 retval
= flash_check_sector_parameters(CMD_CTX
, first
, last
, p
->num_sectors
);
330 if (retval
!= ERROR_OK
)
333 struct duration bench
;
334 duration_start(&bench
);
336 retval
= flash_driver_erase(p
, first
, last
);
338 if ((ERROR_OK
== retval
) && (duration_measure(&bench
) == ERROR_OK
)) {
339 command_print(CMD_CTX
, "erased sectors %" PRIu32
" "
340 "through %" PRIu32
" on flash bank %d "
341 "in %fs", first
, last
, p
->bank_number
, duration_elapsed(&bench
));
347 COMMAND_HANDLER(handle_flash_protect_command
)
350 return ERROR_COMMAND_SYNTAX_ERROR
;
355 struct flash_bank
*p
;
359 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &p
);
360 if (retval
!= ERROR_OK
)
363 if (p
->num_prot_blocks
)
364 num_blocks
= p
->num_prot_blocks
;
366 num_blocks
= p
->num_sectors
;
368 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], first
);
369 if (strcmp(CMD_ARGV
[2], "last") == 0)
370 last
= num_blocks
- 1;
372 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], last
);
375 COMMAND_PARSE_ON_OFF(CMD_ARGV
[3], set
);
377 retval
= flash_check_sector_parameters(CMD_CTX
, first
, last
, num_blocks
);
378 if (retval
!= ERROR_OK
)
381 retval
= flash_driver_protect(p
, set
, first
, last
);
382 if (retval
== ERROR_OK
) {
383 command_print(CMD_CTX
, "%s protection for sectors %" PRIu32
384 " through %" PRIu32
" on flash bank %d",
385 (set
) ? "set" : "cleared", first
, last
, p
->bank_number
);
391 COMMAND_HANDLER(handle_flash_write_image_command
)
393 struct target
*target
= get_current_target(CMD_CTX
);
400 /* flash auto-erase is disabled by default*/
402 bool auto_unlock
= false;
405 if (strcmp(CMD_ARGV
[0], "erase") == 0) {
409 command_print(CMD_CTX
, "auto erase enabled");
410 } else if (strcmp(CMD_ARGV
[0], "unlock") == 0) {
414 command_print(CMD_CTX
, "auto unlock enabled");
420 return ERROR_COMMAND_SYNTAX_ERROR
;
423 LOG_ERROR("no target selected");
427 struct duration bench
;
428 duration_start(&bench
);
431 image
.base_address_set
= 1;
432 COMMAND_PARSE_NUMBER(llong
, CMD_ARGV
[1], image
.base_address
);
434 image
.base_address_set
= 0;
435 image
.base_address
= 0x0;
438 image
.start_address_set
= 0;
440 retval
= image_open(&image
, CMD_ARGV
[0], (CMD_ARGC
== 3) ? CMD_ARGV
[2] : NULL
);
441 if (retval
!= ERROR_OK
)
444 retval
= flash_write_unlock(target
, &image
, &written
, auto_erase
, auto_unlock
);
445 if (retval
!= ERROR_OK
) {
450 if ((ERROR_OK
== retval
) && (duration_measure(&bench
) == ERROR_OK
)) {
451 command_print(CMD_CTX
, "wrote %" PRIu32
" bytes from file %s "
452 "in %fs (%0.3f KiB/s)", written
, CMD_ARGV
[0],
453 duration_elapsed(&bench
), duration_kbps(&bench
, written
));
461 COMMAND_HANDLER(handle_flash_fill_command
)
468 uint32_t cur_size
= 0;
469 uint32_t chunk_count
;
470 struct target
*target
= get_current_target(CMD_CTX
);
473 int retval
= ERROR_OK
;
475 static size_t const chunksize
= 1024;
476 uint8_t *chunk
= NULL
, *readback
= NULL
;
479 retval
= ERROR_COMMAND_SYNTAX_ERROR
;
483 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
484 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], pattern
);
485 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], count
);
487 chunk
= malloc(chunksize
);
491 readback
= malloc(chunksize
);
492 if (readback
== NULL
) {
500 switch (CMD_NAME
[4]) {
511 retval
= ERROR_COMMAND_SYNTAX_ERROR
;
515 chunk_count
= MIN(count
, (chunksize
/ wordsize
));
518 for (i
= 0; i
< chunk_count
; i
++)
519 target_buffer_set_u32(target
, chunk
+ i
* wordsize
, pattern
);
522 for (i
= 0; i
< chunk_count
; i
++)
523 target_buffer_set_u16(target
, chunk
+ i
* wordsize
, pattern
);
526 memset(chunk
, pattern
, chunk_count
);
529 LOG_ERROR("BUG: can't happen");
533 struct duration bench
;
534 duration_start(&bench
);
536 for (wrote
= 0; wrote
< (count
*wordsize
); wrote
+= cur_size
) {
537 struct flash_bank
*bank
;
539 retval
= get_flash_bank_by_addr(target
, address
, true, &bank
);
540 if (retval
!= ERROR_OK
)
543 cur_size
= MIN((count
* wordsize
- wrote
), chunksize
);
544 err
= flash_driver_write(bank
, chunk
, address
- bank
->base
+ wrote
, cur_size
);
545 if (err
!= ERROR_OK
) {
550 err
= flash_driver_read(bank
, readback
, address
- bank
->base
+ wrote
, cur_size
);
551 if (err
!= ERROR_OK
) {
556 for (i
= 0; i
< cur_size
; i
++) {
557 if (readback
[i
] != chunk
[i
]) {
559 "Verification error address 0x%08" PRIx32
", read back 0x%02x, expected 0x%02x",
569 if ((retval
== ERROR_OK
) && (duration_measure(&bench
) == ERROR_OK
)) {
570 command_print(CMD_CTX
, "wrote %" PRIu32
" bytes to 0x%8.8" PRIx32
571 " in %fs (%0.3f KiB/s)", wrote
, address
,
572 duration_elapsed(&bench
), duration_kbps(&bench
, wrote
));
582 COMMAND_HANDLER(handle_flash_write_bank_command
)
586 struct fileio
*fileio
;
589 return ERROR_COMMAND_SYNTAX_ERROR
;
591 struct duration bench
;
592 duration_start(&bench
);
594 struct flash_bank
*p
;
595 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &p
);
596 if (ERROR_OK
!= retval
)
599 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], offset
);
601 if (fileio_open(&fileio
, CMD_ARGV
[1], FILEIO_READ
, FILEIO_BINARY
) != ERROR_OK
)
605 retval
= fileio_size(fileio
, &filesize
);
606 if (retval
!= ERROR_OK
) {
607 fileio_close(fileio
);
611 buffer
= malloc(filesize
);
612 if (buffer
== NULL
) {
613 fileio_close(fileio
);
614 LOG_ERROR("Out of memory");
618 if (fileio_read(fileio
, filesize
, buffer
, &buf_cnt
) != ERROR_OK
) {
620 fileio_close(fileio
);
624 retval
= flash_driver_write(p
, buffer
, offset
, buf_cnt
);
629 if ((ERROR_OK
== retval
) && (duration_measure(&bench
) == ERROR_OK
)) {
630 command_print(CMD_CTX
, "wrote %zu bytes from file %s to flash bank %u"
631 " at offset 0x%8.8" PRIx32
" in %fs (%0.3f KiB/s)",
632 filesize
, CMD_ARGV
[1], p
->bank_number
, offset
,
633 duration_elapsed(&bench
), duration_kbps(&bench
, filesize
));
636 fileio_close(fileio
);
641 COMMAND_HANDLER(handle_flash_read_bank_command
)
645 struct fileio
*fileio
;
650 return ERROR_COMMAND_SYNTAX_ERROR
;
652 struct duration bench
;
653 duration_start(&bench
);
655 struct flash_bank
*p
;
656 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &p
);
657 if (ERROR_OK
!= retval
)
660 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], offset
);
661 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[3], length
);
663 buffer
= malloc(length
);
664 if (buffer
== NULL
) {
665 LOG_ERROR("Out of memory");
669 retval
= flash_driver_read(p
, buffer
, offset
, length
);
670 if (retval
!= ERROR_OK
) {
671 LOG_ERROR("Read error");
676 retval
= fileio_open(&fileio
, CMD_ARGV
[1], FILEIO_WRITE
, FILEIO_BINARY
);
677 if (retval
!= ERROR_OK
) {
678 LOG_ERROR("Could not open file");
683 retval
= fileio_write(fileio
, length
, buffer
, &written
);
684 fileio_close(fileio
);
686 if (retval
!= ERROR_OK
) {
687 LOG_ERROR("Could not write file");
691 if (duration_measure(&bench
) == ERROR_OK
)
692 command_print(CMD_CTX
, "wrote %zd bytes to file %s from flash bank %u"
693 " at offset 0x%8.8" PRIx32
" in %fs (%0.3f KiB/s)",
694 written
, CMD_ARGV
[1], p
->bank_number
, offset
,
695 duration_elapsed(&bench
), duration_kbps(&bench
, written
));
701 COMMAND_HANDLER(handle_flash_verify_bank_command
)
704 uint8_t *buffer_file
, *buffer_flash
;
705 struct fileio
*fileio
;
711 return ERROR_COMMAND_SYNTAX_ERROR
;
713 struct duration bench
;
714 duration_start(&bench
);
716 struct flash_bank
*p
;
717 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &p
);
718 if (ERROR_OK
!= retval
)
721 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], offset
);
723 retval
= fileio_open(&fileio
, CMD_ARGV
[1], FILEIO_READ
, FILEIO_BINARY
);
724 if (retval
!= ERROR_OK
) {
725 LOG_ERROR("Could not open file");
729 retval
= fileio_size(fileio
, &filesize
);
730 if (retval
!= ERROR_OK
) {
731 fileio_close(fileio
);
735 buffer_file
= malloc(filesize
);
736 if (buffer_file
== NULL
) {
737 LOG_ERROR("Out of memory");
738 fileio_close(fileio
);
742 retval
= fileio_read(fileio
, filesize
, buffer_file
, &read_cnt
);
743 fileio_close(fileio
);
744 if (retval
!= ERROR_OK
) {
745 LOG_ERROR("File read failure");
750 if (read_cnt
!= filesize
) {
751 LOG_ERROR("Short read");
756 buffer_flash
= malloc(filesize
);
757 if (buffer_flash
== NULL
) {
758 LOG_ERROR("Out of memory");
763 retval
= flash_driver_read(p
, buffer_flash
, offset
, read_cnt
);
764 if (retval
!= ERROR_OK
) {
765 LOG_ERROR("Flash read error");
771 if (duration_measure(&bench
) == ERROR_OK
)
772 command_print(CMD_CTX
, "read %zd bytes from file %s and flash bank %u"
773 " at offset 0x%8.8" PRIx32
" in %fs (%0.3f KiB/s)",
774 read_cnt
, CMD_ARGV
[1], p
->bank_number
, offset
,
775 duration_elapsed(&bench
), duration_kbps(&bench
, read_cnt
));
777 differ
= memcmp(buffer_file
, buffer_flash
, read_cnt
);
778 command_print(CMD_CTX
, "contents %s", differ
? "differ" : "match");
782 for (t
= 0; t
< read_cnt
; t
++) {
783 if (buffer_flash
[t
] == buffer_file
[t
])
785 command_print(CMD_CTX
, "diff %d address 0x%08x. Was 0x%02x instead of 0x%02x",
786 diffs
, t
+ offset
, buffer_flash
[t
], buffer_file
[t
]);
787 if (diffs
++ >= 127) {
788 command_print(CMD_CTX
, "More than 128 errors, the rest are not printed.");
797 return differ
? ERROR_FAIL
: ERROR_OK
;
800 void flash_set_dirty(void)
802 struct flash_bank
*c
;
805 /* set all flash to require erasing */
806 for (c
= flash_bank_list(); c
; c
= c
->next
) {
807 for (i
= 0; i
< c
->num_sectors
; i
++)
808 c
->sectors
[i
].is_erased
= 0;
812 COMMAND_HANDLER(handle_flash_padded_value_command
)
815 return ERROR_COMMAND_SYNTAX_ERROR
;
817 struct flash_bank
*p
;
818 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &p
);
819 if (ERROR_OK
!= retval
)
822 COMMAND_PARSE_NUMBER(u8
, CMD_ARGV
[1], p
->default_padded_value
);
824 command_print(CMD_CTX
, "Default padded value set to 0x%" PRIx8
" for flash bank %u", \
825 p
->default_padded_value
, p
->bank_number
);
830 static const struct command_registration flash_exec_command_handlers
[] = {
833 .handler
= handle_flash_probe_command
,
834 .mode
= COMMAND_EXEC
,
836 .help
= "Identify a flash bank.",
840 .handler
= handle_flash_info_command
,
841 .mode
= COMMAND_EXEC
,
842 .usage
= "bank_id ['sectors']",
843 .help
= "Print information about a flash bank.",
846 .name
= "erase_check",
847 .handler
= handle_flash_erase_check_command
,
848 .mode
= COMMAND_EXEC
,
850 .help
= "Check erase state of all blocks in a "
854 .name
= "erase_sector",
855 .handler
= handle_flash_erase_command
,
856 .mode
= COMMAND_EXEC
,
857 .usage
= "bank_id first_sector_num last_sector_num",
858 .help
= "Erase a range of sectors in a flash bank.",
861 .name
= "erase_address",
862 .handler
= handle_flash_erase_address_command
,
863 .mode
= COMMAND_EXEC
,
864 .usage
= "['pad'] ['unlock'] address length",
865 .help
= "Erase flash sectors starting at address and "
866 "continuing for length bytes. If 'pad' is specified, "
867 "data outside that range may also be erased: the start "
868 "address may be decreased, and length increased, so "
869 "that all of the first and last sectors are erased. "
870 "If 'unlock' is specified, then the flash is unprotected "
876 .handler
= handle_flash_fill_command
,
877 .mode
= COMMAND_EXEC
,
878 .usage
= "address value n",
879 .help
= "Fill n words with 32-bit value, starting at "
880 "word address. (No autoerase.)",
884 .handler
= handle_flash_fill_command
,
885 .mode
= COMMAND_EXEC
,
886 .usage
= "address value n",
887 .help
= "Fill n halfwords with 16-bit value, starting at "
888 "word address. (No autoerase.)",
892 .handler
= handle_flash_fill_command
,
893 .mode
= COMMAND_EXEC
,
894 .usage
= "address value n",
895 .help
= "Fill n bytes with 8-bit value, starting at "
896 "word address. (No autoerase.)",
899 .name
= "write_bank",
900 .handler
= handle_flash_write_bank_command
,
901 .mode
= COMMAND_EXEC
,
902 .usage
= "bank_id filename offset",
903 .help
= "Write binary data from file to flash bank, "
904 "starting at specified byte offset from the "
905 "beginning of the bank.",
908 .name
= "write_image",
909 .handler
= handle_flash_write_image_command
,
910 .mode
= COMMAND_EXEC
,
911 .usage
= "[erase] [unlock] filename [offset [file_type]]",
912 .help
= "Write an image to flash. Optionally first unprotect "
913 "and/or erase the region to be used. Allow optional "
914 "offset from beginning of bank (defaults to zero)",
918 .handler
= handle_flash_read_bank_command
,
919 .mode
= COMMAND_EXEC
,
920 .usage
= "bank_id filename offset length",
921 .help
= "Read binary data from flash bank to file, "
922 "starting at specified byte offset from the "
923 "beginning of the bank.",
926 .name
= "verify_bank",
927 .handler
= handle_flash_verify_bank_command
,
928 .mode
= COMMAND_EXEC
,
929 .usage
= "bank_id filename offset",
930 .help
= "Read binary data from flash bank and file, "
931 "starting at specified byte offset from the "
932 "beginning of the bank. Compare the contents.",
936 .handler
= handle_flash_protect_command
,
937 .mode
= COMMAND_EXEC
,
938 .usage
= "bank_id first_block [last_block|'last'] "
940 .help
= "Turn protection on or off for a range of protection "
941 "blocks or sectors in a given flash bank. "
942 "See 'flash info' output for a list of blocks.",
945 .name
= "padded_value",
946 .handler
= handle_flash_padded_value_command
,
947 .mode
= COMMAND_EXEC
,
948 .usage
= "bank_id value",
949 .help
= "Set default flash padded value",
951 COMMAND_REGISTRATION_DONE
954 static int flash_init_drivers(struct command_context
*cmd_ctx
)
956 if (!flash_bank_list())
959 struct command
*parent
= command_find_in_context(cmd_ctx
, "flash");
960 return register_commands(cmd_ctx
, parent
, flash_exec_command_handlers
);
963 COMMAND_HANDLER(handle_flash_bank_command
)
966 LOG_ERROR("usage: flash bank <name> <driver> "
967 "<base> <size> <chip_width> <bus_width> <target>");
968 return ERROR_COMMAND_SYNTAX_ERROR
;
970 /* save bank name and advance arguments for compatibility */
971 const char *bank_name
= *CMD_ARGV
++;
974 struct target
*target
= get_target(CMD_ARGV
[5]);
975 if (target
== NULL
) {
976 LOG_ERROR("target '%s' not defined", CMD_ARGV
[5]);
980 const char *driver_name
= CMD_ARGV
[0];
981 struct flash_driver
*driver
= flash_driver_find_by_name(driver_name
);
982 if (NULL
== driver
) {
983 /* no matching flash driver found */
984 LOG_ERROR("flash driver '%s' not found", driver_name
);
988 /* check the flash bank name is unique */
989 if (get_flash_bank_by_name_noprobe(bank_name
) != NULL
) {
990 /* flash bank name already exists */
991 LOG_ERROR("flash bank name '%s' already exists", bank_name
);
995 /* register flash specific commands */
996 if (NULL
!= driver
->commands
) {
997 int retval
= register_commands(CMD_CTX
, NULL
,
999 if (ERROR_OK
!= retval
) {
1000 LOG_ERROR("couldn't register '%s' commands",
1006 struct flash_bank
*c
= malloc(sizeof(*c
));
1007 c
->name
= strdup(bank_name
);
1010 c
->driver_priv
= NULL
;
1011 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], c
->base
);
1012 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], c
->size
);
1013 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[3], c
->chip_width
);
1014 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[4], c
->bus_width
);
1015 c
->default_padded_value
= c
->erased_value
= 0xff;
1018 c
->num_prot_blocks
= 0;
1019 c
->prot_blocks
= NULL
;
1023 retval
= CALL_COMMAND_HANDLER(driver
->flash_bank_command
, c
);
1024 if (ERROR_OK
!= retval
) {
1025 LOG_ERROR("'%s' driver rejected flash bank at 0x%8.8" PRIx32
"; usage: %s",
1026 driver_name
, c
->base
, driver
->usage
);
1031 if (driver
->usage
== NULL
)
1032 LOG_DEBUG("'%s' driver usage field missing", driver_name
);
1039 COMMAND_HANDLER(handle_flash_banks_command
)
1042 return ERROR_COMMAND_SYNTAX_ERROR
;
1045 for (struct flash_bank
*p
= flash_bank_list(); p
; p
= p
->next
, n
++) {
1046 LOG_USER("#%d : %s (%s) at 0x%8.8" PRIx32
", size 0x%8.8" PRIx32
", "
1047 "buswidth %u, chipwidth %u", p
->bank_number
,
1048 p
->name
, p
->driver
->name
, p
->base
, p
->size
,
1049 p
->bus_width
, p
->chip_width
);
1054 static int jim_flash_list(Jim_Interp
*interp
, int argc
, Jim_Obj
* const *argv
)
1057 Jim_WrongNumArgs(interp
, 1, argv
,
1058 "no arguments to 'flash list' command");
1062 Jim_Obj
*list
= Jim_NewListObj(interp
, NULL
, 0);
1064 for (struct flash_bank
*p
= flash_bank_list(); p
; p
= p
->next
) {
1065 Jim_Obj
*elem
= Jim_NewListObj(interp
, NULL
, 0);
1067 Jim_ListAppendElement(interp
, elem
, Jim_NewStringObj(interp
, "name", -1));
1068 Jim_ListAppendElement(interp
, elem
, Jim_NewStringObj(interp
, p
->driver
->name
, -1));
1069 Jim_ListAppendElement(interp
, elem
, Jim_NewStringObj(interp
, "base", -1));
1070 Jim_ListAppendElement(interp
, elem
, Jim_NewIntObj(interp
, p
->base
));
1071 Jim_ListAppendElement(interp
, elem
, Jim_NewStringObj(interp
, "size", -1));
1072 Jim_ListAppendElement(interp
, elem
, Jim_NewIntObj(interp
, p
->size
));
1073 Jim_ListAppendElement(interp
, elem
, Jim_NewStringObj(interp
, "bus_width", -1));
1074 Jim_ListAppendElement(interp
, elem
, Jim_NewIntObj(interp
, p
->bus_width
));
1075 Jim_ListAppendElement(interp
, elem
, Jim_NewStringObj(interp
, "chip_width", -1));
1076 Jim_ListAppendElement(interp
, elem
, Jim_NewIntObj(interp
, p
->chip_width
));
1078 Jim_ListAppendElement(interp
, list
, elem
);
1081 Jim_SetResult(interp
, list
);
1086 COMMAND_HANDLER(handle_flash_init_command
)
1089 return ERROR_COMMAND_SYNTAX_ERROR
;
1091 static bool flash_initialized
;
1092 if (flash_initialized
) {
1093 LOG_INFO("'flash init' has already been called");
1096 flash_initialized
= true;
1098 LOG_DEBUG("Initializing flash devices...");
1099 return flash_init_drivers(CMD_CTX
);
1102 static const struct command_registration flash_config_command_handlers
[] = {
1105 .handler
= handle_flash_bank_command
,
1106 .mode
= COMMAND_CONFIG
,
1107 .usage
= "bank_id driver_name base_address size_bytes "
1108 "chip_width_bytes bus_width_bytes target "
1109 "[driver_options ...]",
1110 .help
= "Define a new bank with the given name, "
1111 "using the specified NOR flash driver.",
1115 .mode
= COMMAND_CONFIG
,
1116 .handler
= handle_flash_init_command
,
1117 .help
= "Initialize flash devices.",
1121 .mode
= COMMAND_ANY
,
1122 .handler
= handle_flash_banks_command
,
1123 .help
= "Display table with information about flash banks.",
1127 .mode
= COMMAND_ANY
,
1128 .jim_handler
= jim_flash_list
,
1129 .help
= "Returns a list of details about the flash banks.",
1131 COMMAND_REGISTRATION_DONE
1133 static const struct command_registration flash_command_handlers
[] = {
1136 .mode
= COMMAND_ANY
,
1137 .help
= "NOR flash command group",
1138 .chain
= flash_config_command_handlers
,
1140 COMMAND_REGISTRATION_DONE
1143 int flash_register_commands(struct command_context
*cmd_ctx
)
1145 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)