1 /***************************************************************************
2 * Copyright (C) 2007 by Dominic Rath <Dominic.Rath@gmx.de> *
3 * Copyright (C) 2002 Thomas Gleixner <tglx@linutronix.de> *
4 * Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
6 * Partially based on drivers/mtd/nand_ids.c from Linux. *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
30 #include <target/target.h>
33 extern struct nand_device
*nand_devices
;
35 COMMAND_HANDLER(handle_nand_list_command
)
37 struct nand_device
*p
;
42 command_print(CMD_CTX
, "no NAND flash devices configured");
46 for (p
= nand_devices
, i
= 0; p
; p
= p
->next
, i
++)
49 command_print(CMD_CTX
, "#%i: %s (%s) "
50 "pagesize: %i, buswidth: %i,\n\t"
51 "blocksize: %i, blocks: %i",
52 i
, p
->device
->name
, p
->manufacturer
->name
,
53 p
->page_size
, p
->bus_width
,
54 p
->erase_size
, p
->num_blocks
);
56 command_print(CMD_CTX
, "#%i: not probed", i
);
62 COMMAND_HANDLER(handle_nand_info_command
)
71 return ERROR_COMMAND_SYNTAX_ERROR
;
77 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[1], i
);
82 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[1], first
);
83 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[2], last
);
87 struct nand_device
*p
;
88 int retval
= CALL_COMMAND_HANDLER(nand_command_get_device
, 0, &p
);
89 if (ERROR_OK
!= retval
)
92 if (NULL
== p
->device
)
94 command_print(CMD_CTX
, "#%s: not probed", CMD_ARGV
[0]);
98 if (first
>= p
->num_blocks
)
99 first
= p
->num_blocks
- 1;
101 if (last
>= p
->num_blocks
)
102 last
= p
->num_blocks
- 1;
104 command_print(CMD_CTX
, "#%i: %s (%s) pagesize: %i, buswidth: %i, erasesize: %i",
105 i
++, p
->device
->name
, p
->manufacturer
->name
, p
->page_size
, p
->bus_width
, p
->erase_size
);
107 for (j
= first
; j
<= last
; j
++)
109 char *erase_state
, *bad_state
;
111 if (p
->blocks
[j
].is_erased
== 0)
112 erase_state
= "not erased";
113 else if (p
->blocks
[j
].is_erased
== 1)
114 erase_state
= "erased";
116 erase_state
= "erase state unknown";
118 if (p
->blocks
[j
].is_bad
== 0)
120 else if (p
->blocks
[j
].is_bad
== 1)
121 bad_state
= " (marked bad)";
123 bad_state
= " (block condition unknown)";
125 command_print(CMD_CTX
,
126 "\t#%i: 0x%8.8" PRIx32
" (%" PRId32
"kB) %s%s",
129 p
->blocks
[j
].size
/ 1024,
137 COMMAND_HANDLER(handle_nand_probe_command
)
141 return ERROR_COMMAND_SYNTAX_ERROR
;
144 struct nand_device
*p
;
145 int retval
= CALL_COMMAND_HANDLER(nand_command_get_device
, 0, &p
);
146 if (ERROR_OK
!= retval
)
149 if ((retval
= nand_probe(p
)) == ERROR_OK
)
151 command_print(CMD_CTX
, "NAND flash device '%s (%s)' found",
152 p
->device
->name
, p
->manufacturer
->name
);
158 COMMAND_HANDLER(handle_nand_erase_command
)
160 if (CMD_ARGC
!= 1 && CMD_ARGC
!= 3)
162 return ERROR_COMMAND_SYNTAX_ERROR
;
166 struct nand_device
*p
;
167 int retval
= CALL_COMMAND_HANDLER(nand_command_get_device
, 0, &p
);
168 if (ERROR_OK
!= retval
)
171 unsigned long offset
;
172 unsigned long length
;
174 /* erase specified part of the chip; or else everything */
176 unsigned long size
= p
->erase_size
* p
->num_blocks
;
178 COMMAND_PARSE_NUMBER(ulong
, CMD_ARGV
[1], offset
);
179 if ((offset
% p
->erase_size
) != 0 || offset
>= size
)
180 return ERROR_INVALID_ARGUMENTS
;
182 COMMAND_PARSE_NUMBER(ulong
, CMD_ARGV
[2], length
);
183 if ((length
== 0) || (length
% p
->erase_size
) != 0
184 || (length
+ offset
) > size
)
185 return ERROR_INVALID_ARGUMENTS
;
187 offset
/= p
->erase_size
;
188 length
/= p
->erase_size
;
191 length
= p
->num_blocks
;
194 retval
= nand_erase(p
, offset
, offset
+ length
- 1);
195 if (retval
== ERROR_OK
)
197 command_print(CMD_CTX
, "erased blocks %lu to %lu "
198 "on NAND flash device #%s '%s'",
199 offset
, offset
+ length
,
200 CMD_ARGV
[0], p
->device
->name
);
206 COMMAND_HANDLER(handle_nand_check_bad_blocks_command
)
211 if ((CMD_ARGC
< 1) || (CMD_ARGC
> 3) || (CMD_ARGC
== 2))
213 return ERROR_COMMAND_SYNTAX_ERROR
;
217 struct nand_device
*p
;
218 int retval
= CALL_COMMAND_HANDLER(nand_command_get_device
, 0, &p
);
219 if (ERROR_OK
!= retval
)
224 unsigned long offset
;
225 unsigned long length
;
227 COMMAND_PARSE_NUMBER(ulong
, CMD_ARGV
[1], offset
);
228 if (offset
% p
->erase_size
)
229 return ERROR_INVALID_ARGUMENTS
;
230 offset
/= p
->erase_size
;
232 COMMAND_PARSE_NUMBER(ulong
, CMD_ARGV
[2], length
);
233 if (length
% p
->erase_size
)
234 return ERROR_INVALID_ARGUMENTS
;
237 length
/= p
->erase_size
;
240 last
= offset
+ length
;
243 retval
= nand_build_bbt(p
, first
, last
);
244 if (retval
== ERROR_OK
)
246 command_print(CMD_CTX
, "checked NAND flash device for bad blocks, "
247 "use \"nand info\" command to list blocks");
253 COMMAND_HANDLER(handle_nand_write_command
)
255 struct nand_device
*nand
= NULL
;
256 struct nand_fileio_state s
;
257 int retval
= CALL_COMMAND_HANDLER(nand_fileio_parse_args
,
258 &s
, &nand
, FILEIO_READ
, false, true);
259 if (ERROR_OK
!= retval
)
262 uint32_t total_bytes
= s
.size
;
265 int bytes_read
= nand_fileio_read(nand
, &s
);
268 command_print(CMD_CTX
, "error while reading file");
269 return nand_fileio_cleanup(&s
);
271 s
.size
-= bytes_read
;
273 retval
= nand_write_page(nand
, s
.address
/ nand
->page_size
,
274 s
.page
, s
.page_size
, s
.oob
, s
.oob_size
);
275 if (ERROR_OK
!= retval
)
277 command_print(CMD_CTX
, "failed writing file %s "
278 "to NAND flash %s at offset 0x%8.8" PRIx32
,
279 CMD_ARGV
[1], CMD_ARGV
[0], s
.address
);
280 return nand_fileio_cleanup(&s
);
282 s
.address
+= s
.page_size
;
285 if (nand_fileio_finish(&s
))
287 command_print(CMD_CTX
, "wrote file %s to NAND flash %s up to "
288 "offset 0x%8.8" PRIx32
" in %fs (%0.3f KiB/s)",
289 CMD_ARGV
[1], CMD_ARGV
[0], s
.address
, duration_elapsed(&s
.bench
),
290 duration_kbps(&s
.bench
, total_bytes
));
295 COMMAND_HANDLER(handle_nand_verify_command
)
297 struct nand_device
*nand
= NULL
;
298 struct nand_fileio_state file
;
299 int retval
= CALL_COMMAND_HANDLER(nand_fileio_parse_args
,
300 &file
, &nand
, FILEIO_READ
, false, true);
301 if (ERROR_OK
!= retval
)
304 struct nand_fileio_state dev
;
305 nand_fileio_init(&dev
);
306 dev
.address
= file
.address
;
307 dev
.size
= file
.size
;
308 dev
.oob_format
= file
.oob_format
;
309 retval
= nand_fileio_start(CMD_CTX
, nand
, NULL
, FILEIO_NONE
, &dev
);
310 if (ERROR_OK
!= retval
)
313 while (file
.size
> 0)
315 retval
= nand_read_page(nand
, dev
.address
/ dev
.page_size
,
316 dev
.page
, dev
.page_size
, dev
.oob
, dev
.oob_size
);
317 if (ERROR_OK
!= retval
)
319 command_print(CMD_CTX
, "reading NAND flash page failed");
320 nand_fileio_cleanup(&dev
);
321 nand_fileio_cleanup(&file
);
325 int bytes_read
= nand_fileio_read(nand
, &file
);
328 command_print(CMD_CTX
, "error while reading file");
329 nand_fileio_cleanup(&dev
);
330 nand_fileio_cleanup(&file
);
334 if ((dev
.page
&& memcmp(dev
.page
, file
.page
, dev
.page_size
)) ||
335 (dev
.oob
&& memcmp(dev
.oob
, file
.oob
, dev
.oob_size
)) )
337 command_print(CMD_CTX
, "NAND flash contents differ "
338 "at 0x%8.8" PRIx32
, dev
.address
);
339 nand_fileio_cleanup(&dev
);
340 nand_fileio_cleanup(&file
);
344 file
.size
-= bytes_read
;
345 dev
.address
+= nand
->page_size
;
348 if (nand_fileio_finish(&file
) == ERROR_OK
)
350 command_print(CMD_CTX
, "verified file %s in NAND flash %s "
351 "up to offset 0x%8.8" PRIx32
" in %fs (%0.3f KiB/s)",
352 CMD_ARGV
[1], CMD_ARGV
[0], dev
.address
, duration_elapsed(&file
.bench
),
353 duration_kbps(&file
.bench
, dev
.size
));
356 return nand_fileio_cleanup(&dev
);
359 COMMAND_HANDLER(handle_nand_dump_command
)
362 struct nand_device
*nand
= NULL
;
363 struct nand_fileio_state s
;
364 int retval
= CALL_COMMAND_HANDLER(nand_fileio_parse_args
,
365 &s
, &nand
, FILEIO_WRITE
, true, false);
366 if (ERROR_OK
!= retval
)
372 retval
= nand_read_page(nand
, s
.address
/ nand
->page_size
,
373 s
.page
, s
.page_size
, s
.oob
, s
.oob_size
);
374 if (ERROR_OK
!= retval
)
376 command_print(CMD_CTX
, "reading NAND flash page failed");
377 nand_fileio_cleanup(&s
);
382 fileio_write(&s
.fileio
, s
.page_size
, s
.page
, &size_written
);
385 fileio_write(&s
.fileio
, s
.oob_size
, s
.oob
, &size_written
);
387 s
.size
-= nand
->page_size
;
388 s
.address
+= nand
->page_size
;
391 retval
= fileio_size(&s
.fileio
, &filesize
);
392 if (retval
!= ERROR_OK
)
395 if (nand_fileio_finish(&s
) == ERROR_OK
)
397 command_print(CMD_CTX
, "dumped %ld bytes in %fs (%0.3f KiB/s)",
398 (long)filesize
, duration_elapsed(&s
.bench
),
399 duration_kbps(&s
.bench
, filesize
));
404 COMMAND_HANDLER(handle_nand_raw_access_command
)
406 if ((CMD_ARGC
< 1) || (CMD_ARGC
> 2))
408 return ERROR_COMMAND_SYNTAX_ERROR
;
411 struct nand_device
*p
;
412 int retval
= CALL_COMMAND_HANDLER(nand_command_get_device
, 0, &p
);
413 if (ERROR_OK
!= retval
)
416 if (NULL
== p
->device
)
418 command_print(CMD_CTX
, "#%s: not probed", CMD_ARGV
[0]);
423 COMMAND_PARSE_ENABLE(CMD_ARGV
[1], p
->use_raw
);
425 const char *msg
= p
->use_raw
? "enabled" : "disabled";
426 command_print(CMD_CTX
, "raw access is %s", msg
);
431 static const struct command_registration nand_exec_command_handlers
[] = {
434 .handler
= handle_nand_list_command
,
435 .mode
= COMMAND_EXEC
,
436 .help
= "list configured NAND flash devices",
440 .handler
= handle_nand_info_command
,
441 .mode
= COMMAND_EXEC
,
442 .usage
= "[banknum | first_bank_num last_bank_num]",
443 .help
= "print info about one or more NAND flash devices",
447 .handler
= handle_nand_probe_command
,
448 .mode
= COMMAND_EXEC
,
450 .help
= "identify NAND flash device",
453 .name
= "check_bad_blocks",
454 .handler
= handle_nand_check_bad_blocks_command
,
455 .mode
= COMMAND_EXEC
,
456 .usage
= "bank_id [offset length]",
457 .help
= "check all or part of NAND flash device for bad blocks",
461 .handler
= handle_nand_erase_command
,
462 .mode
= COMMAND_EXEC
,
463 .usage
= "bank_id [offset length]",
464 .help
= "erase all or subset of blocks on NAND flash device",
468 .handler
= handle_nand_dump_command
,
469 .mode
= COMMAND_EXEC
,
470 .usage
= "bank_id filename offset length "
471 "['oob_raw'|'oob_only']",
472 .help
= "dump from NAND flash device",
476 .handler
= handle_nand_verify_command
,
477 .mode
= COMMAND_EXEC
,
478 .usage
= "bank_id filename offset "
479 "['oob_raw'|'oob_only'|'oob_softecc'|'oob_softecc_kw']",
480 .help
= "verify NAND flash device",
484 .handler
= handle_nand_write_command
,
485 .mode
= COMMAND_EXEC
,
486 .usage
= "bank_id filename offset "
487 "['oob_raw'|'oob_only'|'oob_softecc'|'oob_softecc_kw']",
488 .help
= "write to NAND flash device",
491 .name
= "raw_access",
492 .handler
= handle_nand_raw_access_command
,
493 .mode
= COMMAND_EXEC
,
494 .usage
= "bank_id ['enable'|'disable']",
495 .help
= "raw access to NAND flash device",
497 COMMAND_REGISTRATION_DONE
500 static int nand_init(struct command_context
*cmd_ctx
)
504 struct command
*parent
= command_find_in_context(cmd_ctx
, "nand");
505 return register_commands(cmd_ctx
, parent
, nand_exec_command_handlers
);
508 COMMAND_HANDLER(handle_nand_init_command
)
511 return ERROR_COMMAND_SYNTAX_ERROR
;
513 static bool nand_initialized
= false;
514 if (nand_initialized
)
516 LOG_INFO("'nand init' has already been called");
519 nand_initialized
= true;
521 LOG_DEBUG("Initializing NAND devices...");
522 return nand_init(CMD_CTX
);
525 static int nand_list_walker(struct nand_flash_controller
*c
, void *x
)
527 struct command_context
*cmd_ctx
= (struct command_context
*)x
;
528 command_print(cmd_ctx
, " %s", c
->name
);
532 COMMAND_HANDLER(handle_nand_list_drivers
)
534 command_print(CMD_CTX
, "Available NAND flash controller drivers:");
535 return nand_driver_walk(&nand_list_walker
, CMD_CTX
);
538 static COMMAND_HELPER(create_nand_device
, const char *bank_name
,
539 struct nand_flash_controller
*controller
)
541 struct nand_device
*c
;
542 struct target
*target
;
547 LOG_ERROR("missing target");
548 return ERROR_COMMAND_ARGUMENT_INVALID
;
550 target
= get_target(CMD_ARGV
[1]);
552 LOG_ERROR("invalid target %s", CMD_ARGV
[1]);
553 return ERROR_COMMAND_ARGUMENT_INVALID
;
556 if (NULL
!= controller
->commands
)
558 retval
= register_commands(CMD_CTX
, NULL
,
559 controller
->commands
);
560 if (ERROR_OK
!= retval
)
563 c
= malloc(sizeof(struct nand_device
));
566 LOG_ERROR("End of memory");
570 c
->name
= strdup(bank_name
);
572 c
->controller
= controller
;
573 c
->controller_priv
= NULL
;
574 c
->manufacturer
= NULL
;
577 c
->address_cycles
= 0;
582 retval
= CALL_COMMAND_HANDLER(controller
->nand_device_command
, c
);
583 if (ERROR_OK
!= retval
)
585 LOG_ERROR("'%s' driver rejected nand flash", controller
->name
);
595 COMMAND_HANDLER(handle_nand_device_command
)
599 LOG_ERROR("incomplete nand device configuration");
600 return ERROR_FLASH_BANK_INVALID
;
603 // save name and increment (for compatibility) with drivers
604 const char *bank_name
= *CMD_ARGV
++;
607 const char *driver_name
= CMD_ARGV
[0];
608 struct nand_flash_controller
*controller
;
609 controller
= nand_driver_find_by_name(CMD_ARGV
[0]);
610 if (NULL
== controller
)
612 LOG_ERROR("No valid NAND flash driver found (%s)", driver_name
);
613 return CALL_COMMAND_HANDLER(handle_nand_list_drivers
);
615 return CALL_COMMAND_HANDLER(create_nand_device
, bank_name
, controller
);
618 static const struct command_registration nand_config_command_handlers
[] = {
621 .handler
= &handle_nand_device_command
,
622 .mode
= COMMAND_CONFIG
,
623 .help
= "defines a new NAND bank",
624 .usage
= "bank_id driver target [driver_options ...]",
628 .handler
= &handle_nand_list_drivers
,
630 .help
= "lists available NAND drivers",
634 .mode
= COMMAND_CONFIG
,
635 .handler
= &handle_nand_init_command
,
636 .help
= "initialize NAND devices",
638 COMMAND_REGISTRATION_DONE
640 static const struct command_registration nand_command_handlers
[] = {
644 .help
= "NAND flash command group",
645 .chain
= nand_config_command_handlers
,
647 COMMAND_REGISTRATION_DONE
650 int nand_register_commands(struct command_context
*cmd_ctx
)
652 return register_commands(cmd_ctx
, NULL
, nand_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)