[PATCH 00/11] sandbox: Minor fixes and improvements

This series collects a few patches that correct and improve sandbox and sandbox_spl:
- Fix a bug in --rm-memory works - Support an MMC backing file for MMC emulator, to allow filesystems to be used without needing the 'host' filesystem - Allow skipping console output when checking verbose commands - Suppress unwanted filesystem warnings when probing partitions - Tidy up a few comments
Simon Glass (11): dtoc: Further improve documentation about warnings sandbox: Correct handling of --rm_memory sandbox: Add license headers to the dts files btrfs: Suppress the message about missing filesystem sqfs: Suppress the message about missing filesystem test: Tidy a comment in the bloblist test dm: core: Fix a few incorrect comments on first/next functions sandbox: Add a way to find the size of a file sandbox: Add a way to map a file into memory sandbox: mmc: Support a backing file test: Add a way to skip console checking until a string matches
arch/sandbox/cpu/os.c | 52 +++++++++-- arch/sandbox/dts/overlay0.dts | 5 ++ arch/sandbox/dts/overlay1.dts | 5 ++ arch/sandbox/dts/sandbox.dts | 5 ++ arch/sandbox/dts/sandbox.dtsi | 1 + arch/sandbox/dts/sandbox64.dts | 4 + arch/sandbox/dts/test.dts | 9 ++ doc/develop/driver-model/of-plat.rst | 92 +++++++++++++++++++- doc/device-tree-bindings/mmc/sandbox,mmc.txt | 18 ++++ drivers/mmc/sandbox_mmc.c | 46 ++++++++-- fs/btrfs/disk-io.c | 8 +- fs/squashfs/sqfs.c | 2 +- include/dm/device.h | 4 +- include/dm/uclass.h | 2 +- include/os.h | 21 +++++ include/test/ut.h | 24 +++++ test/bloblist.c | 2 +- test/ut.c | 26 ++++++ 18 files changed, 299 insertions(+), 27 deletions(-) create mode 100644 doc/device-tree-bindings/mmc/sandbox,mmc.txt

