From 555757175eb344d11f3c0123f2f83460ef6ca67b Mon Sep 17 00:00:00 2001 From: Zachary T Welch Date: Sat, 7 Nov 2009 21:20:45 -0800 Subject: 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. --- src/flash/nand.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) (limited to 'src') 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 " " [oob_raw | oob_only]"); + register_command(cmd_ctx, nand_cmd, "verify", + &handle_nand_verify_command, COMMAND_EXEC, + "verify NAND flash device " + "[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 " -- cgit v1.2.3