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 <s...@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@0 {
+               compatible = "sandbox,spi-flash-direct";
+       };
+
        syscon0: syscon@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;
+       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;
+       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);
-- 
2.23.0.444.g18eeb5a265-goog

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to