diff options
| author | Tom Rini <[email protected]> | 2023-11-16 12:46:09 -0500 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2023-11-16 13:49:13 -0500 |
| commit | 5e6a112e1187ebc570b8befd1dd6eef3a64dec39 (patch) | |
| tree | 0f87bf8f8b38403cc7b331ecc1660a2ef6b3af45 /test | |
| parent | a9a73799731807cca117d234c4338b710db3cfdd (diff) | |
| parent | 8502b5bf20505408773d98fbc6e9307cb962e8b0 (diff) | |
Merge patch series "nand: Add sandbox tests"
To quote the author:
This series tests raw nand flash in sandbox and fixes various bugs discovered in
the process. I've tried to do things in a contemporary manner, avoiding the
(numerous) variations present on only a few boards. The test is pretty minimal.
Future work could test the rest of the nand API as well as the MTD API.
Bloat (for v1) at [1] (for boards with SPL_NAND_SUPPORT enabled). Almost
everything grows by a few bytes due to nand_page_size. A few boards grow more,
mostly those using nand_spl_loaders.c. CI at [2].
[1] https://gist.github.com/Forty-Bot/9694f3401893c9e706ccc374922de6c2
[2] https://source.denx.de/u-boot/custodians/u-boot-clk/-/pipelines/18443
Diffstat (limited to 'test')
| -rw-r--r-- | test/dm/Makefile | 1 | ||||
| -rw-r--r-- | test/dm/nand.c | 104 | ||||
| -rw-r--r-- | test/image/Kconfig | 9 | ||||
| -rw-r--r-- | test/image/Makefile | 1 | ||||
| -rw-r--r-- | test/image/spl_load_nand.c | 54 |
5 files changed, 169 insertions, 0 deletions
diff --git a/test/dm/Makefile b/test/dm/Makefile index cb82d839f8a..a3ce7b3889f 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -73,6 +73,7 @@ obj-$(CONFIG_CMD_MUX) += mux-cmd.o obj-$(CONFIG_MULTIPLEXER) += mux-emul.o obj-$(CONFIG_MUX_MMIO) += mux-mmio.o obj-y += fdtdec.o +obj-$(CONFIG_MTD_RAW_NAND) += nand.o obj-$(CONFIG_UT_DM) += nop.o obj-y += ofnode.o obj-y += ofread.o diff --git a/test/dm/nand.c b/test/dm/nand.c new file mode 100644 index 00000000000..0b992fdce1c --- /dev/null +++ b/test/dm/nand.c @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2023 Sean Anderson <[email protected]> + */ + +#include <nand.h> +#include <part.h> +#include <rand.h> +#include <dm/test.h> +#include <test/test.h> +#include <test/ut.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/rawnand.h> + +static int dm_test_nand(struct unit_test_state *uts, int dev, bool end) +{ + nand_erase_options_t opts = { }; + struct mtd_info *mtd; + size_t length; + loff_t size; + char *buf; + int *gold; + u8 oob[NAND_MAX_OOBSIZE]; + int i; + loff_t off = 0; + mtd_oob_ops_t ops = { }; + + /* Seed RNG for bit errors */ + srand((off >> 32) ^ off ^ ~dev); + + mtd = get_nand_dev_by_index(dev); + ut_assertnonnull(mtd); + size = mtd->erasesize * 4; + length = size; + + buf = malloc(size); + ut_assertnonnull(buf); + gold = malloc(size); + ut_assertnonnull(gold); + + /* Mark a block as bad */ + ut_assertok(mtd_block_markbad(mtd, off + mtd->erasesize)); + + /* Erase some stuff */ + if (end) + off = mtd->size - size - mtd->erasesize; + opts.offset = off; + opts.length = size; + opts.spread = 1; + opts.lim = U32_MAX; + ut_assertok(nand_erase_opts(mtd, &opts)); + + /* Make sure everything is erased */ + memset(gold, 0xff, size); + ut_assertok(nand_read_skip_bad(mtd, off, &length, NULL, U64_MAX, buf)); + ut_asserteq(size, length); + ut_asserteq_mem(gold, buf, size); + + /* ...but our bad block marker is still there */ + ops.oobbuf = oob; + ops.ooblen = mtd->oobsize; + ut_assertok(mtd_read_oob(mtd, mtd->erasesize, &ops)); + ut_asserteq(0, oob[mtd_to_nand(mtd)->badblockpos]); + + /* Generate some data and write it */ + for (i = 0; i < size / sizeof(int); i++) + gold[i] = rand(); + ut_assertok(nand_write_skip_bad(mtd, off, &length, NULL, U64_MAX, + (void *)gold, 0)); + ut_asserteq(size, length); + + /* Verify */ + ut_assertok(nand_read_skip_bad(mtd, off, &length, NULL, U64_MAX, buf)); + ut_asserteq(size, length); + ut_asserteq_mem(gold, buf, size); + + /* Erase some blocks */ + memset(((char *)gold) + mtd->erasesize, 0xff, mtd->erasesize * 2); + opts.offset = off + mtd->erasesize; + opts.length = mtd->erasesize * 2; + ut_assertok(nand_erase_opts(mtd, &opts)); + + /* Verify */ + ut_assertok(nand_read_skip_bad(mtd, off, &length, NULL, U64_MAX, buf)); + ut_asserteq(size, length); + ut_asserteq_mem(gold, buf, size); + + return 0; +} + +#define DM_NAND_TEST(dev) \ +static int dm_test_nand##dev##_start(struct unit_test_state *uts) \ +{ \ + return dm_test_nand(uts, dev, false); \ +} \ +DM_TEST(dm_test_nand##dev##_start, UT_TESTF_SCAN_FDT); \ +static int dm_test_nand##dev##_end(struct unit_test_state *uts) \ +{ \ + return dm_test_nand(uts, dev, true); \ +} \ +DM_TEST(dm_test_nand##dev##_end, UT_TESTF_SCAN_FDT) + +DM_NAND_TEST(0); +DM_NAND_TEST(1); diff --git a/test/image/Kconfig b/test/image/Kconfig index 8f9e6ae036b..6f0bb81f835 100644 --- a/test/image/Kconfig +++ b/test/image/Kconfig @@ -23,6 +23,15 @@ config SPL_UT_LOAD_FS help Test filesystems and the various load methods which use them. +config SPL_UT_LOAD_NAND + bool "Test loading from NAND flash" + depends on SANDBOX && SPL_OF_REAL + depends on SPL_NAND_SUPPORT + depends on SPL_MTD + default y + help + Test the NAND flash load method. + config SPL_UT_LOAD_NET bool "Test loading over TFTP" depends on SANDBOX && SPL_OF_REAL diff --git a/test/image/Makefile b/test/image/Makefile index b30210106a4..11ed25734e8 100644 --- a/test/image/Makefile +++ b/test/image/Makefile @@ -4,6 +4,7 @@ obj-y += spl_load.o obj-$(CONFIG_SPL_UT_LOAD_FS) += spl_load_fs.o +obj-$(CONFIG_SPL_UT_LOAD_NAND) += spl_load_nand.o obj-$(CONFIG_SPL_UT_LOAD_NET) += spl_load_net.o obj-$(CONFIG_SPL_NOR_SUPPORT) += spl_load_nor.o obj-$(CONFIG_SPL_UT_LOAD_OS) += spl_load_os.o diff --git a/test/image/spl_load_nand.c b/test/image/spl_load_nand.c new file mode 100644 index 00000000000..30179de98e7 --- /dev/null +++ b/test/image/spl_load_nand.c @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2023 Sean Anderson <[email protected]> + */ + +#include <nand.h> +#include <spl.h> +#include <test/spl.h> +#include <test/ut.h> + +uint32_t spl_nand_get_uboot_raw_page(void); + +static int spl_test_nand_write_image(struct unit_test_state *uts, void *img, + size_t img_size) +{ + uint32_t off = spl_nand_get_uboot_raw_page(); + struct mtd_info *mtd; + struct erase_info erase = { }; + size_t length; + + nand_reinit(); + mtd = get_nand_dev_by_index(0); + ut_assertnonnull(mtd); + + /* Mark the first block as bad to test that it gets skipped */ + ut_assertok(mtd_block_markbad(mtd, off & ~mtd->erasesize_mask)); + off += mtd->erasesize; + + erase.mtd = mtd; + erase.len = img_size + (off & mtd->erasesize_mask); + erase.len += mtd->erasesize_mask; + erase.len &= ~mtd->erasesize_mask; + erase.addr = off & ~mtd->erasesize_mask; + erase.scrub = 1; + ut_assertok(mtd_erase(mtd, &erase)); + + ut_assertok(mtd_write(mtd, off, img_size, &length, img)); + + return 0; +} + +static int spl_test_nand(struct unit_test_state *uts, const char *test_name, + enum spl_test_image type) +{ + return do_spl_test_load(uts, test_name, type, + SPL_LOAD_IMAGE_GET(1, BOOT_DEVICE_NAND, + spl_nand_load_image), + spl_test_nand_write_image); +} +SPL_IMG_TEST(spl_test_nand, LEGACY, DM_FLAGS); +SPL_IMG_TEST(spl_test_nand, LEGACY_LZMA, DM_FLAGS); +SPL_IMG_TEST(spl_test_nand, IMX8, DM_FLAGS); +SPL_IMG_TEST(spl_test_nand, FIT_INTERNAL, DM_FLAGS); +SPL_IMG_TEST(spl_test_nand, FIT_EXTERNAL, DM_FLAGS); |
