diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2016-03-02 10:16:50 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2016-04-06 10:17:53 +0200 |
commit | 1e6955fdb815906bdd2ecbf2c50e5059852f2400 (patch) | |
tree | 365230e849ab4ccc01bb53e754a61f88137f356f /commands/nand-bitflip.c | |
parent | eea6d75d1bfa91ff5da7992ecbc1ff828542c342 (diff) | |
download | barebox-1e6955fdb815906bdd2ecbf2c50e5059852f2400.tar.gz barebox-1e6955fdb815906bdd2ecbf2c50e5059852f2400.tar.xz |
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.c | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/commands/nand-bitflip.c b/commands/nand-bitflip.c new file mode 100644 index 0000000000..fe56f222cf --- /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 |