summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorZachary T Welch <zw@superlucidity.net>2009-11-07 21:20:45 -0800
committerZachary T Welch <zw@superlucidity.net>2009-11-16 01:38:19 -0800
commit555757175eb344d11f3c0123f2f83460ef6ca67b (patch)
tree4a08968050dba7f2b20651d3c9a6752c310c6530 /src
parentda4cb3c029e7f271ee4fa7165ceefbef04d45e49 (diff)
downloadopenocd+libswd-555757175eb344d11f3c0123f2f83460ef6ca67b.tar.gz
openocd+libswd-555757175eb344d11f3c0123f2f83460ef6ca67b.tar.bz2
openocd+libswd-555757175eb344d11f3c0123f2f83460ef6ca67b.tar.xz
openocd+libswd-555757175eb344d11f3c0123f2f83460ef6ca67b.zip
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')
-rw-r--r--src/flash/nand.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/flash/nand.c b/src/flash/nand.c
index da561f63..46ac7286 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> "