[U-Boot] [PATCH v2 14/38] spi: Add support for memory-mapped flash

Bin Meng bmeng.cn at gmail.com
Wed Oct 9 13:55:39 UTC 2019


Hi Simon,

On Wed, Sep 25, 2019 at 10:12 PM Simon Glass <sjg at chromium.org> wrote:
>
> On x86 platforms the SPI flash can be mapped into memory so that the
> contents can be read with normal memory accesses.
>
> Add a new SPI flash method to find the location of the SPI flash in
> memory. This differs from the existing device-tree "memory-map" mechanism
> in that the location can be discovered at run-time.
>
> Signed-off-by: Simon Glass <sjg at chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/mtd/spi/sandbox_direct.c | 11 +++++++++++
>  drivers/mtd/spi/sf-uclass.c      | 11 +++++++++++
>  include/spi_flash.h              | 27 +++++++++++++++++++++++++++
>  test/dm/sf.c                     |  9 +++++++++
>  4 files changed, 58 insertions(+)
>
> diff --git a/drivers/mtd/spi/sandbox_direct.c b/drivers/mtd/spi/sandbox_direct.c
> index 43d8907710c..fb515edcb7c 100644
> --- a/drivers/mtd/spi/sandbox_direct.c
> +++ b/drivers/mtd/spi/sandbox_direct.c
> @@ -68,6 +68,16 @@ static int sandbox_direct_get_sw_write_prot(struct udevice *dev)
>         return priv->write_prot++ ? 1 : 0;
>  }
>
> +static int sandbox_direct_get_mmap(struct udevice *dev, ulong *map_basep,
> +                                  size_t *map_sizep, u32 *offsetp)
> +{
> +       *map_basep = 0x1000;
> +       *map_sizep = 0x2000;
> +       *offsetp = 0x100;
> +
> +       return 0;
> +}
> +
>  static int sandbox_direct_probe(struct udevice *dev)
>  {
>         struct sandbox_direct_priv *priv = dev_get_priv(dev);
> @@ -82,6 +92,7 @@ static struct dm_spi_flash_ops sandbox_direct_ops = {
>         .write = sandbox_direct_write,
>         .erase = sandbox_direct_erase,
>         .get_sw_write_prot = sandbox_direct_get_sw_write_prot,
> +       .get_mmap = sandbox_direct_get_mmap,
>  };
>
>  static const struct udevice_id sandbox_direct_ids[] = {
> diff --git a/drivers/mtd/spi/sf-uclass.c b/drivers/mtd/spi/sf-uclass.c
> index 719a2fd23ae..127ec7e7aa6 100644
> --- a/drivers/mtd/spi/sf-uclass.c
> +++ b/drivers/mtd/spi/sf-uclass.c
> @@ -28,6 +28,17 @@ int spi_flash_erase_dm(struct udevice *dev, u32 offset, size_t len)
>         return log_ret(sf_get_ops(dev)->erase(dev, offset, len));
>  }
>
> +int spi_flash_get_mmap(struct udevice *dev, ulong *map_basep, size_t *map_sizep,
> +                      u32 *offsetp)
> +{
> +       struct dm_spi_flash_ops *ops = sf_get_ops(dev);
> +
> +       if (!ops->get_mmap)
> +               return -ENOSYS;
> +
> +       return ops->get_mmap(dev, map_basep, map_sizep, offsetp);
> +}
> +
>  int spl_flash_get_sw_write_prot(struct udevice *dev)
>  {
>         struct dm_spi_flash_ops *ops = sf_get_ops(dev);
> diff --git a/include/spi_flash.h b/include/spi_flash.h
> index 55b4721813a..840189e22c7 100644
> --- a/include/spi_flash.h
> +++ b/include/spi_flash.h
> @@ -47,6 +47,19 @@ struct dm_spi_flash_ops {
>          *      other -ve value on error
>          */
>         int (*get_sw_write_prot)(struct udevice *dev);
> +
> +       /**
> +        * get_mmap() - Get memory-mapped SPI
> +        *
> +        * @dev:        SPI flash device
> +        * @map_basep:  Returns base memory address for mapped SPI
> +        * @map_sizep:  Returns size of mapped SPI
> +        * @offsetp:    Returns start offset of SPI flash where the map works
> +        *      correctly (offsets before this are not visible)
> +        * @return 0 if OK, -EFAULT if memory mapping is not available
> +        */

I feel odd to add such an op to the flash op, as memory address is not
determined by the flash itself, but the SPI flash controller. We
probably should add the op to the SPI flash controller instead.

> +       int (*get_mmap)(struct udevice *dev, ulong *map_basep,
> +                       size_t *map_sizep, u32 *offsetp);
>  };
>
>  /* Access the serial operations for a device */
> @@ -88,6 +101,20 @@ int spi_flash_write_dm(struct udevice *dev, u32 offset, size_t len,
>   */
>  int spi_flash_erase_dm(struct udevice *dev, u32 offset, size_t len);
>
> +/**
> + * spi_flash_get_mmap() - Get memory-mapped SPI
> + *
> + * @dev:       SPI flash device
> + * @map_basep: Returns base memory address for mapped SPI
> + * @map_sizep: Returns size of mapped SPI
> + * @offsetp:   Returns start offset of SPI flash where the map works
> + *     correctly (offsets before this are not visible)
> + * @return 0 if OK, -ENOSYS if no operation, -EFAULT if memory mapping is not
> + *     available
> + */
> +int spi_flash_get_mmap(struct udevice *dev, ulong *map_basep, size_t *map_sizep,
> +                      u32 *offsetp);
> +
>  /**
>   * spl_flash_get_sw_write_prot() - Check state of software write-protect feature
>   *
> diff --git a/test/dm/sf.c b/test/dm/sf.c
> index 56277954c23..f8f9e717720 100644
> --- a/test/dm/sf.c
> +++ b/test/dm/sf.c
> @@ -102,6 +102,9 @@ static int dm_test_spi_flash_direct(struct unit_test_state *uts)
>  {
>         struct udevice *dev;
>         char buf[BUF_SIZE];
> +       size_t map_size;
> +       ulong map_base;
> +       u32 offset;
>         int i;
>
>         ut_assertok(uclass_get_device(UCLASS_SPI_FLASH, 1, &dev));
> @@ -130,6 +133,12 @@ static int dm_test_spi_flash_direct(struct unit_test_state *uts)
>         ut_asserteq(0, spl_flash_get_sw_write_prot(dev));
>         ut_asserteq(1, spl_flash_get_sw_write_prot(dev));
>
> +       /* Check mapping */
> +       ut_assertok(spi_flash_get_mmap(dev, &map_base, &map_size, &offset));
> +       ut_asserteq(0x1000, map_base);
> +       ut_asserteq(0x2000, map_size);
> +       ut_asserteq(0x100, offset);
> +
>         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