X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fflash%2Fnand.c;h=fba8104a636d66736b86c27d14e418e39442a39b;hp=da561f63f2f7e21e678ec027435932a8725bc37d;hb=cbc05783727122f0052fe6f3be40635eb73ec5bc;hpb=51cd370b396d19555158c1eb913e7c8386d92a0f diff --git a/src/flash/nand.c b/src/flash/nand.c index da561f63f2..fba8104a63 100644 --- a/src/flash/nand.c +++ b/src/flash/nand.c @@ -304,9 +304,10 @@ struct nand_device *get_nand_device_by_num(int num) return NULL; } -int nand_command_get_device_by_num(struct command_context *cmd_ctx, - const char *str, struct nand_device **nand) +COMMAND_HELPER(nand_command_get_device_by_num, unsigned name_index, + struct nand_device **nand) { + const char *str = args[name_index]; unsigned num; COMMAND_PARSE_NUMBER(uint, str, num); *nand = get_nand_device_by_num(num); @@ -1077,7 +1078,7 @@ COMMAND_HANDLER(handle_nand_info_command) int last = -1; struct nand_device *p; - int retval = nand_command_get_device_by_num(cmd_ctx, args[0], &p); + int retval = CALL_COMMAND_HANDLER(nand_command_get_device_by_num, 0, &p); if (ERROR_OK != retval) return retval; @@ -1152,7 +1153,7 @@ COMMAND_HANDLER(handle_nand_probe_command) } struct nand_device *p; - int retval = nand_command_get_device_by_num(cmd_ctx, args[0], &p); + int retval = CALL_COMMAND_HANDLER(nand_command_get_device_by_num, 0, &p); if (ERROR_OK != retval) return retval; @@ -1181,7 +1182,7 @@ COMMAND_HANDLER(handle_nand_erase_command) } struct nand_device *p; - int retval = nand_command_get_device_by_num(cmd_ctx, args[0], &p); + int retval = CALL_COMMAND_HANDLER(nand_command_get_device_by_num, 0, &p); if (ERROR_OK != retval) return retval; @@ -1240,7 +1241,7 @@ COMMAND_HANDLER(handle_nand_check_bad_blocks_command) } struct nand_device *p; - int retval = nand_command_get_device_by_num(cmd_ctx, args[0], &p); + int retval = CALL_COMMAND_HANDLER(nand_command_get_device_by_num, 0, &p); if (ERROR_OK != retval) return retval; @@ -1392,7 +1393,7 @@ static COMMAND_HELPER(nand_fileio_parse_args, struct nand_fileio_state *state, return ERROR_COMMAND_SYNTAX_ERROR; struct nand_device *nand; - int retval = nand_command_get_device_by_num(cmd_ctx, args[0], &nand); + int retval = CALL_COMMAND_HANDLER(nand_command_get_device_by_num, 0, &nand); if (ERROR_OK != retval) return retval; @@ -1543,6 +1544,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; @@ -1590,7 +1652,7 @@ COMMAND_HANDLER(handle_nand_raw_access_command) } struct nand_device *p; - int retval = nand_command_get_device_by_num(cmd_ctx, args[0], &p); + int retval = CALL_COMMAND_HANDLER(nand_command_get_device_by_num, 0, &p); if (ERROR_OK != retval) return retval; @@ -1641,6 +1703,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 "