mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-16 18:04:48 +00:00
test: spl: Add a test for NAND
Add a SPL test for the NAND load method. We use some different functions to do the writing from the main test since things like nand_write_skip_bad aren't available in SPL. We disable BBT scanning, since scan_bbt is only populated when not in SPL. We use nand_spl_loaders.c as it seems to be common to at least a few boards already. However, we do not use nand_spl_simple.c because it would require us to implement cmd_ctrl. The various nand load functions are adapted from omap_gpmc. However, they have been modified for simplicity/correctness. Signed-off-by: Sean Anderson <seanga2@gmail.com>
This commit is contained in:
parent
bc8e8a4bfa
commit
8502b5bf20
7 changed files with 109 additions and 1 deletions
|
@ -15,6 +15,7 @@ enum {
|
|||
BOOT_DEVICE_CPGMAC,
|
||||
BOOT_DEVICE_NOR,
|
||||
BOOT_DEVICE_SPI,
|
||||
BOOT_DEVICE_NAND,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -51,6 +51,13 @@ CONFIG_SPL_ETH=y
|
|||
CONFIG_SPL_FS_EXT4=y
|
||||
CONFIG_SPL_I2C=y
|
||||
CONFIG_SPL_MMC_WRITE=y
|
||||
CONFIG_SPL_MTD=y
|
||||
CONFIG_SPL_NAND_SUPPORT=y
|
||||
CONFIG_SPL_NAND_DRIVERS=y
|
||||
CONFIG_SPL_NAND_ECC=y
|
||||
CONFIG_SPL_NAND_SOFTECC=y
|
||||
CONFIG_SPL_NAND_BASE=y
|
||||
CONFIG_SPL_NAND_IDENT=y
|
||||
CONFIG_SPL_DM_SPI_FLASH=y
|
||||
CONFIG_SPL_NET=y
|
||||
CONFIG_SPL_NOR_SUPPORT=y
|
||||
|
@ -183,12 +190,16 @@ CONFIG_FS_LOADER=y
|
|||
CONFIG_MMC_SANDBOX=y
|
||||
CONFIG_MTD=y
|
||||
CONFIG_DM_MTD=y
|
||||
CONFIG_MTD_CONCAT=y
|
||||
CONFIG_MTD_RAW_NAND=y
|
||||
CONFIG_SYS_MAX_NAND_DEVICE=8
|
||||
CONFIG_SYS_NAND_USE_FLASH_BBT=y
|
||||
CONFIG_NAND_SANDBOX=y
|
||||
CONFIG_SYS_NAND_BLOCK_SIZE=0x2000
|
||||
CONFIG_SYS_NAND_ONFI_DETECTION=y
|
||||
CONFIG_SYS_NAND_PAGE_SIZE=0x200
|
||||
CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
|
||||
CONFIG_SYS_NAND_U_BOOT_OFFS=0x0
|
||||
CONFIG_SPI_FLASH_SANDBOX=y
|
||||
CONFIG_SPI_FLASH_ATMEL=y
|
||||
CONFIG_SPI_FLASH_EON=y
|
||||
|
|
|
@ -451,6 +451,8 @@ config NAND_SANDBOX
|
|||
bool "Support for NAND in sandbox"
|
||||
depends on SANDBOX
|
||||
select SYS_NAND_SELF_INIT
|
||||
select SPL_SYS_NAND_SELF_INIT
|
||||
select SPL_NAND_INIT
|
||||
select SYS_NAND_SOFT_ECC
|
||||
select BCH
|
||||
select NAND_ECC_BCH
|
||||
|
@ -678,7 +680,8 @@ config SYS_NAND_PAGE_SIZE
|
|||
depends on ARCH_SUNXI || NAND_OMAP_GPMC || NAND_LPC32XX_SLC || \
|
||||
SPL_NAND_SIMPLE || (NAND_MXC && SPL_NAND_SUPPORT) || \
|
||||
MVEBU_SPL_BOOT_DEVICE_NAND || \
|
||||
(NAND_ATMEL && SPL_NAND_SUPPORT) || SPL_GENERATE_ATMEL_PMECC_HEADER
|
||||
(NAND_ATMEL && SPL_NAND_SUPPORT) || \
|
||||
SPL_GENERATE_ATMEL_PMECC_HEADER || NAND_SANDBOX
|
||||
depends on !NAND_MXS && !NAND_DENALI_DT && !NAND_LPC32XX_MLC && !NAND_MT7621
|
||||
help
|
||||
Number of data bytes in one page for the NAND chip on the
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include <nand.h>
|
||||
#include <os.h>
|
||||
#include <rand.h>
|
||||
#include <spl.h>
|
||||
#include <system-constants.h>
|
||||
#include <dm/device_compat.h>
|
||||
#include <dm/read.h>
|
||||
#include <dm/uclass.h>
|
||||
|
@ -599,6 +601,7 @@ static int sand_nand_probe(struct udevice *dev)
|
|||
}
|
||||
|
||||
nand = &chip->nand;
|
||||
nand->options = spl_in_proper() ? 0 : NAND_SKIP_BBTSCAN;
|
||||
nand->flash_node = np;
|
||||
nand->dev_ready = sand_nand_dev_ready;
|
||||
nand->cmdfunc = sand_nand_command;
|
||||
|
@ -676,3 +679,29 @@ void board_nand_init(void)
|
|||
if (err && err != -ENODEV)
|
||||
log_info("Failed to get sandbox NAND: %d\n", err);
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_SPL_BUILD) && IS_ENABLED(CONFIG_SPL_NAND_INIT)
|
||||
void nand_deselect(void)
|
||||
{
|
||||
nand_chip->select_chip(nand_to_mtd(nand_chip), -1);
|
||||
}
|
||||
|
||||
static int nand_is_bad_block(int block)
|
||||
{
|
||||
struct mtd_info *mtd = nand_to_mtd(nand_chip);
|
||||
|
||||
return mtd_block_isbad(mtd, block << mtd->erasesize_shift);
|
||||
}
|
||||
|
||||
static int nand_read_page(int block, int page, uchar *dst)
|
||||
{
|
||||
struct mtd_info *mtd = nand_to_mtd(nand_chip);
|
||||
loff_t ofs = ((loff_t)block << mtd->erasesize_shift) +
|
||||
((loff_t)page << mtd->writesize_shift);
|
||||
size_t len = mtd->writesize;
|
||||
|
||||
return nand_read(mtd, ofs, &len, dst);
|
||||
}
|
||||
|
||||
#include "nand_spl_loaders.c"
|
||||
#endif /* CONFIG_SPL_NAND_INIT */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
54
test/image/spl_load_nand.c
Normal file
54
test/image/spl_load_nand.c
Normal file
|
@ -0,0 +1,54 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2023 Sean Anderson <seanga2@gmail.com>
|
||||
*/
|
||||
|
||||
#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);
|
Loading…
Add table
Reference in a new issue