diff mbox series

[v4,5/5] sf: Provide a command to access memory-mapped SPI

Message ID 20210919214937.3829422-6-sjg@chromium.org
State Changes Requested
Delegated to: Jagannadha Sutradharudu Teki
Headers show
Series sf: Add documentation and an 'sf mmap' command | expand

Commit Message

Simon Glass Sept. 19, 2021, 9:49 p.m. UTC
Add a new 'sf mmap' function to show the address of a SPI offset, if the
hardware supports it. This is useful on x86 systems.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

(no changes since v3)

Changes in v3:
- Add configuration and return value also

 arch/Kconfig     |  2 ++
 cmd/Kconfig      |  8 ++++++
 cmd/sf.c         | 35 +++++++++++++++++++++++++++
 doc/usage/sf.rst | 63 ++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 108 insertions(+)

Comments

Jagan Teki Oct. 8, 2021, 12:47 p.m. UTC | #1
On Mon, Sep 20, 2021 at 3:19 AM Simon Glass <sjg@chromium.org> wrote:
>
> Add a new 'sf mmap' function to show the address of a SPI offset, if the
> hardware supports it. This is useful on x86 systems.

I'm not quite sure about growing sf for limited use cases, maybe
support it in existing arguments might be a good option.

Jagan.
Simon Glass Oct. 8, 2021, 8:29 p.m. UTC | #2
Hi Jagan,

On Fri, 8 Oct 2021 at 06:47, Jagan Teki <jagan@amarulasolutions.com> wrote:
>
> On Mon, Sep 20, 2021 at 3:19 AM Simon Glass <sjg@chromium.org> wrote:
> >
> > Add a new 'sf mmap' function to show the address of a SPI offset, if the
> > hardware supports it. This is useful on x86 systems.
>
> I'm not quite sure about growing sf for limited use cases, maybe
> support it in existing arguments might be a good option.

At least on x86 this is a common feature.

What do you suggest for this? Can you give an example of what
arguments might be used?

Regards,
Simon
Heinrich Schuchardt Nov. 13, 2021, 11:47 a.m. UTC | #3
On 9/19/21 23:49, Simon Glass wrote:
> Add a new 'sf mmap' function to show the address of a SPI offset, if the

I would expect a 'spi info' command to provide this information.

Best regards

Heinrich

