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
)
164 return ERROR_COMMAND_SYNTAX_ERROR
;
166 struct flash_bank
*p
;
167 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &p
);
168 if (ERROR_OK
!= retval
)
172 retval
= p
->driver
->erase_check(p
);
173 if (retval
== ERROR_OK
)
174 command_print(CMD_CTX
, "successfully checked erase state");
176 command_print(CMD_CTX
,
177 "unknown error when checking erase state of flash bank #%s at 0x%8.8" PRIx32
,
182 for (j
= 0; j
< p
->num_sectors
; j
++) {
185 if (p
->sectors
[j
].is_erased
== 0)
186 erase_state
= "not erased";
187 else if (p
->sectors
[j
].is_erased
== 1)
188 erase_state
= "erased";
190 erase_state
= "erase state unknown";
192 command_print(CMD_CTX
,
193 "\t#%3i: 0x%8.8" PRIx32
" (0x%" PRIx32
" %" PRIi32
"kB) %s",
195 p
->sectors
[j
].offset
,
197 p
->sectors
[j
].size
>> 10,
204 COMMAND_HANDLER(handle_flash_erase_address_command
)
206 struct flash_bank
*p
;
207 int retval
= ERROR_OK
;
211 bool do_unlock
= false;
212 struct target
*target
= get_current_target(CMD_CTX
);
214 while (CMD_ARGC
>= 3) {
215 /* Optionally pad out the address range to block/sector
216 * boundaries. We can't know if there's data in that part
217 * of the flash; only do padding if we're told to.
219 if (strcmp("pad", CMD_ARGV
[0]) == 0)
221 else if (strcmp("unlock", CMD_ARGV
[0]) == 0)
224 return ERROR_COMMAND_SYNTAX_ERROR
;
229 return ERROR_COMMAND_SYNTAX_ERROR
;
231 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
232 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], length
);
235 command_print(CMD_CTX
, "Length must be >0");
236 return ERROR_COMMAND_SYNTAX_ERROR
;
239 retval
= get_flash_bank_by_addr(target
, address
, true, &p
);
240 if (retval
!= ERROR_OK
)
243 /* We can't know if we did a resume + halt, in which case we no longer know the erased state
247 struct duration bench
;
248 duration_start(&bench
);
251 retval
= flash_unlock_address_range(target
, address
, length
);
253 if (retval
== ERROR_OK
)
254 retval
= flash_erase_address_range(target
, do_pad
, address
, length
);
256 if ((ERROR_OK
== retval
) && (duration_measure(&bench
) == ERROR_OK
)) {
257 command_print(CMD_CTX
, "erased address 0x%8.8" PRIx32
" (length %" PRIi32
")"
258 " in %fs (%0.3f KiB/s)", address
, length
,
259 duration_elapsed(&bench
), duration_kbps(&bench
, length
));
265 static int flash_check_sector_parameters(struct command_context
*cmd_ctx
,
266 uint32_t first
, uint32_t last
, uint32_t num_sectors
)
268 if (!(first
<= last
)) {
269 command_print(cmd_ctx
, "ERROR: "
270 "first sector must be <= last sector");
274 if (!(last
<= (num_sectors
- 1))) {
275 command_print(cmd_ctx
, "ERROR: last sector must be <= %d",
276 (int) num_sectors
- 1);
283 COMMAND_HANDLER(handle_flash_erase_command
)
286 return ERROR_COMMAND_SYNTAX_ERROR
;
291 struct flash_bank
*p
;
294 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &p
);
295 if (retval
!= ERROR_OK
)
298 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], first
);
299 if (strcmp(CMD_ARGV
[2], "last") == 0)
300 last
= p
->num_sectors
- 1;
302 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], last
);
304 retval
= flash_check_sector_parameters(CMD_CTX
, first
, last
, p
->num_sectors
);
305 if (retval
!= ERROR_OK
)
308 struct duration bench
;
309 duration_start(&bench
);
311 retval
= flash_driver_erase(p
, first
, last
);
313 if ((ERROR_OK
== retval
) && (duration_measure(&bench
) == ERROR_OK
)) {
314 command_print(CMD_CTX
, "erased sectors %" PRIu32
" "
315 "through %" PRIu32
" on flash bank %d "
316 "in %fs", first
, last
, p
->bank_number
, duration_elapsed(&bench
));
322 COMMAND_HANDLER(handle_flash_protect_command
)
325 return ERROR_COMMAND_SYNTAX_ERROR
;
330 struct flash_bank
*p
;
333 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &p
);
334 if (retval
!= ERROR_OK
)
337 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], first
);
338 if (strcmp(CMD_ARGV
[2], "last") == 0)
339 last
= p
->num_sectors
- 1;
341 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], last
);
344 COMMAND_PARSE_ON_OFF(CMD_ARGV
[3], set
);
346 retval
= flash_check_sector_parameters(CMD_CTX
, first
, last
, p
->num_sectors
);
347 if (retval
!= ERROR_OK
)
350 retval
= flash_driver_protect(p
, set
, first
, last
);
351 if (retval
== ERROR_OK
) {
352 command_print(CMD_CTX
, "%s protection for sectors %i "
353 "through %i on flash bank %d",
354 (set
) ? "set" : "cleared", (int) first
,
355 (int) last
, p
->bank_number
);
361 COMMAND_HANDLER(handle_flash_write_image_command
)
363 struct target
*target
= get_current_target(CMD_CTX
);
370 /* flash auto-erase is disabled by default*/
372 bool auto_unlock
= false;
375 if (strcmp(CMD_ARGV
[0], "erase") == 0) {
379 command_print(CMD_CTX
, "auto erase enabled");
380 } else if (strcmp(CMD_ARGV
[0], "unlock") == 0) {
384 command_print(CMD_CTX
, "auto unlock enabled");
390 return ERROR_COMMAND_SYNTAX_ERROR
;
393 LOG_ERROR("no target selected");
397 struct duration bench
;
398 duration_start(&bench
);
401 image
.base_address_set
= 1;
402 COMMAND_PARSE_NUMBER(llong
, CMD_ARGV
[1], image
.base_address
);
404 image
.base_address_set
= 0;
405 image
.base_address
= 0x0;
408 image
.start_address_set
= 0;
410 retval
= image_open(&image
, CMD_ARGV
[0], (CMD_ARGC
== 3) ? CMD_ARGV
[2] : NULL
);
411 if (retval
!= ERROR_OK
)
414 retval
= flash_write_unlock(target
, &image
, &written
, auto_erase
, auto_unlock
);
415 if (retval
!= ERROR_OK
) {
420 if ((ERROR_OK
== retval
) && (duration_measure(&bench
) == ERROR_OK
)) {
421 command_print(CMD_CTX
, "wrote %" PRIu32
" bytes from file %s "
422 "in %fs (%0.3f KiB/s)", written
, CMD_ARGV
[0],
423 duration_elapsed(&bench
), duration_kbps(&bench
, written
));
431 COMMAND_HANDLER(handle_flash_fill_command
)
438 uint32_t cur_size
= 0;
439 uint32_t chunk_count
;
440 struct target
*target
= get_current_target(CMD_CTX
);
443 int retval
= ERROR_OK
;
445 static size_t const chunksize
= 1024;
446 uint8_t *chunk
= NULL
, *readback
= NULL
;
449 retval
= ERROR_COMMAND_SYNTAX_ERROR
;
453 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
454 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], pattern
);
455 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], count
);
457 chunk
= malloc(chunksize
);
461 readback
= malloc(chunksize
);
462 if (readback
== NULL
) {
470 switch (CMD_NAME
[4]) {
481 retval
= ERROR_COMMAND_SYNTAX_ERROR
;
485 chunk_count
= MIN(count
, (chunksize
/ wordsize
));
488 for (i
= 0; i
< chunk_count
; i
++)
489 target_buffer_set_u32(target
, chunk
+ i
* wordsize
, pattern
);
492 for (i
= 0; i
< chunk_count
; i
++)
493 target_buffer_set_u16(target
, chunk
+ i
* wordsize
, pattern
);
496 memset(chunk
, pattern
, chunk_count
);
499 LOG_ERROR("BUG: can't happen");
503 struct duration bench
;
504 duration_start(&bench
);
506 for (wrote
= 0; wrote
< (count
*wordsize
); wrote
+= cur_size
) {
507 struct flash_bank
*bank
;
509 retval
= get_flash_bank_by_addr(target
, address
, true, &bank
);
510 if (retval
!= ERROR_OK
)
513 cur_size
= MIN((count
* wordsize
- wrote
), chunksize
);
514 err
= flash_driver_write(bank
, chunk
, address
- bank
->base
+ wrote
, cur_size
);
515 if (err
!= ERROR_OK
) {
520 err
= flash_driver_read(bank
, readback
, address
- bank
->base
+ wrote
, cur_size
);
521 if (err
!= ERROR_OK
) {
526 for (i
= 0; i
< cur_size
; i
++) {
527 if (readback
[i
] != chunk
[i
]) {
529 "Verification error address 0x%08" PRIx32
", read back 0x%02x, expected 0x%02x",
539 if ((retval
== ERROR_OK
) && (duration_measure(&bench
) == ERROR_OK
)) {
540 command_print(CMD_CTX
, "wrote %" PRIu32
" bytes to 0x%8.8" PRIx32
541 " in %fs (%0.3f KiB/s)", wrote
, address
,
542 duration_elapsed(&bench
), duration_kbps(&bench
, wrote
));
552 COMMAND_HANDLER(handle_flash_write_bank_command
)
556 struct fileio
*fileio
;
559 return ERROR_COMMAND_SYNTAX_ERROR
;
561 struct duration bench
;
562 duration_start(&bench
);
564 struct flash_bank
*p
;
565 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &p
);
566 if (ERROR_OK
!= retval
)
569 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], offset
);
571 if (fileio_open(&fileio
, CMD_ARGV
[1], FILEIO_READ
, FILEIO_BINARY
) != ERROR_OK
)
575 retval
= fileio_size(fileio
, &filesize
);
576 if (retval
!= ERROR_OK
) {
577 fileio_close(fileio
);
581 buffer
= malloc(filesize
);
582 if (buffer
== NULL
) {
583 fileio_close(fileio
);
584 LOG_ERROR("Out of memory");
588 if (fileio_read(fileio
, filesize
, buffer
, &buf_cnt
) != ERROR_OK
) {
590 fileio_close(fileio
);
594 retval
= flash_driver_write(p
, buffer
, offset
, buf_cnt
);
599 if ((ERROR_OK
== retval
) && (duration_measure(&bench
) == ERROR_OK
)) {
600 command_print(CMD_CTX
, "wrote %zu bytes from file %s to flash bank %u"
601 " at offset 0x%8.8" PRIx32
" in %fs (%0.3f KiB/s)",
602 filesize
, CMD_ARGV
[1], p
->bank_number
, offset
,
603 duration_elapsed(&bench
), duration_kbps(&bench
, filesize
));
606 fileio_close(fileio
);
611 COMMAND_HANDLER(handle_flash_read_bank_command
)
615 struct fileio
*fileio
;
620 return ERROR_COMMAND_SYNTAX_ERROR
;
622 struct duration bench
;
623 duration_start(&bench
);
625 struct flash_bank
*p
;
626 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &p
);
627 if (ERROR_OK
!= retval
)
630 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], offset
);
631 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[3], length
);
633 buffer
= malloc(length
);
634 if (buffer
== NULL
) {
635 LOG_ERROR("Out of memory");
639 retval
= flash_driver_read(p
, buffer
, offset
, length
);
640 if (retval
!= ERROR_OK
) {
641 LOG_ERROR("Read error");
646 retval
= fileio_open(&fileio
, CMD_ARGV
[1], FILEIO_WRITE
, FILEIO_BINARY
);
647 if (retval
!= ERROR_OK
) {
648 LOG_ERROR("Could not open file");
653 retval
= fileio_write(fileio
, length
, buffer
, &written
);
654 fileio_close(fileio
);
656 if (retval
!= ERROR_OK
) {
657 LOG_ERROR("Could not write file");
661 if (duration_measure(&bench
) == ERROR_OK
)
662 command_print(CMD_CTX
, "wrote %ld bytes to file %s from flash bank %u"
663 " at offset 0x%8.8" PRIx32
" in %fs (%0.3f KiB/s)",
664 (long)written
, CMD_ARGV
[1], p
->bank_number
, offset
,
665 duration_elapsed(&bench
), duration_kbps(&bench
, written
));
671 COMMAND_HANDLER(handle_flash_verify_bank_command
)
674 uint8_t *buffer_file
, *buffer_flash
;
675 struct fileio
*fileio
;
681 return ERROR_COMMAND_SYNTAX_ERROR
;
683 struct duration bench
;
684 duration_start(&bench
);
686 struct flash_bank
*p
;
687 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &p
);
688 if (ERROR_OK
!= retval
)
691 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], offset
);
693 retval
= fileio_open(&fileio
, CMD_ARGV
[1], FILEIO_READ
, FILEIO_BINARY
);
694 if (retval
!= ERROR_OK
) {
695 LOG_ERROR("Could not open file");
699 retval
= fileio_size(fileio
, &filesize
);
700 if (retval
!= ERROR_OK
) {
701 fileio_close(fileio
);
705 buffer_file
= malloc(filesize
);
706 if (buffer_file
== NULL
) {
707 LOG_ERROR("Out of memory");
708 fileio_close(fileio
);
712 retval
= fileio_read(fileio
, filesize
, buffer_file
, &read_cnt
);
713 fileio_close(fileio
);
714 if (retval
!= ERROR_OK
) {
715 LOG_ERROR("File read failure");
720 if (read_cnt
!= filesize
) {
721 LOG_ERROR("Short read");
726 buffer_flash
= malloc(filesize
);
727 if (buffer_flash
== NULL
) {
728 LOG_ERROR("Out of memory");
733 retval
= flash_driver_read(p
, buffer_flash
, offset
, read_cnt
);
734 if (retval
!= ERROR_OK
) {
735 LOG_ERROR("Flash read error");
741 if (duration_measure(&bench
) == ERROR_OK
)
742 command_print(CMD_CTX
, "read %ld bytes from file %s and flash bank %u"
743 " at offset 0x%8.8" PRIx32
" in %fs (%0.3f KiB/s)",
744 (long)read_cnt
, CMD_ARGV
[1], p
->bank_number
, offset
,
745 duration_elapsed(&bench
), duration_kbps(&bench
, read_cnt
));
747 differ
= memcmp(buffer_file
, buffer_flash
, read_cnt
);
748 command_print(CMD_CTX
, "contents %s", differ
? "differ" : "match");
752 for (t
= 0; t
< read_cnt
; t
++) {
753 if (buffer_flash
[t
] == buffer_file
[t
])
755 command_print(CMD_CTX
, "diff %d address 0x%08x. Was 0x%02x instead of 0x%02x",
756 diffs
, t
+ offset
, buffer_flash
[t
], buffer_file
[t
]);
757 if (diffs
++ >= 127) {
758 command_print(CMD_CTX
, "More than 128 errors, the rest are not printed.");
767 return differ
? ERROR_FAIL
: ERROR_OK
;
770 void flash_set_dirty(void)
772 struct flash_bank
*c
;
775 /* set all flash to require erasing */
776 for (c
= flash_bank_list(); c
; c
= c
->next
) {
777 for (i
= 0; i
< c
->num_sectors
; i
++)
778 c
->sectors
[i
].is_erased
= 0;
782 COMMAND_HANDLER(handle_flash_padded_value_command
)
785 return ERROR_COMMAND_SYNTAX_ERROR
;
787 struct flash_bank
*p
;
788 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &p
);
789 if (ERROR_OK
!= retval
)
792 COMMAND_PARSE_NUMBER(u8
, CMD_ARGV
[1], p
->default_padded_value
);
794 command_print(CMD_CTX
, "Default padded value set to 0x%" PRIx8
" for flash bank %u", \
795 p
->default_padded_value
, p
->bank_number
);
800 static const struct command_registration flash_exec_command_handlers
[] = {
803 .handler
= handle_flash_probe_command
,
804 .mode
= COMMAND_EXEC
,
806 .help
= "Identify a flash bank.",
810 .handler
= handle_flash_info_command
,
811 .mode
= COMMAND_EXEC
,
813 .help
= "Print information about a flash bank.",
816 .name
= "erase_check",
817 .handler
= handle_flash_erase_check_command
,
818 .mode
= COMMAND_EXEC
,
820 .help
= "Check erase state of all blocks in a "
824 .name
= "erase_sector",
825 .handler
= handle_flash_erase_command
,
826 .mode
= COMMAND_EXEC
,
827 .usage
= "bank_id first_sector_num last_sector_num",
828 .help
= "Erase a range of sectors in a flash bank.",
831 .name
= "erase_address",
832 .handler
= handle_flash_erase_address_command
,
833 .mode
= COMMAND_EXEC
,
834 .usage
= "['pad'] ['unlock'] address length",
835 .help
= "Erase flash sectors starting at address and "
836 "continuing for length bytes. If 'pad' is specified, "
837 "data outside that range may also be erased: the start "
838 "address may be decreased, and length increased, so "
839 "that all of the first and last sectors are erased. "
840 "If 'unlock' is specified, then the flash is unprotected "
846 .handler
= handle_flash_fill_command
,
847 .mode
= COMMAND_EXEC
,
848 .usage
= "address value n",
849 .help
= "Fill n words with 32-bit value, starting at "
850 "word address. (No autoerase.)",
854 .handler
= handle_flash_fill_command
,
855 .mode
= COMMAND_EXEC
,
856 .usage
= "address value n",
857 .help
= "Fill n halfwords with 16-bit value, starting at "
858 "word address. (No autoerase.)",
862 .handler
= handle_flash_fill_command
,
863 .mode
= COMMAND_EXEC
,
864 .usage
= "address value n",
865 .help
= "Fill n bytes with 8-bit value, starting at "
866 "word address. (No autoerase.)",
869 .name
= "write_bank",
870 .handler
= handle_flash_write_bank_command
,
871 .mode
= COMMAND_EXEC
,
872 .usage
= "bank_id filename offset",
873 .help
= "Write binary data from file to flash bank, "
874 "starting at specified byte offset from the "
875 "beginning of the bank.",
878 .name
= "write_image",
879 .handler
= handle_flash_write_image_command
,
880 .mode
= COMMAND_EXEC
,
881 .usage
= "[erase] [unlock] filename [offset [file_type]]",
882 .help
= "Write an image to flash. Optionally first unprotect "
883 "and/or erase the region to be used. Allow optional "
884 "offset from beginning of bank (defaults to zero)",
888 .handler
= handle_flash_read_bank_command
,
889 .mode
= COMMAND_EXEC
,
890 .usage
= "bank_id filename offset length",
891 .help
= "Read binary data from flash bank to file, "
892 "starting at specified byte offset from the "
893 "beginning of the bank.",
896 .name
= "verify_bank",
897 .handler
= handle_flash_verify_bank_command
,
898 .mode
= COMMAND_EXEC
,
899 .usage
= "bank_id filename offset",
900 .help
= "Read binary data from flash bank and file, "
901 "starting at specified byte offset from the "
902 "beginning of the bank. Compare the contents.",
906 .handler
= handle_flash_protect_command
,
907 .mode
= COMMAND_EXEC
,
908 .usage
= "bank_id first_sector [last_sector|'last'] "
910 .help
= "Turn protection on or off for a range of sectors "
911 "in a given flash bank.",
914 .name
= "padded_value",
915 .handler
= handle_flash_padded_value_command
,
916 .mode
= COMMAND_EXEC
,
917 .usage
= "bank_id value",
918 .help
= "Set default flash padded value",
920 COMMAND_REGISTRATION_DONE
923 static int flash_init_drivers(struct command_context
*cmd_ctx
)
925 if (!flash_bank_list())
928 struct command
*parent
= command_find_in_context(cmd_ctx
, "flash");
929 return register_commands(cmd_ctx
, parent
, flash_exec_command_handlers
);
932 COMMAND_HANDLER(handle_flash_bank_command
)
935 LOG_ERROR("usage: flash bank <name> <driver> "
936 "<base> <size> <chip_width> <bus_width> <target>");
937 return ERROR_COMMAND_SYNTAX_ERROR
;
939 /* save bank name and advance arguments for compatibility */
940 const char *bank_name
= *CMD_ARGV
++;
943 struct target
*target
= get_target(CMD_ARGV
[5]);
944 if (target
== NULL
) {
945 LOG_ERROR("target '%s' not defined", CMD_ARGV
[5]);
949 const char *driver_name
= CMD_ARGV
[0];
950 struct flash_driver
*driver
= flash_driver_find_by_name(driver_name
);
951 if (NULL
== driver
) {
952 /* no matching flash driver found */
953 LOG_ERROR("flash driver '%s' not found", driver_name
);
957 /* check the flash bank name is unique */
958 if (get_flash_bank_by_name_noprobe(bank_name
) != NULL
) {
959 /* flash bank name already exists */
960 LOG_ERROR("flash bank name '%s' already exists", bank_name
);
964 /* register flash specific commands */
965 if (NULL
!= driver
->commands
) {
966 int retval
= register_commands(CMD_CTX
, NULL
,
968 if (ERROR_OK
!= retval
) {
969 LOG_ERROR("couldn't register '%s' commands",
975 struct flash_bank
*c
= malloc(sizeof(*c
));
976 c
->name
= strdup(bank_name
);
979 c
->driver_priv
= NULL
;
980 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], c
->base
);
981 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], c
->size
);
982 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[3], c
->chip_width
);
983 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[4], c
->bus_width
);
984 c
->default_padded_value
= 0xff;
990 retval
= CALL_COMMAND_HANDLER(driver
->flash_bank_command
, c
);
991 if (ERROR_OK
!= retval
) {
992 LOG_ERROR("'%s' driver rejected flash bank at 0x%8.8" PRIx32
"; usage: %s",
993 driver_name
, c
->base
, driver
->usage
);
998 if (driver
->usage
== NULL
)
999 LOG_DEBUG("'%s' driver usage field missing", driver_name
);
1006 COMMAND_HANDLER(handle_flash_banks_command
)
1009 return ERROR_COMMAND_SYNTAX_ERROR
;
1012 for (struct flash_bank
*p
= flash_bank_list(); p
; p
= p
->next
, n
++) {
1013 LOG_USER("#%d : %s (%s) at 0x%8.8" PRIx32
", size 0x%8.8" PRIx32
", "
1014 "buswidth %u, chipwidth %u", p
->bank_number
,
1015 p
->name
, p
->driver
->name
, p
->base
, p
->size
,
1016 p
->bus_width
, p
->chip_width
);
1021 static int jim_flash_list(Jim_Interp
*interp
, int argc
, Jim_Obj
* const *argv
)
1024 Jim_WrongNumArgs(interp
, 1, argv
,
1025 "no arguments to 'flash list' command");
1029 Jim_Obj
*list
= Jim_NewListObj(interp
, NULL
, 0);
1031 for (struct flash_bank
*p
= flash_bank_list(); p
; p
= p
->next
) {
1032 Jim_Obj
*elem
= Jim_NewListObj(interp
, NULL
, 0);
1034 Jim_ListAppendElement(interp
, elem
, Jim_NewStringObj(interp
, "name", -1));
1035 Jim_ListAppendElement(interp
, elem
, Jim_NewStringObj(interp
, p
->driver
->name
, -1));
1036 Jim_ListAppendElement(interp
, elem
, Jim_NewStringObj(interp
, "base", -1));
1037 Jim_ListAppendElement(interp
, elem
, Jim_NewIntObj(interp
, p
->base
));
1038 Jim_ListAppendElement(interp
, elem
, Jim_NewStringObj(interp
, "size", -1));
1039 Jim_ListAppendElement(interp
, elem
, Jim_NewIntObj(interp
, p
->size
));
1040 Jim_ListAppendElement(interp
, elem
, Jim_NewStringObj(interp
, "bus_width", -1));
1041 Jim_ListAppendElement(interp
, elem
, Jim_NewIntObj(interp
, p
->bus_width
));
1042 Jim_ListAppendElement(interp
, elem
, Jim_NewStringObj(interp
, "chip_width", -1));
1043 Jim_ListAppendElement(interp
, elem
, Jim_NewIntObj(interp
, p
->chip_width
));
1045 Jim_ListAppendElement(interp
, list
, elem
);
1048 Jim_SetResult(interp
, list
);
1053 COMMAND_HANDLER(handle_flash_init_command
)
1056 return ERROR_COMMAND_SYNTAX_ERROR
;
1058 static bool flash_initialized
;
1059 if (flash_initialized
) {
1060 LOG_INFO("'flash init' has already been called");
1063 flash_initialized
= true;
1065 LOG_DEBUG("Initializing flash devices...");
1066 return flash_init_drivers(CMD_CTX
);
1069 static const struct command_registration flash_config_command_handlers
[] = {
1072 .handler
= handle_flash_bank_command
,
1073 .mode
= COMMAND_CONFIG
,
1074 .usage
= "bank_id driver_name base_address size_bytes "
1075 "chip_width_bytes bus_width_bytes target "
1076 "[driver_options ...]",
1077 .help
= "Define a new bank with the given name, "
1078 "using the specified NOR flash driver.",
1082 .mode
= COMMAND_CONFIG
,
1083 .handler
= handle_flash_init_command
,
1084 .help
= "Initialize flash devices.",
1088 .mode
= COMMAND_ANY
,
1089 .handler
= handle_flash_banks_command
,
1090 .help
= "Display table with information about flash banks.",
1094 .mode
= COMMAND_ANY
,
1095 .jim_handler
= jim_flash_list
,
1096 .help
= "Returns a list of details about the flash banks.",
1098 COMMAND_REGISTRATION_DONE
1100 static const struct command_registration flash_command_handlers
[] = {
1103 .mode
= COMMAND_ANY
,
1104 .help
= "NOR flash command group",
1105 .chain
= flash_config_command_handlers
,
1107 COMMAND_REGISTRATION_DONE
1110 int flash_register_commands(struct command_context
*cmd_ctx
)
1112 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)