summaryrefslogtreecommitdiffstats
path: root/commands/nand-bitflip.c
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2016-03-02 10:16:50 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2016-04-06 10:17:53 +0200
commit1e6955fdb815906bdd2ecbf2c50e5059852f2400 (patch)
tree365230e849ab4ccc01bb53e754a61f88137f356f /commands/nand-bitflip.c
parenteea6d75d1bfa91ff5da7992ecbc1ff828542c342 (diff)
downloadbarebox-1e6955fdb815906bdd2ecbf2c50e5059852f2400.tar.gz
commands: Create nand_bitflip command
This adds a command to flip bits in a Nand flash. This is useful for testing purposes to check if flipped bits are corrected and if the driver returns the correct number of bitflips. The command writes a configurable number of bitflips to a single Nand page. If the -r option is not given the results are reproducible, so calling the same command twice will revert the bitflips. The command uses the raw read/write Nand operations which are probably less tested than the regular read/write operations, so the command may produce surprising results. As of writing the command has been tested with the GPMI Nand driver and the imx-nand driver with fixes posted. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'commands/nand-bitflip.c')
-rw-r--r--commands/nand-bitflip.c117
1 files changed, 117 insertions, 0 deletions
diff --git a/commands/nand-bitflip.c b/commands/nand-bitflip.c
new file mode 100644
index 0000000..fe56f22
--- /dev/null
+++ b/commands/nand-bitflip.c
@@ -0,0 +1,117 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <malloc.h>
+#include <getopt.h>
+#include <fs.h>
+#include <fcntl.h>
+#include <ioctl.h>
+#include <linux/mtd/mtd.h>
+#include <mtd/mtd-peb.h>
+
+static int do_nand_bitflip(int argc, char *argv[])
+{
+ int opt, ret, fd;
+ static struct mtd_info_user meminfo;
+ int block = 0;
+ int random = 0;
+ int num_bitflips = 1;
+ loff_t offset = 0, roffset;
+ int check = 0;
+ size_t r;
+ void *buf;
+
+ while ((opt = getopt(argc, argv, "b:rn:o:c")) > 0) {
+ switch (opt) {
+ case 'r':
+ random = 1;
+ break;
+ case 'n':
+ num_bitflips = simple_strtoul(optarg, NULL, 0);
+ break;
+ case 'b':
+ block = simple_strtoul(optarg, NULL, 0);
+ break;
+ case 'o':
+ offset = simple_strtoull(optarg, NULL, 0);
+ break;
+ case 'c':
+ check = 1;
+ break;
+ default:
+ return COMMAND_ERROR_USAGE;
+ }
+ }
+
+ if (optind >= argc)
+ return COMMAND_ERROR_USAGE;
+
+ fd = open(argv[optind], O_RDWR);
+ if (fd < 0)
+ return fd;
+
+ ret = ioctl(fd, MEMGETINFO, &meminfo);
+
+ close(fd);
+
+ if (ret)
+ return ret;
+
+ block += mtd_div_by_eb(offset, meminfo.mtd);
+ offset = mtd_mod_by_eb(offset, meminfo.mtd);
+
+ if (!check) {
+ ret = mtd_peb_create_bitflips(meminfo.mtd, block, offset, meminfo.writesize,
+ num_bitflips, random, 1);
+ if (ret) {
+ printf("Creating bitflips failed with: %s\n", strerror(-ret));
+ return ret;
+ }
+ }
+
+ buf = xzalloc(meminfo.writesize);
+
+ roffset = (loff_t)block * meminfo.mtd->erasesize + offset;
+ ret = meminfo.mtd->read(meminfo.mtd, roffset, meminfo.writesize, &r, buf);
+ if (ret > 0) {
+ printf("page at block %d, offset 0x%08llx has %d bitflips%s\n",
+ block, offset, ret,
+ ret >= meminfo.mtd->bitflip_threshold ? ", needs cleanup" : "");
+ } else if (!ret) {
+ printf("No bitflips found on block %d, offset 0x%08llx\n", block, offset);
+ } else {
+ printf("Reading block %d, offset 0x%08llx failed with: %s\n", block, offset,
+ strerror(-ret));
+ }
+
+ free(buf);
+
+ return 0;
+}
+
+BAREBOX_CMD_HELP_START(nand_bitflip)
+BAREBOX_CMD_HELP_TEXT("This command creates bitflips on Nand pages.")
+BAREBOX_CMD_HELP_TEXT("Options:")
+BAREBOX_CMD_HELP_OPT ("-b <block>", "block to work on")
+BAREBOX_CMD_HELP_OPT ("-o <offset>", "offset in Nand")
+BAREBOX_CMD_HELP_OPT ("-r\t", "flip random bits")
+BAREBOX_CMD_HELP_OPT ("-n <numbitflips>", "Specify maximum number of bitflips to generate")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(nand_bitflip)
+ .cmd = do_nand_bitflip,
+ BAREBOX_CMD_DESC("Create bitflips on Nand pages")
+ BAREBOX_CMD_OPTS("NANDDEV")
+ BAREBOX_CMD_GROUP(CMD_GRP_HWMANIP)
+ BAREBOX_CMD_HELP(cmd_nand_bitflip_help)
+BAREBOX_CMD_END