diff options
author | Zachary T Welch <zw@superlucidity.net> | 2009-11-07 21:20:45 -0800 |
---|---|---|
committer | Zachary T Welch <zw@superlucidity.net> | 2009-11-16 01:38:19 -0800 |
commit | 555757175eb344d11f3c0123f2f83460ef6ca67b (patch) | |
tree | 4a08968050dba7f2b20651d3c9a6752c310c6530 /src/flash/nand.c | |
parent | da4cb3c029e7f271ee4fa7165ceefbef04d45e49 (diff) | |
download | riscv-openocd-555757175eb344d11f3c0123f2f83460ef6ca67b.zip riscv-openocd-555757175eb344d11f3c0123f2f83460ef6ca67b.tar.gz riscv-openocd-555757175eb344d11f3c0123f2f83460ef6ca67b.tar.bz2 |
Add 'nand verify' command
Add the 'nand verify' command to perform a dump and fake-write
simultaneously, checking the read bits against those generated by the
write process. Appropriate user documentation for this command has
been added to the user guide as well.
The algorithm presently makes a relatively naive comparison. Some chips
that use ECC may not verify correctly using this implementation, but the
new documentation provides details about this limitation.
Diffstat (limited to 'src/flash/nand.c')
-rw-r--r-- | src/flash/nand.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/src/flash/nand.c b/src/flash/nand.c index da561f6..46ac728 100644 --- a/src/flash/nand.c +++ b/src/flash/nand.c @@ -1543,6 +1543,67 @@ COMMAND_HANDLER(handle_nand_write_command) return ERROR_OK; } +COMMAND_HANDLER(handle_nand_verify_command) +{ + struct nand_device *nand = NULL; + struct nand_fileio_state file; + int retval = CALL_COMMAND_HANDLER(nand_fileio_parse_args, + &file, &nand, FILEIO_READ, false, true); + if (ERROR_OK != retval) + return retval; + + struct nand_fileio_state dev; + nand_fileio_init(&dev); + dev.address = file.address; + dev.size = file.size; + dev.oob_format = file.oob_format; + retval = nand_fileio_start(cmd_ctx, nand, NULL, FILEIO_NONE, &dev); + if (ERROR_OK != retval) + return retval; + + while (file.size > 0) + { + int retval = nand_read_page(nand, dev.address / dev.page_size, + dev.page, dev.page_size, dev.oob, dev.oob_size); + if (ERROR_OK != retval) + { + command_print(cmd_ctx, "reading NAND flash page failed"); + nand_fileio_cleanup(&dev); + return nand_fileio_cleanup(&file); + } + + int bytes_read = nand_fileio_read(nand, &file); + if (bytes_read <= 0) + { + command_print(cmd_ctx, "error while reading file"); + nand_fileio_cleanup(&dev); + return nand_fileio_cleanup(&file); + } + + if ((dev.page && memcmp(dev.page, file.page, dev.page_size)) || + (dev.oob && memcmp(dev.oob, file.oob, dev.oob_size)) ) + { + command_print(cmd_ctx, "NAND flash contents differ " + "at 0x%8.8" PRIx32, dev.address); + nand_fileio_cleanup(&dev); + return nand_fileio_cleanup(&file); + } + + file.size -= bytes_read; + file.address += nand->page_size; + } + + if (nand_fileio_finish(&file) == ERROR_OK) + { + command_print(cmd_ctx, "verified file %s in NAND flash %s " + "up to offset 0x%8.8" PRIx32 " in %fs (%0.3f kb/s)", + args[1], args[0], dev.address, duration_elapsed(&file.bench), + duration_kbps(&file.bench, dev.size)); + } + + return nand_fileio_cleanup(&dev); +} + COMMAND_HANDLER(handle_nand_dump_command) { struct nand_device *nand = NULL; @@ -1641,6 +1702,10 @@ int nand_init(struct command_context *cmd_ctx) handle_nand_dump_command, COMMAND_EXEC, "dump from NAND flash device <num> <filename> " "<offset> <length> [oob_raw | oob_only]"); + register_command(cmd_ctx, nand_cmd, "verify", + &handle_nand_verify_command, COMMAND_EXEC, + "verify NAND flash device <num> <filename> <offset> " + "[oob_raw | oob_only | oob_softecc | oob_softecc_kw]"); register_command(cmd_ctx, nand_cmd, "write", handle_nand_write_command, COMMAND_EXEC, "write to NAND flash device <num> <filename> <offset> " |