[U-Boot] [PATCH v2 13/38] spi: sandbox: Add a test driver for sandbox SPI flash

Bin Meng bmeng.cn at gmail.com
Wed Oct 9 13:50:24 UTC 2019


Hi Simon,

On Wed, Sep 25, 2019 at 10:12 PM Simon Glass <sjg at chromium.org> wrote:
>
> At present SPI-flash testing relies on a sandbox driver which emulates the
> SPI bus and implements a flash chip behind that emulated bus.
>
> This provides good coverage but can only implement features supported by
> the SPI bus.
>
> Add a new 'direct' SPI flash which is implemented directly by sandbox.
> This allows us to write a very simple test of the uclass interface.
>
> Signed-off-by: Simon Glass <sjg at chromium.org>
> ---
>
> Changes in v2: None
>
>  arch/sandbox/dts/test.dts        |  4 ++
>  drivers/mtd/spi/Makefile         |  2 +-
>  drivers/mtd/spi/sandbox_direct.c | 99 ++++++++++++++++++++++++++++++++
>  test/dm/sf.c                     | 42 ++++++++++++++
>  4 files changed, 146 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/mtd/spi/sandbox_direct.c
>
> diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
> index 27b0baab278..208551d7c19 100644
> --- a/arch/sandbox/dts/test.dts
> +++ b/arch/sandbox/dts/test.dts
> @@ -619,6 +619,10 @@
>                 };
>         };
>
> +       spi-flash at 0 {
> +               compatible = "sandbox,spi-flash-direct";
> +       };
> +
>         syscon0: syscon at 0 {
>                 compatible = "sandbox,syscon0";
>                 reg = <0x10 16>;
> diff --git a/drivers/mtd/spi/Makefile b/drivers/mtd/spi/Makefile
> index 11a8f55132a..c700258254b 100644
> --- a/drivers/mtd/spi/Makefile
> +++ b/drivers/mtd/spi/Makefile
> @@ -21,4 +21,4 @@ obj-$(CONFIG_SPI_FLASH) += spi-nor.o
>  obj-$(CONFIG_SPI_FLASH_DATAFLASH) += sf_dataflash.o
>  obj-$(CONFIG_SPI_FLASH_INTEL_FAST) += intel_fast_spi.o
>  obj-$(CONFIG_SPI_FLASH_MTD) += sf_mtd.o
> -obj-$(CONFIG_SPI_FLASH_SANDBOX) += sandbox.o
> +obj-$(CONFIG_SPI_FLASH_SANDBOX) += sandbox.o sandbox_direct.o
> diff --git a/drivers/mtd/spi/sandbox_direct.c b/drivers/mtd/spi/sandbox_direct.c
> new file mode 100644
> index 00000000000..43d8907710c
> --- /dev/null
> +++ b/drivers/mtd/spi/sandbox_direct.c
> @@ -0,0 +1,99 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Simulate a flash chip without an underlying SPI layer. Behaviour is only
> + * useful for testing.
> + *
> + * Copyright 2019 Google LLC
> + *
> + * Licensed under the GPL-2 or later.
> + */
> +
> +#define LOG_CATEGORY UCLASS_SPI_FLASH
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <spi_flash.h>
> +
> +/**
> + * struct sandbox_direct_priv - private data for this driver
> + *
> + * @read_byte: Byte to return when reading from the driver
> + */
> +struct sandbox_direct_priv {
> +       char read_byte;

Just 'byte'? Since it stores a byte that is not only for "read", but
also for "write"

> +       int write_prot;
> +};
> +
> +static int sandbox_direct_read(struct udevice *dev, u32 offset, size_t len,
> +                              void *buf)
> +{
> +       struct sandbox_direct_priv *priv = dev_get_priv(dev);
> +
> +       if (offset == 1)
> +               return -EIO;
> +       memset(buf, priv->read_byte, len);
> +
> +       return 0;
> +}
> +
> +static int sandbox_direct_write(struct udevice *dev, u32 offset, size_t len,
> +                               const void *buf)
> +{
> +       struct sandbox_direct_priv *priv = dev_get_priv(dev);
> +
> +       if (offset == 1)
> +               return -EIO;

No "priv->write_prot" check?

> +       if (len > 0)
> +               priv->read_byte = *(u8 *)buf;
> +
> +       return 0;
> +}
> +
> +static int sandbox_direct_erase(struct udevice *dev, u32 offset, size_t len)
> +{
> +       struct sandbox_direct_priv *priv = dev_get_priv(dev);
> +
> +       if (offset == 1)
> +               return -EIO;
> +       if (len > 0)
> +               priv->read_byte = 'c';
> +
> +       return 0;
> +}
> +
> +static int sandbox_direct_get_sw_write_prot(struct udevice *dev)
> +{
> +       struct sandbox_direct_priv *priv = dev_get_priv(dev);
> +
> +       return priv->write_prot++ ? 1 : 0;
> +}
> +
> +static int sandbox_direct_probe(struct udevice *dev)
> +{
> +       struct sandbox_direct_priv *priv = dev_get_priv(dev);
> +
> +       priv->read_byte = 'a';
> +
> +       return 0;
> +}
> +
> +static struct dm_spi_flash_ops sandbox_direct_ops = {
> +       .read = sandbox_direct_read,
> +       .write = sandbox_direct_write,
> +       .erase = sandbox_direct_erase,
> +       .get_sw_write_prot = sandbox_direct_get_sw_write_prot,
> +};
> +
> +static const struct udevice_id sandbox_direct_ids[] = {
> +       { .compatible = "sandbox,spi-flash-direct" },
> +       { }
> +};
> +
> +U_BOOT_DRIVER(sandbox_sf_direct) = {
> +       .name           = "sandbox_sf_direct",
> +       .id             = UCLASS_SPI_FLASH,
> +       .of_match       = sandbox_direct_ids,
> +       .probe          = sandbox_direct_probe,
> +       .ops            = &sandbox_direct_ops,
> +       .priv_auto_alloc_size   = sizeof(struct sandbox_direct_priv),
> +};
> diff --git a/test/dm/sf.c b/test/dm/sf.c
> index 3788d59052e..56277954c23 100644
> --- a/test/dm/sf.c
> +++ b/test/dm/sf.c
> @@ -14,8 +14,13 @@
>  #include <asm/test.h>
>  #include <dm/test.h>
>  #include <dm/util.h>
> +#include <dm/uclass.h>
>  #include <test/ut.h>
>
> +enum {
> +       BUF_SIZE        = 4,
> +};
> +
>  /* Simple test of sandbox SPI flash */
>  static int dm_test_spi_flash(struct unit_test_state *uts)
>  {
> @@ -91,3 +96,40 @@ static int dm_test_spi_flash_func(struct unit_test_state *uts)
>         return 0;
>  }
>  DM_TEST(dm_test_spi_flash_func, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
> +
> +/* Test of the direct SPI flash interface (no SPI layer) */
> +static int dm_test_spi_flash_direct(struct unit_test_state *uts)
> +{
> +       struct udevice *dev;
> +       char buf[BUF_SIZE];
> +       int i;
> +
> +       ut_assertok(uclass_get_device(UCLASS_SPI_FLASH, 1, &dev));
> +
> +       /* Check the read call */
> +       ut_asserteq(-EIO, spi_flash_read_dm(dev, 1, BUF_SIZE, buf));
> +       ut_assertok(spi_flash_read_dm(dev, 0, BUF_SIZE, buf));
> +       for (i = 0; i < BUF_SIZE; i++)
> +               ut_asserteq('a', buf[i]);
> +
> +       /* Check the write call */
> +       ut_asserteq(-EIO, spi_flash_write_dm(dev, 1, BUF_SIZE, buf));
> +       ut_assertok(spi_flash_write_dm(dev, 0, 1, "b"));
> +       ut_assertok(spi_flash_read_dm(dev, 0, BUF_SIZE, buf));
> +       for (i = 0; i < BUF_SIZE; i++)
> +               ut_asserteq('b', buf[i]);
> +
> +       /* Check erase */
> +       ut_asserteq(-EIO, spi_flash_erase_dm(dev, 1, BUF_SIZE));
> +       ut_assertok(spi_flash_erase_dm(dev, 0, 1));
> +       ut_assertok(spi_flash_read_dm(dev, 0, BUF_SIZE, buf));
> +       for (i = 0; i < BUF_SIZE; i++)
> +               ut_asserteq('c', buf[i]);
> +
> +       /* Check write protection */
> +       ut_asserteq(0, spl_flash_get_sw_write_prot(dev));
> +       ut_asserteq(1, spl_flash_get_sw_write_prot(dev));
> +
> +       return 0;
> +}
> +DM_TEST(dm_test_spi_flash_direct, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
> --

Regards,
Bin


More information about the U-Boot mailing list