Split this information into subsections and expand it.
Signed-off-by: Simon Glass sjg@chromium.org ---
doc/develop/driver-model/of-plat.rst | 92 ++++++++++++++++++++++++++-- 1 file changed, 88 insertions(+), 4 deletions(-)
diff --git a/doc/develop/driver-model/of-plat.rst b/doc/develop/driver-model/of-plat.rst index 8a8eaed4c11..0bd978759c7 100644 --- a/doc/develop/driver-model/of-plat.rst +++ b/doc/develop/driver-model/of-plat.rst @@ -600,6 +600,11 @@ as a macro included in the driver definition:: Problems --------
+This section shows some common problems and how to fix them. + +Driver not found +~~~~~~~~~~~~~~~~ + In some cases you will you see something like this::
WARNING: the driver rockchip_rk3188_grf was not found in the driver list @@ -633,6 +638,9 @@ the devicetree. For example, if the devicetree has:: then dtoc looks at the first compatible string ("rockchip,rk3188-grf"), converts that to a C identifier (rockchip_rk3188_grf) and then looks for that.
+Missing .compatible or Missing .id +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Various things can cause dtoc to fail to find the driver and it tries to warn about these. For example:
@@ -649,6 +657,82 @@ Checks are also made to confirm that the referenced driver has a .compatible member and a .id member. The first provides the array of compatible strings and the second provides the uclass ID.
+Missing parent +~~~~~~~~~~~~~~ + +When a device is used, its parent must be present as well. If you see an error +like:: + + Node '/i2c@0/emul/emul0' requires parent node '/i2c@0/emul' but it is not in + the valid list + +it indicates that you are using a node whose parent is not present in the +devicetree. In this example, if you look at the device tree output +(e.g. fdtdump tpl/u-boot-tpl.dtb in your build directory), you may see something +like this:: + + emul { + emul0 { + compatible = "sandbox,i2c-rtc-emul"; + #emul-cells = <0x00000000>; + phandle = <0x00000003>; + }; + }; + +In this example, 'emul0' exists but its parent 'emul' has no properties. These +have been dropped by fdtgrep in an effort to reduce the devicetree size. This +indicates that the two nodes have different phase settings. Looking at the +source .dts:: + + i2c_emul: emul { + u-boot,dm-spl; + reg = <0xff>; + compatible = "sandbox,i2c-emul-parent"; + emul0: emul0 { + u-boot,dm-pre-reloc; + compatible = "sandbox,i2c-rtc-emul"; + #emul-cells = <0>; + }; + }; + +you can see that the child node 'emul0' usees 'u-boot,dm-pre-reloc', indicating +that the node is present in all SPL builds, but its parent uses 'u-boot,dm-spl' +indicating it is only present in SPL, not TPL. For a TPL build, this will fail +with the above message. The fix is to change 'emul0' to use the same +'u-boot,dm-spl' condition, so that it is not present in TPL, like its parent. + +Link errors / undefined reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Sometimes dtoc does not find the problem for you, but something is wrong and +you get a link error, e.g.:: + + :(.u_boot_list_2_udevice_2_spl_test5+0x0): undefined reference to + `_u_boot_list_2_driver_2_sandbox_spl_test' + /usr/bin/ld: dts/dt-uclass.o:(.u_boot_list_2_uclass_2_misc+0x8): + undefined reference to `_u_boot_list_2_uclass_driver_2_misc' + +The first one indicates that the device cannot find its driver. This means that +there is a driver 'sandbox_spl_test' but it is not compiled into the build. +Check your Kconfig settings to make sure it is. If you don't want that in the +build, adjust your phase settings, e.g. by using 'u-boot,dm-spl' in the node +to exclude it from the TPL build:: + + spl-test5 { + u-boot,dm-tpl; + compatible = "sandbox,spl-test"; + stringarray = "tpl"; + }; + +We can drop the 'u-boot,dm-tpl' line so this node won't appear in the TPL +devicetree and thus the driver won't be needed. + +The second error above indicates that the MISC uclass is needed by the driver +(since it is in the MISC uclass) but that uclass is not compiled in the build. +The fix above would fix this error too. But if you do want this uclass in the +build, check your Kconfig settings to make sure the uclass is being built +(CONFIG_MISC in this case). +
Caveats ------- @@ -697,7 +781,7 @@ Internals ---------
Generated files -``````````````` +~~~~~~~~~~~~~~~
When enabled, dtoc generates the following five files:
@@ -738,7 +822,7 @@ spl/dt-plat.c.
CONFIG options -`````````````` +~~~~~~~~~~~~~~
Several CONFIG options are used to control the behaviour of of-platdata, all available for both SPL and TPL: @@ -793,7 +877,7 @@ READ_ONLY the nodes cannot be updated, OF_PLATDATA_NO_BIND is enabled.
Data structures -``````````````` +~~~~~~~~~~~~~~~
A few extra data structures are used with of-platdata:
@@ -821,7 +905,7 @@ A few extra data structures are used with of-platdata: `device_get_by_ofplat_idx()`.
Other changes -````````````` +~~~~~~~~~~~~~
Some other changes are made with of-platdata:

On Wed, Aug 18, 2021 at 09:40:23PM -0600, Simon Glass wrote:
Split this information into subsections and expand it.
Signed-off-by: Simon Glass sjg@chromium.org
Applied to u-boot/next, thanks!

This option has no argument so we should not trip to skip one.
Fix it.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/sandbox/cpu/os.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index 1103530941b..151f42a5d6c 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -690,7 +690,6 @@ static int add_args(char ***argvp, char *add_args[], int count) continue; } } else if (!strcmp(arg, "--rm_memory")) { - ap++; continue; } argv[argc++] = arg;

On Wed, Aug 18, 2021 at 09:40:24PM -0600, Simon Glass wrote:
This option has no argument so we should not trip to skip one.
Fix it.
Signed-off-by: Simon Glass sjg@chromium.org
Applied to u-boot/next, thanks!

Many of these files are missing a header. Fix this.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/sandbox/dts/overlay0.dts | 5 +++++ arch/sandbox/dts/overlay1.dts | 5 +++++ arch/sandbox/dts/sandbox.dts | 5 +++++ arch/sandbox/dts/sandbox.dtsi | 1 + arch/sandbox/dts/sandbox64.dts | 4 ++++ arch/sandbox/dts/test.dts | 9 +++++++++ 6 files changed, 29 insertions(+)
diff --git a/arch/sandbox/dts/overlay0.dts b/arch/sandbox/dts/overlay0.dts index 70c6cf77aad..9e5f38962bc 100644 --- a/arch/sandbox/dts/overlay0.dts +++ b/arch/sandbox/dts/overlay0.dts @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Overlay test file + */ + /dts-v1/; /plugin/;
diff --git a/arch/sandbox/dts/overlay1.dts b/arch/sandbox/dts/overlay1.dts index 51621b31105..303e713f336 100644 --- a/arch/sandbox/dts/overlay1.dts +++ b/arch/sandbox/dts/overlay1.dts @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Overlay test file + */ + /dts-v1/; /plugin/;
diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts index a8938a3accb..127f168f022 100644 --- a/arch/sandbox/dts/sandbox.dts +++ b/arch/sandbox/dts/sandbox.dts @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Main sandbox devicetree + */ + /dts-v1/;
#include <config.h> diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi index 200fcab6a41..6cf5f14cd11 100644 --- a/arch/sandbox/dts/sandbox.dtsi +++ b/arch/sandbox/dts/sandbox.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * This is the common sandbox device-tree nodes. This is shared between sandbox * and sandbox64 builds. diff --git a/arch/sandbox/dts/sandbox64.dts b/arch/sandbox/dts/sandbox64.dts index a39f94feec0..ec53106af9d 100644 --- a/arch/sandbox/dts/sandbox64.dts +++ b/arch/sandbox/dts/sandbox64.dts @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Main sandbox64 devicetree + */ /dts-v1/;
#include <config.h> diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index d5976318d1c..f1b54131e9c 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -1,3 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Devicetree file for running sandbox tests + * + * This includes lots of extra devices used by various tests. + * + * Note that SPL use the main sandbox.dts file + */ + /dts-v1/;
#include <dt-bindings/gpio/gpio.h>

On Wed, Aug 18, 2021 at 09:40:25PM -0600, Simon Glass wrote:
Many of these files are missing a header. Fix this.
Signed-off-by: Simon Glass sjg@chromium.org
Applied to u-boot/next, thanks!

This message comes up a lot when scanning filesystems. It suggests to the user that there is some sort of error, but in fact there is no reason to expect that a particular partition has a btrfs filesystem. Other filesystems don't print this error.
Turn it into a debug message.
Signed-off-by: Simon Glass sjg@chromium.org ---
fs/btrfs/disk-io.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 349411c3ccd..1b69346e231 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -886,7 +886,11 @@ static int btrfs_scan_fs_devices(struct blk_desc *desc,
ret = btrfs_scan_one_device(desc, part, fs_devices, &total_devs); if (ret) { - fprintf(stderr, "No valid Btrfs found\n"); + /* + * Avoid showing this when probing for a possible Btrfs + * + * fprintf(stderr, "No valid Btrfs found\n"); + */ return ret; } return 0; @@ -975,7 +979,7 @@ struct btrfs_fs_info *open_ctree_fs_info(struct blk_desc *desc, disk_super = fs_info->super_copy; ret = btrfs_read_dev_super(desc, part, disk_super); if (ret) { - printk("No valid btrfs found\n"); + debug("No valid btrfs found\n"); goto out_devices; }

On Wed, 18 Aug 2021 21:40:26 -0600 Simon Glass sjg@chromium.org wrote:
This message comes up a lot when scanning filesystems. It suggests to the user that there is some sort of error, but in fact there is no reason to expect that a particular partition has a btrfs filesystem. Other filesystems don't print this error.
Turn it into a debug message.
Signed-off-by: Simon Glass sjg@chromium.org
Reviewed-by: Marek Behún marek.behun@nic.cz
This must have been introduced after btrfs was reimplemented from the btrfs-progs sources. I remember that I sent a patch fixing this same issue for the previous implementation (or was it another filesystem?).
Marek

On 2021/8/19 上午11:40, Simon Glass wrote:
This message comes up a lot when scanning filesystems. It suggests to the user that there is some sort of error, but in fact there is no reason to expect that a particular partition has a btrfs filesystem. Other filesystems don't print this error.
Turn it into a debug message.
Signed-off-by: Simon Glass sjg@chromium.org
Reviewed-by: Qu Wenruo wqu@suse.com
Thanks, Qu
fs/btrfs/disk-io.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 349411c3ccd..1b69346e231 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -886,7 +886,11 @@ static int btrfs_scan_fs_devices(struct blk_desc *desc,
ret = btrfs_scan_one_device(desc, part, fs_devices, &total_devs); if (ret) {
fprintf(stderr, "No valid Btrfs found\n");
/*
* Avoid showing this when probing for a possible Btrfs
*
* fprintf(stderr, "No valid Btrfs found\n");
return ret; } return 0;*/
@@ -975,7 +979,7 @@ struct btrfs_fs_info *open_ctree_fs_info(struct blk_desc *desc, disk_super = fs_info->super_copy; ret = btrfs_read_dev_super(desc, part, disk_super); if (ret) {
printk("No valid btrfs found\n");
goto out_devices; }debug("No valid btrfs found\n");

On Wed, Aug 18, 2021 at 09:40:26PM -0600, Simon Glass wrote:
This message comes up a lot when scanning filesystems. It suggests to the user that there is some sort of error, but in fact there is no reason to expect that a particular partition has a btrfs filesystem. Other filesystems don't print this error.
Turn it into a debug message.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Marek Behún marek.behun@nic.cz Reviewed-by: Qu Wenruo wqu@suse.com
Applied to u-boot/next, thanks!

This message comes up a lot when scanning filesystems. It suggests to the user that there is some sort of error, but in fact there is no reason to expect that a particular partition has a sqfs filesystem. Other filesystems don't print this error.
Turn it into a debug message.
Signed-off-by: Simon Glass sjg@chromium.org ---
fs/squashfs/sqfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index 92ab8ac6310..e2d91c654cd 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -1090,7 +1090,7 @@ int sqfs_probe(struct blk_desc *fs_dev_desc, struct disk_partition *fs_partition
/* Make sure it has a valid SquashFS magic number*/ if (get_unaligned_le32(&sblk->s_magic) != SQFS_MAGIC_NUMBER) { - printf("Bad magic number for SquashFS image.\n"); + debug("Bad magic number for SquashFS image.\n"); ret = -EINVAL; goto error; }

Hi Simon,
Simon Glass sjg@chromium.org wrote on Wed, 18 Aug 2021 21:40:27 -0600:
This message comes up a lot when scanning filesystems. It suggests to the user that there is some sort of error, but in fact there is no reason to expect that a particular partition has a sqfs filesystem. Other filesystems don't print this error.
Turn it into a debug message.
Signed-off-by: Simon Glass sjg@chromium.org
Reviewed-by: Miquel Raynal miquel.raynal@bootlin.com
fs/squashfs/sqfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index 92ab8ac6310..e2d91c654cd 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -1090,7 +1090,7 @@ int sqfs_probe(struct blk_desc *fs_dev_desc, struct disk_partition *fs_partition
/* Make sure it has a valid SquashFS magic number*/ if (get_unaligned_le32(&sblk->s_magic) != SQFS_MAGIC_NUMBER) {
printf("Bad magic number for SquashFS image.\n");
ret = -EINVAL; goto error; }debug("Bad magic number for SquashFS image.\n");
Thanks, Miquèl

On Wed, Aug 18, 2021 at 09:40:27PM -0600, Simon Glass wrote:
This message comes up a lot when scanning filesystems. It suggests to the user that there is some sort of error, but in fact there is no reason to expect that a particular partition has a sqfs filesystem. Other filesystems don't print this error.
Turn it into a debug message.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Miquel Raynal miquel.raynal@bootlin.com
Applied to u-boot/next, thanks!

Fix up a copy error.
Signed-off-by: Simon Glass sjg@chromium.org ---
test/bloblist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/bloblist.c b/test/bloblist.c index 4104e6a92f6..b48be38dc3e 100644 --- a/test/bloblist.c +++ b/test/bloblist.c @@ -14,7 +14,7 @@
DECLARE_GLOBAL_DATA_PTR;
-/* Declare a new compression test */ +/* Declare a new bloblist test */ #define BLOBLIST_TEST(_name, _flags) \ UNIT_TEST(_name, _flags, bloblist_test)

On Wed, Aug 18, 2021 at 09:40:28PM -0600, Simon Glass wrote:
Fix up a copy error.
Signed-off-by: Simon Glass sjg@chromium.org
Applied to u-boot/next, thanks!

Tighten up these comments to make the behaviour clearer.
Signed-off-by: Simon Glass sjg@chromium.org ---
include/dm/device.h | 4 ++-- include/dm/uclass.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/include/dm/device.h b/include/dm/device.h index 0a9718a5b81..ef6241bca8b 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -738,7 +738,7 @@ int device_find_next_child(struct udevice **devp); * * @parent: Parent device to search * @uclass_id: Uclass to look for - * @devp: Returns device found, if any + * @devp: Returns device found, if any, else NULL * @return 0 if found, else -ENODEV */ int device_find_first_inactive_child(const struct udevice *parent, @@ -750,7 +750,7 @@ int device_find_first_inactive_child(const struct udevice *parent, * * @parent: Parent device to search * @uclass_id: Uclass to look for - * @devp: Returns first child device in that uclass, if any + * @devp: Returns first child device in that uclass, if any, else NULL * @return 0 if found, else -ENODEV */ int device_find_first_child_by_uclass(const struct udevice *parent, diff --git a/include/dm/uclass.h b/include/dm/uclass.h index da0c1bfadb1..15e5f9ef5bc 100644 --- a/include/dm/uclass.h +++ b/include/dm/uclass.h @@ -354,7 +354,7 @@ int uclass_next_device(struct udevice **devp); * The device returned is probed if necessary, and ready for use * * @devp: On entry, pointer to device to lookup. On exit, returns pointer - * to the next device in the uclass if no error occurred, or -ENODEV if + * to the next device in the uclass if no error occurred, or NULL if * there is no next device. * @return 0 if found, -ENODEV if not found, other -ve on error */

On Wed, Aug 18, 2021 at 09:40:29PM -0600, Simon Glass wrote:
Tighten up these comments to make the behaviour clearer.
Signed-off-by: Simon Glass sjg@chromium.org
Applied to u-boot/next, thanks!

Add a function to return the size of a file. This is useful in situations where we need to allocate memory for it before reading it.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/sandbox/cpu/os.c | 22 ++++++++++++++++------ include/os.h | 8 ++++++++ 2 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index 151f42a5d6c..a4262881c54 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -133,6 +133,19 @@ int os_write_file(const char *fname, const void *buf, int size) return 0; }
+int os_filesize(int fd) +{ + off_t size; + + size = os_lseek(fd, 0, OS_SEEK_END); + if (size < 0) + return -errno; + if (os_lseek(fd, 0, OS_SEEK_SET) < 0) + return -errno; + + return size; +} + int os_read_file(const char *fname, void **bufp, int *sizep) { off_t size; @@ -144,15 +157,12 @@ int os_read_file(const char *fname, void **bufp, int *sizep) printf("Cannot open file '%s'\n", fname); goto err; } - size = os_lseek(fd, 0, OS_SEEK_END); + size = os_filesize(fd); if (size < 0) { - printf("Cannot seek to end of file '%s'\n", fname); - goto err; - } - if (os_lseek(fd, 0, OS_SEEK_SET) < 0) { - printf("Cannot seek to start of file '%s'\n", fname); + printf("Cannot get file size of '%s'\n", fname); goto err; } + *bufp = os_malloc(size); if (!*bufp) { printf("Not enough memory to read file '%s'\n", fname); diff --git a/include/os.h b/include/os.h index 7b20d606dd0..7661078d336 100644 --- a/include/os.h +++ b/include/os.h @@ -51,6 +51,14 @@ off_t os_lseek(int fd, off_t offset, int whence); #define OS_SEEK_CUR 1 #define OS_SEEK_END 2
+/** + * os_filesize() - Calculate the size of a file + * + * @fd: File descriptor as returned by os_open() + * Return: file size or negative error code + */ +int os_filesize(int fd); + /** * Access to the OS open() system call *

On Wed, 18 Aug 2021 21:40:30 -0600 Simon Glass sjg@chromium.org wrote:
Add a function to return the size of a file. This is useful in situations where we need to allocate memory for it before reading it.
Signed-off-by: Simon Glass sjg@chromium.org
Reviewed-by: Marek Behún marek.behun@nic.cz

On Wed, Aug 18, 2021 at 09:40:30PM -0600, Simon Glass wrote:
Add a function to return the size of a file. This is useful in situations where we need to allocate memory for it before reading it.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Marek Behún marek.behun@nic.cz
Applied to u-boot/next, thanks!

It is useful to map a file into memory so that it can be accessed using simple pointers. Add a function to support this.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/sandbox/cpu/os.c | 29 +++++++++++++++++++++++++++++ include/os.h | 13 +++++++++++++ 2 files changed, 42 insertions(+)
diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index a4262881c54..b72dafca2ba 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -182,6 +182,35 @@ err: return ret; }
+int os_map_file(const char *pathname, int os_flags, void **bufp, int *sizep) +{ + void *ptr; + int size; + int ifd; + + ifd = os_open(pathname, os_flags); + if (ifd < 0) { + printf("Cannot open file '%s'\n", pathname); + return -EIO; + } + size = os_filesize(ifd); + if (size < 0) { + printf("Cannot get file size of '%s'\n", pathname); + return -EIO; + } + + ptr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, ifd, 0); + if (ptr == MAP_FAILED) { + printf("Can't map file '%s': %s\n", pathname, strerror(errno)); + return -EPERM; + } + + *bufp = ptr; + *sizep = size; + + return 0; +} + /* Restore tty state when we exit */ static struct termios orig_term; static bool term_setup; diff --git a/include/os.h b/include/os.h index 7661078d336..770d76e02f7 100644 --- a/include/os.h +++ b/include/os.h @@ -406,6 +406,19 @@ int os_write_file(const char *name, const void *buf, int size); */ int os_read_file(const char *name, void **bufp, int *sizep);
+/** + * os_map_file() - Map a file from the host filesystem into memory + * + * This can be useful when to provide a backing store for an emulated device + * + * @pathname: File pathname to map + * @os_flags: Flags, like OS_O_RDONLY, OS_O_RDWR + * @bufp: Returns buffer containing the file + * @sizep: Returns size of data + * Return: 0 if OK, -ve on error + */ +int os_map_file(const char *pathname, int os_flags, void **bufp, int *sizep); + /* * os_find_text_base() - Find the text section in this running process *

On Wed, 18 Aug 2021 21:40:31 -0600 Simon Glass sjg@chromium.org wrote:
It is useful to map a file into memory so that it can be accessed using simple pointers. Add a function to support this.
Signed-off-by: Simon Glass sjg@chromium.org
+int os_map_file(const char *pathname, int os_flags, void **bufp, int *sizep) +{
- void *ptr;
- int size;
- int ifd;
- ifd = os_open(pathname, os_flags);
- if (ifd < 0) {
printf("Cannot open file '%s'\n", pathname);
return -EIO;
- }
- size = os_filesize(ifd);
- if (size < 0) {
printf("Cannot get file size of '%s'\n", pathname);
return -EIO;
- }
- ptr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, ifd, 0);
- if (ptr == MAP_FAILED) {
printf("Can't map file '%s': %s\n", pathname, strerror(errno));
return -EPERM;
- }
- *bufp = ptr;
- *sizep = size;
- return 0;
+}
You need to close the file descriptor after mmapping.
Marek

On Wed, Aug 18, 2021 at 09:40:31PM -0600, Simon Glass wrote:
It is useful to map a file into memory so that it can be accessed using simple pointers. Add a function to support this.
Signed-off-by: Simon Glass sjg@chromium.org
Applied to u-boot/next, thanks!

Hi Marek,
On Wed, 22 Sept 2021 at 20:09, Tom Rini trini@konsulko.com wrote:
On Wed, Aug 18, 2021 at 09:40:31PM -0600, Simon Glass wrote:
It is useful to map a file into memory so that it can be accessed using simple pointers. Add a function to support this.
Signed-off-by: Simon Glass sjg@chromium.org
Applied to u-boot/next, thanks!
I'll send a new patch for your comment. I have it locally but the mmc malloc() thing needs a substantial effort to resolve, so I'm not sure when I'll send this.
Regards, Simon

Provide a way for sandbox MMC to present data from a backing file. This allows a filesystem to be created on the host and easily served via an emulated mmc device.
Signed-off-by: Simon Glass sjg@chromium.org ---
doc/device-tree-bindings/mmc/sandbox,mmc.txt | 18 ++++++++ drivers/mmc/sandbox_mmc.c | 46 ++++++++++++++++---- 2 files changed, 55 insertions(+), 9 deletions(-) create mode 100644 doc/device-tree-bindings/mmc/sandbox,mmc.txt
diff --git a/doc/device-tree-bindings/mmc/sandbox,mmc.txt b/doc/device-tree-bindings/mmc/sandbox,mmc.txt new file mode 100644 index 00000000000..1170bcd6a00 --- /dev/null +++ b/doc/device-tree-bindings/mmc/sandbox,mmc.txt @@ -0,0 +1,18 @@ +Sandbox MMC +=========== + +Required properties: +- compatible : "sandbox,mmc" + +Optional properties: +- filename : Name of backing file, if any. This is mapped into the MMC device + so can be used to provide a filesystem or other test data + + +Example +------- + +mmc2 { + compatible = "sandbox,mmc"; + non-removable; +}; diff --git a/drivers/mmc/sandbox_mmc.c b/drivers/mmc/sandbox_mmc.c index 895fbffecfc..1139951c626 100644 --- a/drivers/mmc/sandbox_mmc.c +++ b/drivers/mmc/sandbox_mmc.c @@ -9,23 +9,26 @@ #include <errno.h> #include <fdtdec.h> #include <log.h> +#include <malloc.h> #include <mmc.h> +#include <os.h> #include <asm/test.h>
struct sandbox_mmc_plat { struct mmc_config cfg; struct mmc mmc; + const char *fname; };
-#define MMC_CSIZE 0 -#define MMC_CMULT 8 /* 8 because the card is high-capacity */ -#define MMC_BL_LEN_SHIFT 10 -#define MMC_BL_LEN BIT(MMC_BL_LEN_SHIFT) -#define MMC_CAPACITY (((MMC_CSIZE + 1) << (MMC_CMULT + 2)) \ - * MMC_BL_LEN) /* 1 MiB */ +#define MMC_CMULT 8 /* 8 because the card is high-capacity */ +#define MMC_BL_LEN_SHIFT 10 +#define MMC_BL_LEN BIT(MMC_BL_LEN_SHIFT) +#define SIZE_MULTIPLE ((1 << (MMC_CMULT + 2)) * MMC_BL_LEN)
struct sandbox_mmc_priv { - u8 buf[MMC_CAPACITY]; + int csize; /* CSIZE value to report */ + char *buf; + int size; };
/** @@ -60,8 +63,8 @@ static int sandbox_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, case MMC_CMD_SEND_CSD: cmd->response[0] = 0; cmd->response[1] = (MMC_BL_LEN_SHIFT << 16) | - ((MMC_CSIZE >> 16) & 0x3f); - cmd->response[2] = (MMC_CSIZE & 0xffff) << 16; + ((priv->csize >> 16) & 0x3f); + cmd->response[2] = (priv->csize & 0xffff) << 16; cmd->response[3] = 0; break; case SD_CMD_SWITCH_FUNC: { @@ -143,6 +146,8 @@ static int sandbox_mmc_of_to_plat(struct udevice *dev) struct blk_desc *blk; int ret;
+ plat->fname = dev_read_string(dev, "filename"); + ret = mmc_of_parse(dev, cfg); if (ret) return ret; @@ -156,6 +161,29 @@ static int sandbox_mmc_of_to_plat(struct udevice *dev) static int sandbox_mmc_probe(struct udevice *dev) { struct sandbox_mmc_plat *plat = dev_get_plat(dev); + struct sandbox_mmc_priv *priv = dev_get_priv(dev); + int ret; + + if (plat->fname) { + ret = os_map_file(plat->fname, OS_O_RDWR | OS_O_CREAT, + (void **)&priv->buf, &priv->size); + if (ret) { + log_err("%s: Unable to map file '%s'\n", dev->name, + plat->fname); + return ret; + } + priv->csize = priv->size / SIZE_MULTIPLE - 1; + } else { + priv->csize = 0; + priv->size = (priv->csize + 1) * SIZE_MULTIPLE; /* 1 MiB */ + + priv->buf = malloc(priv->size); + if (!priv->buf) { + log_err("%s: Not enough memory (%x bytes)\n", + dev->name, priv->size); + return -ENOMEM; + } + }
return mmc_init(&plat->mmc); }

On 8/19/21 12:40 PM, Simon Glass wrote:
Provide a way for sandbox MMC to present data from a backing file. This allows a filesystem to be created on the host and easily served via an emulated mmc device.
Signed-off-by: Simon Glass sjg@chromium.org
Reviewed-by: Jaehoon Chung jh80.chung@samsung.com
Best Regards, Jaehoon Chung
doc/device-tree-bindings/mmc/sandbox,mmc.txt | 18 ++++++++ drivers/mmc/sandbox_mmc.c | 46 ++++++++++++++++---- 2 files changed, 55 insertions(+), 9 deletions(-) create mode 100644 doc/device-tree-bindings/mmc/sandbox,mmc.txt
diff --git a/doc/device-tree-bindings/mmc/sandbox,mmc.txt b/doc/device-tree-bindings/mmc/sandbox,mmc.txt new file mode 100644 index 00000000000..1170bcd6a00 --- /dev/null +++ b/doc/device-tree-bindings/mmc/sandbox,mmc.txt @@ -0,0 +1,18 @@ +Sandbox MMC +===========
+Required properties: +- compatible : "sandbox,mmc"
+Optional properties: +- filename : Name of backing file, if any. This is mapped into the MMC device
- so can be used to provide a filesystem or other test data
+Example +-------
+mmc2 {
- compatible = "sandbox,mmc";
- non-removable;
+}; diff --git a/drivers/mmc/sandbox_mmc.c b/drivers/mmc/sandbox_mmc.c index 895fbffecfc..1139951c626 100644 --- a/drivers/mmc/sandbox_mmc.c +++ b/drivers/mmc/sandbox_mmc.c @@ -9,23 +9,26 @@ #include <errno.h> #include <fdtdec.h> #include <log.h> +#include <malloc.h> #include <mmc.h> +#include <os.h> #include <asm/test.h>
struct sandbox_mmc_plat { struct mmc_config cfg; struct mmc mmc;
- const char *fname;
};
-#define MMC_CSIZE 0 -#define MMC_CMULT 8 /* 8 because the card is high-capacity */ -#define MMC_BL_LEN_SHIFT 10 -#define MMC_BL_LEN BIT(MMC_BL_LEN_SHIFT) -#define MMC_CAPACITY (((MMC_CSIZE + 1) << (MMC_CMULT + 2)) \
* MMC_BL_LEN) /* 1 MiB */
+#define MMC_CMULT 8 /* 8 because the card is high-capacity */ +#define MMC_BL_LEN_SHIFT 10 +#define MMC_BL_LEN BIT(MMC_BL_LEN_SHIFT) +#define SIZE_MULTIPLE ((1 << (MMC_CMULT + 2)) * MMC_BL_LEN)
struct sandbox_mmc_priv {
- u8 buf[MMC_CAPACITY];
- int csize; /* CSIZE value to report */
- char *buf;
- int size;
};
/** @@ -60,8 +63,8 @@ static int sandbox_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, case MMC_CMD_SEND_CSD: cmd->response[0] = 0; cmd->response[1] = (MMC_BL_LEN_SHIFT << 16) |
((MMC_CSIZE >> 16) & 0x3f);
cmd->response[2] = (MMC_CSIZE & 0xffff) << 16;
((priv->csize >> 16) & 0x3f);
cmd->response[3] = 0; break; case SD_CMD_SWITCH_FUNC: {cmd->response[2] = (priv->csize & 0xffff) << 16;
@@ -143,6 +146,8 @@ static int sandbox_mmc_of_to_plat(struct udevice *dev) struct blk_desc *blk; int ret;
- plat->fname = dev_read_string(dev, "filename");
- ret = mmc_of_parse(dev, cfg); if (ret) return ret;
@@ -156,6 +161,29 @@ static int sandbox_mmc_of_to_plat(struct udevice *dev) static int sandbox_mmc_probe(struct udevice *dev) { struct sandbox_mmc_plat *plat = dev_get_plat(dev);
struct sandbox_mmc_priv *priv = dev_get_priv(dev);
int ret;
if (plat->fname) {
ret = os_map_file(plat->fname, OS_O_RDWR | OS_O_CREAT,
(void **)&priv->buf, &priv->size);
if (ret) {
log_err("%s: Unable to map file '%s'\n", dev->name,
plat->fname);
return ret;
}
priv->csize = priv->size / SIZE_MULTIPLE - 1;
} else {
priv->csize = 0;
priv->size = (priv->csize + 1) * SIZE_MULTIPLE; /* 1 MiB */
priv->buf = malloc(priv->size);
if (!priv->buf) {
log_err("%s: Not enough memory (%x bytes)\n",
dev->name, priv->size);
return -ENOMEM;
}
}
return mmc_init(&plat->mmc);
}

On 8/18/21 11:40 PM, Simon Glass wrote:
Provide a way for sandbox MMC to present data from a backing file. This allows a filesystem to be created on the host and easily served via an emulated mmc device.
Signed-off-by: Simon Glass sjg@chromium.org
doc/device-tree-bindings/mmc/sandbox,mmc.txt | 18 ++++++++ drivers/mmc/sandbox_mmc.c | 46 ++++++++++++++++---- 2 files changed, 55 insertions(+), 9 deletions(-) create mode 100644 doc/device-tree-bindings/mmc/sandbox,mmc.txt
diff --git a/doc/device-tree-bindings/mmc/sandbox,mmc.txt b/doc/device-tree-bindings/mmc/sandbox,mmc.txt new file mode 100644 index 00000000000..1170bcd6a00 --- /dev/null +++ b/doc/device-tree-bindings/mmc/sandbox,mmc.txt @@ -0,0 +1,18 @@ +Sandbox MMC +===========
+Required properties: +- compatible : "sandbox,mmc"
+Optional properties: +- filename : Name of backing file, if any. This is mapped into the MMC device
- so can be used to provide a filesystem or other test data
Can we stick this in the command line arguments somehow? For testing with different images, I think that editing the device tree is not the best way to do things. It also makes it trickier to add automated tests.
+Example +-------
+mmc2 {
- compatible = "sandbox,mmc";
- non-removable;
+}; diff --git a/drivers/mmc/sandbox_mmc.c b/drivers/mmc/sandbox_mmc.c index 895fbffecfc..1139951c626 100644 --- a/drivers/mmc/sandbox_mmc.c +++ b/drivers/mmc/sandbox_mmc.c @@ -9,23 +9,26 @@ #include <errno.h> #include <fdtdec.h> #include <log.h> +#include <malloc.h> #include <mmc.h> +#include <os.h> #include <asm/test.h>
struct sandbox_mmc_plat { struct mmc_config cfg; struct mmc mmc;
- const char *fname; };
-#define MMC_CSIZE 0 -#define MMC_CMULT 8 /* 8 because the card is high-capacity */ -#define MMC_BL_LEN_SHIFT 10 -#define MMC_BL_LEN BIT(MMC_BL_LEN_SHIFT) -#define MMC_CAPACITY (((MMC_CSIZE + 1) << (MMC_CMULT + 2)) \
* MMC_BL_LEN) /* 1 MiB */
+#define MMC_CMULT 8 /* 8 because the card is high-capacity */ +#define MMC_BL_LEN_SHIFT 10 +#define MMC_BL_LEN BIT(MMC_BL_LEN_SHIFT) +#define SIZE_MULTIPLE ((1 << (MMC_CMULT + 2)) * MMC_BL_LEN)
struct sandbox_mmc_priv {
- u8 buf[MMC_CAPACITY];
- int csize; /* CSIZE value to report */
- char *buf;
- int size;
nit: to save a whole 2 bytes on 64-bit you can reorder this like
char * int int
};
/** @@ -60,8 +63,8 @@ static int sandbox_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, case MMC_CMD_SEND_CSD: cmd->response[0] = 0; cmd->response[1] = (MMC_BL_LEN_SHIFT << 16) |
((MMC_CSIZE >> 16) & 0x3f);
cmd->response[2] = (MMC_CSIZE & 0xffff) << 16;
((priv->csize >> 16) & 0x3f);
cmd->response[3] = 0; break; case SD_CMD_SWITCH_FUNC: {cmd->response[2] = (priv->csize & 0xffff) << 16;
@@ -143,6 +146,8 @@ static int sandbox_mmc_of_to_plat(struct udevice *dev) struct blk_desc *blk; int ret;
- plat->fname = dev_read_string(dev, "filename");
- ret = mmc_of_parse(dev, cfg); if (ret) return ret;
@@ -156,6 +161,29 @@ static int sandbox_mmc_of_to_plat(struct udevice *dev) static int sandbox_mmc_probe(struct udevice *dev) { struct sandbox_mmc_plat *plat = dev_get_plat(dev);
- struct sandbox_mmc_priv *priv = dev_get_priv(dev);
- int ret;
- if (plat->fname) {
ret = os_map_file(plat->fname, OS_O_RDWR | OS_O_CREAT,
(void **)&priv->buf, &priv->size);
if (ret) {
log_err("%s: Unable to map file '%s'\n", dev->name,
plat->fname);
return ret;
}
priv->csize = priv->size / SIZE_MULTIPLE - 1;
Won't this cut off the end of the file? If we can't avoid this, we should at least warn the user that we are truncating it.
--Sean
} else {
priv->csize = 0;
priv->size = (priv->csize + 1) * SIZE_MULTIPLE; /* 1 MiB */
priv->buf = malloc(priv->size);
if (!priv->buf) {
log_err("%s: Not enough memory (%x bytes)\n",
dev->name, priv->size);
return -ENOMEM;
}
}
return mmc_init(&plat->mmc); }

Hi Sean,
On Sat, 28 Aug 2021 at 00:39, Sean Anderson seanga2@gmail.com wrote:
On 8/18/21 11:40 PM, Simon Glass wrote:
Provide a way for sandbox MMC to present data from a backing file. This allows a filesystem to be created on the host and easily served via an emulated mmc device.
Signed-off-by: Simon Glass sjg@chromium.org
doc/device-tree-bindings/mmc/sandbox,mmc.txt | 18 ++++++++ drivers/mmc/sandbox_mmc.c | 46 ++++++++++++++++---- 2 files changed, 55 insertions(+), 9 deletions(-) create mode 100644 doc/device-tree-bindings/mmc/sandbox,mmc.txt
diff --git a/doc/device-tree-bindings/mmc/sandbox,mmc.txt b/doc/device-tree-bindings/mmc/sandbox,mmc.txt new file mode 100644 index 00000000000..1170bcd6a00 --- /dev/null +++ b/doc/device-tree-bindings/mmc/sandbox,mmc.txt @@ -0,0 +1,18 @@ +Sandbox MMC +===========
+Required properties: +- compatible : "sandbox,mmc"
+Optional properties: +- filename : Name of backing file, if any. This is mapped into the MMC device
- so can be used to provide a filesystem or other test data
Can we stick this in the command line arguments somehow? For testing with different images, I think that editing the device tree is not the best way to do things. It also makes it trickier to add automated tests.
We can, of course. We used to have that with SPI flash but we ended up dropping it as it was unwieldy and disconnected from the devicetree . The automated tests can work by setting up a file in advance. In fact we do this with SPI flash and I2C eeprom.
So I think this works much better. See dm_test_spi_flash() for how the file is set up in a unit test.
+Example +-------
+mmc2 {
compatible = "sandbox,mmc";
non-removable;
+}; diff --git a/drivers/mmc/sandbox_mmc.c b/drivers/mmc/sandbox_mmc.c index 895fbffecfc..1139951c626 100644 --- a/drivers/mmc/sandbox_mmc.c +++ b/drivers/mmc/sandbox_mmc.c @@ -9,23 +9,26 @@ #include <errno.h> #include <fdtdec.h> #include <log.h> +#include <malloc.h> #include <mmc.h> +#include <os.h> #include <asm/test.h>
struct sandbox_mmc_plat { struct mmc_config cfg; struct mmc mmc;
};const char *fname;
-#define MMC_CSIZE 0 -#define MMC_CMULT 8 /* 8 because the card is high-capacity */ -#define MMC_BL_LEN_SHIFT 10 -#define MMC_BL_LEN BIT(MMC_BL_LEN_SHIFT) -#define MMC_CAPACITY (((MMC_CSIZE + 1) << (MMC_CMULT + 2)) \
* MMC_BL_LEN) /* 1 MiB */
+#define MMC_CMULT 8 /* 8 because the card is high-capacity */ +#define MMC_BL_LEN_SHIFT 10 +#define MMC_BL_LEN BIT(MMC_BL_LEN_SHIFT) +#define SIZE_MULTIPLE ((1 << (MMC_CMULT + 2)) * MMC_BL_LEN)
struct sandbox_mmc_priv {
u8 buf[MMC_CAPACITY];
int csize; /* CSIZE value to report */
char *buf;
int size;
nit: to save a whole 2 bytes on 64-bit you can reorder this like
char * int int
OK will do.
};
/** @@ -60,8 +63,8 @@ static int sandbox_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, case MMC_CMD_SEND_CSD: cmd->response[0] = 0; cmd->response[1] = (MMC_BL_LEN_SHIFT << 16) |
((MMC_CSIZE >> 16) & 0x3f);
cmd->response[2] = (MMC_CSIZE & 0xffff) << 16;
((priv->csize >> 16) & 0x3f);
cmd->response[2] = (priv->csize & 0xffff) << 16; cmd->response[3] = 0; break; case SD_CMD_SWITCH_FUNC: {
@@ -143,6 +146,8 @@ static int sandbox_mmc_of_to_plat(struct udevice *dev) struct blk_desc *blk; int ret;
plat->fname = dev_read_string(dev, "filename");
ret = mmc_of_parse(dev, cfg); if (ret) return ret;
@@ -156,6 +161,29 @@ static int sandbox_mmc_of_to_plat(struct udevice *dev) static int sandbox_mmc_probe(struct udevice *dev) { struct sandbox_mmc_plat *plat = dev_get_plat(dev);
struct sandbox_mmc_priv *priv = dev_get_priv(dev);
int ret;
if (plat->fname) {
ret = os_map_file(plat->fname, OS_O_RDWR | OS_O_CREAT,
(void **)&priv->buf, &priv->size);
if (ret) {
log_err("%s: Unable to map file '%s'\n", dev->name,
plat->fname);
return ret;
}
priv->csize = priv->size / SIZE_MULTIPLE - 1;
Won't this cut off the end of the file? If we can't avoid this, we should at least warn the user that we are truncating it.
Yes it does and in fact the granularity is 1MB, I think. I can add a warning.
--Sean
} else {
priv->csize = 0;
priv->size = (priv->csize + 1) * SIZE_MULTIPLE; /* 1 MiB */
priv->buf = malloc(priv->size);
if (!priv->buf) {
log_err("%s: Not enough memory (%x bytes)\n",
dev->name, priv->size);
return -ENOMEM;
}
} return mmc_init(&plat->mmc);
}
Regards, Simon

On Wed, Aug 18, 2021 at 09:40:32PM -0600, Simon Glass wrote:
Provide a way for sandbox MMC to present data from a backing file. This allows a filesystem to be created on the host and easily served via an emulated mmc device.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Jaehoon Chung jh80.chung@samsung.com
doc/device-tree-bindings/mmc/sandbox,mmc.txt | 18 ++++++++ drivers/mmc/sandbox_mmc.c | 46 ++++++++++++++++---- 2 files changed, 55 insertions(+), 9 deletions(-) create mode 100644 doc/device-tree-bindings/mmc/sandbox,mmc.txt
As is, this breaks how I've always run pytests on sandbox.

Hi Tom,
On Thu, 16 Sept 2021 at 12:40, Tom Rini trini@konsulko.com wrote:
On Wed, Aug 18, 2021 at 09:40:32PM -0600, Simon Glass wrote:
Provide a way for sandbox MMC to present data from a backing file. This allows a filesystem to be created on the host and easily served via an emulated mmc device.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Jaehoon Chung jh80.chung@samsung.com
doc/device-tree-bindings/mmc/sandbox,mmc.txt | 18 ++++++++ drivers/mmc/sandbox_mmc.c | 46 ++++++++++++++++---- 2 files changed, 55 insertions(+), 9 deletions(-) create mode 100644 doc/device-tree-bindings/mmc/sandbox,mmc.txt
As is, this breaks how I've always run pytests on sandbox.
How does it break it? Do you get an error? The feature is supposed to be optional.
Regards, Simon

On Sat, Sep 18, 2021 at 03:34:54AM -0600, Simon Glass wrote:
Hi Tom,
On Thu, 16 Sept 2021 at 12:40, Tom Rini trini@konsulko.com wrote:
On Wed, Aug 18, 2021 at 09:40:32PM -0600, Simon Glass wrote:
Provide a way for sandbox MMC to present data from a backing file. This allows a filesystem to be created on the host and easily served via an emulated mmc device.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Jaehoon Chung jh80.chung@samsung.com
doc/device-tree-bindings/mmc/sandbox,mmc.txt | 18 ++++++++ drivers/mmc/sandbox_mmc.c | 46 ++++++++++++++++---- 2 files changed, 55 insertions(+), 9 deletions(-) create mode 100644 doc/device-tree-bindings/mmc/sandbox,mmc.txt
As is, this breaks how I've always run pytests on sandbox.
How does it break it? Do you get an error? The feature is supposed to be optional.
Without doing anything to enable it, a few of the mmc unit tests failed. I don't have the logs handy right now (I made that sometimes bad decision to test 2 series at once, and now I'm waiting a bit more on final feedback on the changes the timestamp cleanup needed before I push that + the rest of this series).

Hi Tom,
On Sat, 18 Sept 2021 at 07:16, Tom Rini trini@konsulko.com wrote:
On Sat, Sep 18, 2021 at 03:34:54AM -0600, Simon Glass wrote:
Hi Tom,
On Thu, 16 Sept 2021 at 12:40, Tom Rini trini@konsulko.com wrote:
On Wed, Aug 18, 2021 at 09:40:32PM -0600, Simon Glass wrote:
Provide a way for sandbox MMC to present data from a backing file. This allows a filesystem to be created on the host and easily served via an emulated mmc device.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Jaehoon Chung jh80.chung@samsung.com
doc/device-tree-bindings/mmc/sandbox,mmc.txt | 18 ++++++++ drivers/mmc/sandbox_mmc.c | 46 ++++++++++++++++---- 2 files changed, 55 insertions(+), 9 deletions(-) create mode 100644 doc/device-tree-bindings/mmc/sandbox,mmc.txt
As is, this breaks how I've always run pytests on sandbox.
How does it break it? Do you get an error? The feature is supposed to be optional.
Without doing anything to enable it, a few of the mmc unit tests failed. I don't have the logs handy right now (I made that sometimes bad decision to test 2 series at once, and now I'm waiting a bit more on final feedback on the changes the timestamp cleanup needed before I push that + the rest of this series).
Oh dear, I will take a look and see what is going on there.
Regards, Simon

Hi Tom,
On Sat, 18 Sept 2021 at 10:31, Simon Glass sjg@chromium.org wrote:
Hi Tom,
On Sat, 18 Sept 2021 at 07:16, Tom Rini trini@konsulko.com wrote:
On Sat, Sep 18, 2021 at 03:34:54AM -0600, Simon Glass wrote:
Hi Tom,
On Thu, 16 Sept 2021 at 12:40, Tom Rini trini@konsulko.com wrote:
On Wed, Aug 18, 2021 at 09:40:32PM -0600, Simon Glass wrote:
Provide a way for sandbox MMC to present data from a backing file. This allows a filesystem to be created on the host and easily served via an emulated mmc device.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Jaehoon Chung jh80.chung@samsung.com
doc/device-tree-bindings/mmc/sandbox,mmc.txt | 18 ++++++++ drivers/mmc/sandbox_mmc.c | 46 ++++++++++++++++---- 2 files changed, 55 insertions(+), 9 deletions(-) create mode 100644 doc/device-tree-bindings/mmc/sandbox,mmc.txt
As is, this breaks how I've always run pytests on sandbox.
How does it break it? Do you get an error? The feature is supposed to be optional.
Without doing anything to enable it, a few of the mmc unit tests failed. I don't have the logs handy right now (I made that sometimes bad decision to test 2 series at once, and now I'm waiting a bit more on final feedback on the changes the timestamp cleanup needed before I push that + the rest of this series).
Oh dear, I will take a look and see what is going on there.
The problem seems to me something going wrong with malloc(). I'm not really sure what but I have seen it before. Basically the mallinfo struct becomes corrupted somehow and from there everything goes haywire. It actually happens today in normal operation, but somehow it doesn't cause problems. I looked at it a while back and did not make progress.
Anyway I will see if I can dig into it again.
Regards, Simon

Hi Tom,
On Sun, 19 Sept 2021 at 21:18, Simon Glass sjg@chromium.org wrote:
Hi Tom,
On Sat, 18 Sept 2021 at 10:31, Simon Glass sjg@chromium.org wrote:
Hi Tom,
On Sat, 18 Sept 2021 at 07:16, Tom Rini trini@konsulko.com wrote:
On Sat, Sep 18, 2021 at 03:34:54AM -0600, Simon Glass wrote:
Hi Tom,
On Thu, 16 Sept 2021 at 12:40, Tom Rini trini@konsulko.com wrote:
On Wed, Aug 18, 2021 at 09:40:32PM -0600, Simon Glass wrote:
Provide a way for sandbox MMC to present data from a backing file. This allows a filesystem to be created on the host and easily served via an emulated mmc device.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Jaehoon Chung jh80.chung@samsung.com
doc/device-tree-bindings/mmc/sandbox,mmc.txt | 18 ++++++++ drivers/mmc/sandbox_mmc.c | 46 ++++++++++++++++---- 2 files changed, 55 insertions(+), 9 deletions(-) create mode 100644 doc/device-tree-bindings/mmc/sandbox,mmc.txt
As is, this breaks how I've always run pytests on sandbox.
How does it break it? Do you get an error? The feature is supposed to be optional.
Without doing anything to enable it, a few of the mmc unit tests failed. I don't have the logs handy right now (I made that sometimes bad decision to test 2 series at once, and now I'm waiting a bit more on final feedback on the changes the timestamp cleanup needed before I push that + the rest of this series).
Oh dear, I will take a look and see what is going on there.
The problem seems to me something going wrong with malloc(). I'm not really sure what but I have seen it before. Basically the mallinfo struct becomes corrupted somehow and from there everything goes haywire. It actually happens today in normal operation, but somehow it doesn't cause problems. I looked at it a while back and did not make progress.
Anyway I will see if I can dig into it again.
Actually i did figure this out. Partly is was a calculation issue but mostly it was not unmapping the memory after running, which causes problems when it is 25MB each time.
Regards, Simon

Some tests produce a lot of output that does not need to be individually checked by an assertion. Add a macro to handle this.
Signed-off-by: Simon Glass sjg@chromium.org ---
include/test/ut.h | 24 ++++++++++++++++++++++++ test/ut.c | 26 ++++++++++++++++++++++++++ 2 files changed, 50 insertions(+)
diff --git a/include/test/ut.h b/include/test/ut.h index 656e25fe574..fb2e5fcff2c 100644 --- a/include/test/ut.h +++ b/include/test/ut.h @@ -82,6 +82,21 @@ int ut_check_console_linen(struct unit_test_state *uts, const char *fmt, ...) */ int ut_check_skipline(struct unit_test_state *uts);
+/** + * ut_check_skip_to_line() - skip output until a line is found + * + * This creates a string and then checks it against the following lines of + * console output obtained with console_record_readline() until it is found. + * + * After the function returns, uts->expect_str holds the expected string and + * uts->actual_str holds the actual string read from the console. + * + * @uts: Test state + * @fmt: printf() format string to look for, followed by args + * @return 0 if OK, -ENOENT if not found, other value on error + */ +int ut_check_skip_to_line(struct unit_test_state *uts, const char *fmt, ...); + /** * ut_check_console_end() - Check there is no more console output * @@ -286,6 +301,15 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes); return CMD_RET_FAILURE; \ } \
+/* Assert that a following console output line matches */ +#define ut_assert_skip_to_line(fmt, args...) \ + if (ut_check_skip_to_line(uts, fmt, ##args)) { \ + ut_failf(uts, __FILE__, __LINE__, __func__, \ + "console", "\nExpected '%s',\n got to '%s'", \ + uts->expect_str, uts->actual_str); \ + return CMD_RET_FAILURE; \ + } \ + /* Assert that there is no more console output */ #define ut_assert_console_end() \ if (ut_check_console_end(uts)) { \ diff --git a/test/ut.c b/test/ut.c index 1eec2a57dff..28da417686e 100644 --- a/test/ut.c +++ b/test/ut.c @@ -121,6 +121,32 @@ int ut_check_skipline(struct unit_test_state *uts) return 0; }
+int ut_check_skip_to_line(struct unit_test_state *uts, const char *fmt, ...) +{ + va_list args; + int len; + int ret; + + va_start(args, fmt); + len = vsnprintf(uts->expect_str, sizeof(uts->expect_str), fmt, args); + va_end(args); + if (len >= sizeof(uts->expect_str)) { + ut_fail(uts, __FILE__, __LINE__, __func__, + "unit_test_state->expect_str too small"); + return -EOVERFLOW; + } + while (1) { + if (!console_record_avail()) + return -ENOENT; + ret = readline_check(uts); + if (ret < 0) + return ret; + + if (!strcmp(uts->expect_str, uts->actual_str)) + return 0; + } +} + int ut_check_console_end(struct unit_test_state *uts) { int ret;

On Wed, Aug 18, 2021 at 09:40:33PM -0600, Simon Glass wrote:
Some tests produce a lot of output that does not need to be individually checked by an assertion. Add a macro to handle this.
Signed-off-by: Simon Glass sjg@chromium.org
Applied to u-boot/next, thanks!
participants (7)
-
Jaehoon Chung
-
Marek Behún
-
Miquel Raynal
-
Qu Wenruo
-
Sean Anderson
-
Simon Glass
-
Tom Rini