> hardware supports it. This is useful on x86 systems.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> (no changes since v3)
>
> Changes in v3:
> - Add configuration and return value also
>
>   arch/Kconfig     |  2 ++
>   cmd/Kconfig      |  8 ++++++
>   cmd/sf.c         | 35 +++++++++++++++++++++++++++
>   doc/usage/sf.rst | 63 ++++++++++++++++++++++++++++++++++++++++++++++++
>   4 files changed, 108 insertions(+)
>
> diff --git a/arch/Kconfig b/arch/Kconfig
> index 8f8daadcf92..406e5a6c627 100644
> --- a/arch/Kconfig
> +++ b/arch/Kconfig
> @@ -136,6 +136,7 @@ config SANDBOX
>   	imply CMD_LZMADEC
>   	imply CMD_SATA
>   	imply CMD_SF
> +	imply CMD_SF_MMAP
>   	imply CMD_SF_TEST
>   	imply CRC32_VERIFY
>   	imply FAT_WRITE
> @@ -200,6 +201,7 @@ config X86
>   	imply CMD_IRQ
>   	imply CMD_PCI
>   	imply CMD_SF
> +	imply CMD_SF_MMAP
>   	imply CMD_SF_TEST
>   	imply CMD_ZBOOT
>   	imply DM_ETH
> diff --git a/cmd/Kconfig b/cmd/Kconfig
> index 3a857b3f6e2..44485f1588c 100644
> --- a/cmd/Kconfig
> +++ b/cmd/Kconfig
> @@ -1273,6 +1273,14 @@ config CMD_SF
>   	help
>   	  SPI Flash support
>
> +config CMD_SF_MMAP
> +	bool "sf mmap - Access memory-mapped SPI flash"
> +	depends on CMD_SF
> +	help
> +	  On some systems part of the SPI flash is mapped into mmemory. This
> +	  command provides a way to map a SPI-flash offset to a memory address,
> +	  so that the contents can be browsed using 'md', for example.
> +
>   config CMD_SF_TEST
>   	bool "sf test - Allow testing of SPI flash"
>   	depends on CMD_SF
> diff --git a/cmd/sf.c b/cmd/sf.c
> index 72246d912fe..c78cd7e6342 100644
> --- a/cmd/sf.c
> +++ b/cmd/sf.c
> @@ -384,6 +384,36 @@ static int do_spi_protect(int argc, char *const argv[])
>   	return ret == 0 ? 0 : 1;
>   }
>
> +static int do_spi_flash_mmap(int argc, char *const argv[])
> +{
> +	loff_t offset, len, maxsize;
> +	uint map_offset, map_size;
> +	ulong map_base;
> +	int dev = 0;
> +	int ret;
> +
> +	if (argc < 2)
> +		return CMD_RET_USAGE;
> +
> +	ret = mtd_arg_off_size(argc - 1, &argv[1], &dev, &offset, &len,
> +			       &maxsize, MTD_DEV_TYPE_NOR, flash->size);
> +	if (ret)
> +		return ret;
> +
> +	ret = dm_spi_get_mmap(flash->dev, &map_base, &map_size, &map_offset);
> +	if (ret) {
> +		printf("Mapping not available (err=%d)\n", ret);
> +		return CMD_RET_FAILURE;
> +	}
> +	if (offset < 0 || offset + len > map_size) {
> +		printf("Offset out of range (map size %x)\n", map_size);
> +		return CMD_RET_FAILURE;
> +	}
> +	printf("%lx\n", map_base + (ulong)offset);
> +
> +	return 0;
> +}
> +
>   enum {
>   	STAGE_ERASE,
>   	STAGE_CHECK,
> @@ -580,6 +610,8 @@ static int do_spi_flash(struct cmd_tbl *cmdtp, int flag, int argc,
>   		ret = do_spi_flash_erase(argc, argv);
>   	else if (strcmp(cmd, "protect") == 0)
>   		ret = do_spi_protect(argc, argv);
> +	else if (IS_ENABLED(CONFIG_CMD_SF_MMAP) && !strcmp(cmd, "mmap"))
> +		ret = do_spi_flash_mmap(argc, argv);
>   	else if (IS_ENABLED(CONFIG_CMD_SF_TEST) && !strcmp(cmd, "test"))
>   		ret = do_spi_flash_test(argc, argv);
>   	else
> @@ -611,6 +643,9 @@ static const char long_help[] =
>   	"					  or to start of mtd `partition'\n"
>   	"sf protect lock/unlock sector len	- protect/unprotect 'len' bytes starting\n"
>   	"					  at address 'sector'"
> +#ifdef CONFIG_CMD_SF_MMAP
> +	"\nsf mmap offset len		- get memory address of SPI-flash offset\n"
> +#endif
>   #ifdef CONFIG_CMD_SF_TEST
>   	"\nsf test offset len		- run a very basic destructive test"
>   #endif
> diff --git a/doc/usage/sf.rst b/doc/usage/sf.rst
> index 71bd1be5175..93fb8409370 100644
> --- a/doc/usage/sf.rst
> +++ b/doc/usage/sf.rst
> @@ -14,6 +14,7 @@ Synopis
>       sf erase <offset>|<partition> <len>
>       sf update <addr> <offset>|<partition> <len>
>       sf protect lock|unlock <sector> <len>
> +    sf mmap <offset>|<partition> <len>
>       sf test <offset>|<partition> <len>
>
>   Description
> @@ -143,6 +144,16 @@ lock|unlock
>   	Number of bytes to lock/unlock
>
>
> +Memory-mapped flash
> +-------------------
> +
> +On some systems part of the SPI flash is mapped into mmemory. With *sf mmap*
> +you can map a SPI-flash offset to a memory address, so that the contents can be
> +browsed using 'md', for example.
> +
> +The command will fail if this is not supported by the hardware or driver.
> +
> +
>   Test
>   ~~~~
>
> @@ -240,6 +251,58 @@ This second example is running on coral, an x86 Chromebook::
>      2 write: 227 ticks, 2255 KiB/s 18.040 Mbps
>      3 read: 189 ticks, 2708 KiB/s 21.664 Mbps
>
> +   # On coral, SPI flash offset 0 corresponds to address ff081000 in memory
> +   => sf mmap 0 1000
> +   device 0 offset 0x0, size 0x1000
> +   ff081000
> +
> +   # See below for how this address was obtained
> +   => sf mmap e80000 11e18
> +   device 0 offset 0xe80000, size 0x11e18
> +   fff01000
> +   => md fff01000
> +   fff01000: b2e8e089 89000030 30b4e8c4 c0310000    ....0......0..1.
> +   fff01010: 002c95e8 2ce8e800 feeb0000 dfe8c489    ..,....,........
> +   fff01020: f400002c 83f4fdeb d4e80cec 3100001e    ,..............1
> +   fff01030: 0cc483c0 f883c3c3 8b0b770a df408504    .........w....@.
> +   fff01040: c085fef1 c8b80575 c3fef1e5 53565755    ....u.......UWVS
> +   fff01050: 89c38951 2404c7c5 80000002 8924048b    Q......$......$.
> +   fff01060: 89a20fdf 89fb89de 75890045 084d8904    ........E..u..M.
> +   fff01070: ff0c5589 c5832404 243c8110 80000005    .U...$....<$....
> +   fff01080: 43c6da75 3b800030 43037520 d889f8eb    u..C0..; u.C....
> +   fff01090: 5f5e5b5a 80e6c35d 535657c3 e7e8c689    Z[^_]....WVS....
> +   fff010a0: 89000069 00a164c3 8b000000 408b4c56    i....d......VL.@
> +   fff010b0: 0cec837c ddb9ff6a e8fef1e5 00004e01    |...j........N..
> +   fff010c0: a1640389 00000000 1c80b60f 66000001    ..d............f
> +   fff010d0: b80c4389 00000001 a20fdf89 fb89de89    .C..............
> +   fff010e0: 89104389 c4831453 5bc03110 56c35f5e    .C..S....1.[^_.V
> +   fff010f0: 14ec8353 ce89d389 0000a164 b60f0000    S.......d.......
> +
> +
> +The offset e80000 was obtained using the following binman command, to find the
> +location of U-Boot SPL::
> +
> +   $ binman ls -i /tmp/b/chromebook_coral/u-boot.rom
> +   Name                                   Image-pos  Size      Entry-type        Offset     Uncomp-size
> +   ------------------------------------------------------------------------------------------------------
> +   main-section                                   0   1000000  section                   0
> +     spl                                     e80000     11e18  u-boot-spl         ffe80000
> +     u-boot                                  d00000     9106e  u-boot             ffd00000
> +     ...
> +
>
>   .. _SPI documentation:
>      https://en.wikipedia.org/wiki/Serial_Peripheral_Interface
> +
> +
> +Configuration
> +-------------
> +
> +The *sf* command is only available if `CONFIG_CMD_SF=y`. Note that it depends on
> +`CONFIG_DM_SPI_FLASH`.
> +
> +Return value
> +------------
> +
> +The return value $? is set to 0 (true) if the command succeded and to 1 (false)
> +otherwise.
>
Simon Glass Nov. 25, 2021, 12:12 a.m. UTC | #4
Hi Heinrich,

On Sat, 13 Nov 2021 at 04:47, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:
>
>
>
> On 9/19/21 23:49, Simon Glass wrote:
> > Add a new 'sf mmap' function to show the address of a SPI offset, if the
>
> I would expect a 'spi info' command to provide this information.

Why is that? It depends on the size of actual SPI-flash device. It is
not a property of the SPI bus, so far as I understand it.

Regards,
Simon
diff mbox series

Patch

diff --git a/arch/Kconfig b/arch/Kconfig
index 8f8daadcf92..406e5a6c627 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -136,6 +136,7 @@  config SANDBOX
 	imply CMD_LZMADEC
 	imply CMD_SATA
 	imply CMD_SF
+	imply CMD_SF_MMAP
 	imply CMD_SF_TEST
 	imply CRC32_VERIFY
 	imply FAT_WRITE
@@ -200,6 +201,7 @@  config X86
 	imply CMD_IRQ
 	imply CMD_PCI
 	imply CMD_SF
+	imply CMD_SF_MMAP
 	imply CMD_SF_TEST
 	imply CMD_ZBOOT
 	imply DM_ETH
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 3a857b3f6e2..44485f1588c 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1273,6 +1273,14 @@  config CMD_SF
 	help
 	  SPI Flash support
 
+config CMD_SF_MMAP
+	bool "sf mmap - Access memory-mapped SPI flash"
+	depends on CMD_SF
+	help
+	  On some systems part of the SPI flash is mapped into mmemory. This
+	  command provides a way to map a SPI-flash offset to a memory address,
+	  so that the contents can be browsed using 'md', for example.
+
 config CMD_SF_TEST
 	bool "sf test - Allow testing of SPI flash"
 	depends on CMD_SF
diff --git a/cmd/sf.c b/cmd/sf.c
index 72246d912fe..c78cd7e6342 100644
--- a/cmd/sf.c
+++ b/cmd/sf.c
@@ -384,6 +384,36 @@  static int do_spi_protect(int argc, char *const argv[])
 	return ret == 0 ? 0 : 1;
 }
 
+static int do_spi_flash_mmap(int argc, char *const argv[])
+{
+	loff_t offset, len, maxsize;
+	uint map_offset, map_size;
+	ulong map_base;
+	int dev = 0;
+	int ret;
+
+	if (argc < 2)
+		return CMD_RET_USAGE;
+
+	ret = mtd_arg_off_size(argc - 1, &argv[1], &dev, &offset, &len,
+			       &maxsize, MTD_DEV_TYPE_NOR, flash->size);
+	if (ret)
+		return ret;
+
+	ret = dm_spi_get_mmap(flash->dev, &map_base, &map_size, &map_offset);
+	if (ret) {
+		printf("Mapping not available (err=%d)\n", ret);
+		return CMD_RET_FAILURE;
+	}
+	if (offset < 0 || offset + len > map_size) {
+		printf("Offset out of range (map size %x)\n", map_size);
+		return CMD_RET_FAILURE;
+	}
+	printf("%lx\n", map_base + (ulong)offset);
+
+	return 0;
+}
+
 enum {
 	STAGE_ERASE,
 	STAGE_CHECK,
@@ -580,6 +610,8 @@  static int do_spi_flash(struct cmd_tbl *cmdtp, int flag, int argc,
 		ret = do_spi_flash_erase(argc, argv);
 	else if (strcmp(cmd, "protect") == 0)
 		ret = do_spi_protect(argc, argv);
+	else if (IS_ENABLED(CONFIG_CMD_SF_MMAP) && !strcmp(cmd, "mmap"))
+		ret = do_spi_flash_mmap(argc, argv);
 	else if (IS_ENABLED(CONFIG_CMD_SF_TEST) && !strcmp(cmd, "test"))
 		ret = do_spi_flash_test(argc, argv);
 	else
@@ -611,6 +643,9 @@  static const char long_help[] =
 	"					  or to start of mtd `partition'\n"
 	"sf protect lock/unlock sector len	- protect/unprotect 'len' bytes starting\n"
 	"					  at address 'sector'"
+#ifdef CONFIG_CMD_SF_MMAP
+	"\nsf mmap offset len		- get memory address of SPI-flash offset\n"
+#endif
 #ifdef CONFIG_CMD_SF_TEST
 	"\nsf test offset len		- run a very basic destructive test"
 #endif
diff --git a/doc/usage/sf.rst b/doc/usage/sf.rst
index 71bd1be5175..93fb8409370 100644
--- a/doc/usage/sf.rst
+++ b/doc/usage/sf.rst
@@ -14,6 +14,7 @@  Synopis
     sf erase <offset>|<partition> <len>
     sf update <addr> <offset>|<partition> <len>
     sf protect lock|unlock <sector> <len>
+    sf mmap <offset>|<partition> <len>
     sf test <offset>|<partition> <len>
 
 Description
@@ -143,6 +144,16 @@  lock|unlock
 	Number of bytes to lock/unlock
 
 
+Memory-mapped flash
+-------------------
+
+On some systems part of the SPI flash is mapped into mmemory. With *sf mmap*
+you can map a SPI-flash offset to a memory address, so that the contents can be
+browsed using 'md', for example.
+
+The command will fail if this is not supported by the hardware or driver.
+
+
 Test
 ~~~~
 
@@ -240,6 +251,58 @@  This second example is running on coral, an x86 Chromebook::
    2 write: 227 ticks, 2255 KiB/s 18.040 Mbps
    3 read: 189 ticks, 2708 KiB/s 21.664 Mbps
 
+   # On coral, SPI flash offset 0 corresponds to address ff081000 in memory
+   => sf mmap 0 1000
+   device 0 offset 0x0, size 0x1000
+   ff081000
+
+   # See below for how this address was obtained
+   => sf mmap e80000 11e18
+   device 0 offset 0xe80000, size 0x11e18
+   fff01000
+   => md fff01000
+   fff01000: b2e8e089 89000030 30b4e8c4 c0310000    ....0......0..1.
+   fff01010: 002c95e8 2ce8e800 feeb0000 dfe8c489    ..,....,........
+   fff01020: f400002c 83f4fdeb d4e80cec 3100001e    ,..............1
+   fff01030: 0cc483c0 f883c3c3 8b0b770a df408504    .........w....@.
+   fff01040: c085fef1 c8b80575 c3fef1e5 53565755    ....u.......UWVS
+   fff01050: 89c38951 2404c7c5 80000002 8924048b    Q......$......$.
+   fff01060: 89a20fdf 89fb89de 75890045 084d8904    ........E..u..M.
+   fff01070: ff0c5589 c5832404 243c8110 80000005    .U...$....<$....
+   fff01080: 43c6da75 3b800030 43037520 d889f8eb    u..C0..; u.C....
+   fff01090: 5f5e5b5a 80e6c35d 535657c3 e7e8c689    Z[^_]....WVS....
+   fff010a0: 89000069 00a164c3 8b000000 408b4c56    i....d......VL.@
+   fff010b0: 0cec837c ddb9ff6a e8fef1e5 00004e01    |...j........N..
+   fff010c0: a1640389 00000000 1c80b60f 66000001    ..d............f
+   fff010d0: b80c4389 00000001 a20fdf89 fb89de89    .C..............
+   fff010e0: 89104389 c4831453 5bc03110 56c35f5e    .C..S....1.[^_.V
+   fff010f0: 14ec8353 ce89d389 0000a164 b60f0000    S.......d.......
+
+
+The offset e80000 was obtained using the following binman command, to find the
+location of U-Boot SPL::
+
+   $ binman ls -i /tmp/b/chromebook_coral/u-boot.rom
+   Name                                   Image-pos  Size      Entry-type        Offset     Uncomp-size
+   ------------------------------------------------------------------------------------------------------
+   main-section                                   0   1000000  section                   0
+     spl                                     e80000     11e18  u-boot-spl         ffe80000
+     u-boot                                  d00000     9106e  u-boot             ffd00000
+     ...
+
 
 .. _SPI documentation:
    https://en.wikipedia.org/wiki/Serial_Peripheral_Interface
+
+
+Configuration
+-------------
+
+The *sf* command is only available if `CONFIG_CMD_SF=y`. Note that it depends on
+`CONFIG_DM_SPI_FLASH`.
+
+Return value
+------------
+
+The return value $? is set to 0 (true) if the command succeded and to 1 (false)
+otherwise.