All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts
@ 2023-01-08  2:49 Simon Glass
  2023-01-08  2:49 ` [PATCH v2 01/71] dm: core: Correct ordering of uclasses IDs Simon Glass
                   ` (71 more replies)
  0 siblings, 72 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:49 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: U-Boot Custodians, Simon Glass, Jaehoon Chung, Jeffy Chen,
	Joe Hershberger, Kever Yang, Marek Vasut, Pavel Herrmann,
	Peng Fan, Philipp Tomsich, Rob Herring, huang lin

So far, standard boot does not replicate all the of the functionality
of the distro_bootcmd scripts. In particular it lacks some bootdevs and
some of the bootmeths are incomplete.

Also there is currently no internal mechanism to enumerate buses in order
to discover bootdevs, e.g. with USB.

This series addresses these shortcomings:

- Adds the concept of a 'bootdev hunter' to enumerate buses, etc. in an
  effort to find bootdevs of a certain priority
- Adds bootdevs for SCSI, IDE, NVMe, virtio, SPI flash
- Handles PXE and DHCP properly
- Supports reading the device tree with EFI and reading scripts from the
  network

It also tidies up label processing, so it is possible to use:

   bootflow scan mmc2

to scan just one MMC device (with BOOTSTD_FULL).

As before this implementation still relies on CONFIG_CMDLINE being
enabled, mostly for the network stack. Further work would be required to
disentangle that.

Quite a few tests are added but there are some gaps:

- SPI flash bootdev
- EFI FDT loading

Note that SATA works via SCSI (CONFIG_SCSI_AHCI) and does not use
driver model. Only pogo_v4 seems to be affected. Probably all thats is
needed is to call bootdev_setup_sibling_blk() in the Marvell SATA driver.

Also, while it would be possible to init MMC in a bootdev hunter, there is
no point since U-Boot always inits MMC on startup, if present.

With this series it should be possible to migrate boards to standard boot
by removing the inclusion of config_distro_bootcmd.h and instead adding
a suitable value for boot_targets to the environment, e.g.:

   boot_targets=mmc1 mmc0 nvme scsi usb pxe dhcp spi

Thus it is possible to boot automatically without scripts and boards can
use a text-based environment instead of the config.h files.

To demonstrate this, rockpro64-rk3399 is migrated to standard boot in this
series. Full migration could probably be automated using a script, similar
in concept to moveconfig:

   - obtain the board environment via 'make u-boot-initial-env'
   - get the value of "boot_targets"
   - drop config_distro_bootcmd.h from the config.h file
   - rebuild again to get the environment without distro scripts
   - write the environment (adding boot_targets) to board.env
   - remove CONFIG_EXTRA_ENV_SETTINGS from the config.h file

This series is based on top of the boot menu series v3 [1].
The tree is available at u-boot-dm/dis-working

[1] https://patchwork.ozlabs.org/project/uboot/list/?series=335364

Changes in v2:
- Rebase to -next

Simon Glass (71):
  dm: core: Correct ordering of uclasses IDs
  dm: core: Support sorting devices with dm tree
  dm: test: Correct assertion in dm_test_part()
  lib: Add a function to split a string into substrings
  bootstd: Remove special-case code for boot_targets
  bootstd: Simplify locating existing bootdevs
  test: Fix the help for the ut command
  test: Drop duplicate restore of DM state
  sandbox: mmc: Start off with a zeroed file
  vbe: Avoid a build failure when bloblist is not enabled
  vbe: sandbox: Drop VBE node in chosen
  dm: part: Update test to use mmc2
  dm: test: Correct ordering of DM setup
  ide: Drop non-DM code for BLK
  dm: mmc: Use bootdev_setup_sibling_blk()
  bootstd: Add a default method to get bootflows
  sandbox: Allow ethernet to be disabled at runtime
  sandbox: Allow ethernet bootdevs to be disabled for tests
  sandbox: Enable the Ethernet bootdev
  lib: Support printing an error string
  event: Correct duplicate log message in event_notify()
  efi: Improve logging in efi_disk
  bootstd: Add the concept of a bootdev hunter
  bootstd: Support running bootdev hunters
  dm: usb: Drop some dead code
  dm: usb: Mark the device name as alloced when binding
  test: Add a generic function to skip delays
  bootstd: Add a USB hunter
  bootstd: Add an MMC hunter
  net: Add a function to run dhcp
  bootstd: Add a hunter for ethernet
  part: Add a function to find the first bootable partition
  bootstd: Only scan bootable partitions
  scsi: Correct allocation of block-device name
  scsi: Remove all children of SCSI devices before rescanning
  bootstd: Add a SCSI bootdev
  bootstd: Add an IDE bootdev
  bootstd: Add an NVMe bootdev
  virtio: Avoid repeating a long expression
  virtio: Fix returning -ENODEV
  virtio: Avoid strange behaviour on removal
  virtio: Add a block device
  bootstd: Add a virtio bootdev
  ata: Don't try to use non-existent ports
  bootstd: Rename bootdev checkers
  bootstd: Allow reading an EFI file from the network
  bootstd: Include the device tree in the bootflow
  bootstd: Support reading the device tree with EFI
  bootstd: Set the distro_bootpart env var with scripts
  bootstd: Update docs on bootmeth_try_file() for sandbox
  bootstd: Move label parsing into its own function
  bootstd: Add a new bootmeth method to set the bootflow
  sandbox: Allow SPI flash bootdevs to be disabled for tests
  bootstd: Add a SPI flash bootdev
  bootstd: Support reading a script from network or SPI flash
  bootstd: Treat DHCP and PXE as bootdev labels
  bootstd: Use hunters when scanning for bootflows
  bootstd: Allow hunting for bootdevs of a given priority
  bootstd: Add a new pre-scan priority for bootdevs
  bootstd: Allow hunting for a bootdev by label
  bootstd: Allow iterating to the next label in a list
  bootstd: Allow iterating to the next bootdev priortiy
  extension: Refactor to allow non-command usage
  bootstd: Add a hunter for the extension feature
  bootstd: Switch bootdev scanning to use labels
  bootstd: Allow scanning a single bootdev label
  bootstd: Drop the old bootflow_scan_first()
  bootstd: Record the bootdevs used during scanning
  bootstd: Add a little more logging of bootflows
  bootstd: Update documentation for new features
  rockchip: Convert rockpro64-rk3399 to use standard boot

 arch/sandbox/cpu/state.c           |  30 ++
 arch/sandbox/dts/sandbox.dtsi      |  13 -
 arch/sandbox/dts/test.dts          |   6 +
 arch/sandbox/include/asm/state.h   |   2 +
 arch/sandbox/include/asm/test.h    |  30 ++
 boot/bootdev-uclass.c              | 551 +++++++++++++++++++---------
 boot/bootflow.c                    | 173 ++++++---
 boot/bootmeth-uclass.c             |  11 +
 boot/bootmeth_distro.c             |   2 +-
 boot/bootmeth_efi.c                | 220 ++++++++++-
 boot/bootmeth_efi_mgr.c            |   2 +-
 boot/bootmeth_pxe.c                |   5 +-
 boot/bootmeth_script.c             |  98 ++++-
 boot/bootstd-uclass.c              |  17 +-
 boot/vbe_simple_fw.c               |   2 +-
 cmd/bootdev.c                      |  42 ++-
 cmd/bootflow.c                     |  97 +++--
 cmd/dm.c                           |  10 +-
 cmd/extension_board.c              |  43 ++-
 cmd/net.c                          |  35 ++
 cmd/vbe.c                          |   7 +-
 common/event.c                     |   2 +-
 configs/sandbox_defconfig          |   2 +-
 configs/sandbox_flattree_defconfig |  10 +-
 disk/part.c                        |  16 +
 doc/develop/bootstd.rst            | 221 +++++++----
 doc/develop/driver-model/nvme.rst  |   2 +-
 doc/usage/cmd/bootdev.rst          |  48 ++-
 doc/usage/cmd/bootflow.rst         |  17 +-
 doc/usage/cmd/dm.rst               |   5 +-
 drivers/ata/ahci.c                 |   6 +
 drivers/block/ide.c                |  86 ++---
 drivers/core/dump.c                |  65 +++-
 drivers/mmc/mmc-uclass.c           |   2 +-
 drivers/mmc/mmc_bootdev.c          |  33 +-
 drivers/mmc/sandbox_mmc.c          |   2 +-
 drivers/mtd/spi/Kconfig            |   8 +
 drivers/mtd/spi/Makefile           |   1 +
 drivers/mtd/spi/sf-uclass.c        |  11 +
 drivers/mtd/spi/sf_bootdev.c       |  82 +++++
 drivers/nvme/nvme-uclass.c         |  54 +++
 drivers/nvme/nvme.c                |   5 +
 drivers/scsi/Makefile              |   7 +
 drivers/scsi/scsi.c                |  32 +-
 drivers/scsi/scsi_bootdev.c        |  62 ++++
 drivers/usb/host/usb-uclass.c      |  45 +--
 drivers/usb/host/usb_bootdev.c     |  38 +-
 drivers/virtio/virtio-uclass.c     |  62 +++-
 drivers/virtio/virtio_sandbox.c    |  16 +-
 include/bootdev.h                  | 206 ++++++++++-
 include/bootflow.h                 | 134 +++++--
 include/bootmeth.h                 |  35 +-
 include/bootstd.h                  |  17 +-
 include/configs/rk3399_common.h    |   5 +-
 include/configs/rockchip-common.h  |   2 +
 include/dm/uclass-id.h             |   4 +-
 include/dm/util.h                  |   8 +-
 include/net.h                      |  31 ++
 include/part.h                     |   8 +
 include/test/test.h                |  72 ++++
 include/vsprintf.h                 |  24 ++
 lib/efi_loader/efi_disk.c          |  30 +-
 lib/strto.c                        |  41 +++
 lib/vsprintf.c                     |  12 +
 net/eth-uclass.c                   |  14 +-
 net/eth_bootdev.c                  |  68 ++--
 net/net.c                          |   4 +
 test/boot/bootdev.c                | 563 +++++++++++++++++++++++++++--
 test/boot/bootflow.c               | 138 +++++--
 test/boot/bootstd_common.c         |  19 +
 test/boot/bootstd_common.h         |  13 +
 test/cmd_ut.c                      |   2 +-
 test/dm/part.c                     |  37 +-
 test/dm/virtio_device.c            |   3 +
 test/py/tests/bootstd/mmc1.img.xz  | Bin 4448 -> 4480 bytes
 test/py/tests/test_dm.py           |  38 ++
 test/py/tests/test_ut.py           |  13 +-
 test/str_ut.c                      |  82 +++++
 test/test-main.c                   |  24 +-
 79 files changed, 3225 insertions(+), 758 deletions(-)
 create mode 100644 drivers/mtd/spi/sf_bootdev.c
 create mode 100644 drivers/scsi/scsi_bootdev.c

-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply	[flat|nested] 87+ messages in thread

* [PATCH v2 01/71] dm: core: Correct ordering of uclasses IDs
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
@ 2023-01-08  2:49 ` Simon Glass
  2023-01-08  2:49 ` [PATCH v2 02/71] dm: core: Support sorting devices with dm tree Simon Glass
                   ` (70 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:49 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: U-Boot Custodians, Simon Glass, Marek Vasut, Pavel Herrmann

A few of these are out of order. Fix them.

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

(no changes since v1)

 include/dm/uclass-id.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index 376f741cc2b..33e43c20db6 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -47,9 +47,9 @@ enum uclass_id {
 	UCLASS_CPU,		/* CPU, typically part of an SoC */
 	UCLASS_CROS_EC,		/* Chrome OS EC */
 	UCLASS_DISPLAY,		/* Display (e.g. DisplayPort, HDMI) */
-	UCLASS_DSI_HOST,	/* Display Serial Interface host */
 	UCLASS_DMA,		/* Direct Memory Access */
 	UCLASS_DSA,		/* Distributed (Ethernet) Switch Architecture */
+	UCLASS_DSI_HOST,	/* Display Serial Interface host */
 	UCLASS_ECDSA,		/* Elliptic curve cryptographic device */
 	UCLASS_EFI_LOADER,	/* Devices created by UEFI applications */
 	UCLASS_EFI_MEDIA,	/* Devices provided by UEFI firmware */
@@ -101,6 +101,7 @@ enum uclass_id {
 	UCLASS_PINCTRL,		/* Pinctrl (pin muxing/configuration) device */
 	UCLASS_PMIC,		/* PMIC I/O device */
 	UCLASS_POWER_DOMAIN,	/* (SoC) Power domains */
+	UCLASS_PVBLOCK,		/* Xen virtual block device */
 	UCLASS_PWM,		/* Pulse-width modulator */
 	UCLASS_PWRSEQ,		/* Power sequence device */
 	UCLASS_QFW,		/* QEMU firmware config device */
@@ -142,7 +143,6 @@ enum uclass_id {
 	UCLASS_W1,		/* Dallas 1-Wire bus */
 	UCLASS_W1_EEPROM,	/* one-wire EEPROMs */
 	UCLASS_WDT,		/* Watchdog Timer driver */
-	UCLASS_PVBLOCK,		/* Xen virtual block device */
 
 	UCLASS_COUNT,
 	UCLASS_INVALID = -1,
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 02/71] dm: core: Support sorting devices with dm tree
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
  2023-01-08  2:49 ` [PATCH v2 01/71] dm: core: Correct ordering of uclasses IDs Simon Glass
@ 2023-01-08  2:49 ` Simon Glass
  2023-01-08  2:49 ` [PATCH v2 03/71] dm: test: Correct assertion in dm_test_part() Simon Glass
                   ` (69 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:49 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: U-Boot Custodians, Simon Glass, Marek Vasut, Pavel Herrmann

Add a -s flag to sort the top-level devices in order of uclass ID.

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

(no changes since v1)

 cmd/dm.c                 | 10 +++++--
 doc/usage/cmd/dm.rst     |  5 +++-
 drivers/core/dump.c      | 65 ++++++++++++++++++++++++++++++++++++----
 include/dm/util.h        |  8 +++--
 test/py/tests/test_dm.py | 38 +++++++++++++++++++++++
 5 files changed, 114 insertions(+), 12 deletions(-)

diff --git a/cmd/dm.c b/cmd/dm.c
index 218be85795d..979cd36061e 100644
--- a/cmd/dm.c
+++ b/cmd/dm.c
@@ -59,7 +59,11 @@ static int do_dm_dump_static_driver_info(struct cmd_tbl *cmdtp, int flag,
 static int do_dm_dump_tree(struct cmd_tbl *cmdtp, int flag, int argc,
 			   char *const argv[])
 {
-	dm_dump_tree();
+	bool sort;
+
+	sort = argc > 1 && !strcmp(argv[1], "-s");
+
+	dm_dump_tree(sort);
 
 	return 0;
 }
@@ -87,7 +91,7 @@ static char dm_help_text[] =
 	"dm drivers       Dump list of drivers with uclass and instances\n"
 	DM_MEM_HELP
 	"dm static        Dump list of drivers with static platform data\n"
-	"dm tree          Dump tree of driver model devices ('*' = activated)\n"
+	"dm tree [-s]     Dump tree of driver model devices (-s=sort)\n"
 	"dm uclass        Dump list of instances for each uclass"
 	;
 #endif
@@ -98,5 +102,5 @@ U_BOOT_CMD_WITH_SUBCMDS(dm, "Driver model low level access", dm_help_text,
 	U_BOOT_SUBCMD_MKENT(drivers, 1, 1, do_dm_dump_drivers),
 	DM_MEM
 	U_BOOT_SUBCMD_MKENT(static, 1, 1, do_dm_dump_static_driver_info),
-	U_BOOT_SUBCMD_MKENT(tree, 1, 1, do_dm_dump_tree),
+	U_BOOT_SUBCMD_MKENT(tree, 2, 1, do_dm_dump_tree),
 	U_BOOT_SUBCMD_MKENT(uclass, 1, 1, do_dm_dump_uclass));
diff --git a/doc/usage/cmd/dm.rst b/doc/usage/cmd/dm.rst
index 7bc1962a754..236cd02bd62 100644
--- a/doc/usage/cmd/dm.rst
+++ b/doc/usage/cmd/dm.rst
@@ -12,7 +12,7 @@ Synopis
     dm devres
     dm drivers
     dm static
-    dm tree
+    dm tree [-s]
     dm uclass
 
 Description
@@ -123,6 +123,9 @@ Name
     Shows the device name as well as the tree structure, since child devices are
     shown attached to their parent.
 
+If -s is given, the top-level devices (those which are children of the root
+device) are shown sorted in order of uclass ID, so it is easier to find a
+particular device type.
 
 dm uclass
 ~~~~~~~~~
diff --git a/drivers/core/dump.c b/drivers/core/dump.c
index 1c1f7e4d308..0c7d2ec4d0c 100644
--- a/drivers/core/dump.c
+++ b/drivers/core/dump.c
@@ -5,12 +5,34 @@
 
 #include <common.h>
 #include <dm.h>
+#include <malloc.h>
 #include <mapmem.h>
+#include <sort.h>
 #include <dm/root.h>
 #include <dm/util.h>
 #include <dm/uclass-internal.h>
 
-static void show_devices(struct udevice *dev, int depth, int last_flag)
+/**
+ * struct sort_info - information used for sorting
+ *
+ * @dev: List of devices
+ * @alloced: Maximum number of devices in @dev
+ */
+struct sort_info {
+	struct udevice **dev;
+	int size;
+};
+
+static int h_cmp_uclass_id(const void *d1, const void *d2)
+{
+	const struct udevice *const *dev1 = d1;
+	const struct udevice *const *dev2 = d2;
+
+	return device_get_uclass_id(*dev1) - device_get_uclass_id(*dev2);
+}
+
+static void show_devices(struct udevice *dev, int depth, int last_flag,
+			 struct udevice **devs)
 {
 	int i, is_last;
 	struct udevice *child;
@@ -39,21 +61,52 @@ static void show_devices(struct udevice *dev, int depth, int last_flag)
 
 	printf("%s\n", dev->name);
 
-	device_foreach_child(child, dev) {
-		is_last = list_is_last(&child->sibling_node, &dev->child_head);
-		show_devices(child, depth + 1, (last_flag << 1) | is_last);
+	if (devs) {
+		int count;
+		int i;
+
+		count = 0;
+		device_foreach_child(child, dev)
+			devs[count++] = child;
+		qsort(devs, count, sizeof(struct udevice *), h_cmp_uclass_id);
+
+		for (i = 0; i < count; i++) {
+			show_devices(devs[i], depth + 1,
+				     (last_flag << 1) | (i == count - 1),
+				     devs + count);
+		}
+	} else {
+		device_foreach_child(child, dev) {
+			is_last = list_is_last(&child->sibling_node,
+					       &dev->child_head);
+			show_devices(child, depth + 1,
+				     (last_flag << 1) | is_last, NULL);
+		}
 	}
 }
 
-void dm_dump_tree(void)
+void dm_dump_tree(bool sort)
 {
 	struct udevice *root;
 
 	root = dm_root();
 	if (root) {
+		int dev_count, uclasses;
+		struct udevice **devs = NULL;
+
+		dm_get_stats(&dev_count, &uclasses);
+
 		printf(" Class     Index  Probed  Driver                Name\n");
 		printf("-----------------------------------------------------------\n");
-		show_devices(root, -1, 0);
+		if (sort) {
+			devs = calloc(dev_count, sizeof(struct udevice *));
+			if (!devs) {
+				printf("(out of memory)\n");
+				return;
+			}
+		}
+		show_devices(root, -1, 0, devs);
+		free(devs);
 	}
 }
 
diff --git a/include/dm/util.h b/include/dm/util.h
index e10c6060ce0..4bb49e9e8c0 100644
--- a/include/dm/util.h
+++ b/include/dm/util.h
@@ -26,8 +26,12 @@ struct list_head;
  */
 int list_count_items(struct list_head *head);
 
-/* Dump out a tree of all devices */
-void dm_dump_tree(void);
+/**
+ * Dump out a tree of all devices
+ *
+ * @sort: Sort by uclass name
+ */
+void dm_dump_tree(bool sort);
 
 /* Dump out a list of uclasses and their devices */
 void dm_dump_uclass(void);
diff --git a/test/py/tests/test_dm.py b/test/py/tests/test_dm.py
index ea93061fdfa..68d4ea12235 100644
--- a/test/py/tests/test_dm.py
+++ b/test/py/tests/test_dm.py
@@ -16,6 +16,44 @@ def test_dm_compat(u_boot_console):
     for driver in drivers:
         assert driver in response
 
+    # check sorting - output looks something like this:
+    #  testacpi      0  [   ]   testacpi_drv          |-- acpi-test
+    #  testacpi      1  [   ]   testacpi_drv          |   `-- child
+    #  pci_emul_p    1  [   ]   pci_emul_parent_drv   |-- pci-emul2
+    #  pci_emul      5  [   ]   sandbox_swap_case_em  |   `-- emul2@1f,0
+
+    # The number of '|   ' and '--' matches indicate the indent level. We start
+    # checking sorting only after UCLASS_AXI_EMUL after which the names should
+    # be sorted.
+
+    response = u_boot_console.run_command('dm tree -s')
+    lines = response.split('\n')[2:]
+    stack = []   # holds where we were up to at the previous indent level
+    prev = ''    # uclass name of previous line
+    start = False
+    for line in lines:
+        indent = line.count('|   ') + ('--' in line)
+        cur = line.split()[0]
+        if not start:
+            if cur != 'axi_emul':
+                continue
+            start = True
+
+        # Handle going up or down an indent level
+        if indent > len(stack):
+            stack.append(prev)
+            prev = ''
+        elif indent < len(stack):
+            prev = stack.pop()
+
+        # Check that the current uclass name is not alphabetically before the
+        # previous one
+        if 'emul' not in cur and cur < prev:
+            print('indent', cur >= prev, indent, prev, cur, stack)
+            assert cur >= prev
+            prev = cur
+
+
 @pytest.mark.buildconfigspec('cmd_dm')
 def test_dm_drivers(u_boot_console):
     """Test that each driver in `dm compat` is also listed in `dm drivers`."""
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 03/71] dm: test: Correct assertion in dm_test_part()
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
  2023-01-08  2:49 ` [PATCH v2 01/71] dm: core: Correct ordering of uclasses IDs Simon Glass
  2023-01-08  2:49 ` [PATCH v2 02/71] dm: core: Support sorting devices with dm tree Simon Glass
@ 2023-01-08  2:49 ` Simon Glass
  2023-01-08  2:49 ` [PATCH v2 04/71] lib: Add a function to split a string into substrings Simon Glass
                   ` (68 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:49 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: U-Boot Custodians, Simon Glass, Marek Vasut, Pavel Herrmann

This obscures the line number. Update the test to avoid make sure that
the line which failed is displayed, so it is possible to diagnose the
failure.

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

(no changes since v1)

 test/dm/part.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/test/dm/part.c b/test/dm/part.c
index 78dd8472c2e..5e4efa587c3 100644
--- a/test/dm/part.c
+++ b/test/dm/part.c
@@ -11,8 +11,8 @@
 #include <dm/test.h>
 #include <test/ut.h>
 
-static inline int do_test(struct unit_test_state *uts, int expected,
-			  const char *part_str, bool whole)
+static int do_test(struct unit_test_state *uts, int expected,
+		   const char *part_str, bool whole)
 {
 	struct blk_desc *mmc_dev_desc;
 	struct disk_partition part_info;
@@ -54,11 +54,8 @@ static int dm_test_part(struct unit_test_state *uts)
 
 	oldbootdevice = env_get("bootdevice");
 
-#define test(expected, part_str, whole) do { \
-	ret = do_test(uts, expected, part_str, whole); \
-	if (ret) \
-		goto out; \
-} while (0)
+#define test(expected, part_str, whole) \
+	ut_assertok(do_test(uts, expected, part_str, whole))
 
 	env_set("bootdevice", NULL);
 	test(-ENODEV, NULL, true);
@@ -92,7 +89,6 @@ static int dm_test_part(struct unit_test_state *uts)
 	test(2, "1#test2", false);
 	ret = 0;
 
-out:
 	env_set("bootdevice", oldbootdevice);
 	return ret;
 }
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 04/71] lib: Add a function to split a string into substrings
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (2 preceding siblings ...)
  2023-01-08  2:49 ` [PATCH v2 03/71] dm: test: Correct assertion in dm_test_part() Simon Glass
@ 2023-01-08  2:49 ` Simon Glass
  2023-01-08  2:49 ` [PATCH v2 05/71] bootstd: Remove special-case code for boot_targets Simon Glass
                   ` (67 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:49 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

Some environment variables provide a space-separated list of strings. It
is easier to process these when they are broken out into an array of
strings.

Add a utility function to handle this.

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

(no changes since v1)

 include/vsprintf.h | 24 ++++++++++++++
 lib/strto.c        | 41 +++++++++++++++++++++++
 test/str_ut.c      | 82 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 147 insertions(+)

diff --git a/include/vsprintf.h b/include/vsprintf.h
index e006af200fd..ed8a060ee17 100644
--- a/include/vsprintf.h
+++ b/include/vsprintf.h
@@ -328,6 +328,30 @@ char *strmhz(char *buf, unsigned long hz);
  */
 void str_to_upper(const char *in, char *out, size_t len);
 
+/**
+ * str_to_list() - Convert a string to a list of string pointers
+ *
+ * Splits a string containing space-delimited substrings into a number of
+ * separate strings, e.g. "this is" becomes {"this", "is", NULL}. If @instr is
+ * empty then this returns just {NULL}. The string should have only a single
+ * space between items, with no leading or trailing spaces.
+ *
+ * @instr: String to process (this is alloced by this function)
+ * Returns: List of string pointers, terminated by NULL. Each entry points to
+ * a string. If @instr is empty, the list consists just of a single NULL entry.
+ * Note that the first entry points to the alloced string.
+ * Returns NULL if out of memory
+ */
+const char **str_to_list(const char *instr);
+
+/**
+ * str_free_list() - Free a string list
+ *
+ * @ptr: String list to free, as created by str_to_list(). This can also be
+ * NULL, in which case the function does nothing
+ */
+void str_free_list(const char **ptr);
+
 /**
  * vsscanf - Unformat a buffer into a list of arguments
  * @inp: input buffer
diff --git a/lib/strto.c b/lib/strto.c
index 6462d4fddf1..154921165cb 100644
--- a/lib/strto.c
+++ b/lib/strto.c
@@ -11,6 +11,7 @@
 
 #include <common.h>
 #include <errno.h>
+#include <malloc.h>
 #include <linux/ctype.h>
 
 /* from lib/kstrtox.c */
@@ -222,3 +223,43 @@ void str_to_upper(const char *in, char *out, size_t len)
 	if (len)
 		*out = '\0';
 }
+
+const char **str_to_list(const char *instr)
+{
+	const char **ptr;
+	char *str, *p;
+	int count, i;
+
+	/* don't allocate if the string is empty */
+	str = *instr ? strdup(instr) : (char *)instr;
+	if (!str)
+		return NULL;
+
+	/* count the number of space-separated strings */
+	for (count = *str != '\0', p = str; *p; p++) {
+		if (*p == ' ') {
+			count++;
+			*p = '\0';
+		}
+	}
+
+	/* allocate the pointer array, allowing for a NULL terminator */
+	ptr = calloc(count + 1, sizeof(char *));
+	if (!ptr) {
+		if (*str)
+			free(str);
+		return NULL;
+	}
+
+	for (i = 0, p = str; i < count; p += strlen(p) + 1, i++)
+		ptr[i] = p;
+
+	return ptr;
+}
+
+void str_free_list(const char **ptr)
+{
+	if (ptr)
+		free((char *)ptr[0]);
+	free(ptr);
+}
diff --git a/test/str_ut.c b/test/str_ut.c
index 5a844347c2b..fa9328ede50 100644
--- a/test/str_ut.c
+++ b/test/str_ut.c
@@ -274,6 +274,88 @@ static int str_trailing(struct unit_test_state *uts)
 }
 STR_TEST(str_trailing, 0);
 
+static int test_str_to_list(struct unit_test_state *uts)
+{
+	const char **ptr;
+	ulong start;
+
+	/* check out of memory */
+	start = ut_check_delta(0);
+	malloc_enable_testing(0);
+	ut_assertnull(str_to_list(""));
+	ut_assertok(ut_check_delta(start));
+
+	ut_assertnull(str_to_list("this is a test"));
+	ut_assertok(ut_check_delta(start));
+
+	malloc_enable_testing(1);
+	ut_assertnull(str_to_list("this is a test"));
+	ut_assertok(ut_check_delta(start));
+
+	/* for an empty string, only one nalloc is needed */
+	malloc_enable_testing(1);
+	ptr = str_to_list("");
+	ut_assertnonnull(ptr);
+	ut_assertnull(ptr[0]);
+	str_free_list(ptr);
+	ut_assertok(ut_check_delta(start));
+
+	malloc_disable_testing();
+
+	/* test the same again, without any nalloc restrictions */
+	ptr = str_to_list("");
+	ut_assertnonnull(ptr);
+	ut_assertnull(ptr[0]);
+	str_free_list(ptr);
+	ut_assertok(ut_check_delta(start));
+
+	/* test a single string */
+	start = ut_check_delta(0);
+	ptr = str_to_list("hi");
+	ut_assertnonnull(ptr);
+	ut_assertnonnull(ptr[0]);
+	ut_asserteq_str("hi", ptr[0]);
+	ut_assertnull(ptr[1]);
+	str_free_list(ptr);
+	ut_assertok(ut_check_delta(start));
+
+	/* test two strings */
+	ptr = str_to_list("hi there");
+	ut_assertnonnull(ptr);
+	ut_assertnonnull(ptr[0]);
+	ut_asserteq_str("hi", ptr[0]);
+	ut_assertnonnull(ptr[1]);
+	ut_asserteq_str("there", ptr[1]);
+	ut_assertnull(ptr[2]);
+	str_free_list(ptr);
+	ut_assertok(ut_check_delta(start));
+
+	/* test leading, trailing and multiple spaces */
+	ptr = str_to_list(" more  space  ");
+	ut_assertnonnull(ptr);
+	ut_assertnonnull(ptr[0]);
+	ut_asserteq_str("", ptr[0]);
+	ut_assertnonnull(ptr[1]);
+	ut_asserteq_str("more", ptr[1]);
+	ut_assertnonnull(ptr[2]);
+	ut_asserteq_str("", ptr[2]);
+	ut_assertnonnull(ptr[3]);
+	ut_asserteq_str("space", ptr[3]);
+	ut_assertnonnull(ptr[4]);
+	ut_asserteq_str("", ptr[4]);
+	ut_assertnonnull(ptr[5]);
+	ut_asserteq_str("", ptr[5]);
+	ut_assertnull(ptr[6]);
+	str_free_list(ptr);
+	ut_assertok(ut_check_delta(start));
+
+	/* test freeing a NULL pointer */
+	str_free_list(NULL);
+
+	return 0;
+}
+STR_TEST(test_str_to_list, 0);
+
 int do_ut_str(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
 {
 	struct unit_test *tests = UNIT_TEST_SUITE_START(str_test);
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 05/71] bootstd: Remove special-case code for boot_targets
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (3 preceding siblings ...)
  2023-01-08  2:49 ` [PATCH v2 04/71] lib: Add a function to split a string into substrings Simon Glass
@ 2023-01-08  2:49 ` Simon Glass
  2023-01-08  2:49 ` [PATCH v2 06/71] bootstd: Simplify locating existing bootdevs Simon Glass
                   ` (66 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:49 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

Rather than implement this as its own case in build_order(), process the
boot_targets environment variable in the bootstd_get_bootdev_order()
function. This allows build_order() to be simplified.

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

(no changes since v1)

 boot/bootdev-uclass.c | 32 +++++---------------------------
 boot/bootstd-uclass.c | 17 ++++++++++++++++-
 include/bootstd.h     | 14 +++++++++++---
 3 files changed, 32 insertions(+), 31 deletions(-)

diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c
index affe0d3e04e..696efb4b19e 100644
--- a/boot/bootdev-uclass.c
+++ b/boot/bootdev-uclass.c
@@ -12,7 +12,6 @@
 #include <bootflow.h>
 #include <bootmeth.h>
 #include <bootstd.h>
-#include <env.h>
 #include <fs.h>
 #include <log.h>
 #include <malloc.h>
@@ -504,34 +503,13 @@ static int build_order(struct udevice *bootstd, struct udevice **order,
 	const char *overflow_target = NULL;
 	const char *const *labels;
 	struct udevice *dev;
-	const char *targets;
 	int i, ret, count;
+	bool ok;
 
-	targets = env_get("boot_targets");
-	labels = IS_ENABLED(CONFIG_BOOTSTD_FULL) ?
-		bootstd_get_bootdev_order(bootstd) : NULL;
-	if (targets) {
-		char str[BOOT_TARGETS_MAX_LEN];
-		char *target;
-
-		if (strlen(targets) >= BOOT_TARGETS_MAX_LEN)
-			return log_msg_ret("len", -E2BIG);
-
-		/* make a copy of the string, since strok() will change it */
-		strcpy(str, targets);
-		for (i = 0, target = strtok(str, " "); target;
-		     target = strtok(NULL, " ")) {
-			ret = bootdev_find_by_label(target, &dev);
-			if (!ret) {
-				if (i == max_count) {
-					overflow_target = target;
-					break;
-				}
-				order[i++] = dev;
-			}
-		}
-		count = i;
-	} else if (labels) {
+	labels = bootstd_get_bootdev_order(bootstd, &ok);
+	if (!ok)
+		return log_msg_ret("ord", -ENOMEM);
+	if (labels) {
 		int upto;
 
 		upto = 0;
diff --git a/boot/bootstd-uclass.c b/boot/bootstd-uclass.c
index 7887acdc11b..81555d341e3 100644
--- a/boot/bootstd-uclass.c
+++ b/boot/bootstd-uclass.c
@@ -10,6 +10,7 @@
 #include <bootflow.h>
 #include <bootstd.h>
 #include <dm.h>
+#include <env.h>
 #include <log.h>
 #include <malloc.h>
 #include <dm/device-internal.h>
@@ -72,9 +73,23 @@ static int bootstd_remove(struct udevice *dev)
 	return 0;
 }
 
-const char *const *const bootstd_get_bootdev_order(struct udevice *dev)
+const char *const *const bootstd_get_bootdev_order(struct udevice *dev,
+						   bool *okp)
 {
 	struct bootstd_priv *std = dev_get_priv(dev);
+	const char *targets = env_get("boot_targets");
+
+	*okp = true;
+	log_debug("- targets %s %p\n", targets, std->bootdev_order);
+	if (targets && *targets) {
+		str_free_list(std->env_order);
+		std->env_order = str_to_list(targets);
+		if (!std->env_order) {
+			*okp = false;
+			return NULL;
+		}
+		return std->env_order;
+	}
 
 	return std->bootdev_order;
 }
diff --git a/include/bootstd.h b/include/bootstd.h
index 4fa0d531001..bd305094fdc 100644
--- a/include/bootstd.h
+++ b/include/bootstd.h
@@ -22,7 +22,10 @@ struct udevice;
  * @prefixes: NULL-terminated list of prefixes to use for bootflow filenames,
  *	e.g. "/", "/boot/"; NULL if none
  * @bootdev_order: Order to use for bootdevs (or NULL if none), with each item
- *	being a bootdev label, e.g. "mmc2", "mmc1";
+ *	being a bootdev label, e.g. "mmc2", "mmc1" (NULL terminated)
+ * @env_order: Order as specified by the boot_targets env var (or NULL if none),
+ *	with each item being a bootdev label, e.g. "mmc2", "mmc1" (NULL
+ *	terminated)
  * @cur_bootdev: Currently selected bootdev (for commands)
  * @cur_bootflow: Currently selected bootflow (for commands)
  * @glob_head: Head for the global list of all bootflows across all bootdevs
@@ -34,6 +37,7 @@ struct udevice;
 struct bootstd_priv {
 	const char **prefixes;
 	const char **bootdev_order;
+	const char **env_order;
 	struct udevice *cur_bootdev;
 	struct bootflow *cur_bootflow;
 	struct list_head glob_head;
@@ -51,9 +55,13 @@ struct bootstd_priv {
  * The list is alloced by the bootstd driver so should not be freed. That is the
  * reason for all the const stuff in the function signature
  *
- * Return: list of string points, terminated by NULL; or NULL if no boot order
+ * @dev: bootstd device
+ * @okp: returns true if OK, false if out of memory
+ * Return: list of string pointers, terminated by NULL; or NULL if no boot
+ * order. Note that this returns NULL in the case of an empty list
  */
-const char *const *const bootstd_get_bootdev_order(struct udevice *dev);
+const char *const *const bootstd_get_bootdev_order(struct udevice *dev,
+						   bool *okp);
 
 /**
  * bootstd_get_prefixes() - Get the filename-prefixes list
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 06/71] bootstd: Simplify locating existing bootdevs
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (4 preceding siblings ...)
  2023-01-08  2:49 ` [PATCH v2 05/71] bootstd: Remove special-case code for boot_targets Simon Glass
@ 2023-01-08  2:49 ` Simon Glass
  2023-01-08  2:49 ` [PATCH v2 07/71] test: Fix the help for the ut command Simon Glass
                   ` (65 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:49 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

There is no point in trying to match the alias order for bootdevs, since
build_order() either sorts them by priority, uses the boot_targets
environment variable or the bootdev-order property.

Just use the iterator instead, to simplify the code.

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

(no changes since v1)

 boot/bootdev-uclass.c | 16 +++++-----------
 1 file changed, 5 insertions(+), 11 deletions(-)

diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c
index 696efb4b19e..cffa01824c0 100644
--- a/boot/bootdev-uclass.c
+++ b/boot/bootdev-uclass.c
@@ -544,8 +544,8 @@ static int build_order(struct udevice *bootstd, struct udevice **order,
 int bootdev_setup_iter_order(struct bootflow_iter *iter, struct udevice **devp)
 {
 	struct udevice *bootstd, *dev = *devp, **order;
-	int upto, i;
-	int count;
+	struct uclass *uc;
+	int count, upto;
 	int ret;
 
 	ret = uclass_first_device_err(UCLASS_BOOTSTD, &bootstd);
@@ -568,15 +568,9 @@ int bootdev_setup_iter_order(struct bootflow_iter *iter, struct udevice **devp)
 	if (!order)
 		return log_msg_ret("order", -ENOMEM);
 
-	/*
-	 * Get a list of bootdevs, in seq order (i.e. using aliases). There may
-	 * be gaps so try to count up high enough to find them all.
-	 */
-	for (i = 0, upto = 0; upto < count && i < 20 + count * 2; i++) {
-		ret = uclass_find_device_by_seq(UCLASS_BOOTDEV, i, &dev);
-		if (!ret)
-			order[upto++] = dev;
-	}
+	/* Get the list of bootdevs */
+	uclass_id_foreach_dev(UCLASS_BOOTDEV, dev, uc)
+		order[upto++] = dev;
 	log_debug("Found %d bootdevs\n", count);
 	if (upto != count)
 		log_debug("Expected %d bootdevs, found %d using aliases\n",
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 07/71] test: Fix the help for the ut command
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (5 preceding siblings ...)
  2023-01-08  2:49 ` [PATCH v2 06/71] bootstd: Simplify locating existing bootdevs Simon Glass
@ 2023-01-08  2:49 ` Simon Glass
  2023-01-08  2:49 ` [PATCH v2 08/71] test: Drop duplicate restore of DM state Simon Glass
                   ` (64 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:49 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

The font help has an incorrect newline. Fix it.

Signed-off-by: Simon Glass <sjg@chromium.org>
Fixes: cdd964e3801 ("test: Tidy up help for ut command")
---

(no changes since v1)

 test/cmd_ut.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/cmd_ut.c b/test/cmd_ut.c
index 2736582f11c..82231c9b369 100644
--- a/test/cmd_ut.c
+++ b/test/cmd_ut.c
@@ -188,7 +188,7 @@ static char ut_help_text[] =
 	"\nfdt - fdt command"
 #endif
 #ifdef CONFIG_CONSOLE_TRUETYPE
-	"\nut font - font command\n"
+	"\nut font - font command"
 #endif
 #ifdef CONFIG_CMD_LOADM
 	"\nloadm - loadm command parameters and loading memory blob"
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 08/71] test: Drop duplicate restore of DM state
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (6 preceding siblings ...)
  2023-01-08  2:49 ` [PATCH v2 07/71] test: Fix the help for the ut command Simon Glass
@ 2023-01-08  2:49 ` Simon Glass
  2023-01-08  2:49 ` [PATCH v2 09/71] sandbox: mmc: Start off with a zeroed file Simon Glass
                   ` (63 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:49 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

This code is present twice. Fix it so that it is only executed once.

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

(no changes since v1)

 test/test-main.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/test/test-main.c b/test/test-main.c
index 5931e94a915..9ab090b7b33 100644
--- a/test/test-main.c
+++ b/test/test-main.c
@@ -635,9 +635,5 @@ int ut_run_list(const char *category, const char *prefix,
 	else
 		printf("Failures: %d\n", uts.fail_count);
 
-	/* Best efforts only...ignore errors */
-	if (has_dm_tests)
-		dm_test_restore(uts.of_root);
-
 	return ret;
 }
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 09/71] sandbox: mmc: Start off with a zeroed file
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (7 preceding siblings ...)
  2023-01-08  2:49 ` [PATCH v2 08/71] test: Drop duplicate restore of DM state Simon Glass
@ 2023-01-08  2:49 ` Simon Glass
  2023-01-08  2:49 ` [PATCH v2 10/71] vbe: Avoid a build failure when bloblist is not enabled Simon Glass
                   ` (62 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:49 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: U-Boot Custodians, Simon Glass, Jaehoon Chung, Peng Fan

When running multiple tests the mmc emulator calls malloc() to obtain the
memory for its disk image. Since the memory is not cleared, it is possible
that it happens to contain a partition table.

The dm_test_part() test (for one) relies on mmc0 being empty on startup.
Zero the memory to ensure that it is.

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

(no changes since v1)

 drivers/mmc/sandbox_mmc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mmc/sandbox_mmc.c b/drivers/mmc/sandbox_mmc.c
index ba79a5565c3..0ba7940a4db 100644
--- a/drivers/mmc/sandbox_mmc.c
+++ b/drivers/mmc/sandbox_mmc.c
@@ -183,7 +183,7 @@ static int sandbox_mmc_probe(struct udevice *dev)
 		priv->csize = 0;
 		priv->size = (priv->csize + 1) * SIZE_MULTIPLE; /* 1 MiB */
 
-		priv->buf = malloc(priv->size);
+		priv->buf = calloc(1, priv->size);
 		if (!priv->buf) {
 			log_err("%s: Not enough memory (%x bytes)\n",
 				dev->name, priv->size);
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 10/71] vbe: Avoid a build failure when bloblist is not enabled
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (8 preceding siblings ...)
  2023-01-08  2:49 ` [PATCH v2 09/71] sandbox: mmc: Start off with a zeroed file Simon Glass
@ 2023-01-08  2:49 ` Simon Glass
  2023-01-08  2:49 ` [PATCH v2 11/71] vbe: sandbox: Drop VBE node in chosen Simon Glass
                   ` (61 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:49 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

This needs to be able to work (at least partially) without the bloblist
active. Add a condition for this.

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

(no changes since v1)

 cmd/vbe.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/cmd/vbe.c b/cmd/vbe.c
index befaf07c64d..600690394eb 100644
--- a/cmd/vbe.c
+++ b/cmd/vbe.c
@@ -79,10 +79,13 @@ static int do_vbe_info(struct cmd_tbl *cmdtp, int flag, int argc,
 static int do_vbe_state(struct cmd_tbl *cmdtp, int flag, int argc,
 			char *const argv[])
 {
-	struct vbe_handoff *handoff;
+	struct vbe_handoff *handoff = NULL;
 	int i;
 
-	handoff = bloblist_find(BLOBLISTT_VBE, sizeof(struct vbe_handoff));
+	if (IS_ENABLED(CONFIG_BLOBLIST)) {
+		handoff = bloblist_find(BLOBLISTT_VBE,
+					sizeof(struct vbe_handoff));
+	}
 	if (!handoff) {
 		printf("No VBE state\n");
 		return CMD_RET_FAILURE;
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 11/71] vbe: sandbox: Drop VBE node in chosen
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (9 preceding siblings ...)
  2023-01-08  2:49 ` [PATCH v2 10/71] vbe: Avoid a build failure when bloblist is not enabled Simon Glass
@ 2023-01-08  2:49 ` Simon Glass
  2023-01-08  2:49 ` [PATCH v2 12/71] dm: part: Update test to use mmc2 Simon Glass
                   ` (60 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:49 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

This is not needed anymore since VBE creates the node when it sets up the
OS requests. Drop it.

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

(no changes since v1)

 arch/sandbox/dts/sandbox.dtsi | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi
index afe598a4f56..18bf1cb5b69 100644
--- a/arch/sandbox/dts/sandbox.dtsi
+++ b/arch/sandbox/dts/sandbox.dtsi
@@ -12,19 +12,6 @@
 
 	chosen {
 		stdout-path = "/serial";
-
-		fwupd {
-			compatible = "simple-bus";
-			firmware {
-				compatible = "fwupd,vbe-simple";
-				cur-version = "1.2.3";
-				bootloader-version = "2022.01";
-				storage = "mmc1";
-				area-start = <0x0>;
-				area-size = <0x1000000>;
-				skip-offset = <0x8000>;
-			};
-		};
 	};
 
 	alarm_wdt: alarm-wdt {
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 12/71] dm: part: Update test to use mmc2
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (10 preceding siblings ...)
  2023-01-08  2:49 ` [PATCH v2 11/71] vbe: sandbox: Drop VBE node in chosen Simon Glass
@ 2023-01-08  2:49 ` Simon Glass
  2023-01-08  2:49 ` [PATCH v2 13/71] dm: test: Correct ordering of DM setup Simon Glass
                   ` (59 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:49 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: U-Boot Custodians, Simon Glass, Marek Vasut, Pavel Herrmann

At present this test sets up a partition table on mmc1. But this is used
by the bootstd tests, so it is not possible to run those after this test
has run, without restarting the Python test harness.

This is inconvenient when running tests repeatedly with 'ut dm'. Move the
test to use mmc2, which is not used by anything.

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

(no changes since v1)

 test/dm/part.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/test/dm/part.c b/test/dm/part.c
index 5e4efa587c3..b60687114f1 100644
--- a/test/dm/part.c
+++ b/test/dm/part.c
@@ -43,7 +43,7 @@ static int dm_test_part(struct unit_test_state *uts)
 		},
 	};
 
-	ut_asserteq(1, blk_get_device_by_str("mmc", "1", &mmc_dev_desc));
+	ut_asserteq(2, blk_get_device_by_str("mmc", "2", &mmc_dev_desc));
 	if (CONFIG_IS_ENABLED(RANDOM_UUID)) {
 		gen_rand_uuid_str(parts[0].uuid, UUID_STR_FORMAT_STD);
 		gen_rand_uuid_str(parts[1].uuid, UUID_STR_FORMAT_STD);
@@ -63,7 +63,7 @@ static int dm_test_part(struct unit_test_state *uts)
 	env_set("bootdevice", "0");
 	test(0, NULL, true);
 	test(0, "", true);
-	env_set("bootdevice", "1");
+	env_set("bootdevice", "2");
 	test(1, NULL, false);
 	test(1, "", false);
 	test(1, "-", false);
@@ -74,8 +74,8 @@ static int dm_test_part(struct unit_test_state *uts)
 	test(0, ".0", true);
 	test(0, ".0:0", true);
 	test(-EINVAL, "#test1", true);
-	test(1, "1", false);
-	test(1, "1", true);
+	test(1, "2", false);
+	test(1, "2", true);
 	test(-ENOENT, "1:0", false);
 	test(0, "1:0", true);
 	test(1, "1:1", false);
@@ -85,8 +85,8 @@ static int dm_test_part(struct unit_test_state *uts)
 	test(1, "1.0:1", false);
 	test(2, "1.0:2", false);
 	test(-EINVAL, "1#bogus", false);
-	test(1, "1#test1", false);
-	test(2, "1#test2", false);
+	test(1, "2#test1", false);
+	test(2, "2#test2", false);
 	ret = 0;
 
 	env_set("bootdevice", oldbootdevice);
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 13/71] dm: test: Correct ordering of DM setup
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (11 preceding siblings ...)
  2023-01-08  2:49 ` [PATCH v2 12/71] dm: part: Update test to use mmc2 Simon Glass
@ 2023-01-08  2:49 ` Simon Glass
  2023-01-08  2:49 ` [PATCH v2 14/71] ide: Drop non-DM code for BLK Simon Glass
                   ` (58 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:49 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: U-Boot Custodians, Simon Glass, Marek Vasut, Pavel Herrmann

We must call dm_scan_other() after devices from the device tree have been
created, since that function behaves differently if there is no bootstd
device.

Adjust the logic to achieve this.

Also fix the bootflow_system() test which was relying on this broken
behaviour.

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

(no changes since v1)

 test/boot/bootflow.c | 10 ++++++----
 test/test-main.c     | 11 ++++++++---
 2 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c
index 5b76cd3ab14..12976005e41 100644
--- a/test/boot/bootflow.c
+++ b/test/boot/bootflow.c
@@ -338,12 +338,14 @@ BOOTSTD_TEST(bootflow_iter, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
 /* Check using the system bootdev */
 static int bootflow_system(struct unit_test_state *uts)
 {
-	struct udevice *dev;
+	struct udevice *bootstd, *dev;
 
 	if (!IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR))
 		return -EAGAIN;
-	ut_assertok(uclass_get_device_by_name(UCLASS_BOOTMETH, "efi_mgr",
-					      &dev));
+	ut_assertok(uclass_first_device_err(UCLASS_BOOTSTD, &bootstd));
+	ut_assertok(device_bind(bootstd, DM_DRIVER_GET(bootmeth_efi_mgr),
+				"efi_mgr", 0, ofnode_null(), &dev));
+	ut_assertok(device_probe(dev));
 	sandbox_set_fake_efi_mgr_dev(dev, true);
 
 	/* We should get a single 'bootmgr' method right at the end */
@@ -353,7 +355,7 @@ static int bootflow_system(struct unit_test_state *uts)
 	ut_assert_skip_to_line(
 		"  0  efi_mgr      ready   (none)       0  <NULL>                    <NULL>");
 	ut_assert_skip_to_line("No more bootdevs");
-	ut_assert_skip_to_line("(5 bootflows, 5 valid)");
+	ut_assert_skip_to_line("(2 bootflows, 2 valid)");
 	ut_assert_console_end();
 
 	return 0;
diff --git a/test/test-main.c b/test/test-main.c
index 9ab090b7b33..72aa3a0aa8f 100644
--- a/test/test-main.c
+++ b/test/test-main.c
@@ -296,10 +296,8 @@ static int test_pre_run(struct unit_test_state *uts, struct unit_test *test)
 
 	uts->start = mallinfo();
 
-	if (test->flags & UT_TESTF_SCAN_PDATA) {
+	if (test->flags & UT_TESTF_SCAN_PDATA)
 		ut_assertok(dm_scan_plat(false));
-		ut_assertok(dm_scan_other(false));
-	}
 
 	if (test->flags & UT_TESTF_PROBE_TEST)
 		ut_assertok(do_autoprobe(uts));
@@ -308,6 +306,13 @@ static int test_pre_run(struct unit_test_state *uts, struct unit_test *test)
 	    (test->flags & UT_TESTF_SCAN_FDT))
 		ut_assertok(dm_extended_scan(false));
 
+	/*
+	 * Do this after FDT scan since dm_scan_other() in bootstd-uclass.c
+	 * checks for the existence of bootstd
+	 */
+	if (test->flags & UT_TESTF_SCAN_PDATA)
+		ut_assertok(dm_scan_other(false));
+
 	if (IS_ENABLED(CONFIG_SANDBOX) && (test->flags & UT_TESTF_OTHER_FDT)) {
 		/* make sure the other FDT is available */
 		ut_assertok(test_load_other_fdt(uts));
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 14/71] ide: Drop non-DM code for BLK
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (12 preceding siblings ...)
  2023-01-08  2:49 ` [PATCH v2 13/71] dm: test: Correct ordering of DM setup Simon Glass
@ 2023-01-08  2:49 ` Simon Glass
  2023-01-08  2:49 ` [PATCH v2 15/71] dm: mmc: Use bootdev_setup_sibling_blk() Simon Glass
                   ` (57 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:49 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

We require CONFIG_BLK to be enabled now, so this code is unused. Drop it.

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

(no changes since v1)

 drivers/block/ide.c | 42 +-----------------------------------------
 1 file changed, 1 insertion(+), 41 deletions(-)

diff --git a/drivers/block/ide.c b/drivers/block/ide.c
index eaa58d859c6..13a1cb4b9e4 100644
--- a/drivers/block/ide.c
+++ b/drivers/block/ide.c
@@ -443,9 +443,6 @@ static void atapi_inquiry(struct blk_desc *dev_desc)
 
 	device = dev_desc->devnum;
 	dev_desc->type = DEV_TYPE_UNKNOWN;	/* not yet valid */
-#ifndef CONFIG_BLK
-	dev_desc->block_read = atapi_read;
-#endif
 
 	memset(ccb, 0, sizeof(ccb));
 	memset(iobuf, 0, sizeof(iobuf));
@@ -692,6 +689,7 @@ __weak unsigned char ide_inb(int dev, int port)
 
 void ide_init(void)
 {
+	struct udevice *dev;
 	unsigned char c;
 	int i, bus;
 
@@ -759,29 +757,14 @@ void ide_init(void)
 		ide_dev_desc[i].log2blksz =
 			LOG2_INVALID(typeof(ide_dev_desc[i].log2blksz));
 		ide_dev_desc[i].lba = 0;
-#ifndef CONFIG_BLK
-		ide_dev_desc[i].block_read = ide_read;
-		ide_dev_desc[i].block_write = ide_write;
-#endif
 		if (!ide_bus_ok[IDE_BUS(i)])
 			continue;
 		ide_ident(&ide_dev_desc[i]);
 		dev_print(&ide_dev_desc[i]);
-
-#ifndef CONFIG_BLK
-		if ((ide_dev_desc[i].lba > 0) && (ide_dev_desc[i].blksz > 0)) {
-			/* initialize partition type */
-			part_init(&ide_dev_desc[i]);
-		}
-#endif
 	}
 	schedule();
 
-#ifdef CONFIG_BLK
-	struct udevice *dev;
-
 	uclass_first_device(UCLASS_IDE, &dev);
-#endif
 }
 
 __weak void ide_input_swap_data(int dev, ulong *sect_buf, int words)
@@ -830,17 +813,10 @@ __weak void ide_input_data(int dev, ulong *sect_buf, int words)
 	}
 }
 
-#ifdef CONFIG_BLK
 ulong ide_read(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
 	       void *buffer)
-#else
-ulong ide_read(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt,
-	       void *buffer)
-#endif
 {
-#ifdef CONFIG_BLK
 	struct blk_desc *block_dev = dev_get_uclass_plat(dev);
-#endif
 	int device = block_dev->devnum;
 	ulong n = 0;
 	unsigned char c;
@@ -957,17 +933,10 @@ IDE_READ_E:
 	return n;
 }
 
-#ifdef CONFIG_BLK
 ulong ide_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
 		const void *buffer)
-#else
-ulong ide_write(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt,
-		const void *buffer)
-#endif
 {
-#ifdef CONFIG_BLK
 	struct blk_desc *block_dev = dev_get_uclass_plat(dev);
-#endif
 	int device = block_dev->devnum;
 	ulong n = 0;
 	unsigned char c;
@@ -1056,7 +1025,6 @@ int ide_device_present(int dev)
 }
 #endif
 
-#ifdef CONFIG_BLK
 static int ide_blk_probe(struct udevice *udev)
 {
 	struct blk_desc *desc = dev_get_uclass_plat(udev);
@@ -1141,11 +1109,3 @@ UCLASS_DRIVER(ide) = {
 	.name		= "ide",
 	.id		= UCLASS_IDE,
 };
-#else
-U_BOOT_LEGACY_BLK(ide) = {
-	.uclass_idname	= "ide",
-	.uclass_id	= UCLASS_IDE,
-	.max_devs	= CONFIG_SYS_IDE_MAXDEVICE,
-	.desc		= ide_dev_desc,
-};
-#endif
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 15/71] dm: mmc: Use bootdev_setup_sibling_blk()
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (13 preceding siblings ...)
  2023-01-08  2:49 ` [PATCH v2 14/71] ide: Drop non-DM code for BLK Simon Glass
@ 2023-01-08  2:49 ` Simon Glass
  2023-01-08  2:49 ` [PATCH v2 16/71] bootstd: Add a default method to get bootflows Simon Glass
                   ` (56 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:49 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: U-Boot Custodians, Simon Glass, Jaehoon Chung, Marek Vasut,
	Pavel Herrmann, Peng Fan

At present MMC uses the bootdev_setup_for_dev() function to set up the
bootdev. This is because MMC only has one block-device child, so does not
need to worry about naming of the bootdev.

However this inconsistency with other bootdevs that use block devices is a
bit annoying. The only real reason for it is to have a name like
'mmc0.bootdev' instead of 'mmc0.blk.bootdev'.

Update bootdev_setup_sibling_blk() to drop '.blk' from the name where it
appears, thus removing the only reason to use the bootdev_setup_for_dev().
Switch MMC over to the subling function.

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

(no changes since v1)

 boot/bootdev-uclass.c    | 42 ++++++++++++++++++++++++++++------------
 drivers/mmc/mmc-uclass.c |  2 +-
 include/bootdev.h        |  5 ++++-
 3 files changed, 35 insertions(+), 14 deletions(-)

diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c
index cffa01824c0..97f75cba49d 100644
--- a/boot/bootdev-uclass.c
+++ b/boot/bootdev-uclass.c
@@ -234,13 +234,27 @@ int bootdev_setup_for_dev(struct udevice *parent, const char *drv_name)
 	return 0;
 }
 
+static int bootdev_get_suffix_start(struct udevice *dev, const char *suffix)
+{
+	int len, slen;
+
+	len = strlen(dev->name);
+	slen = strlen(suffix);
+	if (len > slen && !strcmp(suffix, dev->name + len - slen))
+		return len - slen;
+
+	return len;
+}
+
 int bootdev_setup_sibling_blk(struct udevice *blk, const char *drv_name)
 {
 	struct udevice *parent, *dev;
 	char dev_name[50];
-	int ret;
+	int ret, len;
 
-	snprintf(dev_name, sizeof(dev_name), "%s.%s", blk->name, "bootdev");
+	len = bootdev_get_suffix_start(blk, ".blk");
+	snprintf(dev_name, sizeof(dev_name), "%.*s.%s", len, blk->name,
+		 "bootdev");
 
 	parent = dev_get_parent(blk);
 	ret = device_find_child_by_name(parent, dev_name, &dev);
@@ -271,20 +285,22 @@ int bootdev_get_sibling_blk(struct udevice *dev, struct udevice **blkp)
 	struct udevice *parent = dev_get_parent(dev);
 	struct udevice *blk;
 	int ret, len;
-	char *p;
 
 	if (device_get_uclass_id(dev) != UCLASS_BOOTDEV)
 		return -EINVAL;
 
 	/* This should always work if bootdev_setup_sibling_blk() was used */
-	p = strstr(dev->name, ".bootdev");
-	if (!p)
-		return log_msg_ret("str", -EINVAL);
-
-	len = p - dev->name;
+	len = bootdev_get_suffix_start(dev, ".bootdev");
 	ret = device_find_child_by_namelen(parent, dev->name, len, &blk);
-	if (ret)
-		return log_msg_ret("find", ret);
+	if (ret) {
+		char dev_name[50];
+
+		snprintf(dev_name, sizeof(dev_name), "%.*s.blk", len,
+			 dev->name);
+		ret = device_find_child_by_name(parent, dev_name, &blk);
+		if (ret)
+			return log_msg_ret("find", ret);
+	}
 	*blkp = blk;
 
 	return 0;
@@ -295,13 +311,15 @@ static int bootdev_get_from_blk(struct udevice *blk, struct udevice **bootdevp)
 	struct udevice *parent = dev_get_parent(blk);
 	struct udevice *bootdev;
 	char dev_name[50];
-	int ret;
+	int ret, len;
 
 	if (device_get_uclass_id(blk) != UCLASS_BLK)
 		return -EINVAL;
 
 	/* This should always work if bootdev_setup_sibling_blk() was used */
-	snprintf(dev_name, sizeof(dev_name), "%s.%s", blk->name, "bootdev");
+	len = bootdev_get_suffix_start(blk, ".blk");
+	snprintf(dev_name, sizeof(dev_name), "%.*s.%s", len, blk->name,
+		 "bootdev");
 	ret = device_find_child_by_name(parent, dev_name, &bootdev);
 	if (ret)
 		return log_msg_ret("find", ret);
diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c
index 759a6b728c8..01d9b0201f2 100644
--- a/drivers/mmc/mmc-uclass.c
+++ b/drivers/mmc/mmc-uclass.c
@@ -421,7 +421,7 @@ int mmc_bind(struct udevice *dev, struct mmc *mmc, const struct mmc_config *cfg)
 	mmc->cfg = cfg;
 	mmc->priv = dev;
 
-	ret = bootdev_setup_for_dev(dev, "mmc_bootdev");
+	ret = bootdev_setup_sibling_blk(bdev, "mmc_bootdev");
 	if (ret)
 		return log_msg_ret("bootdev", ret);
 
diff --git a/include/bootdev.h b/include/bootdev.h
index 9fc219839fe..d0ca51c6d5e 100644
--- a/include/bootdev.h
+++ b/include/bootdev.h
@@ -204,7 +204,10 @@ int bootdev_setup_iter_order(struct bootflow_iter *iter, struct udevice **devp);
 
 #if CONFIG_IS_ENABLED(BOOTSTD)
 /**
- * bootdev_setup_for_dev() - Bind a new bootdev device
+ * bootdev_setup_for_dev() - Bind a new bootdev device (deprecated)
+ *
+ * Please use bootdev_setup_sibling_blk() instead since it supports multiple
+ * (child) block devices for each media device.
  *
  * Creates a bootdev device as a child of @parent. This should be called from
  * the driver's bind() method or its uclass' post_bind() method.
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 16/71] bootstd: Add a default method to get bootflows
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (14 preceding siblings ...)
  2023-01-08  2:49 ` [PATCH v2 15/71] dm: mmc: Use bootdev_setup_sibling_blk() Simon Glass
@ 2023-01-08  2:49 ` Simon Glass
  2023-01-08  2:49 ` [PATCH v2 17/71] sandbox: Allow ethernet to be disabled at runtime Simon Glass
                   ` (55 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:49 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

The code in these functions turns out to often be the same. Add a default
get_bootflow() function and allow the drivers to select it by setting
the method to NULL.

This saves a little code space.

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

(no changes since v1)

 boot/bootdev-uclass.c          | 27 +++++++++++++++++++++++++--
 drivers/mmc/mmc_bootdev.c      | 25 -------------------------
 drivers/usb/host/usb_bootdev.c | 24 ------------------------
 include/bootdev.h              |  5 ++++-
 4 files changed, 29 insertions(+), 52 deletions(-)

diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c
index 97f75cba49d..0ef3daf24cb 100644
--- a/boot/bootdev-uclass.c
+++ b/boot/bootdev-uclass.c
@@ -450,14 +450,37 @@ int bootdev_find_by_any(const char *name, struct udevice **devp)
 	return 0;
 }
 
+static int default_get_bootflow(struct udevice *dev, struct bootflow_iter *iter,
+				struct bootflow *bflow)
+{
+	struct udevice *blk;
+	int ret;
+
+	ret = bootdev_get_sibling_blk(dev, &blk);
+	/*
+	 * If there is no media, indicate that no more partitions should be
+	 * checked
+	 */
+	if (ret == -EOPNOTSUPP)
+		ret = -ESHUTDOWN;
+	if (ret)
+		return log_msg_ret("blk", ret);
+	assert(blk);
+	ret = bootdev_find_in_blk(dev, blk, iter, bflow);
+	if (ret)
+		return log_msg_ret("find", ret);
+
+	return 0;
+}
+
 int bootdev_get_bootflow(struct udevice *dev, struct bootflow_iter *iter,
 			 struct bootflow *bflow)
 {
 	const struct bootdev_ops *ops = bootdev_get_ops(dev);
 
-	if (!ops->get_bootflow)
-		return -ENOSYS;
 	bootflow_init(bflow, dev, iter->method);
+	if (!ops->get_bootflow)
+		return default_get_bootflow(dev, iter, bflow);
 
 	return ops->get_bootflow(dev, iter, bflow);
 }
diff --git a/drivers/mmc/mmc_bootdev.c b/drivers/mmc/mmc_bootdev.c
index b4f41fb3a67..037b67bc0ff 100644
--- a/drivers/mmc/mmc_bootdev.c
+++ b/drivers/mmc/mmc_bootdev.c
@@ -11,30 +11,6 @@
 #include <dm.h>
 #include <mmc.h>
 
-static int mmc_get_bootflow(struct udevice *dev, struct bootflow_iter *iter,
-			    struct bootflow *bflow)
-{
-	struct udevice *mmc_dev = dev_get_parent(dev);
-	struct udevice *blk;
-	int ret;
-
-	ret = mmc_get_blk(mmc_dev, &blk);
-	/*
-	 * If there is no media, indicate that no more partitions should be
-	 * checked
-	 */
-	if (ret == -EOPNOTSUPP)
-		ret = -ESHUTDOWN;
-	if (ret)
-		return log_msg_ret("blk", ret);
-	assert(blk);
-	ret = bootdev_find_in_blk(dev, blk, iter, bflow);
-	if (ret)
-		return log_msg_ret("find", ret);
-
-	return 0;
-}
-
 static int mmc_bootdev_bind(struct udevice *dev)
 {
 	struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
@@ -45,7 +21,6 @@ static int mmc_bootdev_bind(struct udevice *dev)
 }
 
 struct bootdev_ops mmc_bootdev_ops = {
-	.get_bootflow	= mmc_get_bootflow,
 };
 
 static const struct udevice_id mmc_bootdev_ids[] = {
diff --git a/drivers/usb/host/usb_bootdev.c b/drivers/usb/host/usb_bootdev.c
index b85f699933d..b2d157faf33 100644
--- a/drivers/usb/host/usb_bootdev.c
+++ b/drivers/usb/host/usb_bootdev.c
@@ -11,29 +11,6 @@
 #include <dm.h>
 #include <usb.h>
 
-static int usb_get_bootflow(struct udevice *dev, struct bootflow_iter *iter,
-			    struct bootflow *bflow)
-{
-	struct udevice *blk;
-	int ret;
-
-	ret = bootdev_get_sibling_blk(dev, &blk);
-	/*
-	 * If there is no media, indicate that no more partitions should be
-	 * checked
-	 */
-	if (ret == -EOPNOTSUPP)
-		ret = -ESHUTDOWN;
-	if (ret)
-		return log_msg_ret("blk", ret);
-	assert(blk);
-	ret = bootdev_find_in_blk(dev, blk, iter, bflow);
-	if (ret)
-		return log_msg_ret("find", ret);
-
-	return 0;
-}
-
 static int usb_bootdev_bind(struct udevice *dev)
 {
 	struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
@@ -44,7 +21,6 @@ static int usb_bootdev_bind(struct udevice *dev)
 }
 
 struct bootdev_ops usb_bootdev_ops = {
-	.get_bootflow	= usb_get_bootflow,
 };
 
 static const struct udevice_id usb_bootdev_ids[] = {
diff --git a/include/bootdev.h b/include/bootdev.h
index d0ca51c6d5e..1e91d4130e7 100644
--- a/include/bootdev.h
+++ b/include/bootdev.h
@@ -50,7 +50,10 @@ struct bootdev_uc_plat {
 /** struct bootdev_ops - Operations for the bootdev uclass */
 struct bootdev_ops {
 	/**
-	 * get_bootflow() - get a bootflow
+	 * get_bootflow() - get a bootflow (optional)
+	 *
+	 * If this is NULL then the default implementaton is used, which is
+	 * default_get_bootflow()
 	 *
 	 * @dev:	Bootflow device to check
 	 * @iter:	Provides current dev, part, method to get. Should update
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 17/71] sandbox: Allow ethernet to be disabled at runtime
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (15 preceding siblings ...)
  2023-01-08  2:49 ` [PATCH v2 16/71] bootstd: Add a default method to get bootflows Simon Glass
@ 2023-01-08  2:49 ` Simon Glass
  2023-01-08  2:49 ` [PATCH v2 18/71] sandbox: Allow ethernet bootdevs to be disabled for tests Simon Glass
                   ` (54 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:49 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

For bootstd tests it is seldom useful to have ethernet enabled. Add a way
to disable it, so that ethernet operations like tftpboot do nothing.

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

(no changes since v1)

 arch/sandbox/cpu/state.c         | 16 ++++++++++++++++
 arch/sandbox/include/asm/state.h |  1 +
 arch/sandbox/include/asm/test.h  | 16 ++++++++++++++++
 include/test/test.h              | 25 +++++++++++++++++++++++++
 net/net.c                        |  4 ++++
 5 files changed, 62 insertions(+)

diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c
index a681e472ab6..76e65741424 100644
--- a/arch/sandbox/cpu/state.c
+++ b/arch/sandbox/cpu/state.c
@@ -12,6 +12,7 @@
 #include <os.h>
 #include <asm/malloc.h>
 #include <asm/state.h>
+#include <asm/test.h>
 
 /* Main state record for the sandbox */
 static struct sandbox_state main_state;
@@ -366,6 +367,7 @@ void state_reset_for_test(struct sandbox_state *state)
 	state->sysreset_allowed[SYSRESET_POWER_OFF] = true;
 	state->sysreset_allowed[SYSRESET_COLD] = true;
 	state->allow_memio = false;
+	sandbox_set_eth_enable(true);
 
 	memset(&state->wdt, '\0', sizeof(state->wdt));
 	memset(state->spi, '\0', sizeof(state->spi));
@@ -444,6 +446,20 @@ int state_load_other_fdt(const char **bufp, int *sizep)
 	return 0;
 }
 
+void sandbox_set_eth_enable(bool enable)
+{
+	struct sandbox_state *state = state_get_current();
+
+	state->disable_eth = !enable;
+}
+
+bool sandbox_eth_enabled(void)
+{
+	struct sandbox_state *state = state_get_current();
+
+	return !state->disable_eth;
+}
+
 int state_init(void)
 {
 	state = &main_state;
diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h
index 49ea483d332..f125fb87af7 100644
--- a/arch/sandbox/include/asm/state.h
+++ b/arch/sandbox/include/asm/state.h
@@ -96,6 +96,7 @@ struct sandbox_state {
 	const char *select_unittests;	/* Unit test to run */
 	bool handle_signals;		/* Handle signals within sandbox */
 	bool autoboot_keyed;		/* Use keyed-autoboot feature */
+	bool disable_eth;		/* Disable Ethernet devices */
 
 	/* Pointer to information for each SPI bus/cs */
 	struct sandbox_spi_info spi[CONFIG_SANDBOX_SPI_MAX_BUS]
diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h
index 568738c16d5..1c522e38f3d 100644
--- a/arch/sandbox/include/asm/test.h
+++ b/arch/sandbox/include/asm/test.h
@@ -344,4 +344,20 @@ void sandbox_set_fake_efi_mgr_dev(struct udevice *dev, bool fake_dev);
  */
 int sandbox_load_other_fdt(void **fdtp, int *sizep);
 
+/**
+ * sandbox_set_eth_enable() - Enable / disable Ethernet
+ *
+ * Allows control of whether Ethernet packets are actually send/received
+ *
+ * @enable: true to enable Ethernet, false to disable
+ */
+void sandbox_set_eth_enable(bool enable);
+
+/**
+ * sandbox_eth_enabled() - Check if Ethernet is enabled
+ *
+ * Returns: true if Ethernet is enabled on sandbox, False if not
+ */
+bool sandbox_eth_enabled(void);
+
 #endif
diff --git a/include/test/test.h b/include/test/test.h
index 4ad74614afc..76ec4d739a3 100644
--- a/include/test/test.h
+++ b/include/test/test.h
@@ -169,4 +169,29 @@ static inline int test_load_other_fdt(struct unit_test_state *uts)
 	return ret;
 }
 
+/**
+ * test_set_eth_enable() - Enable / disable Ethernet
+ *
+ * Allows control of whether Ethernet packets are actually send/received
+ *
+ * @enable: true to enable Ethernet, false to disable
+ */
+static inline void test_set_eth_enable(bool enable)
+{
+#ifdef CONFIG_SANDBOX
+	sandbox_set_eth_enable(enable);
+#endif
+}
+
+/* Allow ethernet to be disabled for testing purposes */
+static inline bool test_eth_enabled(void)
+{
+	bool enabled = true;
+
+#ifdef CONFIG_SANDBOX
+	enabled = sandbox_eth_enabled();
+#endif
+	return enabled;
+}
+
 #endif /* __TEST_TEST_H */
diff --git a/net/net.c b/net/net.c
index 57da9bda85a..c9a749f6cc8 100644
--- a/net/net.c
+++ b/net/net.c
@@ -106,6 +106,7 @@
 #endif
 #include <watchdog.h>
 #include <linux/compiler.h>
+#include <test/test.h>
 #include "arp.h"
 #include "bootp.h"
 #include "cdp.h"
@@ -465,6 +466,9 @@ restart:
 	debug_cond(DEBUG_INT_STATE, "--- net_loop Init\n");
 	net_init_loop();
 
+	if (!test_eth_enabled())
+		return 0;
+
 	switch (net_check_prereq(protocol)) {
 	case 1:
 		/* network not configured */
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 18/71] sandbox: Allow ethernet bootdevs to be disabled for tests
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (16 preceding siblings ...)
  2023-01-08  2:49 ` [PATCH v2 17/71] sandbox: Allow ethernet to be disabled at runtime Simon Glass
@ 2023-01-08  2:49 ` Simon Glass
  2023-01-08  2:49 ` [PATCH v2 19/71] sandbox: Enable the Ethernet bootdev Simon Glass
                   ` (53 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:49 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

Most tests don't want these and can create a lot of noise. Add a way to
disable them. Use that in tests, with a flag provided to enable them for
tests that need this feature.

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

(no changes since v1)

 include/net.h       | 16 ++++++++++++++++
 include/test/test.h | 12 ++++++++++++
 net/eth-uclass.c    | 14 +++++++++++++-
 test/test-main.c    |  8 +++++++-
 4 files changed, 48 insertions(+), 2 deletions(-)

diff --git a/include/net.h b/include/net.h
index 1a99009959d..749f20fa967 100644
--- a/include/net.h
+++ b/include/net.h
@@ -957,4 +957,20 @@ static inline struct in_addr env_get_ip(char *var)
  */
 void reset_phy(void);
 
+#if CONFIG_IS_ENABLED(NET)
+/**
+ * eth_set_enable_bootdevs() - Enable or disable binding of Ethernet bootdevs
+ *
+ * These get in the way of bootstd testing, so are normally disabled by tests.
+ * This provide control of this setting. It only affects binding of Ethernet
+ * devices, so if that has already happened, this flag does nothing.
+ *
+ * @enable: true to enable binding of bootdevs when binding new Ethernet
+ * devices, false to disable it
+ */
+void eth_set_enable_bootdevs(bool enable);
+#else
+static inline void eth_set_enable_bootdevs(bool enable) {}
+#endif
+
 #endif /* __NET_H__ */
diff --git a/include/test/test.h b/include/test/test.h
index 76ec4d739a3..beabe9333dc 100644
--- a/include/test/test.h
+++ b/include/test/test.h
@@ -71,6 +71,7 @@ enum {
 	 * since it cannot access the flags.
 	 */
 	UT_TESTF_MANUAL		= BIT(8),
+	UT_TESTF_ETH_BOOTDEV	= BIT(9),	/* enable Ethernet bootdevs */
 };
 
 /**
@@ -194,4 +195,15 @@ static inline bool test_eth_enabled(void)
 	return enabled;
 }
 
+/* Allow ethernet bootdev to be ignored for testing purposes */
+static inline bool test_eth_bootdev_enabled(void)
+{
+	bool enabled = true;
+
+#ifdef CONFIG_SANDBOX
+	enabled = sandbox_eth_enabled();
+#endif
+	return enabled;
+}
+
 #endif /* __TEST_TEST_H */
diff --git a/net/eth-uclass.c b/net/eth-uclass.c
index f41da4b37b3..b01a910938e 100644
--- a/net/eth-uclass.c
+++ b/net/eth-uclass.c
@@ -38,9 +38,12 @@ struct eth_device_priv {
  * struct eth_uclass_priv - The structure attached to the uclass itself
  *
  * @current: The Ethernet device that the network functions are using
+ * @no_bootdevs: true to skip binding Ethernet bootdevs (this is a negative flag
+ * so that the default value enables it)
  */
 struct eth_uclass_priv {
 	struct udevice *current;
+	bool no_bootdevs;
 };
 
 /* eth_errno - This stores the most recent failure code from DM functions */
@@ -59,6 +62,14 @@ static struct eth_uclass_priv *eth_get_uclass_priv(void)
 	return uclass_get_priv(uc);
 }
 
+void eth_set_enable_bootdevs(bool enable)
+{
+	struct eth_uclass_priv *priv = eth_get_uclass_priv();
+
+	if (priv)
+		priv->no_bootdevs = !enable;
+}
+
 void eth_set_current_to_next(void)
 {
 	struct eth_uclass_priv *uc_priv;
@@ -477,6 +488,7 @@ int eth_initialize(void)
 
 static int eth_post_bind(struct udevice *dev)
 {
+	struct eth_uclass_priv *priv = uclass_get_priv(dev->uclass);
 	int ret;
 
 	if (strchr(dev->name, ' ')) {
@@ -488,7 +500,7 @@ static int eth_post_bind(struct udevice *dev)
 #ifdef CONFIG_DM_ETH_PHY
 	eth_phy_binds_nodes(dev);
 #endif
-	if (CONFIG_IS_ENABLED(BOOTDEV_ETH)) {
+	if (CONFIG_IS_ENABLED(BOOTDEV_ETH) && !priv->no_bootdevs) {
 		ret = bootdev_setup_for_dev(dev, "eth_bootdev");
 		if (ret)
 			return log_msg_ret("bootdev", ret);
diff --git a/test/test-main.c b/test/test-main.c
index 72aa3a0aa8f..9d0f6643d5e 100644
--- a/test/test-main.c
+++ b/test/test-main.c
@@ -10,6 +10,7 @@
 #include <cyclic.h>
 #include <dm.h>
 #include <event.h>
+#include <net.h>
 #include <of_live.h>
 #include <os.h>
 #include <dm/ofnode.h>
@@ -303,8 +304,13 @@ static int test_pre_run(struct unit_test_state *uts, struct unit_test *test)
 		ut_assertok(do_autoprobe(uts));
 
 	if (!CONFIG_IS_ENABLED(OF_PLATDATA) &&
-	    (test->flags & UT_TESTF_SCAN_FDT))
+	    (test->flags & UT_TESTF_SCAN_FDT)) {
+		/*
+		 * only set this if we know the ethernet uclass will be created
+		 */
+		eth_set_enable_bootdevs(test->flags & UT_TESTF_ETH_BOOTDEV);
 		ut_assertok(dm_extended_scan(false));
+	}
 
 	/*
 	 * Do this after FDT scan since dm_scan_other() in bootstd-uclass.c
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 19/71] sandbox: Enable the Ethernet bootdev
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (17 preceding siblings ...)
  2023-01-08  2:49 ` [PATCH v2 18/71] sandbox: Allow ethernet bootdevs to be disabled for tests Simon Glass
@ 2023-01-08  2:49 ` Simon Glass
  2023-01-08  2:49 ` [PATCH v2 20/71] lib: Support printing an error string Simon Glass
                   ` (52 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:49 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

This bootdev is disabled at present since it messes with the tests. Now
that there is a way to disable networking at runtime, enable the driver.
This allows running tests with it if necessary.

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

(no changes since v1)

 configs/sandbox_defconfig          | 1 -
 configs/sandbox_flattree_defconfig | 1 -
 2 files changed, 2 deletions(-)

diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 0b26673bf4f..42d961b2e60 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -132,7 +132,6 @@ CONFIG_ENV_IS_IN_EXT4=y
 CONFIG_ENV_EXT4_INTERFACE="host"
 CONFIG_ENV_EXT4_DEVICE_AND_PART="0:0"
 CONFIG_ENV_IMPORT_FDT=y
-# CONFIG_BOOTDEV_ETH is not set
 CONFIG_BOOTP_SEND_HOSTNAME=y
 CONFIG_NETCONSOLE=y
 CONFIG_IP_DEFRAG=y
diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig
index 41453e0e2fa..eaaec42b1fe 100644
--- a/configs/sandbox_flattree_defconfig
+++ b/configs/sandbox_flattree_defconfig
@@ -75,7 +75,6 @@ CONFIG_ENV_IS_NOWHERE=y
 CONFIG_ENV_IS_IN_EXT4=y
 CONFIG_ENV_EXT4_INTERFACE="host"
 CONFIG_ENV_EXT4_DEVICE_AND_PART="0:0"
-# CONFIG_BOOTDEV_ETH is not set
 CONFIG_BOOTP_SEND_HOSTNAME=y
 CONFIG_NETCONSOLE=y
 CONFIG_IP_DEFRAG=y
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 20/71] lib: Support printing an error string
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (18 preceding siblings ...)
  2023-01-08  2:49 ` [PATCH v2 19/71] sandbox: Enable the Ethernet bootdev Simon Glass
@ 2023-01-08  2:49 ` Simon Glass
  2023-01-08  2:49 ` [PATCH v2 21/71] event: Correct duplicate log message in event_notify() Simon Glass
                   ` (51 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:49 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

It is often useful to show an error code to give the user a clue as to
what went wrong. When error strings are compiled into U-Boot it is
possible to show a message as well.

But at present it is not very convenient, since code must check if the
error strings are present, then obtain the error string and use it in
a printf() string.

Add a %dE option which shows an error code along with an error string,
if available. This makes it easy to show one or both.

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

(no changes since v1)

 lib/vsprintf.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 530d8088c7f..8de3882fb6c 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -145,6 +145,7 @@ static noinline char *put_dec(char *buf, uint64_t num)
 #define LEFT	16		/* left justified */
 #define SMALL	32		/* Must be 32 == 0x20 */
 #define SPECIAL	64		/* 0x */
+#define ERRSTR	128		/* %dE showing error string if enabled */
 
 /*
  * Macro to add a new character to our output string, but only if it will
@@ -678,6 +679,8 @@ repeat:
 			break;
 
 		case 'd':
+			if (fmt[1] == 'E')
+				flags |= ERRSTR;
 		case 'i':
 			flags |= SIGN;
 		case 'u':
@@ -712,6 +715,15 @@ repeat:
 		}
 		str = number(str, end, num, base, field_width, precision,
 			     flags);
+		if (IS_ENABLED(CONFIG_ERRNO_STR) && (flags & ERRSTR)) {
+			const char *p;
+
+			ADDCH(str, ':');
+			ADDCH(str, ' ');
+			for (p = errno_str(num); *p; p++)
+				ADDCH(str, *p);
+			fmt++;
+		}
 	}
 
 	if (size > 0) {
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 21/71] event: Correct duplicate log message in event_notify()
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (19 preceding siblings ...)
  2023-01-08  2:49 ` [PATCH v2 20/71] lib: Support printing an error string Simon Glass
@ 2023-01-08  2:49 ` Simon Glass
  2023-01-08  2:49 ` [PATCH v2 22/71] efi: Improve logging in efi_disk Simon Glass
                   ` (50 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:49 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

Use a different one for each call.

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

(no changes since v1)

 common/event.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/common/event.c b/common/event.c
index 231b9e6ffdd..c312556490e 100644
--- a/common/event.c
+++ b/common/event.c
@@ -123,7 +123,7 @@ int event_notify(enum event_t type, void *data, int size)
 
 	ret = notify_static(&event);
 	if (ret)
-		return log_msg_ret("dyn", ret);
+		return log_msg_ret("sta", ret);
 
 	if (CONFIG_IS_ENABLED(EVENT_DYNAMIC)) {
 		ret = notify_dynamic(&event);
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 22/71] efi: Improve logging in efi_disk
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (20 preceding siblings ...)
  2023-01-08  2:49 ` [PATCH v2 21/71] event: Correct duplicate log message in event_notify() Simon Glass
@ 2023-01-08  2:49 ` Simon Glass
  2023-01-13 20:35   ` Heinrich Schuchardt
  2023-01-08  2:49 ` [PATCH v2 23/71] bootstd: Add the concept of a bootdev hunter Simon Glass
                   ` (49 subsequent siblings)
  71 siblings, 1 reply; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:49 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

When this fails it can be time-consuming to debug. Add some debugging
to help with this. Also try to return error codes instead of just using
-1.

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

(no changes since v1)

 lib/efi_loader/efi_disk.c | 30 +++++++++++++++++++++---------
 1 file changed, 21 insertions(+), 9 deletions(-)

diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
index 7ea0334083f..37123dd2474 100644
--- a/lib/efi_loader/efi_disk.c
+++ b/lib/efi_loader/efi_disk.c
@@ -421,13 +421,16 @@ static efi_status_t efi_disk_add_dev(
 
 		if (!node) {
 			ret = EFI_OUT_OF_RESOURCES;
+			log_debug("no node\n");
 			goto error;
 		}
 
 		/* Parent must expose EFI_BLOCK_IO_PROTOCOL */
 		ret = efi_search_protocol(parent, &efi_block_io_guid, &handler);
-		if (ret != EFI_SUCCESS)
+		if (ret != EFI_SUCCESS) {
+			log_debug("search failed\n");
 			goto error;
+		}
 
 		/*
 		 * Link the partition (child controller) to the block device
@@ -436,8 +439,10 @@ static efi_status_t efi_disk_add_dev(
 		ret = efi_protocol_open(handler, &protocol_interface, NULL,
 					&diskobj->header,
 					EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER);
-		if (ret != EFI_SUCCESS)
-				goto error;
+		if (ret != EFI_SUCCESS) {
+			log_debug("prot open failed\n");
+			goto error;
+		}
 
 		diskobj->dp = efi_dp_append_node(dp_parent, node);
 		efi_free_pool(node);
@@ -468,8 +473,10 @@ static efi_status_t efi_disk_add_dev(
 					 */
 					esp_guid, NULL,
 					NULL);
-	if (ret != EFI_SUCCESS)
+	if (ret != EFI_SUCCESS) {
+		log_debug("install failed %lx\n", ret);
 		goto error;
+	}
 
 	/*
 	 * On partitions or whole disks without partitions install the
@@ -482,8 +489,10 @@ static efi_status_t efi_disk_add_dev(
 		ret = efi_add_protocol(&diskobj->header,
 				       &efi_simple_file_system_protocol_guid,
 				       diskobj->volume);
-		if (ret != EFI_SUCCESS)
+		if (ret != EFI_SUCCESS) {
+			log_debug("simple FS failed\n");
 			return ret;
+		}
 	}
 	diskobj->ops = block_io_disk_template;
 	diskobj->dev_index = dev_index;
@@ -552,18 +561,21 @@ static int efi_disk_create_raw(struct udevice *dev)
 	ret = efi_disk_add_dev(NULL, NULL, desc,
 			       diskid, NULL, 0, &disk);
 	if (ret != EFI_SUCCESS) {
-		if (ret == EFI_NOT_READY)
+		if (ret == EFI_NOT_READY) {
 			log_notice("Disk %s not ready\n", dev->name);
-		else
+			ret = -EBUSY;
+		} else {
 			log_err("Adding disk for %s failed (err=%ld/%#lx)\n", dev->name, ret, ret);
+			ret = -ENOENT;
+		}
 
-		return -1;
+		return ret;
 	}
 	if (efi_link_dev(&disk->header, dev)) {
 		efi_free_pool(disk->dp);
 		efi_delete_handle(&disk->header);
 
-		return -1;
+		return -EINVAL;
 	}
 
 	return 0;
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 23/71] bootstd: Add the concept of a bootdev hunter
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (21 preceding siblings ...)
  2023-01-08  2:49 ` [PATCH v2 22/71] efi: Improve logging in efi_disk Simon Glass
@ 2023-01-08  2:49 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 24/71] bootstd: Support running bootdev hunters Simon Glass
                   ` (48 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:49 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

Some bootdevs must be enumerated before they appear. For example, USB
bootdevs are not visible until USB is enumerated.

With standard boot this needs to happen automatically, since we only
want to enumerate a bus if it is needed.

Add a way to define bootdev 'hunters' which can be used to hunt for
bootdevs of a given type. Track which ones have been used and add a
command to list them.

Include a clang work-around which seems to be needed.

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

(no changes since v1)

 boot/bootdev-uclass.c | 31 +++++++++++++++++++++++
 cmd/bootdev.c         | 35 +++++++++++++++++++++++---
 include/bootdev.h     | 58 +++++++++++++++++++++++++++++++++++++++++++
 include/bootstd.h     |  3 +++
 test/boot/bootdev.c   | 52 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 176 insertions(+), 3 deletions(-)

diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c
index 0ef3daf24cb..62eb0b617cd 100644
--- a/boot/bootdev-uclass.c
+++ b/boot/bootdev-uclass.c
@@ -636,6 +636,37 @@ int bootdev_setup_iter_order(struct bootflow_iter *iter, struct udevice **devp)
 	return 0;
 }
 
+void bootdev_list_hunters(struct bootstd_priv *std)
+{
+	struct bootdev_hunter *orig, *start;
+	int n_ent, i;
+
+	orig = ll_entry_start(struct bootdev_hunter, bootdev_hunter);
+	n_ent = ll_entry_count(struct bootdev_hunter, bootdev_hunter);
+
+	/*
+	 * workaround for strange bug in clang-12 which sees all the below data
+	 * as zeroes. Any access of start seems to fix it, such as
+	 *
+	 *    printf("%p", start);
+	 *
+	 * Use memcpy() to force the correct behaviour.
+	 */
+	memcpy(&start, &orig, sizeof(orig));
+	printf("%4s  %4s  %-15s  %s\n", "Prio", "Used", "Uclass", "Hunter");
+	printf("%4s  %4s  %-15s  %s\n", "----", "----", "---------------", "---------------");
+	for (i = 0; i < n_ent; i++) {
+		struct bootdev_hunter *info = start + i;
+
+		printf("%4d  %4s  %-15s  %s\n", info->prio,
+		       std->hunters_used & BIT(i) ? "*" : "",
+		       uclass_get_name(info->uclass),
+		       info->drv ? info->drv->name : "(none)");
+	}
+
+	printf("(total hunters: %d)\n", n_ent);
+}
+
 static int bootdev_post_bind(struct udevice *dev)
 {
 	struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
diff --git a/cmd/bootdev.c b/cmd/bootdev.c
index ecd797c0503..80bfe2812e4 100644
--- a/cmd/bootdev.c
+++ b/cmd/bootdev.c
@@ -107,14 +107,43 @@ static int do_bootdev_info(struct cmd_tbl *cmdtp, int flag, int argc,
 	return 0;
 }
 
+static int do_bootdev_hunt(struct cmd_tbl *cmdtp, int flag, int argc,
+			   char *const argv[])
+{
+	struct bootstd_priv *priv;
+	const char *spec = NULL;
+	bool list = false;
+	int ret = 0;
+
+	if (argc >= 2) {
+		if (!strcmp(argv[1], "-l"))
+			list = true;
+		else
+			spec = argv[1];
+	}
+
+	ret = bootstd_get_priv(&priv);
+	if (ret)
+		return ret;
+	if (list) {
+		bootdev_list_hunters(priv);
+	} else {
+		/* TODO: implement hunting */
+	}
+
+	return 0;
+}
+
 #ifdef CONFIG_SYS_LONGHELP
 static char bootdev_help_text[] =
-	"list [-p]      - list all available bootdevs (-p to probe)\n"
-	"bootdev select <bd>    - select a bootdev by name | label | seq\n"
-	"bootdev info [-p]      - show information about a bootdev (-p to probe)";
+	"list [-p]         - list all available bootdevs (-p to probe)\n"
+	"bootdev hunt [-l|<spec>]  - use hunt drivers to find bootdevs\n"
+	"bootdev select <bd>       - select a bootdev by name | label | seq\n"
+	"bootdev info [-p]         - show information about a bootdev (-p to probe)";
 #endif
 
 U_BOOT_CMD_WITH_SUBCMDS(bootdev, "Boot devices", bootdev_help_text,
 	U_BOOT_SUBCMD_MKENT(list, 2, 1, do_bootdev_list),
+	U_BOOT_SUBCMD_MKENT(hunt, 2, 1, do_bootdev_hunt),
 	U_BOOT_SUBCMD_MKENT(select, 2, 1, do_bootdev_select),
 	U_BOOT_SUBCMD_MKENT(info, 2, 1, do_bootdev_info));
diff --git a/include/bootdev.h b/include/bootdev.h
index 1e91d4130e7..cafb5285a28 100644
--- a/include/bootdev.h
+++ b/include/bootdev.h
@@ -11,6 +11,7 @@
 
 struct bootflow;
 struct bootflow_iter;
+struct bootstd_priv;
 struct udevice;
 
 /**
@@ -33,6 +34,53 @@ enum bootdev_prio_t {
 	BOOTDEVP_COUNT,
 };
 
+struct bootdev_hunter;
+
+/**
+ * bootdev_hunter_func - function to probe for bootdevs of a given type
+ *
+ * This should hunt around for bootdevs of the given type, binding them as it
+ * finds them. This may involve bus enumeration, etc.
+ *
+ * @info: Info structure describing this hunter
+ * @show: true to show information from the hunter
+ * Returns: 0 if OK, -ve on error
+ */
+typedef int (*bootdev_hunter_func)(struct bootdev_hunter *info, bool show);
+
+/**
+ * struct bootdev_hunter - information about how to hunt for bootdevs
+ *
+ * @prio: Scanning priority of this hunter
+ * @uclass: Uclass ID for the media associated with this bootdev
+ * @drv: bootdev driver for the things found by this hunter
+ * @hunt: Function to call to hunt for bootdevs of this type (NULL if none)
+ *
+ * Some bootdevs are not visible until other devices are enumerated. For
+ * example, USB bootdevs only appear when the USB bus is enumerated.
+ *
+ * On the other hand, we don't always want to enumerate all the buses just to
+ * find the first valid bootdev. Ideally we want to work through them in
+ * priority order, so that the fastest bootdevs are discovered first.
+ *
+ * This struct holds information about the bootdev so we can determine the probe
+ * order and how to hunt for bootdevs of this type
+ */
+struct bootdev_hunter {
+	enum bootdev_prio_t prio;
+	enum uclass_id uclass;
+	struct driver *drv;
+	bootdev_hunter_func hunt;
+};
+
+/* declare a new bootdev hunter */
+#define BOOTDEV_HUNTER(__name)						\
+	ll_entry_declare(struct bootdev_hunter, __name, bootdev_hunter)
+
+/* access a bootdev hunter by name */
+#define BOOTDEV_HUNTER_GET(__name)						\
+	ll_entry_get(struct bootdev_hunter, __name, bootdev_hunter)
+
 /**
  * struct bootdev_uc_plat - uclass information about a bootdev
  *
@@ -205,6 +253,16 @@ int bootdev_find_by_any(const char *name, struct udevice **devp);
  */
 int bootdev_setup_iter_order(struct bootflow_iter *iter, struct udevice **devp);
 
+/**
+ * bootdev_list_hunters() - List the available bootdev hunters
+ *
+ * These provide a way to find new bootdevs by enumerating buses, etc. This
+ * function lists the available hunters
+ *
+ * @std: Pointer to bootstd private info
+ */
+void bootdev_list_hunters(struct bootstd_priv *std);
+
 #if CONFIG_IS_ENABLED(BOOTSTD)
 /**
  * bootdev_setup_for_dev() - Bind a new bootdev device (deprecated)
diff --git a/include/bootstd.h b/include/bootstd.h
index bd305094fdc..dddb3e15384 100644
--- a/include/bootstd.h
+++ b/include/bootstd.h
@@ -33,6 +33,8 @@ struct udevice;
  * @bootmeth_order: List of bootmeth devices to use, in order, NULL-terminated
  * @vbe_bootmeth: Currently selected VBE bootmeth, NULL if none
  * @theme: Node containing the theme information
+ * @hunters_used: Bitmask of used hunters, indexed by their position in the
+ * linker list. The bit is set if the hunter has been used already
  */
 struct bootstd_priv {
 	const char **prefixes;
@@ -45,6 +47,7 @@ struct bootstd_priv {
 	struct udevice **bootmeth_order;
 	struct udevice *vbe_bootmeth;
 	ofnode theme;
+	uint hunters_used;
 };
 
 /**
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c
index 1c2a79fb108..a8ca12a3c8f 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -221,3 +221,55 @@ static int bootdev_test_prio(struct unit_test_state *uts)
 	return 0;
 }
 BOOTSTD_TEST(bootdev_test_prio, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
+
+/* Check listing hunters */
+static int bootdev_test_hunter(struct unit_test_state *uts)
+{
+	struct bootstd_priv *std;
+
+	/* get access to the used hunters */
+	ut_assertok(bootstd_get_priv(&std));
+
+	console_record_reset_enable();
+	bootdev_list_hunters(std);
+	ut_assert_nextline("Prio  Used  Uclass           Hunter");
+	ut_assert_nextlinen("----");
+	ut_assert_nextline("(total hunters: 0)");
+	ut_assert_console_end();
+
+	return 0;
+}
+BOOTSTD_TEST(bootdev_test_hunter, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
+
+/* Check 'bootdev hunt' command */
+static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
+{
+	struct bootstd_priv *std;
+
+	/* get access to the used hunters */
+	ut_assertok(bootstd_get_priv(&std));
+
+	console_record_reset_enable();
+	ut_assertok(run_command("bootdev hunt -l", 0));
+	ut_assert_nextline("Prio  Used  Uclass           Hunter");
+	ut_assert_nextlinen("----");
+	ut_assert_nextline("(total hunters: 0)");
+	ut_assert_console_end();
+
+	/* Scan all hunters */
+	ut_assertok(run_command("bootdev hunt", 0));
+	ut_assert_console_end();
+
+	/* List available hunters */
+	ut_assertok(run_command("bootdev hunt -l", 0));
+	ut_assert_nextlinen("Prio");
+	ut_assert_nextlinen("----");
+	ut_assert_nextline("(total hunters: 0)");
+	ut_assert_console_end();
+
+	ut_asserteq(0, std->hunters_used);
+
+	return 0;
+}
+BOOTSTD_TEST(bootdev_test_cmd_hunt, UT_TESTF_DM | UT_TESTF_SCAN_FDT |
+	     UT_TESTF_ETH_BOOTDEV);
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 24/71] bootstd: Support running bootdev hunters
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (22 preceding siblings ...)
  2023-01-08  2:49 ` [PATCH v2 23/71] bootstd: Add the concept of a bootdev hunter Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 25/71] dm: usb: Drop some dead code Simon Glass
                   ` (47 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

Add a way to run a bootdev hunter to find bootdevs of a certain type. Add
this to the 'bootdev hunt' command. Test for this are added in a later
patch, since a useful test needs some hunters to work with.

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

(no changes since v1)

 boot/bootdev-uclass.c | 61 +++++++++++++++++++++++++++++++++++++++++++
 cmd/bootdev.c         |  7 ++++-
 include/bootdev.h     | 14 ++++++++++
 test/boot/bootdev.c   |  3 +++
 4 files changed, 84 insertions(+), 1 deletion(-)

diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c
index 62eb0b617cd..081b94ce332 100644
--- a/boot/bootdev-uclass.c
+++ b/boot/bootdev-uclass.c
@@ -636,6 +636,67 @@ int bootdev_setup_iter_order(struct bootflow_iter *iter, struct udevice **devp)
 	return 0;
 }
 
+static int bootdev_hunt_drv(struct bootdev_hunter *info, uint seq, bool show)
+{
+	const char *name = uclass_get_name(info->uclass);
+	struct bootstd_priv *std;
+	int ret;
+
+	ret = bootstd_get_priv(&std);
+	if (ret)
+		return log_msg_ret("std", ret);
+
+	if (!(std->hunters_used & BIT(seq))) {
+		if (show)
+			printf("Hunting with: %s\n",
+			       uclass_get_name(info->uclass));
+		log_debug("Hunting with: %s\n", name);
+		if (info->hunt) {
+			ret = info->hunt(info, show);
+			if (ret)
+				return ret;
+		}
+		std->hunters_used |= BIT(seq);
+	}
+
+	return 0;
+}
+
+int bootdev_hunt(const char *spec, bool show)
+{
+	struct bootdev_hunter *start;
+	const char *end;
+	int n_ent, i;
+	int result;
+	size_t len;
+
+	start = ll_entry_start(struct bootdev_hunter, bootdev_hunter);
+	n_ent = ll_entry_count(struct bootdev_hunter, bootdev_hunter);
+	result = 0;
+
+	len = SIZE_MAX;
+	if (spec) {
+		trailing_strtoln_end(spec, NULL, &end);
+		len = end - spec;
+	}
+
+	for (i = 0; i < n_ent; i++) {
+		struct bootdev_hunter *info = start + i;
+		const char *name = uclass_get_name(info->uclass);
+		int ret;
+
+		log_debug("looking at %.*s for %s\n",
+			  (int)max(strlen(name), len), spec, name);
+		if (spec && strncmp(spec, name, max(strlen(name), len)))
+			continue;
+		ret = bootdev_hunt_drv(info, i, show);
+		if (ret)
+			result = ret;
+	}
+
+	return result;
+}
+
 void bootdev_list_hunters(struct bootstd_priv *std)
 {
 	struct bootdev_hunter *orig, *start;
diff --git a/cmd/bootdev.c b/cmd/bootdev.c
index 80bfe2812e4..28866faac76 100644
--- a/cmd/bootdev.c
+++ b/cmd/bootdev.c
@@ -128,7 +128,12 @@ static int do_bootdev_hunt(struct cmd_tbl *cmdtp, int flag, int argc,
 	if (list) {
 		bootdev_list_hunters(priv);
 	} else {
-		/* TODO: implement hunting */
+		ret = bootdev_hunt(spec, true);
+		if (ret) {
+			printf("Failed (err=%dE)\n", ret);
+
+			return CMD_RET_FAILURE;
+		}
 	}
 
 	return 0;
diff --git a/include/bootdev.h b/include/bootdev.h
index cafb5285a28..deef7890489 100644
--- a/include/bootdev.h
+++ b/include/bootdev.h
@@ -263,6 +263,20 @@ int bootdev_setup_iter_order(struct bootflow_iter *iter, struct udevice **devp);
  */
 void bootdev_list_hunters(struct bootstd_priv *std);
 
+/**
+ * bootdev_hunt() - Hunt for bootdevs matching a particular spec
+ *
+ * This runs the selected hunter (or all if @spec is NULL) to try to find new
+ * bootdevs.
+ *
+ * @spec: Spec to match, e.g. "mmc0", or NULL for any. If provided, this must
+ * match a uclass name so that the hunter can be determined. Any trailing number
+ * is ignored
+ * @show: true to show each hunter before using it
+ * Returns: 0 if OK, -ve on error
+ */
+int bootdev_hunt(const char *spec, bool show);
+
 #if CONFIG_IS_ENABLED(BOOTSTD)
 /**
  * bootdev_setup_for_dev() - Bind a new bootdev device (deprecated)
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c
index a8ca12a3c8f..45a00c34c0c 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -237,6 +237,9 @@ static int bootdev_test_hunter(struct unit_test_state *uts)
 	ut_assert_nextline("(total hunters: 0)");
 	ut_assert_console_end();
 
+	ut_assertok(bootdev_hunt("mmc1", false));
+	ut_assert_console_end();
+
 	return 0;
 }
 BOOTSTD_TEST(bootdev_test_hunter, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 25/71] dm: usb: Drop some dead code
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (23 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 24/71] bootstd: Support running bootdev hunters Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 26/71] dm: usb: Mark the device name as alloced when binding Simon Glass
                   ` (46 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: U-Boot Custodians, Simon Glass, Marek Vasut, Pavel Herrmann

Since DM_USB migration is complete this code is not used any more. Drop
it.

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

(no changes since v1)

 drivers/usb/host/usb-uclass.c | 43 -----------------------------------
 1 file changed, 43 deletions(-)

diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c
index 060f3441df0..956e2a4e8e4 100644
--- a/drivers/usb/host/usb-uclass.c
+++ b/drivers/usb/host/usb-uclass.c
@@ -346,49 +346,6 @@ int usb_init(void)
 	return usb_started ? 0 : -1;
 }
 
-/*
- * TODO(sjg@chromium.org): Remove this legacy function. At present it is needed
- * to support boards which use driver model for USB but not Ethernet, and want
- * to use USB Ethernet.
- *
- * The #if clause is here to ensure that remains the only case.
- */
-#if !defined(CONFIG_DM_ETH) && defined(CONFIG_USB_HOST_ETHER)
-static struct usb_device *find_child_devnum(struct udevice *parent, int devnum)
-{
-	struct usb_device *udev;
-	struct udevice *dev;
-
-	if (!device_active(parent))
-		return NULL;
-	udev = dev_get_parent_priv(parent);
-	if (udev->devnum == devnum)
-		return udev;
-
-	for (device_find_first_child(parent, &dev);
-	     dev;
-	     device_find_next_child(&dev)) {
-		udev = find_child_devnum(dev, devnum);
-		if (udev)
-			return udev;
-	}
-
-	return NULL;
-}
-
-struct usb_device *usb_get_dev_index(struct udevice *bus, int index)
-{
-	struct udevice *dev;
-	int devnum = index + 1; /* Addresses are allocated from 1 on USB */
-
-	device_find_first_child(bus, &dev);
-	if (!dev)
-		return NULL;
-
-	return find_child_devnum(dev, devnum);
-}
-#endif
-
 int usb_setup_ehci_gadget(struct ehci_ctrl **ctlrp)
 {
 	struct usb_plat *plat;
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 26/71] dm: usb: Mark the device name as alloced when binding
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (24 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 25/71] dm: usb: Drop some dead code Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 27/71] test: Add a generic function to skip delays Simon Glass
                   ` (45 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: U-Boot Custodians, Simon Glass, Marek Vasut, Pavel Herrmann

Since usb_find_and_bind_driver() allocates the device name it should tell
driver about that, to avoid memory leaks. Fix this.

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

(no changes since v1)

 drivers/usb/host/usb-uclass.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c
index 956e2a4e8e4..04256eff879 100644
--- a/drivers/usb/host/usb-uclass.c
+++ b/drivers/usb/host/usb-uclass.c
@@ -559,6 +559,8 @@ static int usb_find_and_bind_driver(struct udevice *parent,
 	if (!str)
 		return -ENOMEM;
 	ret = device_bind_driver(parent, "usb_dev_generic_drv", str, devp);
+	if (!ret)
+		device_set_name_alloced(*devp);
 
 error:
 	debug("%s: No match found: %d\n", __func__, ret);
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 27/71] test: Add a generic function to skip delays
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (25 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 26/71] dm: usb: Mark the device name as alloced when binding Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 28/71] bootstd: Add a USB hunter Simon Glass
                   ` (44 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

At present this feature is sandbox-specific. For running tests on boards,
we need a nop version. Add one.

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

(no changes since v1)

 include/test/test.h | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/include/test/test.h b/include/test/test.h
index beabe9333dc..752897cf06f 100644
--- a/include/test/test.h
+++ b/include/test/test.h
@@ -170,6 +170,22 @@ static inline int test_load_other_fdt(struct unit_test_state *uts)
 	return ret;
 }
 
+/**
+ * Control skipping of time delays
+ *
+ * Some tests have unnecessay time delays (e.g. USB). Allow these to be
+ * skipped to speed up testing
+ *
+ * @param skip_delays	true to skip delays from now on, false to honour delay
+ *			requests
+ */
+static inline void test_set_skip_delays(bool skip_delays)
+{
+#ifdef CONFIG_SANDBOX
+	state_set_skip_delays(skip_delays);
+#endif
+}
+
 /**
  * test_set_eth_enable() - Enable / disable Ethernet
  *
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 28/71] bootstd: Add a USB hunter
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (26 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 27/71] test: Add a generic function to skip delays Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 29/71] bootstd: Add an MMC hunter Simon Glass
                   ` (43 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

Add a hunter for USB which enumerates the bus to find new bootdevs.

Update the tests and speed up bootdev_test_prio() while we are here, by
dropping the USB delays.

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

(no changes since v1)

 drivers/usb/host/usb_bootdev.c | 12 ++++++++++++
 test/boot/bootdev.c            | 26 +++++++++++++++++++++-----
 2 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/host/usb_bootdev.c b/drivers/usb/host/usb_bootdev.c
index b2d157faf33..66d0b6ae8f5 100644
--- a/drivers/usb/host/usb_bootdev.c
+++ b/drivers/usb/host/usb_bootdev.c
@@ -20,6 +20,11 @@ static int usb_bootdev_bind(struct udevice *dev)
 	return 0;
 }
 
+static int usb_bootdev_hunt(struct bootdev_hunter *info, bool show)
+{
+	return usb_init();
+}
+
 struct bootdev_ops usb_bootdev_ops = {
 };
 
@@ -35,3 +40,10 @@ U_BOOT_DRIVER(usb_bootdev) = {
 	.bind		= usb_bootdev_bind,
 	.of_match	= usb_bootdev_ids,
 };
+
+BOOTDEV_HUNTER(usb_bootdev_hunter) = {
+	.prio		= BOOTDEVP_3_SCAN_SLOW,
+	.uclass		= UCLASS_USB,
+	.hunt		= usb_bootdev_hunt,
+	.drv		= DM_DRIVER_REF(usb_bootdev),
+};
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c
index 45a00c34c0c..7a0c5793890 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -190,6 +190,8 @@ static int bootdev_test_prio(struct unit_test_state *uts)
 	struct bootflow bflow;
 	struct udevice *blk;
 
+	test_set_skip_delays(true);
+
 	/* Start up USB which gives us three additional bootdevs */
 	usb_started = false;
 	ut_assertok(run_command("usb start", 0));
@@ -227,6 +229,8 @@ static int bootdev_test_hunter(struct unit_test_state *uts)
 {
 	struct bootstd_priv *std;
 
+	test_set_skip_delays(true);
+
 	/* get access to the used hunters */
 	ut_assertok(bootstd_get_priv(&std));
 
@@ -234,12 +238,17 @@ static int bootdev_test_hunter(struct unit_test_state *uts)
 	bootdev_list_hunters(std);
 	ut_assert_nextline("Prio  Used  Uclass           Hunter");
 	ut_assert_nextlinen("----");
-	ut_assert_nextline("(total hunters: 0)");
+	ut_assert_nextline("  40        usb              usb_bootdev");
+	ut_assert_nextline("(total hunters: 1)");
 	ut_assert_console_end();
 
-	ut_assertok(bootdev_hunt("mmc1", false));
+	ut_assertok(bootdev_hunt("usb1", false));
+	ut_assert_nextline(
+		"Bus usb@1: scanning bus usb@1 for devices... 5 USB Device(s) found");
 	ut_assert_console_end();
 
+	ut_asserteq(GENMASK(0, 0), std->hunters_used);
+
 	return 0;
 }
 BOOTSTD_TEST(bootdev_test_hunter, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
@@ -249,6 +258,8 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
 {
 	struct bootstd_priv *std;
 
+	test_set_skip_delays(true);
+
 	/* get access to the used hunters */
 	ut_assertok(bootstd_get_priv(&std));
 
@@ -256,21 +267,26 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
 	ut_assertok(run_command("bootdev hunt -l", 0));
 	ut_assert_nextline("Prio  Used  Uclass           Hunter");
 	ut_assert_nextlinen("----");
-	ut_assert_nextline("(total hunters: 0)");
+	ut_assert_nextline("  40        usb              usb_bootdev");
+	ut_assert_nextline("(total hunters: 1)");
 	ut_assert_console_end();
 
 	/* Scan all hunters */
 	ut_assertok(run_command("bootdev hunt", 0));
+	ut_assert_nextline("Hunting with: usb");
+	ut_assert_nextline(
+		"Bus usb@1: scanning bus usb@1 for devices... 5 USB Device(s) found");
 	ut_assert_console_end();
 
 	/* List available hunters */
 	ut_assertok(run_command("bootdev hunt -l", 0));
 	ut_assert_nextlinen("Prio");
 	ut_assert_nextlinen("----");
-	ut_assert_nextline("(total hunters: 0)");
+	ut_assert_nextline("  40     *  usb              usb_bootdev");
+	ut_assert_nextline("(total hunters: 1)");
 	ut_assert_console_end();
 
-	ut_asserteq(0, std->hunters_used);
+	ut_asserteq(GENMASK(0, 0), std->hunters_used);
 
 	return 0;
 }
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 29/71] bootstd: Add an MMC hunter
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (27 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 28/71] bootstd: Add a USB hunter Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 30/71] net: Add a function to run dhcp Simon Glass
                   ` (42 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

Add a hunter for MMC. This doesn't do anything at present, since MMC is
currently set up when U-Boot starts. If MMC moves to lazy init then we can
add a hunter function.

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

(no changes since v1)

 drivers/mmc/mmc_bootdev.c |  6 ++++++
 test/boot/bootdev.c       | 16 ++++++++++------
 2 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/mmc_bootdev.c b/drivers/mmc/mmc_bootdev.c
index 037b67bc0ff..300208f0c71 100644
--- a/drivers/mmc/mmc_bootdev.c
+++ b/drivers/mmc/mmc_bootdev.c
@@ -35,3 +35,9 @@ U_BOOT_DRIVER(mmc_bootdev) = {
 	.bind		= mmc_bootdev_bind,
 	.of_match	= mmc_bootdev_ids,
 };
+
+BOOTDEV_HUNTER(mmc_bootdev_hunter) = {
+	.prio		= BOOTDEVP_0_INTERNAL_FAST,
+	.uclass		= UCLASS_MMC,
+	.drv		= DM_DRIVER_REF(mmc_bootdev),
+};
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c
index 7a0c5793890..78cb0ac628a 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -238,8 +238,9 @@ static int bootdev_test_hunter(struct unit_test_state *uts)
 	bootdev_list_hunters(std);
 	ut_assert_nextline("Prio  Used  Uclass           Hunter");
 	ut_assert_nextlinen("----");
+	ut_assert_nextline("  10        mmc              mmc_bootdev");
 	ut_assert_nextline("  40        usb              usb_bootdev");
-	ut_assert_nextline("(total hunters: 1)");
+	ut_assert_nextline("(total hunters: 2)");
 	ut_assert_console_end();
 
 	ut_assertok(bootdev_hunt("usb1", false));
@@ -247,7 +248,8 @@ static int bootdev_test_hunter(struct unit_test_state *uts)
 		"Bus usb@1: scanning bus usb@1 for devices... 5 USB Device(s) found");
 	ut_assert_console_end();
 
-	ut_asserteq(GENMASK(0, 0), std->hunters_used);
+	/* USB is second in the list, so bit 1 */
+	ut_asserteq(BIT(1), std->hunters_used);
 
 	return 0;
 }
@@ -267,12 +269,12 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
 	ut_assertok(run_command("bootdev hunt -l", 0));
 	ut_assert_nextline("Prio  Used  Uclass           Hunter");
 	ut_assert_nextlinen("----");
-	ut_assert_nextline("  40        usb              usb_bootdev");
-	ut_assert_nextline("(total hunters: 1)");
+	ut_assert_skip_to_line("(total hunters: 2)");
 	ut_assert_console_end();
 
 	/* Scan all hunters */
 	ut_assertok(run_command("bootdev hunt", 0));
+	ut_assert_nextline("Hunting with: mmc");
 	ut_assert_nextline("Hunting with: usb");
 	ut_assert_nextline(
 		"Bus usb@1: scanning bus usb@1 for devices... 5 USB Device(s) found");
@@ -282,11 +284,13 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
 	ut_assertok(run_command("bootdev hunt -l", 0));
 	ut_assert_nextlinen("Prio");
 	ut_assert_nextlinen("----");
+	ut_assert_nextline("  10     *  mmc              mmc_bootdev");
 	ut_assert_nextline("  40     *  usb              usb_bootdev");
-	ut_assert_nextline("(total hunters: 1)");
+
+	ut_assert_nextline("(total hunters: 2)");
 	ut_assert_console_end();
 
-	ut_asserteq(GENMASK(0, 0), std->hunters_used);
+	ut_asserteq(GENMASK(1, 0), std->hunters_used);
 
 	return 0;
 }
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 30/71] net: Add a function to run dhcp
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (28 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 29/71] bootstd: Add an MMC hunter Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-10 17:03   ` Ramon Fried
  2023-01-08  2:50 ` [PATCH v2 31/71] bootstd: Add a hunter for ethernet Simon Glass
                   ` (41 subsequent siblings)
  71 siblings, 1 reply; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass, Joe Hershberger

At present this must be done by executing the command. Also it involves
fiddling with the environment to determine the correct autoload behaviour.

Ideally it should be possible to run network operations without even
having the command line present (CONFIG_CMDLINE).

For now, add a function to handle DHCP, so it can be called from a bootdev
more easily.

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

(no changes since v1)

 cmd/net.c     | 35 +++++++++++++++++++++++++++++++++++
 include/net.h | 15 +++++++++++++++
 2 files changed, 50 insertions(+)

diff --git a/cmd/net.c b/cmd/net.c
index 0e9f200ca97..6b3774bfe7c 100644
--- a/cmd/net.c
+++ b/cmd/net.c
@@ -4,6 +4,8 @@
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  */
 
+#define LOG_CATEGORY	UCLASS_ETH
+
 /*
  * Boot support
  */
@@ -13,6 +15,7 @@
 #include <dm.h>
 #include <env.h>
 #include <image.h>
+#include <log.h>
 #include <net.h>
 #include <net6.h>
 #include <net/udp.h>
@@ -120,6 +123,38 @@ U_BOOT_CMD(
 	"boot image via network using DHCP/TFTP protocol",
 	"[loadAddress] [[hostIPaddr:]bootfilename]"
 );
+
+int dhcp_run(ulong addr, const char *fname, bool autoload)
+{
+	char *dhcp_argv[] = {"dhcp", NULL, (char *)fname, NULL};
+	struct cmd_tbl cmdtp = {};	/* dummy */
+	char file_addr[17];
+	int old_autoload;
+	int ret, result;
+
+	log_debug("addr=%lx, fname=%s, autoload=%d\n", addr, fname, autoload);
+	old_autoload = env_get_yesno("autoload");
+	ret = env_set("autoload", autoload ? "y" : "n");
+	if (ret)
+		return log_msg_ret("en1", -EINVAL);
+
+	if (autoload) {
+		sprintf(file_addr, "%lx", addr);
+		dhcp_argv[1] = file_addr;
+	}
+
+	result = do_dhcp(&cmdtp, 0, !autoload ? 1 : fname ? 3 : 2, dhcp_argv);
+
+	ret = env_set("autoload", old_autoload == -1 ? NULL :
+		      old_autoload ? "y" : "n");
+	if (ret)
+		return log_msg_ret("en2", -EINVAL);
+
+	if (result)
+		return log_msg_ret("res", -ENOENT);
+
+	return 0;
+}
 #endif
 
 #if defined(CONFIG_CMD_NFS)
diff --git a/include/net.h b/include/net.h
index 749f20fa967..c296d06c266 100644
--- a/include/net.h
+++ b/include/net.h
@@ -65,6 +65,21 @@ struct in_addr {
  */
 int do_tftpb(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 
+/**
+ * dhcp_run() - Run DHCP on the current ethernet device
+ *
+ * This sets the autoload variable, then puts it back to similar to its original
+ * state (y, n or unset).
+ *
+ * @addr: Address to load the file into (0 if @autoload is false)
+ * @fname: Filename of file to load (NULL if @autoload is false or to use the
+ * default filename)
+ * @autoload: true to load the file, false to just get the network IP
+ * @return 0 if OK, -EINVAL if the environment failed, -ENOENT if ant file was
+ * not found
+ */
+int dhcp_run(ulong addr, const char *fname, bool autoload);
+
 /**
  * An incoming packet handler.
  * @param pkt    pointer to the application packet
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 31/71] bootstd: Add a hunter for ethernet
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (29 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 30/71] net: Add a function to run dhcp Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 32/71] part: Add a function to find the first bootable partition Simon Glass
                   ` (40 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

Sometimes ethernet devices are attached to PCI. Since it is quick to scan,
add this into the ethernet hunter.

Run dhcp to establish the network connection. Drop this from the bootdev
since that is not needed now. Update a log message for clarity.

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

(no changes since v1)

 net/eth_bootdev.c   | 64 +++++++++++++++++++++++++++++----------------
 test/boot/bootdev.c | 17 +++++++-----
 2 files changed, 52 insertions(+), 29 deletions(-)

diff --git a/net/eth_bootdev.c b/net/eth_bootdev.c
index b735966d2bc..fdf48f00131 100644
--- a/net/eth_bootdev.c
+++ b/net/eth_bootdev.c
@@ -6,6 +6,8 @@
  * Written by Simon Glass <sjg@chromium.org>
  */
 
+#define LOG_CATEGORY UCLASS_BOOTSTD
+
 #include <common.h>
 #include <bootdev.h>
 #include <bootflow.h>
@@ -13,8 +15,10 @@
 #include <bootmeth.h>
 #include <distro.h>
 #include <dm.h>
+#include <init.h>
 #include <log.h>
 #include <net.h>
+#include <test/test.h>
 
 static int eth_get_bootflow(struct udevice *dev, struct bootflow_iter *iter,
 			    struct bootflow *bflow)
@@ -41,30 +45,8 @@ static int eth_get_bootflow(struct udevice *dev, struct bootflow_iter *iter,
 	if (!bflow->name)
 		return log_msg_ret("name", -ENOMEM);
 
-	/*
-	 * There is not a direct interface to the network stack so run
-	 * everything through the command-line interpreter for now.
-	 *
-	 * Don't bother checking the result of dhcp. It can fail with:
-	 *
-	 * DHCP client bound to address 192.168.4.50 (4 ms)
-	 * *** Warning: no boot file name; using 'C0A80432.img'
-	 * Using smsc95xx_eth device
-	 * TFTP from server 192.168.4.1; our IP address is 192.168.4.50
-	 * Filename 'C0A80432.img'.
-	 * Load address: 0x200000
-	 * Loading: *
-	 * TFTP error: 'File not found' (1)
-	 *
-	 * This is not a real failure, since we don't actually care if the
-	 * boot file exists.
-	 */
-	log_debug("running dhcp\n");
-	run_command("dhcp", 0);
-	bflow->state = BOOTFLOWST_MEDIA;
-
 	/* See distro_pxe_read_bootflow() for the standard impl of this */
-	log_debug("dhcp complete - reading bootflow with method %s\n",
+	log_debug("dhcp complete - reading bootflow with method '%s'\n",
 		  bflow->method->name);
 	ret = bootmeth_read_bootflow(bflow->method, bflow);
 	log_debug("reading bootflow returned %d\n", ret);
@@ -83,6 +65,35 @@ static int eth_bootdev_bind(struct udevice *dev)
 	return 0;
 }
 
+static int eth_bootdev_hunt(struct bootdev_hunter *info, bool show)
+{
+	int ret;
+
+	if (!test_eth_enabled())
+		return 0;
+
+	/* init PCI first since this is often used to provide Ehternet */
+	if (IS_ENABLED(CONFIG_PCI)) {
+		ret = pci_init();
+		if (ret)
+			log_warning("Failed to init PCI (%dE)\n", ret);
+	}
+
+	/*
+	 * Ethernet devices can also come from USB, but that is a higher
+	 * priority (BOOTDEVP_5_SCAN_SLOW) than ethernet, so it should have been
+	 * enumerated already. If something like 'bootflow scan dhcp' is used
+	 * then the user will need to run 'usb start' first.
+	 */
+	if (IS_ENABLED(CONFIG_CMD_DHCP)) {
+		ret = dhcp_run(0, NULL, false);
+		if (ret)
+			return -EINVAL;
+	}
+
+	return 0;
+}
+
 struct bootdev_ops eth_bootdev_ops = {
 	.get_bootflow	= eth_get_bootflow,
 };
@@ -99,3 +110,10 @@ U_BOOT_DRIVER(eth_bootdev) = {
 	.bind		= eth_bootdev_bind,
 	.of_match	= eth_bootdev_ids,
 };
+
+BOOTDEV_HUNTER(eth_bootdev_hunt) = {
+	.prio		= BOOTDEVP_4_NET_BASE,
+	.uclass		= UCLASS_ETH,
+	.hunt		= eth_bootdev_hunt,
+	.drv		= DM_DRIVER_REF(eth_bootdev),
+};
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c
index 78cb0ac628a..32a31c44609 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -238,9 +238,10 @@ static int bootdev_test_hunter(struct unit_test_state *uts)
 	bootdev_list_hunters(std);
 	ut_assert_nextline("Prio  Used  Uclass           Hunter");
 	ut_assert_nextlinen("----");
+	ut_assert_nextline("  50        ethernet         eth_bootdev");
 	ut_assert_nextline("  10        mmc              mmc_bootdev");
 	ut_assert_nextline("  40        usb              usb_bootdev");
-	ut_assert_nextline("(total hunters: 2)");
+	ut_assert_nextline("(total hunters: 3)");
 	ut_assert_console_end();
 
 	ut_assertok(bootdev_hunt("usb1", false));
@@ -248,8 +249,8 @@ static int bootdev_test_hunter(struct unit_test_state *uts)
 		"Bus usb@1: scanning bus usb@1 for devices... 5 USB Device(s) found");
 	ut_assert_console_end();
 
-	/* USB is second in the list, so bit 1 */
-	ut_asserteq(BIT(1), std->hunters_used);
+	/* USB is third in the list, so bit 2 */
+	ut_asserteq(BIT(2), std->hunters_used);
 
 	return 0;
 }
@@ -269,11 +270,14 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
 	ut_assertok(run_command("bootdev hunt -l", 0));
 	ut_assert_nextline("Prio  Used  Uclass           Hunter");
 	ut_assert_nextlinen("----");
-	ut_assert_skip_to_line("(total hunters: 2)");
+	ut_assert_skip_to_line("(total hunters: 3)");
 	ut_assert_console_end();
 
 	/* Scan all hunters */
+	sandbox_set_eth_enable(false);
+
 	ut_assertok(run_command("bootdev hunt", 0));
+	ut_assert_nextline("Hunting with: ethernet");
 	ut_assert_nextline("Hunting with: mmc");
 	ut_assert_nextline("Hunting with: usb");
 	ut_assert_nextline(
@@ -284,13 +288,14 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
 	ut_assertok(run_command("bootdev hunt -l", 0));
 	ut_assert_nextlinen("Prio");
 	ut_assert_nextlinen("----");
+	ut_assert_nextline("  50     *  ethernet         eth_bootdev");
 	ut_assert_nextline("  10     *  mmc              mmc_bootdev");
 	ut_assert_nextline("  40     *  usb              usb_bootdev");
 
-	ut_assert_nextline("(total hunters: 2)");
+	ut_assert_nextline("(total hunters: 3)");
 	ut_assert_console_end();
 
-	ut_asserteq(GENMASK(1, 0), std->hunters_used);
+	ut_asserteq(GENMASK(2, 0), std->hunters_used);
 
 	return 0;
 }
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 32/71] part: Add a function to find the first bootable partition
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (30 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 31/71] bootstd: Add a hunter for ethernet Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 33/71] bootstd: Only scan bootable partitions Simon Glass
                   ` (39 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

If a disk has a bootable partition we are expected to use it to locate the
boot files. Add a function to find it.

To test this, update mmc1 to have two paritions, fixing up other tests
accordingly.

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

(no changes since v1)

 disk/part.c                       |  16 ++++++++++++++++
 include/part.h                    |   8 ++++++++
 test/boot/bootflow.c              |   6 +++---
 test/dm/part.c                    |  13 +++++++++++++
 test/py/tests/bootstd/mmc1.img.xz | Bin 4448 -> 4480 bytes
 test/py/tests/test_ut.py          |  13 +++++++++----
 6 files changed, 49 insertions(+), 7 deletions(-)

diff --git a/disk/part.c b/disk/part.c
index 5ee60a7fb59..d449635254e 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -770,3 +770,19 @@ void part_set_generic_name(const struct blk_desc *dev_desc,
 
 	sprintf(name, "%s%c%d", devtype, 'a' + dev_desc->devnum, part_num);
 }
+
+int part_get_bootable(struct blk_desc *desc)
+{
+	struct disk_partition info;
+	int p;
+
+	for (p = 1; p <= MAX_SEARCH_PARTITIONS; p++) {
+		int ret;
+
+		ret = part_get_info(desc, p, &info);
+		if (!ret && info.bootable)
+			return p;
+	}
+
+	return 0;
+}
diff --git a/include/part.h b/include/part.h
index 807370d9429..be75c735495 100644
--- a/include/part.h
+++ b/include/part.h
@@ -303,6 +303,14 @@ part_get_info_by_dev_and_name_or_num(const char *dev_iface,
 }
 #endif
 
+/**
+ * part_get_bootable() - Find the first bootable partition
+ *
+ * @desc: Block-device descriptor
+ * @return first bootable partition, or 0 if there is none
+ */
+int part_get_bootable(struct blk_desc *desc);
+
 struct udevice;
 /**
  * part_create_block_devices - Create block devices for disk partitions
diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c
index 12976005e41..38ffe8fa9be 100644
--- a/test/boot/bootflow.c
+++ b/test/boot/bootflow.c
@@ -315,15 +315,15 @@ static int bootflow_iter(struct unit_test_state *uts)
 	ut_asserteq(BOOTFLOWST_FS, bflow.state);
 	bootflow_free(&bflow);
 
-	/* Then more to partition 2 which doesn't exist */
-	ut_asserteq(-ENOENT, bootflow_scan_next(&iter, &bflow));
+	/* Then more to partition 2 which exists but is not bootable */
+	ut_asserteq(-EPERM, bootflow_scan_next(&iter, &bflow));
 	ut_asserteq(2, iter.num_methods);
 	ut_asserteq(0, iter.cur_method);
 	ut_asserteq(2, iter.part);
 	ut_asserteq(0x1e, iter.max_part);
 	ut_asserteq_str("syslinux", iter.method->name);
 	ut_asserteq(0, bflow.err);
-	ut_asserteq(BOOTFLOWST_MEDIA, bflow.state);
+	ut_asserteq(BOOTFLOWST_PART, bflow.state);
 	bootflow_free(&bflow);
 
 	bootflow_iter_uninit(&iter);
diff --git a/test/dm/part.c b/test/dm/part.c
index b60687114f1..35e99eeb01a 100644
--- a/test/dm/part.c
+++ b/test/dm/part.c
@@ -93,3 +93,16 @@ static int dm_test_part(struct unit_test_state *uts)
 	return ret;
 }
 DM_TEST(dm_test_part, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+
+static int dm_test_part_bootable(struct unit_test_state *uts)
+{
+	struct blk_desc *desc;
+	struct udevice *dev;
+
+	ut_assertok(uclass_get_device_by_name(UCLASS_BLK, "mmc1.blk", &dev));
+	desc = dev_get_uclass_plat(dev);
+	ut_asserteq(1, part_get_bootable(desc));
+
+	return 0;
+}
+DM_TEST(dm_test_part_bootable, UT_TESTF_SCAN_FDT);
diff --git a/test/py/tests/bootstd/mmc1.img.xz b/test/py/tests/bootstd/mmc1.img.xz
index 4e7f39b830eb4bddcb9ff6df39e89f130b5706b9..cebf7b9c53b3ed2370dbc65f0d26dd9bf096fab8 100644
GIT binary patch
delta 1655
zcmV--28j9KB7h@*{Wp48S^xk9=GL@E0stWa8~^|S5YJf5|NmMBd|dzlZ~gpA<{Uz|
zzgb+hQv3zT1yKgH@;2zWF3PJ~6cavY@U&ANJ0gCP@g^CK!(rj@H-&MG2+zt#VrMq1
z-bKm%b2F*>ab%+I**3@5=eRQUvo=zPEG1lh0FMJM7*2m;f5_u>M)rb8W}+Uqf+ks)
z_#_Lj9#uBA9K(VBR-_^mmJcn)WfTd{;~te;2sbZTUWEL8Ce`b-Jt10-wlVDTu17Rv
z4VaVs=u)K>0j21p2`cQW|5_%jats!dr@lFlB;k`$3txXy+a#DV!4|8tN&)+Lh{XiP
zVol6p;1;M=YgT!hV3^xhq6kT^pvtCdcsw##ssXd#S4+B)%GmE^iJuWCu6oZ}pJD9s
z`5K;^&Q>pwgZ@W#?<Ar+4>43SjFfDh&0r#>&hl5~mNbUgZ8U1#x{hSCvZikVj<Ab&
zbCz7PQ*nReV8Up!azo-eA!KemoFEGODQW6jTa`gICYLDmA@i8-1_wn>1k;>{8^d^7
zLg>&U@uq9E$6xZvh&l$FOl?xq{b&{NB=g?qmeFk5cgCCIZ?CrYEJ-LLMpd6h)hC=q
zzRSVQ!8553c{1arJOgZG`#wznKO7b7FMmwg$LxREB*TT&O>G`dqd^Ih93Z#d-K*=)
zB)cm55`*cT+@1Ydj{@IW@FEnmg>)#(gV4|lVc9LZ64Ot3r`x`b9TwuPQS117K6VKm
zl4s4)`kLs1X<z^ogIa#)ROp|?#lGd;UypSU)1^a@UmRdq(1>`71Z@E(8n)q_&iJAu
zxrcxBv2_h4N#VeAIVRirRLy0xDeR^;;Vt?=n$Td*Al4sMA_xLBPMEI_h7m8eKcl<M
z{|upLU8vxj)k6=(dq8(Euht38iCG*3$4MQ3K{Ui{za9MDk_C>nG!mg*6f3@RV!!Dy
zYU+!M?V<y8_f~8MZ)Yn)OFlq2ta~XZ@lJo<c~1HE8S<{2f^$;~<VJe^w6%mOI8y*^
zo<kVZU(F{4b@4G<9saho^b+e(PK{anN!YrSS{?-WmHF+h5FZk5_y$|D{K2pF@4hd<
zm3NXpLh8E=J}Xo?Sxt?J9iaz>T~mD+f6->%5e(H(O~9j2-0lS3Zz)dxe0S#EnU;TS
z1+1Ngg5l(_;}Gf<HpOLNNMV(1KgvJwuQCtVC>W7P-o32Rt7w0p$R@00nGCgd@1H>W
z>mvvhif|1nW{sZiRe4N<^SQN<<#+#?0AH6Dij6NKGjqrw3#H*wc1Om*DX%Y_j=q%{
zXCpEp3>^z@l5blk3EN&soj}hZr(J*5Kyt+`<ueH37$m*7UT62oA2gzw^cKPvg$3`d
z>2QqO39ZhCv?^TkQZF(NvEooQvZb5Y<iqIG9ZZPiuMu>Q2_Ok;$%a*I2t@M5()&$Q
zuV=`l72@)HIyule&bL9;-q&H&xA3Xxc|8DS`hJ-e^zB)(=ryl3L>8eKYJh+Ke!cK(
zwmHfOzQ8A%A?^JQAX0xp!To?PeLc@XvxgAG7QpKBDB5$%SMwfIwI>kGz&<(}KCq79
z_uig^In$u^bS?|I(*e!CouC=N%slEv86cwifl_Dsu3QefK_gtT&7j@j63>@_2q)R4
zrZV2K-w`h{0z<J3Cd(N;$*6y&y`piW(sI>YK~I_WYrIP0<ACL2sjTK`R~zIY$%{DZ
z0`tLhD+3xi49C-Im-e&t04juSaVzNf8xJ2by5oA0w>NLdKl+jI3O9iA8VaviOYeV(
zTKFljND&c=eUd343kD+Rb078iL#ms`<tQ`-xn<ZG!+QZns~8Wwr9^+`fZp?|160SU
zA_7uPQLXxkg{eW&3&r>bg7moAG7Pd;l?P40x+rM2QzGdz?dmEn*GYUkzwP^7jB&Wh
zfS-SG_@D&{8E!xr<E**sjws;Z0?GA7(s3|N_UNc4l2qEV5F8{5-#YxAMSRs=>xM!T
zJ!haq_%|(J-Rp9)<VG>}RPcy(EHK-`P*jm3mj(l0$#6Rqz%n<Or4<3C=%WcL?5h7-
zCaiJ{7LupFIgcdalTiyV1x$(G+xD^$F#)m=F#)m=F#)m=F#)m=F#)m=F#)m=F#)m=
zF#)m=G65?I3jhTG#f?^#n*c{~)fG7pq8I=H+#-O0fC>YslFG5fXZr#G00004Sz0zM
B8fpLl

delta 1580
zcmV+{2GjX~Bj6%`{Wp48S^xk9=GL@E0stWa761SMbT8$j|Nr9#SzQ1CZ~gp9mywT@
zX9SH~J$HQgn~xH8r*R%x@0<=h+lgT<_xrs-<w`xbRIw|E&$gheUrHepu{KmP1B)_~
zM8<xh5C?0oE?x{<-@`|Q`0vF~UZ=nbS6u7XQHW+SB;W8rb_fO2_8U;JWbdWX*Hr3S
zcy7{e*Ne)CKVLEX$WQ1KJ-6e4x+AFg28-GCf7T5fKYe$rgA^fd(banMJ`_`8lYbCT
zf8Z|5A>znV_419+K~}pr5i6t;;X5H=eceQvOcz_m&Of`5M?Jg<Tn2?0R!MXtuX*BF
z+4(C_$BiyXY&LRfHp@aTx>ubSFnsOe+W}JM1vca*@H`m~N2QSki3RrWs?u`efk)`Q
z1I4j(WS_wYySbVdeqbLrhyrft+P^Wzf571<6mAn+(ayStI^6-?9Fj{Gs}2-@F;yAl
zAQOk)7XLbruq4a2$s4F#dasOsO^R3gu)9P6O%UzUxh^V$sh<-dfsA}`+boMeRiGPY
zHb_fTFwNahDh<r6Eb+8J37g*;%p||ZZ5x=`YuX;ofY(C}ssHAEjO()c*|a}7f3vtr
zzdz&9*wuZW;{Hq+l2l*EtIE;DNjbR3z^+P$Z9%FO>gBW3n>8?}IRO(WSH}POQ<0wl
zF!z5*OIwmO-cwSxzreS*!N~4_jW?h<+JIB;zC;lmb+L<aG~E!0>P&V;{_Lr_1Kndj
zqC4_Y7L)_}b=<n;N5yRXC_inse|eiRAIt_yf4<PYBan@S9YsR?t@s{>v{EpiRcl{@
z(6s$?Vc$rX3-Bu2_dtb&zY9Uk?{0C)>TF*|z<yZ_PEMgaS5;bZ!26iM1R#x9D#2Mh
zT0gTSAb(^xcf|bw%gIYq$tlLV5E}4EAcj{`<|OI>{<P$=$&tE)Mf&wff601DZ-A;U
zZF{_;HK}x9>)b5M>QOyU2(e%>yohpf1>1(R#|F^Hc-17;yAyM~LkW#W2`CT75_U7J
zxojLkA%oKe7gYnM614d2W`i%suCVf(9QPuGO$GLNTPdH0EpA*&OIR~b2Pe~|1|4<k
z7!~U^Ot_B19!X-!Ek952e=(G*;-?ahy)9{>#c*3#T*fO7SGKF^YW7GpTbWD$R-k(a
zP`C~@itq8#G#Cb%4OWwphP_No3N9Voq<nNZGfaDMFtdKj<7GoqSxbelhYGjiBBOfW
zk{V9{cDtUBxVAy()2g1K65E%{vyy3ZXAb}_EfCGP?g}j>QpA$)fAzcK!YH%-PC0q)
zHc`?8x(xn~H?y)XqTn)90O>*@{&pI<cYrAf>95tQm6NY}2?gPsKGDD<4lc)Q;-uK&
zVRB7<Rqo8Y0Vp2&OqN>!Xz7-)wq(Y*`$x=Rkg26+lHFQf>(vzXE8oiK$7v@B;nPh!
zb5^(04D6|me}<(ne=-;Z8cFKLTNA**CxYb+d4!i%?T|pB7!QfT59)C$75dFOasor+
zrB5HUPWpVffF-(L69owH?ird#UnAH>E%?|nRP5f!k?8w3fe<1V|2OGJ9m;yqxw)m>
zHooGc=ROmb$F15b2C5~M%n1-@A$}(cds-s8=12K?Z3J<xfAbZ?K#=O<LnU6KRVK+?
z95hvl*1hk%*8aftJraq7u~tk0*f!SQ``IU0bc57?#lH7!od>JadoXCDN)@Dot{Yl<
zdq^?V9nxMDrw#2SM@Xeo;Gh1K0t`TUEtkL!x_NFC(EMPASHtlBC;wb<9CV}n5={?B
zq3451GV+&de{TMM-hczKl26E4EHe`3n&yWhCX?@KX`(lZlX0TZV?Zj5_|v|NqU@l7
zm;}ZS?8YON!pN()9pDTEVzXKJbDDG1gk8N?HvAmPpT|AQ-syX5hWnN{b>b=Ktj(Lo
zE@t+o7-y~t`5t!!)3~}CU2nmN3!7;VkF^<ERXO3k8lpZ{WqwHX&~#RVoCI#nz1irB
zt(PtTF6)|;a1d4mtO^=%v%w9M1GA6}#00aD3}ON=fCz#B1pvR!##;aY0000~`63&P
ec4B=10l6Z8fPf0>Hmj1c#Ao{g000001X)@WZu`Cf

diff --git a/test/py/tests/test_ut.py b/test/py/tests/test_ut.py
index 6958fabfa34..e8c8a6d6bd5 100644
--- a/test/py/tests/test_ut.py
+++ b/test/py/tests/test_ut.py
@@ -19,13 +19,14 @@ def mkdir_cond(dirname):
     if not os.path.exists(dirname):
         os.mkdir(dirname)
 
-def setup_image(cons, mmc_dev, part_type):
+def setup_image(cons, mmc_dev, part_type, second_part=False):
     """Create a 20MB disk image with a single partition
 
     Args:
         cons (ConsoleBase): Console to use
         mmc_dev (int): MMC device number to use, e.g. 1
         part_type (int): Partition type, e.g. 0xc for FAT32
+        second_part (bool): True to contain a small second partition
 
     Returns:
         tuple:
@@ -36,9 +37,13 @@ def setup_image(cons, mmc_dev, part_type):
     mnt = os.path.join(cons.config.persistent_data_dir, 'mnt')
     mkdir_cond(mnt)
 
+    spec = f'type={part_type:x}, size=18M, bootable'
+    if second_part:
+        spec += '\ntype=c'
+
     u_boot_utils.run_and_log(cons, 'qemu-img create %s 20M' % fname)
     u_boot_utils.run_and_log(cons, 'sudo sfdisk %s' % fname,
-                             stdin=f'type={part_type:x}'.encode('utf-8'))
+                             stdin=spec.encode('utf-8'))
     return fname, mnt
 
 def mount_image(cons, fname, mnt, fstype):
@@ -59,7 +64,7 @@ def mount_image(cons, fname, mnt, fstype):
     u_boot_utils.run_and_log(cons, f'sudo mkfs.{fstype} {part}')
     opts = ''
     if fstype == 'vfat':
-         opts += ' -o uid={os.getuid()},gid={os.getgid()}'
+         opts += f' -o uid={os.getuid()},gid={os.getgid()}'
     u_boot_utils.run_and_log(cons, f'sudo mount -o loop {part} {mnt}{opts}')
     u_boot_utils.run_and_log(cons, f'sudo chown {getpass.getuser()} {mnt}')
     return loop
@@ -218,7 +223,7 @@ booti ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r}
 def setup_bootflow_image(cons):
     """Create a 20MB disk image with a single FAT partition"""
     mmc_dev = 1
-    fname, mnt = setup_image(cons, mmc_dev, 0xc)
+    fname, mnt = setup_image(cons, mmc_dev, 0xc, second_part=True)
 
     loop = None
     mounted = False
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 33/71] bootstd: Only scan bootable partitions
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (31 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 32/71] part: Add a function to find the first bootable partition Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 34/71] scsi: Correct allocation of block-device name Simon Glass
                   ` (38 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

At present all partitions are scanned, whether marked bootable or not.
Use only bootable partitions, defaulting to partition 1 if none is
found.

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

(no changes since v1)

 boot/bootdev-uclass.c | 10 +++++++++-
 include/bootflow.h    |  2 ++
 test/boot/bootdev.c   | 37 +++++++++++++++++++++++++++++++++++++
 test/boot/bootflow.c  |  4 ++--
 4 files changed, 50 insertions(+), 3 deletions(-)

diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c
index 081b94ce332..3dcf317c150 100644
--- a/boot/bootdev-uclass.c
+++ b/boot/bootdev-uclass.c
@@ -163,7 +163,15 @@ int bootdev_find_in_blk(struct udevice *dev, struct udevice *blk,
 	 */
 	iter->max_part = MAX_PART_PER_BOOTDEV;
 
-	if (iter->part) {
+	/* If this is the whole disk, check if we have bootable partitions */
+	if (!iter->part) {
+		iter->first_bootable = part_get_bootable(desc);
+		log_debug("checking bootable=%d\n", iter->first_bootable);
+
+	/* if there are bootable partitions, scan only those */
+	} else if (iter->first_bootable ? !info.bootable : iter->part != 1) {
+		return log_msg_ret("boot", -EINVAL);
+	} else {
 		ret = fs_set_blk_dev_with_part(desc, bflow->part);
 		bflow->state = BOOTFLOWST_PART;
 
diff --git a/include/bootflow.h b/include/bootflow.h
index c201246c6de..3a93e4b5cab 100644
--- a/include/bootflow.h
+++ b/include/bootflow.h
@@ -123,6 +123,7 @@ enum bootflow_flags_t {
  * @method: Current bootmeth
  * @max_part: Maximum hardware partition number in @dev, 0 if there is no
  *	partition table
+ * @first_bootable: First bootable partition, or 0 if none
  * @err: Error obtained from checking the last iteration. This is used to skip
  *	forward (e.g. to skip the current partition because it is not valid)
  *	-ESHUTDOWN: try next bootdev
@@ -144,6 +145,7 @@ struct bootflow_iter {
 	int part;
 	struct udevice *method;
 	int max_part;
+	int first_bootable;
 	int err;
 	int num_devs;
 	int cur_dev;
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c
index 32a31c44609..db0e0ca20fa 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -301,3 +301,40 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
 }
 BOOTSTD_TEST(bootdev_test_cmd_hunt, UT_TESTF_DM | UT_TESTF_SCAN_FDT |
 	     UT_TESTF_ETH_BOOTDEV);
+
+/* Check that only bootable partitions are processed */
+static int bootdev_test_bootable(struct unit_test_state *uts)
+{
+	struct bootflow_iter iter;
+	struct bootflow bflow;
+	struct udevice *blk;
+
+	memset(&iter, '\0', sizeof(iter));
+	memset(&bflow, '\0', sizeof(bflow));
+	iter.part = 0;
+	ut_assertok(uclass_get_device_by_name(UCLASS_BLK, "mmc1.blk", &blk));
+	iter.dev = blk;
+	ut_assertok(device_find_next_child(&iter.dev));
+	uclass_first_device(UCLASS_BOOTMETH, &bflow.method);
+
+	/*
+	 * initially we don't have any knowledge of which partitions are
+	 * bootable, but mmc1 has two partitions, with the first one being
+	 * bootable
+	 */
+	iter.part = 2;
+	ut_asserteq(-EINVAL, bootdev_find_in_blk(iter.dev, blk, &iter, &bflow));
+	ut_asserteq(0, iter.first_bootable);
+
+	/* scan with part == 0 to get the partition info */
+	iter.part = 0;
+	ut_asserteq(-ENOENT, bootdev_find_in_blk(iter.dev, blk, &iter, &bflow));
+	ut_asserteq(1, iter.first_bootable);
+
+	/* now it will refuse to use non-bootable partitions */
+	iter.part = 2;
+	ut_asserteq(-EINVAL, bootdev_find_in_blk(iter.dev, blk, &iter, &bflow));
+
+	return 0;
+}
+BOOTSTD_TEST(bootdev_test_bootable, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c
index 38ffe8fa9be..f852b6e9b6f 100644
--- a/test/boot/bootflow.c
+++ b/test/boot/bootflow.c
@@ -316,14 +316,14 @@ static int bootflow_iter(struct unit_test_state *uts)
 	bootflow_free(&bflow);
 
 	/* Then more to partition 2 which exists but is not bootable */
-	ut_asserteq(-EPERM, bootflow_scan_next(&iter, &bflow));
+	ut_asserteq(-EINVAL, bootflow_scan_next(&iter, &bflow));
 	ut_asserteq(2, iter.num_methods);
 	ut_asserteq(0, iter.cur_method);
 	ut_asserteq(2, iter.part);
 	ut_asserteq(0x1e, iter.max_part);
 	ut_asserteq_str("syslinux", iter.method->name);
 	ut_asserteq(0, bflow.err);
-	ut_asserteq(BOOTFLOWST_PART, bflow.state);
+	ut_asserteq(BOOTFLOWST_MEDIA, bflow.state);
 	bootflow_free(&bflow);
 
 	bootflow_iter_uninit(&iter);
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 34/71] scsi: Correct allocation of block-device name
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (32 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 33/71] bootstd: Only scan bootable partitions Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 35/71] scsi: Remove all children of SCSI devices before rescanning Simon Glass
                   ` (37 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass, Rob Herring

This should be allocated so that it does not go out of scope. Fix this and
set the log category while we are here.

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

(no changes since v1)

 drivers/scsi/scsi.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 3e769b0843f..6419f4be210 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -4,6 +4,8 @@
  * Denis Peter, MPL AG Switzerland
  */
 
+#define LOG_CATEGORY	UCLASS_SCSI
+
 #include <common.h>
 #include <blk.h>
 #include <bootstage.h>
@@ -558,7 +560,7 @@ static int do_scsi_scan_one(struct udevice *dev, int id, int lun, bool verbose)
 	struct udevice *bdev;
 	struct blk_desc bd;
 	struct blk_desc *bdesc;
-	char str[10];
+	char str[10], *name;
 
 	/*
 	 * detect the scsi driver to get information about its geometry (block
@@ -574,12 +576,16 @@ static int do_scsi_scan_one(struct udevice *dev, int id, int lun, bool verbose)
 	* block devices created
 	*/
 	snprintf(str, sizeof(str), "id%dlun%d", id, lun);
-	ret = blk_create_devicef(dev, "scsi_blk", str, UCLASS_SCSI, -1,
+	name = strdup(str);
+	if (!name)
+		return log_msg_ret("nam", -ENOMEM);
+	ret = blk_create_devicef(dev, "scsi_blk", name, UCLASS_SCSI, -1,
 				 bd.blksz, bd.lba, &bdev);
 	if (ret) {
 		debug("Can't create device\n");
 		return ret;
 	}
+	device_set_name_alloced(bdev);
 
 	bdesc = dev_get_uclass_plat(bdev);
 	bdesc->target = id;
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 35/71] scsi: Remove all children of SCSI devices before rescanning
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (33 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 34/71] scsi: Correct allocation of block-device name Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 36/71] bootstd: Add a SCSI bootdev Simon Glass
                   ` (36 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass, Rob Herring

At present this only unbinds block devices of a certain type. But SCSI
device can have different types of children, including bootdevs.

Unbind all children so tht everything is clean and ready for a new scan.

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

(no changes since v1)

 drivers/scsi/scsi.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 6419f4be210..2ae96e171eb 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -644,12 +644,23 @@ int scsi_scan(bool verbose)
 	if (verbose)
 		printf("scanning bus for devices...\n");
 
-	blk_unbind_all(UCLASS_SCSI);
-
 	ret = uclass_get(UCLASS_SCSI, &uc);
 	if (ret)
 		return ret;
 
+	/* remove all children of the SCSI devices */
+	uclass_foreach_dev(dev, uc) {
+		log_debug("unbind %s\n", dev->name);
+		ret = device_chld_remove(dev, NULL, DM_REMOVE_NORMAL);
+		if (!ret)
+			ret = device_chld_unbind(dev, NULL);
+		if (ret) {
+			if (verbose)
+				printf("unable to unbind devices (%dE)\n", ret);
+			return log_msg_ret("unb", ret);
+		}
+	}
+
 	uclass_foreach_dev(dev, uc) {
 		ret = scsi_scan_dev(dev, verbose);
 		if (ret)
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 36/71] bootstd: Add a SCSI bootdev
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (34 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 35/71] scsi: Remove all children of SCSI devices before rescanning Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 37/71] bootstd: Add an IDE bootdev Simon Glass
                   ` (35 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

Add a bootdev for SCSI so that these devices can be used with standard
boot.

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

(no changes since v1)

 drivers/scsi/Makefile       |  7 +++++
 drivers/scsi/scsi.c         |  7 ++++-
 drivers/scsi/scsi_bootdev.c | 62 +++++++++++++++++++++++++++++++++++++
 test/boot/bootdev.c         | 18 ++++++-----
 4 files changed, 86 insertions(+), 8 deletions(-)
 create mode 100644 drivers/scsi/scsi_bootdev.c

diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index d1b40c61401..d8d6de59090 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -6,6 +6,13 @@
 ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_DM_SCSI) += scsi-uclass.o
 obj-$(CONFIG_SCSI) += scsi.o
+
+ifdef CONFIG_SCSI
+ifdef CONFIG_DM_SCSI
+obj-$(CONFIG_$(SPL_TPL_)BOOTSTD) += scsi_bootdev.o
+endif
+endif
+
 endif
 
 ifdef CONFIG_SPL_BUILD
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 2ae96e171eb..8d6af2a5068 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -8,6 +8,7 @@
 
 #include <common.h>
 #include <blk.h>
+#include <bootdev.h>
 #include <bootstage.h>
 #include <dm.h>
 #include <env.h>
@@ -604,7 +605,11 @@ static int do_scsi_scan_one(struct udevice *dev, int id, int lun, bool verbose)
 	ret = blk_probe_or_unbind(bdev);
 	if (ret < 0)
 		/* TODO: undo create */
-		return ret;
+		return log_msg_ret("pro", ret);
+
+	ret = bootdev_setup_sibling_blk(bdev, "scsi_bootdev");
+	if (ret)
+		return log_msg_ret("bd", ret);
 
 	if (verbose) {
 		printf("  Device %d: ", bdesc->devnum);
diff --git a/drivers/scsi/scsi_bootdev.c b/drivers/scsi/scsi_bootdev.c
new file mode 100644
index 00000000000..2367b33da9c
--- /dev/null
+++ b/drivers/scsi/scsi_bootdev.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Bootdevice for USB
+ *
+ * Copyright 2021 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <common.h>
+#include <bootdev.h>
+#include <dm.h>
+#include <init.h>
+#include <scsi.h>
+
+static int scsi_bootdev_bind(struct udevice *dev)
+{
+	struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
+
+	ucp->prio = BOOTDEVP_2_SCAN_FAST;
+
+	return 0;
+}
+
+static int scsi_bootdev_hunt(struct bootdev_hunter *info, bool show)
+{
+	int ret;
+
+	if (IS_ENABLED(CONFIG_PCI)) {
+		ret = pci_init();
+		if (ret)
+			return log_msg_ret("pci", ret);
+	}
+
+	ret = scsi_scan(true);
+	if (ret)
+		return log_msg_ret("scs", ret);
+
+	return 0;
+}
+
+struct bootdev_ops scsi_bootdev_ops = {
+};
+
+static const struct udevice_id scsi_bootdev_ids[] = {
+	{ .compatible = "u-boot,bootdev-scsi" },
+	{ }
+};
+
+U_BOOT_DRIVER(scsi_bootdev) = {
+	.name		= "scsi_bootdev",
+	.id		= UCLASS_BOOTDEV,
+	.ops		= &scsi_bootdev_ops,
+	.bind		= scsi_bootdev_bind,
+	.of_match	= scsi_bootdev_ids,
+};
+
+BOOTDEV_HUNTER(scsi_bootdev_hunter) = {
+	.prio		= BOOTDEVP_2_SCAN_FAST,
+	.uclass		= UCLASS_SCSI,
+	.hunt		= scsi_bootdev_hunt,
+	.drv		= DM_DRIVER_REF(scsi_bootdev),
+};
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c
index db0e0ca20fa..5661a3c0009 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -240,8 +240,9 @@ static int bootdev_test_hunter(struct unit_test_state *uts)
 	ut_assert_nextlinen("----");
 	ut_assert_nextline("  50        ethernet         eth_bootdev");
 	ut_assert_nextline("  10        mmc              mmc_bootdev");
+	ut_assert_nextline("  30        scsi             scsi_bootdev");
 	ut_assert_nextline("  40        usb              usb_bootdev");
-	ut_assert_nextline("(total hunters: 3)");
+	ut_assert_nextline("(total hunters: 4)");
 	ut_assert_console_end();
 
 	ut_assertok(bootdev_hunt("usb1", false));
@@ -249,8 +250,8 @@ static int bootdev_test_hunter(struct unit_test_state *uts)
 		"Bus usb@1: scanning bus usb@1 for devices... 5 USB Device(s) found");
 	ut_assert_console_end();
 
-	/* USB is third in the list, so bit 2 */
-	ut_asserteq(BIT(2), std->hunters_used);
+	/* USB is fourth in the list, so bit 3 */
+	ut_asserteq(BIT(3), std->hunters_used);
 
 	return 0;
 }
@@ -270,7 +271,7 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
 	ut_assertok(run_command("bootdev hunt -l", 0));
 	ut_assert_nextline("Prio  Used  Uclass           Hunter");
 	ut_assert_nextlinen("----");
-	ut_assert_skip_to_line("(total hunters: 3)");
+	ut_assert_skip_to_line("(total hunters: 4)");
 	ut_assert_console_end();
 
 	/* Scan all hunters */
@@ -279,7 +280,9 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
 	ut_assertok(run_command("bootdev hunt", 0));
 	ut_assert_nextline("Hunting with: ethernet");
 	ut_assert_nextline("Hunting with: mmc");
-	ut_assert_nextline("Hunting with: usb");
+	ut_assert_nextline("Hunting with: scsi");
+	ut_assert_nextline("scanning bus for devices...");
+	ut_assert_skip_to_line("Hunting with: usb");
 	ut_assert_nextline(
 		"Bus usb@1: scanning bus usb@1 for devices... 5 USB Device(s) found");
 	ut_assert_console_end();
@@ -290,12 +293,13 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
 	ut_assert_nextlinen("----");
 	ut_assert_nextline("  50     *  ethernet         eth_bootdev");
 	ut_assert_nextline("  10     *  mmc              mmc_bootdev");
+	ut_assert_nextline("  30     *  scsi             scsi_bootdev");
 	ut_assert_nextline("  40     *  usb              usb_bootdev");
 
-	ut_assert_nextline("(total hunters: 3)");
+	ut_assert_nextline("(total hunters: 4)");
 	ut_assert_console_end();
 
-	ut_asserteq(GENMASK(2, 0), std->hunters_used);
+	ut_asserteq(GENMASK(3, 0), std->hunters_used);
 
 	return 0;
 }
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 37/71] bootstd: Add an IDE bootdev
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (35 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 36/71] bootstd: Add a SCSI bootdev Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 38/71] bootstd: Add an NVMe bootdev Simon Glass
                   ` (34 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

Add a bootdev for IDE so that these devices can be used with standard
boot.

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

(no changes since v1)

 configs/sandbox_flattree_defconfig |  8 ++++++
 drivers/block/ide.c                | 44 ++++++++++++++++++++++++++++++
 test/boot/bootdev.c                | 16 +++++++----
 3 files changed, 62 insertions(+), 6 deletions(-)

diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig
index eaaec42b1fe..6e8faf56797 100644
--- a/configs/sandbox_flattree_defconfig
+++ b/configs/sandbox_flattree_defconfig
@@ -40,6 +40,7 @@ CONFIG_CMD_MEMTEST=y
 CONFIG_CMD_DEMO=y
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_GPT=y
+CONFIG_CMD_IDE=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_OSD=y
@@ -90,6 +91,13 @@ CONFIG_ADC=y
 CONFIG_ADC_SANDBOX=y
 CONFIG_AXI=y
 CONFIG_AXI_SANDBOX=y
+CONFIG_SYS_IDE_MAXBUS=1
+CONFIG_SYS_ATA_BASE_ADDR=0x100
+CONFIG_SYS_ATA_STRIDE=4
+CONFIG_SYS_ATA_DATA_OFFSET=0
+CONFIG_SYS_ATA_REG_OFFSET=1
+CONFIG_SYS_ATA_ALT_OFFSET=2
+CONFIG_SYS_ATA_IDE0_OFFSET=0
 CONFIG_CLK=y
 CONFIG_CLK_COMPOSITE_CCF=y
 CONFIG_CLK_K210=y
diff --git a/drivers/block/ide.c b/drivers/block/ide.c
index 13a1cb4b9e4..80c8b64de2f 100644
--- a/drivers/block/ide.c
+++ b/drivers/block/ide.c
@@ -9,6 +9,7 @@
 #include <common.h>
 #include <ata.h>
 #include <blk.h>
+#include <bootdev.h>
 #include <dm.h>
 #include <ide.h>
 #include <log.h>
@@ -1055,6 +1056,45 @@ U_BOOT_DRIVER(ide_blk) = {
 	.probe		= ide_blk_probe,
 };
 
+static int ide_bootdev_bind(struct udevice *dev)
+{
+	struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
+
+	ucp->prio = BOOTDEVP_3_SCAN_SLOW;
+
+	return 0;
+}
+
+static int ide_bootdev_hunt(struct bootdev_hunter *info, bool show)
+{
+	ide_init();
+
+	return 0;
+}
+
+struct bootdev_ops ide_bootdev_ops = {
+};
+
+static const struct udevice_id ide_bootdev_ids[] = {
+	{ .compatible = "u-boot,bootdev-ide" },
+	{ }
+};
+
+U_BOOT_DRIVER(ide_bootdev) = {
+	.name		= "ide_bootdev",
+	.id		= UCLASS_BOOTDEV,
+	.ops		= &ide_bootdev_ops,
+	.bind		= ide_bootdev_bind,
+	.of_match	= ide_bootdev_ids,
+};
+
+BOOTDEV_HUNTER(ide_bootdev_hunter) = {
+	.prio		= BOOTDEVP_3_SCAN_SLOW,
+	.uclass		= UCLASS_IDE,
+	.hunt		= ide_bootdev_hunt,
+	.drv		= DM_DRIVER_REF(ide_bootdev),
+};
+
 static int ide_probe(struct udevice *udev)
 {
 	struct udevice *blk_dev;
@@ -1086,6 +1126,10 @@ static int ide_probe(struct udevice *udev)
 			ret = blk_probe_or_unbind(blk_dev);
 			if (ret)
 				return ret;
+
+			ret = bootdev_setup_for_dev(udev, "ide_bootdev");
+			if (ret)
+				return log_msg_ret("bootdev", ret);
 		}
 	}
 
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c
index 5661a3c0009..a3acdcbdba3 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -239,10 +239,11 @@ static int bootdev_test_hunter(struct unit_test_state *uts)
 	ut_assert_nextline("Prio  Used  Uclass           Hunter");
 	ut_assert_nextlinen("----");
 	ut_assert_nextline("  50        ethernet         eth_bootdev");
+	ut_assert_nextline("  40        ide              ide_bootdev");
 	ut_assert_nextline("  10        mmc              mmc_bootdev");
 	ut_assert_nextline("  30        scsi             scsi_bootdev");
 	ut_assert_nextline("  40        usb              usb_bootdev");
-	ut_assert_nextline("(total hunters: 4)");
+	ut_assert_nextline("(total hunters: 5)");
 	ut_assert_console_end();
 
 	ut_assertok(bootdev_hunt("usb1", false));
@@ -250,8 +251,8 @@ static int bootdev_test_hunter(struct unit_test_state *uts)
 		"Bus usb@1: scanning bus usb@1 for devices... 5 USB Device(s) found");
 	ut_assert_console_end();
 
-	/* USB is fourth in the list, so bit 3 */
-	ut_asserteq(BIT(3), std->hunters_used);
+	/* USB is fifth in the list, so bit 4 */
+	ut_asserteq(BIT(4), std->hunters_used);
 
 	return 0;
 }
@@ -271,7 +272,7 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
 	ut_assertok(run_command("bootdev hunt -l", 0));
 	ut_assert_nextline("Prio  Used  Uclass           Hunter");
 	ut_assert_nextlinen("----");
-	ut_assert_skip_to_line("(total hunters: 4)");
+	ut_assert_skip_to_line("(total hunters: 5)");
 	ut_assert_console_end();
 
 	/* Scan all hunters */
@@ -279,6 +280,8 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
 
 	ut_assertok(run_command("bootdev hunt", 0));
 	ut_assert_nextline("Hunting with: ethernet");
+	ut_assert_nextline("Hunting with: ide");
+	ut_assert_nextline("Bus 0: not available  ");
 	ut_assert_nextline("Hunting with: mmc");
 	ut_assert_nextline("Hunting with: scsi");
 	ut_assert_nextline("scanning bus for devices...");
@@ -292,14 +295,15 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
 	ut_assert_nextlinen("Prio");
 	ut_assert_nextlinen("----");
 	ut_assert_nextline("  50     *  ethernet         eth_bootdev");
+	ut_assert_nextline("  40     *  ide              ide_bootdev");
 	ut_assert_nextline("  10     *  mmc              mmc_bootdev");
 	ut_assert_nextline("  30     *  scsi             scsi_bootdev");
 	ut_assert_nextline("  40     *  usb              usb_bootdev");
 
-	ut_assert_nextline("(total hunters: 4)");
+	ut_assert_nextline("(total hunters: 5)");
 	ut_assert_console_end();
 
-	ut_asserteq(GENMASK(3, 0), std->hunters_used);
+	ut_asserteq(GENMASK(4, 0), std->hunters_used);
 
 	return 0;
 }
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 38/71] bootstd: Add an NVMe bootdev
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (36 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 37/71] bootstd: Add an IDE bootdev Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 39/71] virtio: Avoid repeating a long expression Simon Glass
                   ` (33 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

Add a bootdev for NVMe so that these devices can be used with standard
boot.

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

(no changes since v1)

 drivers/nvme/nvme-uclass.c | 54 ++++++++++++++++++++++++++++++++++++++
 drivers/nvme/nvme.c        |  5 ++++
 test/boot/bootdev.c        | 15 ++++++-----
 3 files changed, 68 insertions(+), 6 deletions(-)

diff --git a/drivers/nvme/nvme-uclass.c b/drivers/nvme/nvme-uclass.c
index 239a92abba6..7a8ff06e78c 100644
--- a/drivers/nvme/nvme-uclass.c
+++ b/drivers/nvme/nvme-uclass.c
@@ -7,9 +7,63 @@
 #define LOG_CATEGORY UCLASS_NVME
 
 #include <common.h>
+#include <bootdev.h>
 #include <dm.h>
+#include <init.h>
+#include <log.h>
+#include <nvme.h>
+
+static int nvme_bootdev_bind(struct udevice *dev)
+{
+	struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
+
+	ucp->prio = BOOTDEVP_2_SCAN_FAST;
+
+	return 0;
+}
+
+static int nvme_bootdev_hunt(struct bootdev_hunter *info, bool show)
+{
+	int ret;
+
+	/* init PCI first since this is often used to provide NVMe */
+	if (IS_ENABLED(CONFIG_PCI)) {
+		ret = pci_init();
+		if (ret)
+			log_warning("Failed to init PCI (%dE)\n", ret);
+	}
+
+	ret = nvme_scan_namespace();
+	if (ret)
+		return log_msg_ret("scan", ret);
+
+	return 0;
+}
 
 UCLASS_DRIVER(nvme) = {
 	.name	= "nvme",
 	.id	= UCLASS_NVME,
 };
+
+struct bootdev_ops nvme_bootdev_ops = {
+};
+
+static const struct udevice_id nvme_bootdev_ids[] = {
+	{ .compatible = "u-boot,bootdev-nvme" },
+	{ }
+};
+
+U_BOOT_DRIVER(nvme_bootdev) = {
+	.name		= "nvme_bootdev",
+	.id		= UCLASS_BOOTDEV,
+	.ops		= &nvme_bootdev_ops,
+	.bind		= nvme_bootdev_bind,
+	.of_match	= nvme_bootdev_ids,
+};
+
+BOOTDEV_HUNTER(nvme_bootdev_hunter) = {
+	.prio		= BOOTDEVP_2_SCAN_FAST,
+	.uclass		= UCLASS_NVME,
+	.hunt		= nvme_bootdev_hunt,
+	.drv		= DM_DRIVER_REF(nvme_bootdev),
+};
diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c
index 6d0d3f3ca2b..74e7a5b0110 100644
--- a/drivers/nvme/nvme.c
+++ b/drivers/nvme/nvme.c
@@ -6,6 +6,7 @@
 
 #include <common.h>
 #include <blk.h>
+#include <bootdev.h>
 #include <cpu_func.h>
 #include <dm.h>
 #include <errno.h>
@@ -893,6 +894,10 @@ int nvme_init(struct udevice *udev)
 		if (ret)
 			goto free_id;
 
+		ret = bootdev_setup_sibling_blk(ns_udev, "nvme_bootdev");
+		if (ret)
+			return log_msg_ret("bootdev", ret);
+
 		ret = blk_probe_or_unbind(ns_udev);
 		if (ret)
 			goto free_id;
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c
index a3acdcbdba3..6f150175f69 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -241,9 +241,10 @@ static int bootdev_test_hunter(struct unit_test_state *uts)
 	ut_assert_nextline("  50        ethernet         eth_bootdev");
 	ut_assert_nextline("  40        ide              ide_bootdev");
 	ut_assert_nextline("  10        mmc              mmc_bootdev");
+	ut_assert_nextline("  30        nvme             nvme_bootdev");
 	ut_assert_nextline("  30        scsi             scsi_bootdev");
 	ut_assert_nextline("  40        usb              usb_bootdev");
-	ut_assert_nextline("(total hunters: 5)");
+	ut_assert_nextline("(total hunters: 6)");
 	ut_assert_console_end();
 
 	ut_assertok(bootdev_hunt("usb1", false));
@@ -251,8 +252,8 @@ static int bootdev_test_hunter(struct unit_test_state *uts)
 		"Bus usb@1: scanning bus usb@1 for devices... 5 USB Device(s) found");
 	ut_assert_console_end();
 
-	/* USB is fifth in the list, so bit 4 */
-	ut_asserteq(BIT(4), std->hunters_used);
+	/* USB is fifth in the list, so bit 5 */
+	ut_asserteq(BIT(5), std->hunters_used);
 
 	return 0;
 }
@@ -272,7 +273,7 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
 	ut_assertok(run_command("bootdev hunt -l", 0));
 	ut_assert_nextline("Prio  Used  Uclass           Hunter");
 	ut_assert_nextlinen("----");
-	ut_assert_skip_to_line("(total hunters: 5)");
+	ut_assert_skip_to_line("(total hunters: 6)");
 	ut_assert_console_end();
 
 	/* Scan all hunters */
@@ -283,6 +284,7 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
 	ut_assert_nextline("Hunting with: ide");
 	ut_assert_nextline("Bus 0: not available  ");
 	ut_assert_nextline("Hunting with: mmc");
+	ut_assert_nextline("Hunting with: nvme");
 	ut_assert_nextline("Hunting with: scsi");
 	ut_assert_nextline("scanning bus for devices...");
 	ut_assert_skip_to_line("Hunting with: usb");
@@ -297,13 +299,14 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
 	ut_assert_nextline("  50     *  ethernet         eth_bootdev");
 	ut_assert_nextline("  40     *  ide              ide_bootdev");
 	ut_assert_nextline("  10     *  mmc              mmc_bootdev");
+	ut_assert_nextline("  30     *  nvme             nvme_bootdev");
 	ut_assert_nextline("  30     *  scsi             scsi_bootdev");
 	ut_assert_nextline("  40     *  usb              usb_bootdev");
 
-	ut_assert_nextline("(total hunters: 5)");
+	ut_assert_nextline("(total hunters: 6)");
 	ut_assert_console_end();
 
-	ut_asserteq(GENMASK(4, 0), std->hunters_used);
+	ut_asserteq(GENMASK(5, 0), std->hunters_used);
 
 	return 0;
 }
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 39/71] virtio: Avoid repeating a long expression
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (37 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 38/71] bootstd: Add an NVMe bootdev Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 40/71] virtio: Fix returning -ENODEV Simon Glass
                   ` (32 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

Use a local variable to hold this name, to reduce the amount of code that
needs to be read.

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

(no changes since v1)

 drivers/virtio/virtio-uclass.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/virtio/virtio-uclass.c b/drivers/virtio/virtio-uclass.c
index da4f2f26a63..6d9b029390e 100644
--- a/drivers/virtio/virtio-uclass.c
+++ b/drivers/virtio/virtio-uclass.c
@@ -214,6 +214,7 @@ static int virtio_uclass_post_probe(struct udevice *udev)
 	struct virtio_dev_priv *uc_priv = dev_get_uclass_priv(udev);
 	char dev_name[30], *str;
 	struct udevice *vdev;
+	const char *name;
 	int ret;
 
 	if (uc_priv->device >= VIRTIO_ID_MAX_NUM) {
@@ -222,20 +223,19 @@ static int virtio_uclass_post_probe(struct udevice *udev)
 		return 0;
 	}
 
-	if (!virtio_drv_name[uc_priv->device]) {
+	name = virtio_drv_name[uc_priv->device];
+	if (!name) {
 		debug("(%s): underlying virtio device driver unavailable\n",
 		      udev->name);
 		return 0;
 	}
 
-	snprintf(dev_name, sizeof(dev_name), "%s#%d",
-		 virtio_drv_name[uc_priv->device], dev_seq(udev));
+	snprintf(dev_name, sizeof(dev_name), "%s#%d", name, dev_seq(udev));
 	str = strdup(dev_name);
 	if (!str)
 		return -ENOMEM;
 
-	ret = device_bind_driver(udev, virtio_drv_name[uc_priv->device],
-				 str, &vdev);
+	ret = device_bind_driver(udev, name, str, &vdev);
 	if (ret == -ENOENT) {
 		debug("(%s): no driver configured\n", udev->name);
 		return 0;
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 40/71] virtio: Fix returning -ENODEV
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (38 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 39/71] virtio: Avoid repeating a long expression Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 41/71] virtio: Avoid strange behaviour on removal Simon Glass
                   ` (31 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

This has a special meaning in driver model. There is clearly a device, so
it does not make sense to return this error code. Fix it.

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

(no changes since v1)

 drivers/virtio/virtio-uclass.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/virtio/virtio-uclass.c b/drivers/virtio/virtio-uclass.c
index 6d9b029390e..a6bff630ca8 100644
--- a/drivers/virtio/virtio-uclass.c
+++ b/drivers/virtio/virtio-uclass.c
@@ -163,7 +163,7 @@ int virtio_finalize_features(struct udevice *vdev)
 		return ret;
 	if (!(status & VIRTIO_CONFIG_S_FEATURES_OK)) {
 		debug("(%s): device refuses features %x\n", vdev->name, status);
-		return -ENODEV;
+		return -EINVAL;
 	}
 
 	return 0;
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 41/71] virtio: Avoid strange behaviour on removal
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (39 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 40/71] virtio: Fix returning -ENODEV Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 42/71] virtio: Add a block device Simon Glass
                   ` (30 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

This device does a check on removal which is better handled in the actual
test. Move it.

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

(no changes since v1)

 drivers/virtio/virtio_sandbox.c | 13 -------------
 test/dm/virtio_device.c         |  3 +++
 2 files changed, 3 insertions(+), 13 deletions(-)

diff --git a/drivers/virtio/virtio_sandbox.c b/drivers/virtio/virtio_sandbox.c
index 5484ae3a1a0..cf7761c75ee 100644
--- a/drivers/virtio/virtio_sandbox.c
+++ b/drivers/virtio/virtio_sandbox.c
@@ -167,18 +167,6 @@ static int virtio_sandbox_probe(struct udevice *udev)
 	return 0;
 }
 
-/* check virtio device driver's remove routine was called to reset the device */
-static int virtio_sandbox_child_post_remove(struct udevice *vdev)
-{
-	u8 status;
-
-	virtio_get_status(vdev, &status);
-	if (status)
-		panic("virtio device was not reset\n");
-
-	return 0;
-}
-
 static const struct dm_virtio_ops virtio_sandbox1_ops = {
 	.get_config	= virtio_sandbox_get_config,
 	.set_config	= virtio_sandbox_set_config,
@@ -203,7 +191,6 @@ U_BOOT_DRIVER(virtio_sandbox1) = {
 	.of_match = virtio_sandbox1_ids,
 	.ops	= &virtio_sandbox1_ops,
 	.probe	= virtio_sandbox_probe,
-	.child_post_remove = virtio_sandbox_child_post_remove,
 	.priv_auto	= sizeof(struct virtio_sandbox_priv),
 };
 
diff --git a/test/dm/virtio_device.c b/test/dm/virtio_device.c
index b5c4523a028..fdda4da4178 100644
--- a/test/dm/virtio_device.c
+++ b/test/dm/virtio_device.c
@@ -100,6 +100,7 @@ DM_TEST(dm_test_virtio_all_ops, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
 static int dm_test_virtio_remove(struct unit_test_state *uts)
 {
 	struct udevice *bus, *dev;
+	u8 status;
 
 	/* check probe success */
 	ut_assertok(uclass_first_device_err(UCLASS_VIRTIO, &bus));
@@ -117,6 +118,8 @@ static int dm_test_virtio_remove(struct unit_test_state *uts)
 	ut_asserteq(-EKEYREJECTED, device_remove(bus, DM_REMOVE_ACTIVE_ALL));
 
 	ut_asserteq(false, device_active(dev));
+	virtio_get_status(dev, &status);
+	ut_assertok(status);
 
 	return 0;
 }
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 42/71] virtio: Add a block device
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (40 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 41/71] virtio: Avoid strange behaviour on removal Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 43/71] bootstd: Add a virtio bootdev Simon Glass
                   ` (29 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

The test code for virtio is fairly simplistic and does not actually create
a block device. Add a way to specify the device type in the device tree.
Add a block device so that we can do more testing.

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

(no changes since v1)

 arch/sandbox/dts/test.dts       | 6 ++++++
 drivers/virtio/virtio_sandbox.c | 3 ++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 2e580f980fc..9d96e479ca8 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -1527,12 +1527,18 @@
 
 	sandbox_virtio1 {
 		compatible = "sandbox,virtio1";
+		virtio-type = <4>;	/* rng */
 	};
 
 	sandbox_virtio2 {
 		compatible = "sandbox,virtio2";
 	};
 
+	sandbox-virtio-blk {
+		compatible = "sandbox,virtio1";
+		virtio-type = <2>;	/* block */
+	};
+
 	sandbox_scmi {
 		compatible = "sandbox,scmi-devices";
 		clocks = <&clk_scmi 2>, <&clk_scmi 0>;
diff --git a/drivers/virtio/virtio_sandbox.c b/drivers/virtio/virtio_sandbox.c
index cf7761c75ee..b34f1d60455 100644
--- a/drivers/virtio/virtio_sandbox.c
+++ b/drivers/virtio/virtio_sandbox.c
@@ -161,7 +161,8 @@ static int virtio_sandbox_probe(struct udevice *udev)
 
 	/* fake some information for testing */
 	priv->device_features = BIT_ULL(VIRTIO_F_VERSION_1);
-	uc_priv->device = VIRTIO_ID_RNG;
+	uc_priv->device = dev_read_u32_default(udev, "virtio-type",
+					       VIRTIO_ID_RNG);
 	uc_priv->vendor = ('u' << 24) | ('b' << 16) | ('o' << 8) | 't';
 
 	return 0;
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 43/71] bootstd: Add a virtio bootdev
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (41 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 42/71] virtio: Add a block device Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 44/71] ata: Don't try to use non-existent ports Simon Glass
                   ` (28 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

Add a bootdev for virtio so that these devices can be used with standard
boot.

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

(no changes since v1)

 drivers/virtio/virtio-uclass.c | 50 ++++++++++++++++++++++++++++++++++
 test/boot/bootdev.c            | 12 ++++----
 2 files changed, 57 insertions(+), 5 deletions(-)

diff --git a/drivers/virtio/virtio-uclass.c b/drivers/virtio/virtio-uclass.c
index a6bff630ca8..27efac0d48e 100644
--- a/drivers/virtio/virtio-uclass.c
+++ b/drivers/virtio/virtio-uclass.c
@@ -18,6 +18,7 @@
 #define LOG_CATEGORY UCLASS_VIRTIO
 
 #include <common.h>
+#include <bootdev.h>
 #include <dm.h>
 #include <log.h>
 #include <malloc.h>
@@ -246,6 +247,12 @@ static int virtio_uclass_post_probe(struct udevice *udev)
 	}
 	device_set_name_alloced(vdev);
 
+	if (uc_priv->device == VIRTIO_ID_BLOCK) {
+		ret = bootdev_setup_for_dev(udev, name);
+		if (ret)
+			return log_msg_ret("bootdev", ret);
+	}
+
 	INIT_LIST_HEAD(&uc_priv->vqs);
 
 	return 0;
@@ -349,6 +356,26 @@ static int virtio_uclass_child_post_probe(struct udevice *vdev)
 	return 0;
 }
 
+static int virtio_bootdev_bind(struct udevice *dev)
+{
+	struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
+
+	ucp->prio = BOOTDEVP_2_SCAN_FAST;
+
+	return 0;
+}
+
+static int virtio_bootdev_hunt(struct bootdev_hunter *info, bool show)
+{
+	int ret;
+
+	ret = uclass_probe_all(UCLASS_VIRTIO);
+	if (ret && ret != -ENOENT)
+		return log_msg_ret("vir", ret);
+
+	return 0;
+}
+
 UCLASS_DRIVER(virtio) = {
 	.name	= "virtio",
 	.id	= UCLASS_VIRTIO,
@@ -360,3 +387,26 @@ UCLASS_DRIVER(virtio) = {
 	.child_post_probe = virtio_uclass_child_post_probe,
 	.per_device_auto	= sizeof(struct virtio_dev_priv),
 };
+
+struct bootdev_ops virtio_bootdev_ops = {
+};
+
+static const struct udevice_id virtio_bootdev_ids[] = {
+	{ .compatible = "u-boot,bootdev-virtio" },
+	{ }
+};
+
+U_BOOT_DRIVER(virtio_bootdev) = {
+	.name		= "virtio_bootdev",
+	.id		= UCLASS_BOOTDEV,
+	.ops		= &virtio_bootdev_ops,
+	.bind		= virtio_bootdev_bind,
+	.of_match	= virtio_bootdev_ids,
+};
+
+BOOTDEV_HUNTER(virtio_bootdev_hunter) = {
+	.prio		= BOOTDEVP_2_SCAN_FAST,
+	.uclass		= UCLASS_VIRTIO,
+	.hunt		= virtio_bootdev_hunt,
+	.drv		= DM_DRIVER_REF(virtio_bootdev),
+};
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c
index 6f150175f69..2ad31a0ef66 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -244,7 +244,8 @@ static int bootdev_test_hunter(struct unit_test_state *uts)
 	ut_assert_nextline("  30        nvme             nvme_bootdev");
 	ut_assert_nextline("  30        scsi             scsi_bootdev");
 	ut_assert_nextline("  40        usb              usb_bootdev");
-	ut_assert_nextline("(total hunters: 6)");
+	ut_assert_nextline("  30        virtio           virtio_bootdev");
+	ut_assert_nextline("(total hunters: 7)");
 	ut_assert_console_end();
 
 	ut_assertok(bootdev_hunt("usb1", false));
@@ -273,7 +274,7 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
 	ut_assertok(run_command("bootdev hunt -l", 0));
 	ut_assert_nextline("Prio  Used  Uclass           Hunter");
 	ut_assert_nextlinen("----");
-	ut_assert_skip_to_line("(total hunters: 6)");
+	ut_assert_skip_to_line("(total hunters: 7)");
 	ut_assert_console_end();
 
 	/* Scan all hunters */
@@ -290,6 +291,7 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
 	ut_assert_skip_to_line("Hunting with: usb");
 	ut_assert_nextline(
 		"Bus usb@1: scanning bus usb@1 for devices... 5 USB Device(s) found");
+	ut_assert_skip_to_line("Hunting with: virtio");
 	ut_assert_console_end();
 
 	/* List available hunters */
@@ -302,11 +304,11 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
 	ut_assert_nextline("  30     *  nvme             nvme_bootdev");
 	ut_assert_nextline("  30     *  scsi             scsi_bootdev");
 	ut_assert_nextline("  40     *  usb              usb_bootdev");
-
-	ut_assert_nextline("(total hunters: 6)");
+	ut_assert_nextline("  30     *  virtio           virtio_bootdev");
+	ut_assert_nextline("(total hunters: 7)");
 	ut_assert_console_end();
 
-	ut_asserteq(GENMASK(5, 0), std->hunters_used);
+	ut_asserteq(GENMASK(6, 0), std->hunters_used);
 
 	return 0;
 }
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 44/71] ata: Don't try to use non-existent ports
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (42 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 43/71] bootstd: Add a virtio bootdev Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 45/71] bootstd: Rename bootdev checkers Simon Glass
                   ` (27 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

The controller indicates the number of ports but also has a port map
which specifies which ports are actually valid. Make use of this to
avoid trying to send commands to an invalid port.

This avoids a crash on some controllers.

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

(no changes since v1)

 drivers/ata/ahci.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index de6131f1d9b..272c48b8e57 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -675,6 +675,12 @@ static int ata_scsiop_inquiry(struct ahci_uc_priv *uc_priv,
 	/* Read id from sata */
 	port = pccb->target;
 
+	/* If this port number is not valid, give up */
+	if (!(uc_priv->port_map & (1 << port))) {
+		debug("Port %x not valid in map %x\n", port, uc_priv->port_map);
+		return -ENODEV;
+	}
+
 	if (ahci_device_data_io(uc_priv, port, (u8 *)&fis, sizeof(fis),
 				(u8 *)tmpid, ATA_ID_WORDS * 2, 0)) {
 		debug("scsi_ahci: SCSI inquiry command failure.\n");
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 45/71] bootstd: Rename bootdev checkers
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (43 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 44/71] ata: Don't try to use non-existent ports Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 46/71] bootstd: Allow reading an EFI file from the network Simon Glass
                   ` (26 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

These functions return 0 if the check passes, so the names are somewhat
confusing. Rename them.

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

(no changes since v1)

 boot/bootflow.c         |  6 +++---
 boot/bootmeth_distro.c  |  2 +-
 boot/bootmeth_efi.c     |  2 +-
 boot/bootmeth_efi_mgr.c |  2 +-
 boot/bootmeth_pxe.c     |  2 +-
 boot/bootmeth_script.c  |  2 +-
 include/bootflow.h      | 12 ++++++------
 net/eth_bootdev.c       |  2 +-
 8 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/boot/bootflow.c b/boot/bootflow.c
index 163cd4953dd..0345755f58f 100644
--- a/boot/bootflow.c
+++ b/boot/bootflow.c
@@ -427,7 +427,7 @@ int bootflow_run_boot(struct bootflow_iter *iter, struct bootflow *bflow)
 	return ret;
 }
 
-int bootflow_iter_uses_blk_dev(const struct bootflow_iter *iter)
+int bootflow_iter_check_blk(const struct bootflow_iter *iter)
 {
 	const struct udevice *media = dev_get_parent(iter->dev);
 	enum uclass_id id = device_get_uclass_id(media);
@@ -439,7 +439,7 @@ int bootflow_iter_uses_blk_dev(const struct bootflow_iter *iter)
 	return -ENOTSUPP;
 }
 
-int bootflow_iter_uses_network(const struct bootflow_iter *iter)
+int bootflow_iter_check_net(const struct bootflow_iter *iter)
 {
 	const struct udevice *media = dev_get_parent(iter->dev);
 	enum uclass_id id = device_get_uclass_id(media);
@@ -451,7 +451,7 @@ int bootflow_iter_uses_network(const struct bootflow_iter *iter)
 	return -ENOTSUPP;
 }
 
-int bootflow_iter_uses_system(const struct bootflow_iter *iter)
+int bootflow_iter_check_system(const struct bootflow_iter *iter)
 {
 	const struct udevice *media = dev_get_parent(iter->dev);
 	enum uclass_id id = device_get_uclass_id(media);
diff --git a/boot/bootmeth_distro.c b/boot/bootmeth_distro.c
index 6ef0fa1f2c9..356929828b9 100644
--- a/boot/bootmeth_distro.c
+++ b/boot/bootmeth_distro.c
@@ -59,7 +59,7 @@ static int distro_check(struct udevice *dev, struct bootflow_iter *iter)
 	int ret;
 
 	/* This only works on block devices */
-	ret = bootflow_iter_uses_blk_dev(iter);
+	ret = bootflow_iter_check_blk(iter);
 	if (ret)
 		return log_msg_ret("blk", ret);
 
diff --git a/boot/bootmeth_efi.c b/boot/bootmeth_efi.c
index d5438eb67b9..f7bb153d9de 100644
--- a/boot/bootmeth_efi.c
+++ b/boot/bootmeth_efi.c
@@ -104,7 +104,7 @@ static int distro_efi_check(struct udevice *dev, struct bootflow_iter *iter)
 	int ret;
 
 	/* This only works on block devices */
-	ret = bootflow_iter_uses_blk_dev(iter);
+	ret = bootflow_iter_check_blk(iter);
 	if (ret)
 		return log_msg_ret("blk", ret);
 
diff --git a/boot/bootmeth_efi_mgr.c b/boot/bootmeth_efi_mgr.c
index 2f327c1f8ce..e9d973429f7 100644
--- a/boot/bootmeth_efi_mgr.c
+++ b/boot/bootmeth_efi_mgr.c
@@ -36,7 +36,7 @@ static int efi_mgr_check(struct udevice *dev, struct bootflow_iter *iter)
 	int ret;
 
 	/* Must be an bootstd device */
-	ret = bootflow_iter_uses_system(iter);
+	ret = bootflow_iter_check_system(iter);
 	if (ret)
 		return log_msg_ret("net", ret);
 
diff --git a/boot/bootmeth_pxe.c b/boot/bootmeth_pxe.c
index e6992168c06..13e2ff486dc 100644
--- a/boot/bootmeth_pxe.c
+++ b/boot/bootmeth_pxe.c
@@ -44,7 +44,7 @@ static int distro_pxe_check(struct udevice *dev, struct bootflow_iter *iter)
 	int ret;
 
 	/* This only works on network devices */
-	ret = bootflow_iter_uses_network(iter);
+	ret = bootflow_iter_check_net(iter);
 	if (ret)
 		return log_msg_ret("net", ret);
 
diff --git a/boot/bootmeth_script.c b/boot/bootmeth_script.c
index a8f77e29f99..11dab91c18c 100644
--- a/boot/bootmeth_script.c
+++ b/boot/bootmeth_script.c
@@ -28,7 +28,7 @@ static int script_check(struct udevice *dev, struct bootflow_iter *iter)
 	int ret;
 
 	/* This only works on block devices */
-	ret = bootflow_iter_uses_blk_dev(iter);
+	ret = bootflow_iter_check_blk(iter);
 	if (ret)
 		return log_msg_ret("blk", ret);
 
diff --git a/include/bootflow.h b/include/bootflow.h
index 3a93e4b5cab..8ff9e332b1f 100644
--- a/include/bootflow.h
+++ b/include/bootflow.h
@@ -314,33 +314,33 @@ const char *bootflow_state_get_name(enum bootflow_state_t state);
 void bootflow_remove(struct bootflow *bflow);
 
 /**
- * bootflow_iter_uses_blk_dev() - Check that a bootflow uses a block device
+ * bootflow_iter_check_blk() - Check that a bootflow uses a block device
  *
  * This checks the bootdev in the bootflow to make sure it uses a block device
  *
  * Return: 0 if OK, -ENOTSUPP if some other device is used (e.g. ethernet)
  */
-int bootflow_iter_uses_blk_dev(const struct bootflow_iter *iter);
+int bootflow_iter_check_blk(const struct bootflow_iter *iter);
 
 /**
- * bootflow_iter_uses_network() - Check that a bootflow uses a network device
+ * bootflow_iter_check_net() - Check that a bootflow uses a network device
  *
  * This checks the bootdev in the bootflow to make sure it uses a network
  * device
  *
  * Return: 0 if OK, -ENOTSUPP if some other device is used (e.g. MMC)
  */
-int bootflow_iter_uses_network(const struct bootflow_iter *iter);
+int bootflow_iter_check_net(const struct bootflow_iter *iter);
 
 /**
- * bootflow_iter_uses_system() - Check that a bootflow uses the bootstd device
+ * bootflow_iter_check_system() - Check that a bootflow uses the bootstd device
  *
  * This checks the bootdev in the bootflow to make sure it uses the bootstd
  * device
  *
  * Return: 0 if OK, -ENOTSUPP if some other device is used (e.g. MMC)
  */
-int bootflow_iter_uses_system(const struct bootflow_iter *iter);
+int bootflow_iter_check_system(const struct bootflow_iter *iter);
 
 /**
  * bootflow_menu_new() - Create a new bootflow menu
diff --git a/net/eth_bootdev.c b/net/eth_bootdev.c
index fdf48f00131..bcbb35a74cd 100644
--- a/net/eth_bootdev.c
+++ b/net/eth_bootdev.c
@@ -27,7 +27,7 @@ static int eth_get_bootflow(struct udevice *dev, struct bootflow_iter *iter,
 	int ret;
 
 	/* Must be an Ethernet device */
-	ret = bootflow_iter_uses_network(iter);
+	ret = bootflow_iter_check_net(iter);
 	if (ret)
 		return log_msg_ret("net", ret);
 
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 46/71] bootstd: Allow reading an EFI file from the network
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (44 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 45/71] bootstd: Rename bootdev checkers Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 47/71] bootstd: Include the device tree in the bootflow Simon Glass
                   ` (25 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

At present this bootmeth only supports reading from a filesystem. Add
support for reading from a network also, using DHCP with autoload.

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

(no changes since v1)

 boot/bootmeth_efi.c | 117 +++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 109 insertions(+), 8 deletions(-)

diff --git a/boot/bootmeth_efi.c b/boot/bootmeth_efi.c
index f7bb153d9de..77b4ba22470 100644
--- a/boot/bootmeth_efi.c
+++ b/boot/bootmeth_efi.c
@@ -19,6 +19,7 @@
 #include <malloc.h>
 #include <mapmem.h>
 #include <mmc.h>
+#include <net.h>
 #include <pxe_utils.h>
 
 #define EFI_DIRNAME	"efi/boot/"
@@ -59,6 +60,40 @@ static int get_efi_leafname(char *str, int max_len)
 	return 0;
 }
 
+static int get_efi_pxe_arch(void)
+{
+	/* http://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xml */
+	if (IS_ENABLED(CONFIG_ARM64))
+		return 0xb;
+	else if (IS_ENABLED(CONFIG_ARM))
+		return 0xa;
+	else if (IS_ENABLED(CONFIG_X86_64))
+		return 0x6;
+	else if (IS_ENABLED(CONFIG_X86))
+		return 0x7;
+	else if (IS_ENABLED(CONFIG_ARCH_RV32I))
+		return 0x19;
+	else if (IS_ENABLED(CONFIG_ARCH_RV64I))
+		return 0x1b;
+	else if (IS_ENABLED(CONFIG_SANDBOX))
+		return 0;	/* not used */
+
+	return -EINVAL;
+}
+
+static int get_efi_pxe_vci(char *str, int max_len)
+{
+	int ret;
+
+	ret = get_efi_pxe_arch();
+	if (ret < 0)
+		return ret;
+
+	snprintf(str, max_len, "PXEClient:Arch:%05x:UNDI:003000", ret);
+
+	return 0;
+}
+
 static int efiload_read_file(struct blk_desc *desc, struct bootflow *bflow)
 {
 	const struct udevice *media_dev;
@@ -101,20 +136,18 @@ static int efiload_read_file(struct blk_desc *desc, struct bootflow *bflow)
 
 static int distro_efi_check(struct udevice *dev, struct bootflow_iter *iter)
 {
-	int ret;
-
-	/* This only works on block devices */
-	ret = bootflow_iter_check_blk(iter);
-	if (ret)
-		return log_msg_ret("blk", ret);
+	/* This only works on block and network devices */
+	if (bootflow_iter_check_blk(iter) && bootflow_iter_check_net(iter))
+		return log_msg_ret("blk", -ENOTSUPP);
 
 	return 0;
 }
 
-static int distro_efi_read_bootflow(struct udevice *dev, struct bootflow *bflow)
+static int distro_efi_read_bootflow_file(struct udevice *dev,
+					 struct bootflow *bflow)
 {
 	struct blk_desc *desc = NULL;
-	char fname[sizeof(EFI_DIRNAME) + 16];
+	char fname[256];
 	int ret;
 
 	/* We require a partition table */
@@ -140,6 +173,74 @@ static int distro_efi_read_bootflow(struct udevice *dev, struct bootflow *bflow)
 	return 0;
 }
 
+static int distro_efi_read_bootflow_net(struct bootflow *bflow)
+{
+	const char *addr_str;
+	int ret, arch, size;
+	char str[36];
+	ulong addr;
+
+	ret = get_efi_pxe_vci(str, sizeof(str));
+	if (ret)
+		return log_msg_ret("vci", ret);
+	ret = get_efi_pxe_arch();
+	if (ret < 0)
+		return log_msg_ret("arc", ret);
+	arch = ret;
+
+	ret = env_set("bootp_vci", str);
+	if (ret)
+		return log_msg_ret("vcs", ret);
+	ret = env_set_ulong("bootp_arch", arch);
+	if (ret)
+		return log_msg_ret("ars", ret);
+
+	/* figure out the load address */
+	addr_str = env_get("kernel_addr_r");
+	addr = addr_str ? hextoul(addr_str, NULL) : image_load_addr;
+
+	/* clear any previous bootfile */
+	env_set("bootfile", NULL);
+
+	/* read the kernel */
+	ret = dhcp_run(addr, NULL, true);
+	if (ret)
+		return log_msg_ret("dhc", ret);
+
+	size = env_get_hex("filesize", -1);
+	if (size <= 0)
+		return log_msg_ret("sz", -EINVAL);
+	bflow->size = size;
+
+	/* do the hideous EFI hack */
+	efi_set_bootdev("Net", "", bflow->fname, map_sysmem(addr, 0),
+			bflow->size);
+
+	bflow->state = BOOTFLOWST_READY;
+
+	return 0;
+}
+
+static int distro_efi_read_bootflow(struct udevice *dev, struct bootflow *bflow)
+{
+	const struct udevice *media = dev_get_parent(bflow->dev);
+	int ret;
+
+	if (IS_ENABLED(CONFIG_CMD_DHCP) &&
+	    device_get_uclass_id(media) == UCLASS_ETH) {
+		/* we only support reading from one device, so ignore 'dev' */
+		ret = distro_efi_read_bootflow_net(bflow);
+		if (ret)
+			return log_msg_ret("net", ret);
+	} else {
+		ret = distro_efi_read_bootflow_file(dev, bflow);
+		if (ret)
+			return log_msg_ret("blk", ret);
+	}
+
+	return 0;
+}
+
 int distro_efi_boot(struct udevice *dev, struct bootflow *bflow)
 {
 	char cmd[50];
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 47/71] bootstd: Include the device tree in the bootflow
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (45 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 46/71] bootstd: Allow reading an EFI file from the network Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 48/71] bootstd: Support reading the device tree with EFI Simon Glass
                   ` (24 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

Some bootmeths provide a way to load a device tree as well as the base
OS image. Add a way to store this in the bootflow. Update the
'bootflow info' command to show this information.

Note that the device tree is not allocated, but instead is stored at
an address provided by an environment variable. This may need to be
adjusted at some point, but for now it works well and fits in with the
existing distro-boot scripts.

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

(no changes since v1)

 boot/bootflow.c      | 1 +
 cmd/bootflow.c       | 6 ++++++
 include/bootflow.h   | 6 ++++++
 test/boot/bootflow.c | 1 +
 4 files changed, 14 insertions(+)

diff --git a/boot/bootflow.c b/boot/bootflow.c
index 0345755f58f..52cc2f9d548 100644
--- a/boot/bootflow.c
+++ b/boot/bootflow.c
@@ -355,6 +355,7 @@ void bootflow_free(struct bootflow *bflow)
 	free(bflow->fname);
 	free(bflow->buf);
 	free(bflow->os_name);
+	free(bflow->fdt_fname);
 }
 
 void bootflow_remove(struct bootflow *bflow)
diff --git a/cmd/bootflow.c b/cmd/bootflow.c
index 2b6ed26fdcb..56dd35b69cf 100644
--- a/cmd/bootflow.c
+++ b/cmd/bootflow.c
@@ -344,6 +344,12 @@ static int do_bootflow_info(struct cmd_tbl *cmdtp, int flag, int argc,
 		printf("Logo size: %x (%d bytes)\n", bflow->logo_size,
 		       bflow->logo_size);
 	}
+	printf("FDT:       %s\n", bflow->fdt_fname);
+	if (bflow->fdt_fname) {
+		printf("FDT size:  %x (%d bytes)\n", bflow->fdt_size,
+		       bflow->fdt_size);
+		printf("FDT addr:  %lx\n", bflow->fdt_addr);
+	}
 	printf("Error:     %d\n", bflow->err);
 	if (dump && bflow->buf) {
 		/* Set some sort of maximum on the size */
diff --git a/include/bootflow.h b/include/bootflow.h
index 8ff9e332b1f..bf71b09edad 100644
--- a/include/bootflow.h
+++ b/include/bootflow.h
@@ -60,6 +60,9 @@ enum bootflow_state_t {
  * @err: Error number received (0 if OK)
  * @os_name: Name of the OS / distro being booted, or NULL if not known
  *	(allocated)
+ * @fdt_fname: Filename of FDT file
+ * @fdt_size: Size of FDT file
+ * @fdt_addr: Address of loaded fdt
  */
 struct bootflow {
 	struct list_head bm_node;
@@ -79,6 +82,9 @@ struct bootflow {
 	int size;
 	int err;
 	char *os_name;
+	char *fdt_fname;
+	int fdt_size;
+	ulong fdt_addr;
 };
 
 /**
diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c
index f852b6e9b6f..b71ec52eb7a 100644
--- a/test/boot/bootflow.c
+++ b/test/boot/bootflow.c
@@ -199,6 +199,7 @@ static int bootflow_cmd_info(struct unit_test_state *uts)
 	ut_assert_nextline("Size:      253 (595 bytes)");
 	ut_assert_nextline("OS:        Fedora-Workstation-armhfp-31-1.9 (5.3.7-301.fc31.armv7hl)");
 	ut_assert_nextline("Logo:      (none)");
+	ut_assert_nextline("FDT:       <NULL>");
 	ut_assert_nextline("Error:     0");
 	ut_assert_console_end();
 
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 48/71] bootstd: Support reading the device tree with EFI
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (46 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 47/71] bootstd: Include the device tree in the bootflow Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08 10:25   ` Mark Kettenis
  2023-01-08  2:50 ` [PATCH v2 49/71] bootstd: Set the distro_bootpart env var with scripts Simon Glass
                   ` (23 subsequent siblings)
  71 siblings, 1 reply; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

With EFI booting the device tree is required but is not actually specified
in any way. The normal method is to use a fdtfile environment variable to
get the filename, then look for that file on the media.

Implement this in the bootmeth.

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

(no changes since v1)

 boot/bootmeth_efi.c | 105 +++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 99 insertions(+), 6 deletions(-)

diff --git a/boot/bootmeth_efi.c b/boot/bootmeth_efi.c
index 77b4ba22470..53a0489b93c 100644
--- a/boot/bootmeth_efi.c
+++ b/boot/bootmeth_efi.c
@@ -143,10 +143,32 @@ static int distro_efi_check(struct udevice *dev, struct bootflow_iter *iter)
 	return 0;
 }
 
+static void distro_efi_get_fdt_name(char *fname, int size)
+{
+	const char *fdt_fname;
+
+	fdt_fname = env_get("fdtfile");
+	if (fdt_fname) {
+		snprintf(fname, size, "dtb/%s", fdt_fname);
+		log_debug("Using device tree: %s\n", fname);
+	} else {
+		const char *soc = env_get("soc");
+		const char *board = env_get("board");
+		const char *boardver = env_get("boardver");
+
+		/* cf the code in label_boot() which seems very complex */
+		snprintf(fname, size, "dtb/%s%s%s%s.dtb",
+			 soc ? soc : "", soc ? "-" : "", board ? board : "",
+			 boardver ? boardver : "");
+		log_debug("Using default device tree: %s\n", fname);
+	}
+}
+
 static int distro_efi_read_bootflow_file(struct udevice *dev,
 					 struct bootflow *bflow)
 {
 	struct blk_desc *desc = NULL;
+	ulong fdt_addr, size;
 	char fname[256];
 	int ret;
 
@@ -170,15 +192,43 @@ static int distro_efi_read_bootflow_file(struct udevice *dev,
 	if (ret)
 		return log_msg_ret("read", -EINVAL);
 
+	distro_efi_get_fdt_name(fname, sizeof(fname));
+	bflow->fdt_fname = strdup(fname);
+	if (!bflow->fdt_fname)
+		return log_msg_ret("fil", -ENOMEM);
+
+	fdt_addr = env_get_hex("fdt_addr_r", 0);
+	ret = bootmeth_common_read_file(dev, bflow, fname, fdt_addr, &size);
+	if (!ret) {
+		bflow->fdt_size = size;
+		bflow->fdt_addr = fdt_addr;
+
+		/*
+		 * TODO: Apply extension overlay
+		 *
+		 * Here we need to load and apply the extension overlay. This is
+		 * not implemented. See do_extension_apply(). The extension
+		 * stuff needs an implementation in boot/extension.c so it is
+		 * separate from the command code. Really the extension stuff
+		 * should use the device tree and a uclass / driver interface
+		 * rather than implementing its own list
+		 */
+	} else {
+		log_debug("No device tree available\n");
+	}
+
 	return 0;
 }
 
 static int distro_efi_read_bootflow_net(struct bootflow *bflow)
 {
-	const char *addr_str;
+	char file_addr[17], fname[256];
+	char *tftp_argv[] = {"tftp", file_addr, fname, NULL};
+	struct cmd_tbl cmdtp = {};	/* dummy */
+	const char *addr_str, *fdt_addr_str;
 	int ret, arch, size;
+	ulong addr, fdt_addr;
 	char str[36];
-	ulong addr;
 
 	ret = get_efi_pxe_vci(str, sizeof(str));
 	if (ret)
@@ -216,6 +266,25 @@ static int distro_efi_read_bootflow_net(struct bootflow *bflow)
 	efi_set_bootdev("Net", "", bflow->fname, map_sysmem(addr, 0),
 			bflow->size);
 
+	/* read the DT file also */
+	fdt_addr_str = env_get("fdt_addr_r");
+	if (!fdt_addr_str)
+		return log_msg_ret("fdt", -EINVAL);
+	fdt_addr = hextoul(fdt_addr_str, NULL);
+	sprintf(file_addr, "%lx", fdt_addr);
+
+	distro_efi_get_fdt_name(fname, sizeof(fname));
+	bflow->fdt_fname = strdup(fname);
+	if (!bflow->fdt_fname)
+		return log_msg_ret("fil", -ENOMEM);
+
+	if (!do_tftpb(&cmdtp, 0, 3, tftp_argv)) {
+		bflow->fdt_size = env_get_hex("filesize", 0);
+		bflow->fdt_addr = fdt_addr;
+	} else {
+		log_debug("No device tree available\n");
+	}
+
 	bflow->state = BOOTFLOWST_READY;
 
 	return 0;
@@ -243,15 +312,39 @@ static int distro_efi_read_bootflow(struct udevice *dev, struct bootflow *bflow)
 
 int distro_efi_boot(struct udevice *dev, struct bootflow *bflow)
 {
+	ulong kernel, fdt;
 	char cmd[50];
 
+	/* A non-zero buffer indicates the kernel is there */
+	if (bflow->buf) {
+		kernel = (ulong)map_to_sysmem(bflow->buf);
+
+		/*
+		 * use the provided device tree if available, else fall back to
+		 * the control FDT
+		 */
+		if (bflow->fdt_fname)
+			fdt = bflow->fdt_addr;
+		else
+			fdt = (ulong)map_to_sysmem(gd->fdt_blob);
+	} else {
+		/*
+		 * This doesn't actually work for network devices:
+		 *
+		 * do_bootefi_image() No UEFI binary known at 0x02080000
+		 *
+		 * But this is the same behaviour for distro boot, so it can be
+		 * fixed here.
+		 */
+		kernel = env_get_hex("kernel_addr_r", 0);
+		fdt = env_get_hex("fdt_addr_r", 0);
+	}
+
 	/*
 	 * At some point we can add a real interface to bootefi so we can call
-	 * this directly. For now, go through the CLI like distro boot.
+	 * this directly. For now, go through the CLI, like distro boot.
 	 */
-	snprintf(cmd, sizeof(cmd), "bootefi %lx %lx",
-		 (ulong)map_to_sysmem(bflow->buf),
-		 (ulong)map_to_sysmem(gd->fdt_blob));
+	snprintf(cmd, sizeof(cmd), "bootefi %lx %lx", kernel, fdt);
 	if (run_command(cmd, 0))
 		return log_msg_ret("run", -EINVAL);
 
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 49/71] bootstd: Set the distro_bootpart env var with scripts
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (47 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 48/71] bootstd: Support reading the device tree with EFI Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 50/71] bootstd: Update docs on bootmeth_try_file() for sandbox Simon Glass
                   ` (22 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

This environment variable is supposed to be set so that the script knows
which partition holds the script. Set it before invoking the script.

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

(no changes since v1)

 boot/bootmeth_script.c | 3 +++
 include/bootflow.h     | 3 +++
 2 files changed, 6 insertions(+)

diff --git a/boot/bootmeth_script.c b/boot/bootmeth_script.c
index 11dab91c18c..f062cb97ca0 100644
--- a/boot/bootmeth_script.c
+++ b/boot/bootmeth_script.c
@@ -125,6 +125,8 @@ static int script_boot(struct udevice *dev, struct bootflow *bflow)
 	ret = env_set("devtype", blk_get_devtype(bflow->blk));
 	if (!ret)
 		ret = env_set_hex("devnum", desc->devnum);
+	if (!ret)
+		ret = env_set_hex("distro_bootpart", bflow->part);
 	if (!ret)
 		ret = env_set("prefix", bflow->subdir);
 	if (!ret && IS_ENABLED(CONFIG_ARCH_SUNXI) &&
@@ -135,6 +137,7 @@ static int script_boot(struct udevice *dev, struct bootflow *bflow)
 
 	log_debug("devtype: %s\n", env_get("devtype"));
 	log_debug("devnum: %s\n", env_get("devnum"));
+	log_debug("distro_bootpart: %s\n", env_get("distro_bootpart"));
 	log_debug("prefix: %s\n", env_get("prefix"));
 	log_debug("mmc_bootdev: %s\n", env_get("mmc_bootdev"));
 
diff --git a/include/bootflow.h b/include/bootflow.h
index bf71b09edad..ed9b61f5118 100644
--- a/include/bootflow.h
+++ b/include/bootflow.h
@@ -144,6 +144,8 @@ enum bootflow_flags_t {
  *	appear first, then the global ones, if any
  * @doing_global: true if we are iterating through the global bootmeths (which
  *	happens before the normal ones)
+ * @method_flags: flags controlling which methods should be used for this @dev
+ * (enum bootflow_meth_flags_t)
  */
 struct bootflow_iter {
 	int flags;
@@ -161,6 +163,7 @@ struct bootflow_iter {
 	int first_glob_method;
 	struct udevice **method_order;
 	bool doing_global;
+	int method_flags;
 };
 
 /**
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 50/71] bootstd: Update docs on bootmeth_try_file() for sandbox
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (48 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 49/71] bootstd: Set the distro_bootpart env var with scripts Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 51/71] bootstd: Move label parsing into its own function Simon Glass
                   ` (21 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

Mention that this function is also used with a NULL block devices to
access files on the host, when using sandbox.

Update the comment on struct bootflow also.

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

(no changes since v1)

 include/bootflow.h | 2 +-
 include/bootmeth.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/bootflow.h b/include/bootflow.h
index ed9b61f5118..735ed87a001 100644
--- a/include/bootflow.h
+++ b/include/bootflow.h
@@ -43,7 +43,7 @@ enum bootflow_state_t {
  * @glob_node: Points to siblings in the global list (all bootdev)
  * @dev: Bootdevice device which produced this bootflow
  * @blk: Block device which contains this bootflow, NULL if this is a network
- *	device
+ *	device or sandbox 'host' device
  * @part: Partition number (0 for whole device)
  * @fs_type: Filesystem type (FS_TYPE...) if this is fixed by the media, else 0.
  *	For example, the sandbox host-filesystem bootdev sets this to
diff --git a/include/bootmeth.h b/include/bootmeth.h
index 669b14ce81e..bdce301e925 100644
--- a/include/bootmeth.h
+++ b/include/bootmeth.h
@@ -240,7 +240,7 @@ int bootmeth_set_order(const char *order_str);
  * caller before reading the file.
  *
  * @bflow: Information about file to try
- * @desc: Block descriptor to read from
+ * @desc: Block descriptor to read from (NULL for sandbox host)
  * @prefix: Filename prefix to prepend to @fname (NULL for none)
  * @fname: Filename to read
  * Return: 0 if OK, -ENOMEM if not enough memory to allocate bflow->fname,
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 51/71] bootstd: Move label parsing into its own function
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (49 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 50/71] bootstd: Update docs on bootmeth_try_file() for sandbox Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 52/71] bootstd: Add a new bootmeth method to set the bootflow Simon Glass
                   ` (20 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

This is complicated enough to merit its own function, particularly as we
are about to add to it. Create a new label_to_uclass() function to decode
a label.

Also update the code to ignore an empty label or one consisting of just a
number.

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

(no changes since v1)

 boot/bootdev-uclass.c | 48 ++++++++++++++++++++++++++++++++-----------
 1 file changed, 36 insertions(+), 12 deletions(-)

diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c
index 3dcf317c150..f43307d006d 100644
--- a/boot/bootdev-uclass.c
+++ b/boot/bootdev-uclass.c
@@ -354,6 +354,37 @@ int bootdev_unbind_dev(struct udevice *parent)
 	return 0;
 }
 
+/**
+ * label_to_uclass() - Convert a label to a uclass and sequence number
+ *
+ * @label: Label to look up (e.g. "mmc1" or "mmc0")
+ * @seqp: Returns the sequence number, or -1 if none
+ * Returns: sequence number on success, else -ve error code
+ */
+static int label_to_uclass(const char *label, int *seqp)
+{
+	enum uclass_id id;
+	const char *end;
+	int seq, len;
+
+	seq = trailing_strtoln_end(label, NULL, &end);
+	len = end - label;
+	if (!len)
+		return -EINVAL;
+	id = uclass_get_by_namelen(label, len);
+	log_debug("find %s: seq=%d, id=%d/%s\n", label, seq, id,
+		  uclass_get_name(id));
+	if (id == UCLASS_INVALID) {
+		log_warning("Unknown uclass '%s' in label\n", label);
+		return -EINVAL;
+	}
+	if (id == UCLASS_USB)
+		id = UCLASS_MASS_STORAGE;
+	*seqp = seq;
+
+	return id;
+}
+
 /**
  * bootdev_find_by_label() - Convert a label string to a bootdev device
  *
@@ -372,19 +403,12 @@ int bootdev_find_by_label(const char *label, struct udevice **devp)
 	struct udevice *media;
 	struct uclass *uc;
 	enum uclass_id id;
-	const char *end;
-	int seq;
+	int seq, ret;
 
-	seq = trailing_strtoln_end(label, NULL, &end);
-	id = uclass_get_by_namelen(label, end - label);
-	log_debug("find %s: seq=%d, id=%d/%s\n", label, seq, id,
-		  uclass_get_name(id));
-	if (id == UCLASS_INVALID) {
-		log_warning("Unknown uclass '%s' in label\n", label);
-		return -EINVAL;
-	}
-	if (id == UCLASS_USB)
-		id = UCLASS_MASS_STORAGE;
+	ret = label_to_uclass(label, &seq);
+	if (ret < 0)
+		return log_msg_ret("uc", ret);
+	id = ret;
 
 	/* Iterate through devices in the media uclass (e.g. UCLASS_MMC) */
 	uclass_id_foreach_dev(id, media, uc) {
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 52/71] bootstd: Add a new bootmeth method to set the bootflow
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (50 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 51/71] bootstd: Move label parsing into its own function Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 53/71] sandbox: Allow SPI flash bootdevs to be disabled for tests Simon Glass
                   ` (19 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

Normally the bootmeth driver reads the bootflow from the bootdev, since
it knows the correct way to do it.

However it is easier for some bootdevs to handle this themselves. For
example, reading from SPI flash is quite different from other devices.

Add a way for the bootdev to pass a bootflow to the bootmeth, so that
this can be supported.

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

(no changes since v1)

 boot/bootmeth-uclass.c | 11 +++++++++++
 include/bootmeth.h     | 33 +++++++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+)

diff --git a/boot/bootmeth-uclass.c b/boot/bootmeth-uclass.c
index 4c3529d1555..2aee1e0f0c5 100644
--- a/boot/bootmeth-uclass.c
+++ b/boot/bootmeth-uclass.c
@@ -50,6 +50,17 @@ int bootmeth_read_bootflow(struct udevice *dev, struct bootflow *bflow)
 	return ops->read_bootflow(dev, bflow);
 }
 
+int bootmeth_set_bootflow(struct udevice *dev, struct bootflow *bflow,
+			  char *buf, int size)
+{
+	const struct bootmeth_ops *ops = bootmeth_get_ops(dev);
+
+	if (!ops->set_bootflow)
+		return -ENOSYS;
+
+	return ops->set_bootflow(dev, bflow, buf, size);
+}
+
 int bootmeth_boot(struct udevice *dev, struct bootflow *bflow)
 {
 	const struct bootmeth_ops *ops = bootmeth_get_ops(dev);
diff --git a/include/bootmeth.h b/include/bootmeth.h
index bdce301e925..b12dfd42c90 100644
--- a/include/bootmeth.h
+++ b/include/bootmeth.h
@@ -87,6 +87,22 @@ struct bootmeth_ops {
 	 */
 	int (*read_bootflow)(struct udevice *dev, struct bootflow *bflow);
 
+	/**
+	 * set_bootflow() - set the bootflow for a device
+	 *
+	 * This provides a bootflow file to the bootmeth, to see if it is valid.
+	 * If it is, the bootflow is set up accordingly.
+	 *
+	 * @dev:	Bootmethod device to use
+	 * @bflow:	On entry, provides bootdev.
+	 *	Returns updated bootflow if found
+	 * @buf:	Buffer containing the possible bootflow file
+	 * @size:	Size of file
+	 * Return: 0 if OK, -ve on error
+	 */
+	int (*set_bootflow)(struct udevice *dev, struct bootflow *bflow,
+			    char *buf, int size);
+
 	/**
 	 * read_file() - read a file needed for a bootflow
 	 *
@@ -173,6 +189,23 @@ int bootmeth_check(struct udevice *dev, struct bootflow_iter *iter);
  */
 int bootmeth_read_bootflow(struct udevice *dev, struct bootflow *bflow);
 
+/**
+ * bootmeth_set_bootflow() - set the bootflow for a device
+ *
+ * This provides a bootflow file to the bootmeth, to see if it is valid.
+ * If it is, the bootflow is set up accordingly.
+ *
+ * @dev:	Bootmethod device to use
+ * @bflow:	On entry, provides bootdev.
+ *	Returns updated bootflow if found
+ * @buf:	Buffer containing the possible bootflow file (must be allocated
+ * by caller to @size + 1 bytes)
+ * @size:	Size of file
+ * Return: 0 if OK, -ve on error
+ */
+int bootmeth_set_bootflow(struct udevice *dev, struct bootflow *bflow,
+			  char *buf, int size);
+
 /**
  * bootmeth_read_file() - read a file needed for a bootflow
  *
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 53/71] sandbox: Allow SPI flash bootdevs to be disabled for tests
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (51 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 52/71] bootstd: Add a new bootmeth method to set the bootflow Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 54/71] bootstd: Add a SPI flash bootdev Simon Glass
                   ` (18 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

Most tests don't want these and they can create a lot of noise. Add a way
to disable them. Use that in tests, with a flag provided to enable them
for tests that need this feature.

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

(no changes since v1)

 arch/sandbox/cpu/state.c         | 14 ++++++++++++++
 arch/sandbox/include/asm/state.h |  1 +
 arch/sandbox/include/asm/test.h  | 14 ++++++++++++++
 include/test/test.h              | 19 +++++++++++++++++++
 test/test-main.c                 |  1 +
 5 files changed, 49 insertions(+)

diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c
index 76e65741424..4105fd5366e 100644
--- a/arch/sandbox/cpu/state.c
+++ b/arch/sandbox/cpu/state.c
@@ -460,6 +460,20 @@ bool sandbox_eth_enabled(void)
 	return !state->disable_eth;
 }
 
+void sandbox_sf_set_enable_bootdevs(bool enable)
+{
+	struct sandbox_state *state = state_get_current();
+
+	state->disable_sf_bootdevs = !enable;
+}
+
+bool sandbox_sf_bootdev_enabled(void)
+{
+	struct sandbox_state *state = state_get_current();
+
+	return !state->disable_sf_bootdevs;
+}
+
 int state_init(void)
 {
 	state = &main_state;
diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h
index f125fb87af7..59a20595f51 100644
--- a/arch/sandbox/include/asm/state.h
+++ b/arch/sandbox/include/asm/state.h
@@ -97,6 +97,7 @@ struct sandbox_state {
 	bool handle_signals;		/* Handle signals within sandbox */
 	bool autoboot_keyed;		/* Use keyed-autoboot feature */
 	bool disable_eth;		/* Disable Ethernet devices */
+	bool disable_sf_bootdevs;	/* Don't bind SPI flash bootdevs */
 
 	/* Pointer to information for each SPI bus/cs */
 	struct sandbox_spi_info spi[CONFIG_SANDBOX_SPI_MAX_BUS]
diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h
index 1c522e38f3d..4853dc948f3 100644
--- a/arch/sandbox/include/asm/test.h
+++ b/arch/sandbox/include/asm/test.h
@@ -360,4 +360,18 @@ void sandbox_set_eth_enable(bool enable);
  */
 bool sandbox_eth_enabled(void);
 
+/**
+ * sandbox_sf_bootdev_enabled() - Check if SPI flash bootdevs should be bound
+ *
+ * Returns: true if sandbox should bind bootdevs for SPI flash, false if not
+ */
+bool sandbox_sf_bootdev_enabled(void);
+
+/**
+ * sandbox_sf_set_enable_bootdevs() - Enable / disable the SPI flash bootdevs
+ *
+ * @enable: true to bind the SPI flash bootdevs, false to skip
+ */
+void sandbox_sf_set_enable_bootdevs(bool enable);
+
 #endif
diff --git a/include/test/test.h b/include/test/test.h
index 752897cf06f..838e3ce8a8f 100644
--- a/include/test/test.h
+++ b/include/test/test.h
@@ -72,6 +72,7 @@ enum {
 	 */
 	UT_TESTF_MANUAL		= BIT(8),
 	UT_TESTF_ETH_BOOTDEV	= BIT(9),	/* enable Ethernet bootdevs */
+	UT_TESTF_SF_BOOTDEV	= BIT(10),	/* enable SPI flash bootdevs */
 };
 
 /**
@@ -222,4 +223,22 @@ static inline bool test_eth_bootdev_enabled(void)
 	return enabled;
 }
 
+/* Allow SPI flash bootdev to be ignored for testing purposes */
+static inline bool test_sf_bootdev_enabled(void)
+{
+	bool enabled = true;
+
+#ifdef CONFIG_SANDBOX
+	enabled = sandbox_sf_bootdev_enabled();
+#endif
+	return enabled;
+}
+
+static inline void test_sf_set_enable_bootdevs(bool enable)
+{
+#ifdef CONFIG_SANDBOX
+	sandbox_sf_set_enable_bootdevs(enable);
+#endif
+}
+
 #endif /* __TEST_TEST_H */
diff --git a/test/test-main.c b/test/test-main.c
index 9d0f6643d5e..ea959f4e859 100644
--- a/test/test-main.c
+++ b/test/test-main.c
@@ -309,6 +309,7 @@ static int test_pre_run(struct unit_test_state *uts, struct unit_test *test)
 		 * only set this if we know the ethernet uclass will be created
 		 */
 		eth_set_enable_bootdevs(test->flags & UT_TESTF_ETH_BOOTDEV);
+		test_sf_set_enable_bootdevs(test->flags & UT_TESTF_SF_BOOTDEV);
 		ut_assertok(dm_extended_scan(false));
 	}
 
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 54/71] bootstd: Add a SPI flash bootdev
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (52 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 53/71] sandbox: Allow SPI flash bootdevs to be disabled for tests Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 55/71] bootstd: Support reading a script from network or SPI flash Simon Glass
                   ` (17 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

Add a bootdev for SPI flash so that these devices can be used with
standard boot. It only supports loading a script.

Add a special case for the label, since we want to use "spi", not
"spi_flash".

Enable the new bootdev on sandbox.

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

(no changes since v1)

 boot/bootdev-uclass.c              | 10 +++-
 boot/bootflow.c                    | 12 +++++
 configs/sandbox_defconfig          |  1 +
 configs/sandbox_flattree_defconfig |  1 +
 drivers/mtd/spi/Kconfig            |  8 +++
 drivers/mtd/spi/Makefile           |  1 +
 drivers/mtd/spi/sf-uclass.c        | 11 ++++
 drivers/mtd/spi/sf_bootdev.c       | 82 ++++++++++++++++++++++++++++++
 include/bootflow.h                 |  9 ++++
 test/boot/bootdev.c                | 19 ++++---
 10 files changed, 144 insertions(+), 10 deletions(-)
 create mode 100644 drivers/mtd/spi/sf_bootdev.c

diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c
index f43307d006d..dd9ec668e16 100644
--- a/boot/bootdev-uclass.c
+++ b/boot/bootdev-uclass.c
@@ -375,8 +375,14 @@ static int label_to_uclass(const char *label, int *seqp)
 	log_debug("find %s: seq=%d, id=%d/%s\n", label, seq, id,
 		  uclass_get_name(id));
 	if (id == UCLASS_INVALID) {
-		log_warning("Unknown uclass '%s' in label\n", label);
-		return -EINVAL;
+		/* try some special cases */
+		if (IS_ENABLED(CONFIG_BOOTDEV_SPI_FLASH) &&
+		    !strncmp("spi", label, len)) {
+			id = UCLASS_SPI_FLASH;
+		} else {
+			log_warning("Unknown uclass '%s' in label\n", label);
+			return -EINVAL;
+		}
 	}
 	if (id == UCLASS_USB)
 		id = UCLASS_MASS_STORAGE;
diff --git a/boot/bootflow.c b/boot/bootflow.c
index 52cc2f9d548..d2dbc9d4450 100644
--- a/boot/bootflow.c
+++ b/boot/bootflow.c
@@ -440,6 +440,18 @@ int bootflow_iter_check_blk(const struct bootflow_iter *iter)
 	return -ENOTSUPP;
 }
 
+int bootflow_iter_check_sf(const struct bootflow_iter *iter)
+{
+	const struct udevice *media = dev_get_parent(iter->dev);
+	enum uclass_id id = device_get_uclass_id(media);
+
+	log_debug("uclass %d: %s\n", id, uclass_get_name(id));
+	if (id == UCLASS_SPI_FLASH)
+		return 0;
+
+	return -ENOTSUPP;
+}
+
 int bootflow_iter_check_net(const struct bootflow_iter *iter)
 {
 	const struct udevice *media = dev_get_parent(iter->dev);
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 42d961b2e60..5cadc437dc4 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -211,6 +211,7 @@ CONFIG_MMC_SANDBOX=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MTD=y
 CONFIG_SPI_FLASH_SANDBOX=y
+CONFIG_BOOTDEV_SPI_FLASH=y
 CONFIG_SPI_FLASH_ATMEL=y
 CONFIG_SPI_FLASH_EON=y
 CONFIG_SPI_FLASH_GIGADEVICE=y
diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig
index 6e8faf56797..f465b99a6bf 100644
--- a/configs/sandbox_flattree_defconfig
+++ b/configs/sandbox_flattree_defconfig
@@ -138,6 +138,7 @@ CONFIG_PWRSEQ=y
 CONFIG_I2C_EEPROM=y
 CONFIG_MMC_SANDBOX=y
 CONFIG_SPI_FLASH_SANDBOX=y
+CONFIG_BOOTDEV_SPI_FLASH=y
 CONFIG_SPI_FLASH_ATMEL=y
 CONFIG_SPI_FLASH_EON=y
 CONFIG_SPI_FLASH_GIGADEVICE=y
diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig
index 7b858a3a919..a9617c6c58c 100644
--- a/drivers/mtd/spi/Kconfig
+++ b/drivers/mtd/spi/Kconfig
@@ -80,6 +80,14 @@ config SF_DEFAULT_SPEED
 
 if SPI_FLASH
 
+config BOOTDEV_SPI_FLASH
+	bool "SPI Flash bootdev support"
+	help
+	  Enable a boot device for SPI flash. This allows reading a script
+	  from SPI flash so that it can be used to boot an Operating System.
+
+	  If unsure, say N
+
 config SPI_FLASH_SFDP_SUPPORT
 	bool "SFDP table parsing support for SPI NOR flashes"
 	depends on !SPI_FLASH_BAR
diff --git a/drivers/mtd/spi/Makefile b/drivers/mtd/spi/Makefile
index 99cc4185522..409395382f5 100644
--- a/drivers/mtd/spi/Makefile
+++ b/drivers/mtd/spi/Makefile
@@ -21,3 +21,4 @@ obj-$(CONFIG_SPI_FLASH) += spi-nor.o
 obj-$(CONFIG_SPI_FLASH_DATAFLASH) += sf_dataflash.o
 obj-$(CONFIG_$(SPL_TPL_)SPI_FLASH_MTD) += sf_mtd.o
 obj-$(CONFIG_SPI_FLASH_SANDBOX) += sandbox.o
+obj-$(CONFIG_$(SPL_TPL_)BOOTDEV_SPI_FLASH) += sf_bootdev.o
diff --git a/drivers/mtd/spi/sf-uclass.c b/drivers/mtd/spi/sf-uclass.c
index e6e650ef8c0..df1f75390c4 100644
--- a/drivers/mtd/spi/sf-uclass.c
+++ b/drivers/mtd/spi/sf-uclass.c
@@ -6,6 +6,7 @@
 #define LOG_CATEGORY UCLASS_SPI_FLASH
 
 #include <common.h>
+#include <bootdev.h>
 #include <dm.h>
 #include <log.h>
 #include <malloc.h>
@@ -13,6 +14,7 @@
 #include <spi_flash.h>
 #include <asm/global_data.h>
 #include <dm/device-internal.h>
+#include <test/test.h>
 #include "sf_internal.h"
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -86,6 +88,14 @@ int spi_flash_probe_bus_cs(unsigned int busnum, unsigned int cs,
 
 static int spi_flash_post_bind(struct udevice *dev)
 {
+	int ret;
+
+	if (CONFIG_IS_ENABLED(BOOTDEV_SPI_FLASH) && test_sf_bootdev_enabled()) {
+		ret = bootdev_setup_for_dev(dev, "sf_bootdev");
+		if (ret)
+			return log_msg_ret("bd", ret);
+	}
+
 #if defined(CONFIG_NEEDS_MANUAL_RELOC)
 	struct dm_spi_flash_ops *ops = sf_get_ops(dev);
 	static int reloc_done;
@@ -101,6 +111,7 @@ static int spi_flash_post_bind(struct udevice *dev)
 		reloc_done++;
 	}
 #endif
+
 	return 0;
 }
 
diff --git a/drivers/mtd/spi/sf_bootdev.c b/drivers/mtd/spi/sf_bootdev.c
new file mode 100644
index 00000000000..2272e8567ce
--- /dev/null
+++ b/drivers/mtd/spi/sf_bootdev.c
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Read a bootflow from SPI flash
+ *
+ * Copyright 2022 Google LLC
+ */
+
+#include <common.h>
+#include <bootdev.h>
+#include <bootflow.h>
+#include <bootmeth.h>
+#include <dm.h>
+#include <env.h>
+#include <malloc.h>
+#include <spi_flash.h>
+
+static int sf_get_bootflow(struct udevice *dev, struct bootflow_iter *iter,
+			   struct bootflow *bflow)
+{
+	struct udevice *sf = dev_get_parent(dev);
+	uint size;
+	char *buf;
+	int ret;
+
+	/* We only support the whole device, not partitions */
+	if (iter->part)
+		return log_msg_ret("max", -ESHUTDOWN);
+
+	size = env_get_hex("script_size_f", 0);
+	if (!size)
+		return log_msg_ret("sz", -EINVAL);
+
+	buf = malloc(size + 1);
+	if (!buf)
+		return log_msg_ret("buf", -ENOMEM);
+
+	ret = spi_flash_read_dm(sf, env_get_hex("script_offset_f", 0),
+				size, buf);
+	if (ret)
+		return log_msg_ret("cmd", -EINVAL);
+	bflow->state = BOOTFLOWST_MEDIA;
+
+	ret = bootmeth_set_bootflow(bflow->method, bflow, buf, size);
+	if (ret) {
+		free(buf);
+		return log_msg_ret("method", ret);
+	}
+
+	return 0;
+}
+
+static int sf_bootdev_bind(struct udevice *dev)
+{
+	struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
+
+	ucp->prio = BOOTDEVP_2_SCAN_FAST;
+
+	return 0;
+}
+
+struct bootdev_ops sf_bootdev_ops = {
+	.get_bootflow	= sf_get_bootflow,
+};
+
+static const struct udevice_id sf_bootdev_ids[] = {
+	{ .compatible = "u-boot,bootdev-sf" },
+	{ }
+};
+
+U_BOOT_DRIVER(sf_bootdev) = {
+	.name		= "sf_bootdev",
+	.id		= UCLASS_BOOTDEV,
+	.ops		= &sf_bootdev_ops,
+	.bind		= sf_bootdev_bind,
+	.of_match	= sf_bootdev_ids,
+};
+
+BOOTDEV_HUNTER(sf_bootdev_hunter) = {
+	.prio		= BOOTDEVP_2_SCAN_FAST,
+	.uclass		= UCLASS_SPI_FLASH,
+	.drv		= DM_DRIVER_REF(sf_bootdev),
+};
diff --git a/include/bootflow.h b/include/bootflow.h
index 735ed87a001..319dda8e0be 100644
--- a/include/bootflow.h
+++ b/include/bootflow.h
@@ -331,6 +331,15 @@ void bootflow_remove(struct bootflow *bflow);
  */
 int bootflow_iter_check_blk(const struct bootflow_iter *iter);
 
+/**
+ * bootflow_iter_check_sf() - Check that a bootflow uses SPI FLASH
+ *
+ * This checks the bootdev in the bootflow to make sure it uses SPI flash
+ *
+ * Return: 0 if OK, -ENOTSUPP if some other device is used (e.g. ethernet)
+ */
+int bootflow_iter_check_sf(const struct bootflow_iter *iter);
+
 /**
  * bootflow_iter_check_net() - Check that a bootflow uses a network device
  *
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c
index 2ad31a0ef66..ea0703fa5c8 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -243,9 +243,10 @@ static int bootdev_test_hunter(struct unit_test_state *uts)
 	ut_assert_nextline("  10        mmc              mmc_bootdev");
 	ut_assert_nextline("  30        nvme             nvme_bootdev");
 	ut_assert_nextline("  30        scsi             scsi_bootdev");
+	ut_assert_nextline("  30        spi_flash        sf_bootdev");
 	ut_assert_nextline("  40        usb              usb_bootdev");
 	ut_assert_nextline("  30        virtio           virtio_bootdev");
-	ut_assert_nextline("(total hunters: 7)");
+	ut_assert_nextline("(total hunters: 8)");
 	ut_assert_console_end();
 
 	ut_assertok(bootdev_hunt("usb1", false));
@@ -253,8 +254,8 @@ static int bootdev_test_hunter(struct unit_test_state *uts)
 		"Bus usb@1: scanning bus usb@1 for devices... 5 USB Device(s) found");
 	ut_assert_console_end();
 
-	/* USB is fifth in the list, so bit 5 */
-	ut_asserteq(BIT(5), std->hunters_used);
+	/* USB is fifth in the list, so bit 6 */
+	ut_asserteq(BIT(6), std->hunters_used);
 
 	return 0;
 }
@@ -274,7 +275,7 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
 	ut_assertok(run_command("bootdev hunt -l", 0));
 	ut_assert_nextline("Prio  Used  Uclass           Hunter");
 	ut_assert_nextlinen("----");
-	ut_assert_skip_to_line("(total hunters: 7)");
+	ut_assert_skip_to_line("(total hunters: 8)");
 	ut_assert_console_end();
 
 	/* Scan all hunters */
@@ -288,10 +289,11 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
 	ut_assert_nextline("Hunting with: nvme");
 	ut_assert_nextline("Hunting with: scsi");
 	ut_assert_nextline("scanning bus for devices...");
-	ut_assert_skip_to_line("Hunting with: usb");
+	ut_assert_skip_to_line("Hunting with: spi_flash");
+	ut_assert_nextline("Hunting with: usb");
 	ut_assert_nextline(
 		"Bus usb@1: scanning bus usb@1 for devices... 5 USB Device(s) found");
-	ut_assert_skip_to_line("Hunting with: virtio");
+	ut_assert_nextline("Hunting with: virtio");
 	ut_assert_console_end();
 
 	/* List available hunters */
@@ -303,12 +305,13 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
 	ut_assert_nextline("  10     *  mmc              mmc_bootdev");
 	ut_assert_nextline("  30     *  nvme             nvme_bootdev");
 	ut_assert_nextline("  30     *  scsi             scsi_bootdev");
+	ut_assert_nextline("  30     *  spi_flash        sf_bootdev");
 	ut_assert_nextline("  40     *  usb              usb_bootdev");
 	ut_assert_nextline("  30     *  virtio           virtio_bootdev");
-	ut_assert_nextline("(total hunters: 7)");
+	ut_assert_nextline("(total hunters: 8)");
 	ut_assert_console_end();
 
-	ut_asserteq(GENMASK(6, 0), std->hunters_used);
+	ut_asserteq(GENMASK(7, 0), std->hunters_used);
 
 	return 0;
 }
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 55/71] bootstd: Support reading a script from network or SPI flash
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (53 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 54/71] bootstd: Add a SPI flash bootdev Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 56/71] bootstd: Treat DHCP and PXE as bootdev labels Simon Glass
                   ` (16 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

At present this bootmeth only supports a block device and the sandbox
host filesystem. Add support for obtaining the script from a network
device. Also implement the set_bootflow() method so that it is easy
for other bootdevs (such as enabling SPI flash to support scripts).

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

(no changes since v1)

 boot/bootmeth_script.c | 93 ++++++++++++++++++++++++++++++++++++------
 1 file changed, 80 insertions(+), 13 deletions(-)

diff --git a/boot/bootmeth_script.c b/boot/bootmeth_script.c
index f062cb97ca0..64653d95b87 100644
--- a/boot/bootmeth_script.c
+++ b/boot/bootmeth_script.c
@@ -19,18 +19,14 @@
 #include <image.h>
 #include <malloc.h>
 #include <mapmem.h>
+#include <net.h>
 
 #define SCRIPT_FNAME1	"boot.scr.uimg"
 #define SCRIPT_FNAME2	"boot.scr"
 
 static int script_check(struct udevice *dev, struct bootflow_iter *iter)
 {
-	int ret;
-
-	/* This only works on block devices */
-	ret = bootflow_iter_check_blk(iter);
-	if (ret)
-		return log_msg_ret("blk", ret);
+	/* This works on block devices, network devices and SPI Flash */
 
 	return 0;
 }
@@ -65,11 +61,11 @@ static int script_fill_info(struct bootflow *bflow)
 	return 0;
 }
 
-static int script_read_bootflow(struct udevice *dev, struct bootflow *bflow)
+static int script_read_bootflow_file(struct udevice *bootstd,
+				     struct bootflow *bflow)
 {
 	struct blk_desc *desc = NULL;
 	const char *const *prefixes;
-	struct udevice *bootstd;
 	const char *prefix;
 	int ret, i;
 
@@ -77,12 +73,12 @@ static int script_read_bootflow(struct udevice *dev, struct bootflow *bflow)
 	if (ret)
 		return log_msg_ret("std", ret);
 
-	/* We require a partition table */
-	if (!bflow->part)
-		return -ENOENT;
-
-	if (bflow->blk)
+	if (bflow->blk) {
+		/* We require a partition table */
+		if (!bflow->part)
+			return -ENOENT;
 		 desc = dev_get_uclass_plat(bflow->blk);
+	}
 
 	prefixes = bootstd_get_prefixes(bootstd);
 	i = 0;
@@ -116,6 +112,76 @@ static int script_read_bootflow(struct udevice *dev, struct bootflow *bflow)
 	return 0;
 }
 
+static int script_read_bootflow_net(struct bootflow *bflow)
+{
+	const char *addr_str;
+	int size, ret;
+	char *fname;
+	ulong addr;
+
+	/* figure out the load address */
+	addr_str = env_get("scriptaddr");
+	addr = addr_str ? hextoul(addr_str, NULL) : image_load_addr;
+
+	fname = env_get("boot_script_dhcp");
+	if (!fname)
+		return log_msg_ret("dhc", -EINVAL);
+
+	ret = dhcp_run(addr, fname, true);
+	if (ret)
+		return log_msg_ret("dhc", ret);
+
+	size = env_get_hex("filesize", 0);
+	if (!size)
+		return log_msg_ret("sz", -EINVAL);
+
+	bflow->buf = malloc(size + 1);
+	if (!bflow->buf)
+		return log_msg_ret("buf", -ENOMEM);
+	memcpy(bflow->buf, map_sysmem(addr, size), size);
+	bflow->buf[size] = '\0';
+	bflow->size = size;
+	bflow->state = BOOTFLOWST_READY;
+
+	return 0;
+}
+
+static int script_read_bootflow(struct udevice *dev, struct bootflow *bflow)
+{
+	const struct udevice *media = dev_get_parent(bflow->dev);
+	struct udevice *bootstd;
+	int ret;
+
+	ret = uclass_first_device_err(UCLASS_BOOTSTD, &bootstd);
+	if (ret)
+		return log_msg_ret("std", ret);
+
+	if (IS_ENABLED(CONFIG_CMD_DHCP) &&
+	    device_get_uclass_id(media) == UCLASS_ETH) {
+		/* we only support reading from one device, so ignore 'dev' */
+		ret = script_read_bootflow_net(bflow);
+		if (ret)
+			return log_msg_ret("net", ret);
+	} else {
+		ret = script_read_bootflow_file(bootstd, bflow);
+		if (ret)
+			return log_msg_ret("blk", ret);
+	}
+
+	return 0;
+}
+
+static int script_set_bootflow(struct udevice *dev, struct bootflow *bflow,
+			       char *buf, int size)
+{
+	buf[size] = '\0';
+	bflow->buf = buf;
+	bflow->size = size;
+	bflow->state = BOOTFLOWST_READY;
+
+	return 0;
+}
+
 static int script_boot(struct udevice *dev, struct bootflow *bflow)
 {
 	struct blk_desc *desc = dev_get_uclass_plat(bflow->blk);
@@ -162,6 +228,7 @@ static int script_bootmeth_bind(struct udevice *dev)
 static struct bootmeth_ops script_bootmeth_ops = {
 	.check		= script_check,
 	.read_bootflow	= script_read_bootflow,
+	.set_bootflow	= script_set_bootflow,
 	.read_file	= bootmeth_common_read_file,
 	.boot		= script_boot,
 };
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 56/71] bootstd: Treat DHCP and PXE as bootdev labels
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (54 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 55/71] bootstd: Support reading a script from network or SPI flash Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 57/71] bootstd: Use hunters when scanning for bootflows Simon Glass
                   ` (15 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

These are associated with the ethernet boot device but do not match its
uclass name, so handle them as special cases.

Provide a way to pass flags through with the bootdev so that we know
how to process it. The flags are checked by the bootmeths, to ensure that
only the selected bootmeth is used.

While these both use the network device, they work quite differently. It
is common to run only one of these, or to run PXE before DHCP. Provide
bootflow flags to control which methods are used. Check these in the two
bootmeths so that only the chosen one is used.

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

(no changes since v1)

 boot/bootdev-uclass.c  | 53 ++++++++++++++++++++++++------------------
 boot/bootmeth_efi.c    |  4 ++++
 boot/bootmeth_pxe.c    |  3 +++
 boot/bootmeth_script.c |  2 ++
 boot/vbe_simple_fw.c   |  2 +-
 cmd/bootdev.c          |  2 +-
 cmd/bootflow.c         |  2 +-
 include/bootdev.h      | 15 ++++++++----
 include/bootflow.h     | 15 ++++++++++++
 test/boot/bootdev.c    | 17 ++++++++++----
 10 files changed, 81 insertions(+), 34 deletions(-)

diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c
index dd9ec668e16..7ac42afd7b3 100644
--- a/boot/bootdev-uclass.c
+++ b/boot/bootdev-uclass.c
@@ -359,14 +359,17 @@ int bootdev_unbind_dev(struct udevice *parent)
  *
  * @label: Label to look up (e.g. "mmc1" or "mmc0")
  * @seqp: Returns the sequence number, or -1 if none
+ * @method_flagsp: If non-NULL, returns any flags implied by the label
+ * (enum bootflow_meth_flags_t), 0 if none
  * Returns: sequence number on success, else -ve error code
  */
-static int label_to_uclass(const char *label, int *seqp)
+static int label_to_uclass(const char *label, int *seqp, int *method_flagsp)
 {
+	int seq, len, method_flags;
 	enum uclass_id id;
 	const char *end;
-	int seq, len;
 
+	method_flags = 0;
 	seq = trailing_strtoln_end(label, NULL, &end);
 	len = end - label;
 	if (!len)
@@ -379,6 +382,14 @@ static int label_to_uclass(const char *label, int *seqp)
 		if (IS_ENABLED(CONFIG_BOOTDEV_SPI_FLASH) &&
 		    !strncmp("spi", label, len)) {
 			id = UCLASS_SPI_FLASH;
+		} else if (IS_ENABLED(CONFIG_BOOTDEV_ETH) &&
+		    !strncmp("pxe", label, len)) {
+			id = UCLASS_ETH;
+			method_flags |= BOOTFLOW_METHF_PXE_ONLY;
+		} else if (IS_ENABLED(CONFIG_BOOTDEV_ETH) &&
+		    !strncmp("dhcp", label, len)) {
+			id = UCLASS_ETH;
+			method_flags |= BOOTFLOW_METHF_DHCP_ONLY;
 		} else {
 			log_warning("Unknown uclass '%s' in label\n", label);
 			return -EINVAL;
@@ -387,31 +398,21 @@ static int label_to_uclass(const char *label, int *seqp)
 	if (id == UCLASS_USB)
 		id = UCLASS_MASS_STORAGE;
 	*seqp = seq;
+	if (method_flagsp)
+		*method_flagsp = method_flags;
 
 	return id;
 }
 
-/**
- * bootdev_find_by_label() - Convert a label string to a bootdev device
- *
- * Looks up a label name to find the associated bootdev. For example, if the
- * label name is "mmc2", this will find a bootdev for an mmc device whose
- * sequence number is 2.
- *
- * @label: Label string to convert, e.g. "mmc2"
- * @devp: Returns bootdev device corresponding to that boot label
- * Return: 0 if OK, -EINVAL if the label name (e.g. "mmc") does not refer to a
- *	uclass, -ENOENT if no bootdev for that media has the sequence number
- *	(e.g. 2)
- */
-int bootdev_find_by_label(const char *label, struct udevice **devp)
+int bootdev_find_by_label(const char *label, struct udevice **devp,
+			  int *method_flagsp)
 {
+	int seq, ret, method_flags = 0;
 	struct udevice *media;
 	struct uclass *uc;
 	enum uclass_id id;
-	int seq, ret;
 
-	ret = label_to_uclass(label, &seq);
+	ret = label_to_uclass(label, &seq, &method_flags);
 	if (ret < 0)
 		return log_msg_ret("uc", ret);
 	id = ret;
@@ -441,6 +442,8 @@ int bootdev_find_by_label(const char *label, struct udevice **devp)
 		if (!ret) {
 			log_debug("- found %s\n", bdev->name);
 			*devp = bdev;
+			if (method_flagsp)
+				*method_flagsp = method_flags;
 			return 0;
 		}
 		log_debug("- no device in %s\n", media->name);
@@ -450,9 +453,11 @@ int bootdev_find_by_label(const char *label, struct udevice **devp)
 	return -ENOENT;
 }
 
-int bootdev_find_by_any(const char *name, struct udevice **devp)
+int bootdev_find_by_any(const char *name, struct udevice **devp,
+			int *method_flagsp)
 {
 	struct udevice *dev;
+	int method_flags = 0;
 	int ret, seq;
 	char *endp;
 
@@ -462,18 +467,18 @@ int bootdev_find_by_any(const char *name, struct udevice **devp)
 	if (*endp) {
 		ret = uclass_get_device_by_name(UCLASS_BOOTDEV, name, &dev);
 		if (ret == -ENODEV) {
-			ret = bootdev_find_by_label(name, &dev);
+			ret = bootdev_find_by_label(name, &dev, &method_flags);
 			if (ret) {
 				printf("Cannot find bootdev '%s' (err=%d)\n",
 				       name, ret);
-				return ret;
+				return log_msg_ret("lab", ret);
 			}
 			ret = device_probe(dev);
 		}
 		if (ret) {
 			printf("Cannot probe bootdev '%s' (err=%d)\n", name,
 			       ret);
-			return ret;
+			return log_msg_ret("pro", ret);
 		}
 	} else {
 		ret = uclass_get_device_by_seq(UCLASS_BOOTDEV, seq, &dev);
@@ -484,6 +489,8 @@ int bootdev_find_by_any(const char *name, struct udevice **devp)
 	}
 
 	*devp = dev;
+	if (method_flagsp)
+		*method_flagsp = method_flags;
 
 	return 0;
 }
@@ -593,7 +600,7 @@ static int build_order(struct udevice *bootstd, struct udevice **order,
 
 		upto = 0;
 		for (i = 0; labels[i]; i++) {
-			ret = bootdev_find_by_label(labels[i], &dev);
+			ret = bootdev_find_by_label(labels[i], &dev, NULL);
 			if (!ret) {
 				if (upto == max_count) {
 					overflow_target = labels[i];
diff --git a/boot/bootmeth_efi.c b/boot/bootmeth_efi.c
index 53a0489b93c..67c972e3fe4 100644
--- a/boot/bootmeth_efi.c
+++ b/boot/bootmeth_efi.c
@@ -140,6 +140,10 @@ static int distro_efi_check(struct udevice *dev, struct bootflow_iter *iter)
 	if (bootflow_iter_check_blk(iter) && bootflow_iter_check_net(iter))
 		return log_msg_ret("blk", -ENOTSUPP);
 
+	/* This works on block devices and network devices */
+	if (iter->method_flags & BOOTFLOW_METHF_PXE_ONLY)
+		return log_msg_ret("pxe", -ENOTSUPP);
+
 	return 0;
 }
 
diff --git a/boot/bootmeth_pxe.c b/boot/bootmeth_pxe.c
index 13e2ff486dc..ecf8557af83 100644
--- a/boot/bootmeth_pxe.c
+++ b/boot/bootmeth_pxe.c
@@ -48,6 +48,9 @@ static int distro_pxe_check(struct udevice *dev, struct bootflow_iter *iter)
 	if (ret)
 		return log_msg_ret("net", ret);
 
+	if (iter->method_flags & BOOTFLOW_METHF_DHCP_ONLY)
+		return log_msg_ret("dhcp", -ENOTSUPP);
+
 	return 0;
 }
 
diff --git a/boot/bootmeth_script.c b/boot/bootmeth_script.c
index 64653d95b87..ec7c68964e6 100644
--- a/boot/bootmeth_script.c
+++ b/boot/bootmeth_script.c
@@ -27,6 +27,8 @@
 static int script_check(struct udevice *dev, struct bootflow_iter *iter)
 {
 	/* This works on block devices, network devices and SPI Flash */
+	if (iter->method_flags & BOOTFLOW_METHF_PXE_ONLY)
+		return log_msg_ret("pxe", -ENOTSUPP);
 
 	return 0;
 }
diff --git a/boot/vbe_simple_fw.c b/boot/vbe_simple_fw.c
index 0a49d286703..d59a704ddba 100644
--- a/boot/vbe_simple_fw.c
+++ b/boot/vbe_simple_fw.c
@@ -176,7 +176,7 @@ static int simple_load_from_image(struct spl_image_info *spl_image,
 
 	priv = dev_get_priv(meth);
 	log_debug("simple %s\n", priv->storage);
-	ret = bootdev_find_by_label(priv->storage, &bdev);
+	ret = bootdev_find_by_label(priv->storage, &bdev, NULL);
 	if (ret)
 		return log_msg_ret("bd", ret);
 	log_debug("bootdev %s\n", bdev->name);
diff --git a/cmd/bootdev.c b/cmd/bootdev.c
index 28866faac76..5b1efaaee87 100644
--- a/cmd/bootdev.c
+++ b/cmd/bootdev.c
@@ -57,7 +57,7 @@ static int do_bootdev_select(struct cmd_tbl *cmdtp, int flag, int argc,
 		std->cur_bootdev = NULL;
 		return 0;
 	}
-	if (bootdev_find_by_any(argv[1], &dev))
+	if (bootdev_find_by_any(argv[1], &dev, NULL))
 		return CMD_RET_FAILURE;
 
 	std->cur_bootdev = dev;
diff --git a/cmd/bootflow.c b/cmd/bootflow.c
index 56dd35b69cf..c8b2f5efdeb 100644
--- a/cmd/bootflow.c
+++ b/cmd/bootflow.c
@@ -121,7 +121,7 @@ static int do_bootflow_scan(struct cmd_tbl *cmdtp, int flag, int argc,
 		if (argc > 1) {
 			const char *label = argv[1];
 
-			if (bootdev_find_by_any(label, &dev))
+			if (bootdev_find_by_any(label, &dev, NULL))
 				return CMD_RET_FAILURE;
 		}
 	} else {
diff --git a/include/bootdev.h b/include/bootdev.h
index deef7890489..db03c5c032e 100644
--- a/include/bootdev.h
+++ b/include/bootdev.h
@@ -222,19 +222,26 @@ int bootdev_next_bootflow(struct bootflow **bflowp);
  * @label: Label to look up (e.g. "mmc1" or "mmc0")
  * @devp: Returns the bootdev device found, or NULL if none (note it does not
  *	return the media device, but its bootdev child)
+ * @method_flagsp: If non-NULL, returns any flags implied by the label
+ * (enum bootflow_meth_flags_t), 0 if none. Unset if function fails
  * Return: 0 if OK, -EINVAL if the uclass is not supported by this board,
- *	-ENOENT if there is no device with that number
+ * -ENOENT if there is no device with that number
  */
-int bootdev_find_by_label(const char *label, struct udevice **devp);
+int bootdev_find_by_label(const char *label, struct udevice **devp,
+			  int *method_flagsp);
 
 /**
  * bootdev_find_by_any() - Find a bootdev by name, label or sequence
  *
  * @name: name (e.g. "mmc2.bootdev"), label ("mmc2"), or sequence ("2") to find
  * @devp: returns the device found, on success
- * Return: 0 if OK, -ve on error
+ * @method_flagsp: If non-NULL, returns any flags implied by the label
+ * (enum bootflow_meth_flags_t), 0 if none. Unset if function fails
+ * Return: 0 if OK, -EINVAL if the uclass is not supported by this board,
+ * -ENOENT if there is no device with that number
  */
-int bootdev_find_by_any(const char *name, struct udevice **devp);
+int bootdev_find_by_any(const char *name, struct udevice **devp,
+			int *method_flagsp);
 
 /**
  * bootdev_setup_iter_order() - Set up the ordering of bootdevs to scan
diff --git a/include/bootflow.h b/include/bootflow.h
index 319dda8e0be..9c6610bb922 100644
--- a/include/bootflow.h
+++ b/include/bootflow.h
@@ -104,6 +104,21 @@ enum bootflow_flags_t {
 	BOOTFLOWF_SKIP_GLOBAL	= 1 << 4,
 };
 
+/**
+ * enum bootflow_meth_flags_t - flags controlling which bootmeths are used
+ *
+ * Used during iteration, e.g. by bootdev_find_by_label(), to determine which
+ * bootmeths are used for the current bootdev. The flags reset when the bootdev
+ * changes
+ *
+ * @BOOTFLOW_METHF_DHCP_ONLY: Only use dhcp (scripts and EFI)
+ * @BOOTFLOW_METHF_PXE_ONLY: Only use pxe (PXE boot)
+ */
+enum bootflow_meth_flags_t {
+	BOOTFLOW_METHF_DHCP_ONLY	= 1 << 0,
+	BOOTFLOW_METHF_PXE_ONLY		= 1 << 1,
+};
+
 /**
  * struct bootflow_iter - state for iterating through bootflows
  *
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c
index ea0703fa5c8..e6045b05d81 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -102,22 +102,31 @@ BOOTSTD_TEST(bootdev_test_cmd_select, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
 static int bootdev_test_labels(struct unit_test_state *uts)
 {
 	struct udevice *dev, *media;
+	int mflags = 0;
 
-	ut_assertok(bootdev_find_by_label("mmc2", &dev));
+	ut_assertok(bootdev_find_by_label("mmc2", &dev, &mflags));
 	ut_asserteq(UCLASS_BOOTDEV, device_get_uclass_id(dev));
+	ut_asserteq(0, mflags);
 	media = dev_get_parent(dev);
 	ut_asserteq(UCLASS_MMC, device_get_uclass_id(media));
 	ut_asserteq_str("mmc2", media->name);
 
+	/* Check method flags */
+	ut_assertok(bootdev_find_by_label("pxe", &dev, &mflags));
+	ut_asserteq(BOOTFLOW_METHF_PXE_ONLY, mflags);
+	ut_assertok(bootdev_find_by_label("dhcp", &dev, &mflags));
+	ut_asserteq(BOOTFLOW_METHF_DHCP_ONLY, mflags);
+
 	/* Check invalid uclass */
-	ut_asserteq(-EINVAL, bootdev_find_by_label("fred0", &dev));
+	ut_asserteq(-EINVAL, bootdev_find_by_label("fred0", &dev, &mflags));
 
 	/* Check unknown sequence number */
-	ut_asserteq(-ENOENT, bootdev_find_by_label("mmc6", &dev));
+	ut_asserteq(-ENOENT, bootdev_find_by_label("mmc6", &dev, &mflags));
 
 	return 0;
 }
-BOOTSTD_TEST(bootdev_test_labels, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
+BOOTSTD_TEST(bootdev_test_labels, UT_TESTF_DM | UT_TESTF_SCAN_FDT |
+	     UT_TESTF_ETH_BOOTDEV);
 
 /* Check bootdev ordering with the bootdev-order property */
 static int bootdev_test_order(struct unit_test_state *uts)
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 57/71] bootstd: Use hunters when scanning for bootflows
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (55 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 56/71] bootstd: Treat DHCP and PXE as bootdev labels Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 58/71] bootstd: Allow hunting for bootdevs of a given priority Simon Glass
                   ` (14 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

Add a flag to control whether hunters are used when scanning for
bootflows. Enable it by default and tidy up the flag comments a little.

Fow now this has no effect, until a future patch enables this feature.

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

(no changes since v1)

 cmd/bootflow.c     |  5 ++++-
 include/bootflow.h | 21 ++++++++++++++++-----
 2 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/cmd/bootflow.c b/cmd/bootflow.c
index c8b2f5efdeb..fe58de5fa59 100644
--- a/cmd/bootflow.c
+++ b/cmd/bootflow.c
@@ -96,7 +96,7 @@ static int do_bootflow_scan(struct cmd_tbl *cmdtp, int flag, int argc,
 	struct udevice *dev;
 	struct bootflow bflow;
 	bool all = false, boot = false, errors = false, no_global = false;
-	bool list = false;
+	bool list = false, no_hunter = false;
 	int num_valid = 0;
 	bool has_args;
 	int ret, i;
@@ -115,6 +115,7 @@ static int do_bootflow_scan(struct cmd_tbl *cmdtp, int flag, int argc,
 			errors = strchr(argv[1], 'e');
 			no_global = strchr(argv[1], 'G');
 			list = strchr(argv[1], 'l');
+			no_hunter = strchr(argv[1], 'H');
 			argc--;
 			argv++;
 		}
@@ -141,6 +142,8 @@ static int do_bootflow_scan(struct cmd_tbl *cmdtp, int flag, int argc,
 		flags |= BOOTFLOWF_ALL;
 	if (no_global)
 		flags |= BOOTFLOWF_SKIP_GLOBAL;
+	if (!no_hunter)
+		flags |= BOOTFLOWF_HUNT;
 
 	/*
 	 * If we have a device, just scan for bootflows attached to that device
diff --git a/include/bootflow.h b/include/bootflow.h
index 9c6610bb922..4012f4b8a82 100644
--- a/include/bootflow.h
+++ b/include/bootflow.h
@@ -91,17 +91,28 @@ struct bootflow {
  * enum bootflow_flags_t - flags for the bootflow iterator
  *
  * @BOOTFLOWF_FIXED: Only used fixed/internal media
- * @BOOTFLOWF_SHOW: Show each bootdev before scanning it
+ * @BOOTFLOWF_SHOW: Show each bootdev before scanning it; show each hunter
+ * before using it
  * @BOOTFLOWF_ALL: Return bootflows with errors as well
- * @BOOTFLOWF_SINGLE_DEV: Just scan one bootmeth
- * @BOOTFLOWF_SKIP_GLOBAL: Don't scan global bootmeths
+ * @BOOTFLOWF_HUNT: Hunt for new bootdevs using the bootdrv hunters
+ *
+ * Internal flags:
+ * @BOOTFLOWF_SINGLE_DEV: (internal) Just scan one bootdev
+ * @BOOTFLOWF_SKIP_GLOBAL: (internal) Don't scan global bootmeths
+ * this uclass
  */
 enum bootflow_flags_t {
 	BOOTFLOWF_FIXED		= 1 << 0,
 	BOOTFLOWF_SHOW		= 1 << 1,
 	BOOTFLOWF_ALL		= 1 << 2,
-	BOOTFLOWF_SINGLE_DEV	= 1 << 3,
-	BOOTFLOWF_SKIP_GLOBAL	= 1 << 4,
+	BOOTFLOWF_HUNT		= 1 << 3,
+
+	/*
+	 * flags used internally by standard boot - do not set these when
+	 * calling bootflow_scan_bootdev() etc.
+	 */
+	BOOTFLOWF_SINGLE_DEV	= 1 << 16,
+	BOOTFLOWF_SKIP_GLOBAL	= 1 << 17,
 };
 
 /**
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 58/71] bootstd: Allow hunting for bootdevs of a given priority
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (56 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 57/71] bootstd: Use hunters when scanning for bootflows Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 59/71] bootstd: Add a new pre-scan priority for bootdevs Simon Glass
                   ` (13 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

Add a way to run the hunter function for a particular priority, so that
new bootdevs can be found.

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

(no changes since v1)

 boot/bootdev-uclass.c | 25 +++++++++++++++++++++++++
 include/bootdev.h     | 11 +++++++++++
 test/boot/bootdev.c   | 25 +++++++++++++++++++++++++
 3 files changed, 61 insertions(+)

diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c
index 7ac42afd7b3..e8686159f2b 100644
--- a/boot/bootdev-uclass.c
+++ b/boot/bootdev-uclass.c
@@ -742,6 +742,31 @@ int bootdev_hunt(const char *spec, bool show)
 	return result;
 }
 
+int bootdev_hunt_prio(enum bootdev_prio_t prio, bool show)
+{
+	struct bootdev_hunter *start;
+	int n_ent, i;
+	int result;
+
+	start = ll_entry_start(struct bootdev_hunter, bootdev_hunter);
+	n_ent = ll_entry_count(struct bootdev_hunter, bootdev_hunter);
+	result = 0;
+
+	log_debug("Hunting for priority %d\n", prio);
+	for (i = 0; i < n_ent; i++) {
+		struct bootdev_hunter *info = start + i;
+		int ret;
+
+		if (prio != info->prio)
+			continue;
+		ret = bootdev_hunt_drv(info, i, show);
+		if (ret && ret != -ENOENT)
+			result = ret;
+	}
+
+	return result;
+}
+
 void bootdev_list_hunters(struct bootstd_priv *std)
 {
 	struct bootdev_hunter *orig, *start;
diff --git a/include/bootdev.h b/include/bootdev.h
index db03c5c032e..b7973fa5760 100644
--- a/include/bootdev.h
+++ b/include/bootdev.h
@@ -284,6 +284,17 @@ void bootdev_list_hunters(struct bootstd_priv *std);
  */
 int bootdev_hunt(const char *spec, bool show);
 
+/**
+ * bootdev_hunt_prio() - Hunt for bootdevs of a particular priority
+ *
+ * This runs all hunters which can find bootdevs of the given priority.
+ *
+ * @prio: Priority to use
+ * @show: true to show each hunter as it is used
+ * Returns: 0 if OK, -ve on error
+ */
+int bootdev_hunt_prio(enum bootdev_prio_t prio, bool show);
+
 #if CONFIG_IS_ENABLED(BOOTSTD)
 /**
  * bootdev_setup_for_dev() - Bind a new bootdev device (deprecated)
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c
index e6045b05d81..f9653633a68 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -363,3 +363,28 @@ static int bootdev_test_bootable(struct unit_test_state *uts)
 	return 0;
 }
 BOOTSTD_TEST(bootdev_test_bootable, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
+
+/* Check hunting for bootdev of a particular priority */
+static int bootdev_test_hunt_prio(struct unit_test_state *uts)
+{
+	test_set_skip_delays(true);
+
+	console_record_reset_enable();
+	ut_assertok(bootdev_hunt_prio(BOOTDEVP_2_SCAN_FAST, false));
+	ut_assert_nextline("scanning bus for devices...");
+	ut_assert_skip_to_line("            Type: Hard Disk");
+	ut_assert_nextlinen("            Capacity:");
+	ut_assert_console_end();
+
+	/* now try a different priority, verbosely */
+	ut_assertok(bootdev_hunt_prio(BOOTDEVP_3_SCAN_SLOW, true));
+	ut_assert_nextline("Hunting with: ide");
+	ut_assert_nextline("Bus 0: not available  ");
+	ut_assert_nextline("Hunting with: usb");
+	ut_assert_nextline(
+		"Bus usb@1: scanning bus usb@1 for devices... 5 USB Device(s) found");
+	ut_assert_console_end();
+
+	return 0;
+}
+BOOTSTD_TEST(bootdev_test_hunt_prio, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 59/71] bootstd: Add a new pre-scan priority for bootdevs
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (57 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 58/71] bootstd: Allow hunting for bootdevs of a given priority Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 60/71] bootstd: Allow hunting for a bootdev by label Simon Glass
                   ` (12 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

We need extensions to be set up before we start trying to boot any of the
bootdevs. Add a new priority before all the others for tht sort of thing.
Also add a 'none' option, so that the first one is not 0.

While we are here, comment enum bootdev_prio_t fully and expand the test
for the 'bootdev hunt' command.

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

(no changes since v1)

 boot/bootdev-uclass.c          |  8 ++++++
 doc/develop/bootstd.rst        |  2 +-
 drivers/block/ide.c            |  4 +--
 drivers/mmc/mmc_bootdev.c      |  4 +--
 drivers/mtd/spi/sf_bootdev.c   |  4 +--
 drivers/nvme/nvme-uclass.c     |  4 +--
 drivers/scsi/scsi_bootdev.c    |  4 +--
 drivers/usb/host/usb_bootdev.c |  4 +--
 drivers/virtio/virtio-uclass.c |  4 +--
 include/bootdev.h              | 35 ++++++++++++++++++-----
 net/eth_bootdev.c              |  4 +--
 test/boot/bootdev.c            | 51 +++++++++++++++++++++-------------
 12 files changed, 84 insertions(+), 44 deletions(-)

diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c
index e8686159f2b..5ed310c554f 100644
--- a/boot/bootdev-uclass.c
+++ b/boot/bootdev-uclass.c
@@ -630,6 +630,7 @@ static int build_order(struct udevice *bootstd, struct udevice **order,
 int bootdev_setup_iter_order(struct bootflow_iter *iter, struct udevice **devp)
 {
 	struct udevice *bootstd, *dev = *devp, **order;
+	bool show = iter->flags & BOOTFLOWF_SHOW;
 	struct uclass *uc;
 	int count, upto;
 	int ret;
@@ -640,6 +641,13 @@ int bootdev_setup_iter_order(struct bootflow_iter *iter, struct udevice **devp)
 		return log_msg_ret("std", ret);
 	}
 
+	/* hunt for any pre-scan devices */
+	if (iter->flags & BOOTFLOWF_HUNT) {
+		ret = bootdev_hunt_prio(BOOTDEVP_1_PRE_SCAN, show);
+		if (ret)
+			return log_msg_ret("pre", ret);
+	}
+
 	/* Handle scanning a single device */
 	if (dev) {
 		iter->flags |= BOOTFLOWF_SINGLE_DEV;
diff --git a/doc/develop/bootstd.rst b/doc/develop/bootstd.rst
index 1ccc49424eb..bfa8cbd7561 100644
--- a/doc/develop/bootstd.rst
+++ b/doc/develop/bootstd.rst
@@ -211,7 +211,7 @@ A bootdev driver is typically fairly simple. Here is one for mmc::
     {
         struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
 
-        ucp->prio = BOOTDEVP_0_INTERNAL_FAST;
+        ucp->prio = BOOTDEVP_2_INTERNAL_FAST;
 
         return 0;
     }
diff --git a/drivers/block/ide.c b/drivers/block/ide.c
index 80c8b64de2f..1ad9b6c1267 100644
--- a/drivers/block/ide.c
+++ b/drivers/block/ide.c
@@ -1060,7 +1060,7 @@ static int ide_bootdev_bind(struct udevice *dev)
 {
 	struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
 
-	ucp->prio = BOOTDEVP_3_SCAN_SLOW;
+	ucp->prio = BOOTDEVP_5_SCAN_SLOW;
 
 	return 0;
 }
@@ -1089,7 +1089,7 @@ U_BOOT_DRIVER(ide_bootdev) = {
 };
 
 BOOTDEV_HUNTER(ide_bootdev_hunter) = {
-	.prio		= BOOTDEVP_3_SCAN_SLOW,
+	.prio		= BOOTDEVP_5_SCAN_SLOW,
 	.uclass		= UCLASS_IDE,
 	.hunt		= ide_bootdev_hunt,
 	.drv		= DM_DRIVER_REF(ide_bootdev),
diff --git a/drivers/mmc/mmc_bootdev.c b/drivers/mmc/mmc_bootdev.c
index 300208f0c71..b57b8a62276 100644
--- a/drivers/mmc/mmc_bootdev.c
+++ b/drivers/mmc/mmc_bootdev.c
@@ -15,7 +15,7 @@ static int mmc_bootdev_bind(struct udevice *dev)
 {
 	struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
 
-	ucp->prio = BOOTDEVP_0_INTERNAL_FAST;
+	ucp->prio = BOOTDEVP_2_INTERNAL_FAST;
 
 	return 0;
 }
@@ -37,7 +37,7 @@ U_BOOT_DRIVER(mmc_bootdev) = {
 };
 
 BOOTDEV_HUNTER(mmc_bootdev_hunter) = {
-	.prio		= BOOTDEVP_0_INTERNAL_FAST,
+	.prio		= BOOTDEVP_2_INTERNAL_FAST,
 	.uclass		= UCLASS_MMC,
 	.drv		= DM_DRIVER_REF(mmc_bootdev),
 };
diff --git a/drivers/mtd/spi/sf_bootdev.c b/drivers/mtd/spi/sf_bootdev.c
index 2272e8567ce..d6b47b11ce4 100644
--- a/drivers/mtd/spi/sf_bootdev.c
+++ b/drivers/mtd/spi/sf_bootdev.c
@@ -53,7 +53,7 @@ static int sf_bootdev_bind(struct udevice *dev)
 {
 	struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
 
-	ucp->prio = BOOTDEVP_2_SCAN_FAST;
+	ucp->prio = BOOTDEVP_4_SCAN_FAST;
 
 	return 0;
 }
@@ -76,7 +76,7 @@ U_BOOT_DRIVER(sf_bootdev) = {
 };
 
 BOOTDEV_HUNTER(sf_bootdev_hunter) = {
-	.prio		= BOOTDEVP_2_SCAN_FAST,
+	.prio		= BOOTDEVP_4_SCAN_FAST,
 	.uclass		= UCLASS_SPI_FLASH,
 	.drv		= DM_DRIVER_REF(sf_bootdev),
 };
diff --git a/drivers/nvme/nvme-uclass.c b/drivers/nvme/nvme-uclass.c
index 7a8ff06e78c..f3af6a27b63 100644
--- a/drivers/nvme/nvme-uclass.c
+++ b/drivers/nvme/nvme-uclass.c
@@ -17,7 +17,7 @@ static int nvme_bootdev_bind(struct udevice *dev)
 {
 	struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
 
-	ucp->prio = BOOTDEVP_2_SCAN_FAST;
+	ucp->prio = BOOTDEVP_4_SCAN_FAST;
 
 	return 0;
 }
@@ -62,7 +62,7 @@ U_BOOT_DRIVER(nvme_bootdev) = {
 };
 
 BOOTDEV_HUNTER(nvme_bootdev_hunter) = {
-	.prio		= BOOTDEVP_2_SCAN_FAST,
+	.prio		= BOOTDEVP_4_SCAN_FAST,
 	.uclass		= UCLASS_NVME,
 	.hunt		= nvme_bootdev_hunt,
 	.drv		= DM_DRIVER_REF(nvme_bootdev),
diff --git a/drivers/scsi/scsi_bootdev.c b/drivers/scsi/scsi_bootdev.c
index 2367b33da9c..991013fe1ef 100644
--- a/drivers/scsi/scsi_bootdev.c
+++ b/drivers/scsi/scsi_bootdev.c
@@ -16,7 +16,7 @@ static int scsi_bootdev_bind(struct udevice *dev)
 {
 	struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
 
-	ucp->prio = BOOTDEVP_2_SCAN_FAST;
+	ucp->prio = BOOTDEVP_4_SCAN_FAST;
 
 	return 0;
 }
@@ -55,7 +55,7 @@ U_BOOT_DRIVER(scsi_bootdev) = {
 };
 
 BOOTDEV_HUNTER(scsi_bootdev_hunter) = {
-	.prio		= BOOTDEVP_2_SCAN_FAST,
+	.prio		= BOOTDEVP_4_SCAN_FAST,
 	.uclass		= UCLASS_SCSI,
 	.hunt		= scsi_bootdev_hunt,
 	.drv		= DM_DRIVER_REF(scsi_bootdev),
diff --git a/drivers/usb/host/usb_bootdev.c b/drivers/usb/host/usb_bootdev.c
index 66d0b6ae8f5..32919f99286 100644
--- a/drivers/usb/host/usb_bootdev.c
+++ b/drivers/usb/host/usb_bootdev.c
@@ -15,7 +15,7 @@ static int usb_bootdev_bind(struct udevice *dev)
 {
 	struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
 
-	ucp->prio = BOOTDEVP_3_SCAN_SLOW;
+	ucp->prio = BOOTDEVP_5_SCAN_SLOW;
 
 	return 0;
 }
@@ -42,7 +42,7 @@ U_BOOT_DRIVER(usb_bootdev) = {
 };
 
 BOOTDEV_HUNTER(usb_bootdev_hunter) = {
-	.prio		= BOOTDEVP_3_SCAN_SLOW,
+	.prio		= BOOTDEVP_5_SCAN_SLOW,
 	.uclass		= UCLASS_USB,
 	.hunt		= usb_bootdev_hunt,
 	.drv		= DM_DRIVER_REF(usb_bootdev),
diff --git a/drivers/virtio/virtio-uclass.c b/drivers/virtio/virtio-uclass.c
index 27efac0d48e..91af412ec1d 100644
--- a/drivers/virtio/virtio-uclass.c
+++ b/drivers/virtio/virtio-uclass.c
@@ -360,7 +360,7 @@ static int virtio_bootdev_bind(struct udevice *dev)
 {
 	struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
 
-	ucp->prio = BOOTDEVP_2_SCAN_FAST;
+	ucp->prio = BOOTDEVP_4_SCAN_FAST;
 
 	return 0;
 }
@@ -405,7 +405,7 @@ U_BOOT_DRIVER(virtio_bootdev) = {
 };
 
 BOOTDEV_HUNTER(virtio_bootdev_hunter) = {
-	.prio		= BOOTDEVP_2_SCAN_FAST,
+	.prio		= BOOTDEVP_4_SCAN_FAST,
 	.uclass		= UCLASS_VIRTIO,
 	.hunt		= virtio_bootdev_hunt,
 	.drv		= DM_DRIVER_REF(virtio_bootdev),
diff --git a/include/bootdev.h b/include/bootdev.h
index b7973fa5760..65d14f24686 100644
--- a/include/bootdev.h
+++ b/include/bootdev.h
@@ -21,15 +21,36 @@ struct udevice;
  *
  * Smallest value is the highest priority. By default, bootdevs are scanned from
  * highest to lowest priority
+ *
+ * BOOTDEVP_0_NONE: Invalid value, do not use
+ * @BOOTDEVP_6_PRE_SCAN: Scan bootdevs with this priority always, before
+ * starting any bootflow scan
+ * @BOOTDEVP_2_INTERNAL_FAST: Internal devices which don't need scanning and
+ * generally very quick to access, e.g. less than 100ms
+ * @BOOTDEVP_3_INTERNAL_SLOW: Internal devices which don't need scanning but
+ * take a significant fraction of a second to access
+ * @BOOTDEVP_4_SCAN_FAST: Extenal devices which need scanning or bus
+ * enumeration to find, but this enumeration happens quickly, typically under
+ * 100ms
+ * @BOOTDEVP_5_SCAN_SLOW: Extenal devices which need scanning or bus
+ * enumeration to find. The enumeration takes significant fraction of a second
+ * to complete
+ * @BOOTDEVP_6_NET_BASE: Basic network devices which are quickly and easily
+ * available. Typically used for an internal Ethernet device
+ * @BOOTDEVP_7_NET_FALLBACK: Secondary network devices which require extra time
+ * to start up, or are less desirable. Typically used for secondary Ethernet
+ * devices. Note that USB ethernet devices are found during USB enumeration,
+ * so do not use this priority
  */
 enum bootdev_prio_t {
-	BOOTDEVP_0_INTERNAL_FAST	= 10,
-	BOOTDEVP_1_INTERNAL_SLOW	= 20,
-	BOOTDEVP_2_SCAN_FAST		= 30,
-	BOOTDEVP_3_SCAN_SLOW		= 40,
-	BOOTDEVP_4_NET_BASE		= 50,
-	BOOTDEVP_5_NET_FALLBACK		= 60,
-	BOOTDEVP_6_SYSTEM		= 70,
+	BOOTDEVP_0_NONE,
+	BOOTDEVP_1_PRE_SCAN,
+	BOOTDEVP_2_INTERNAL_FAST,
+	BOOTDEVP_3_INTERNAL_SLOW,
+	BOOTDEVP_4_SCAN_FAST,
+	BOOTDEVP_5_SCAN_SLOW,
+	BOOTDEVP_6_NET_BASE,
+	BOOTDEVP_7_NET_FALLBACK,
 
 	BOOTDEVP_COUNT,
 };
diff --git a/net/eth_bootdev.c b/net/eth_bootdev.c
index bcbb35a74cd..13e5fcd3bdf 100644
--- a/net/eth_bootdev.c
+++ b/net/eth_bootdev.c
@@ -60,7 +60,7 @@ static int eth_bootdev_bind(struct udevice *dev)
 {
 	struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
 
-	ucp->prio = BOOTDEVP_4_NET_BASE;
+	ucp->prio = BOOTDEVP_6_NET_BASE;
 
 	return 0;
 }
@@ -112,7 +112,7 @@ U_BOOT_DRIVER(eth_bootdev) = {
 };
 
 BOOTDEV_HUNTER(eth_bootdev_hunt) = {
-	.prio		= BOOTDEVP_4_NET_BASE,
+	.prio		= BOOTDEVP_6_NET_BASE,
 	.uclass		= UCLASS_ETH,
 	.hunt		= eth_bootdev_hunt,
 	.drv		= DM_DRIVER_REF(eth_bootdev),
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c
index f9653633a68..86607f7695e 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -247,14 +247,14 @@ static int bootdev_test_hunter(struct unit_test_state *uts)
 	bootdev_list_hunters(std);
 	ut_assert_nextline("Prio  Used  Uclass           Hunter");
 	ut_assert_nextlinen("----");
-	ut_assert_nextline("  50        ethernet         eth_bootdev");
-	ut_assert_nextline("  40        ide              ide_bootdev");
-	ut_assert_nextline("  10        mmc              mmc_bootdev");
-	ut_assert_nextline("  30        nvme             nvme_bootdev");
-	ut_assert_nextline("  30        scsi             scsi_bootdev");
-	ut_assert_nextline("  30        spi_flash        sf_bootdev");
-	ut_assert_nextline("  40        usb              usb_bootdev");
-	ut_assert_nextline("  30        virtio           virtio_bootdev");
+	ut_assert_nextline("   6        ethernet         eth_bootdev");
+	ut_assert_nextline("   5        ide              ide_bootdev");
+	ut_assert_nextline("   2        mmc              mmc_bootdev");
+	ut_assert_nextline("   4        nvme             nvme_bootdev");
+	ut_assert_nextline("   4        scsi             scsi_bootdev");
+	ut_assert_nextline("   4        spi_flash        sf_bootdev");
+	ut_assert_nextline("   5        usb              usb_bootdev");
+	ut_assert_nextline("   4        virtio           virtio_bootdev");
 	ut_assert_nextline("(total hunters: 8)");
 	ut_assert_console_end();
 
@@ -284,17 +284,28 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
 	ut_assertok(run_command("bootdev hunt -l", 0));
 	ut_assert_nextline("Prio  Used  Uclass           Hunter");
 	ut_assert_nextlinen("----");
+	ut_assert_nextline("   6        ethernet         eth_bootdev");
+	ut_assert_skip_to_line("(total hunters: 8)");
+	ut_assert_console_end();
+
+	/* Use the MMC hunter and see that it updates */
+	ut_assertok(run_command("bootdev hunt mmc", 0));
+	ut_assertok(run_command("bootdev hunt -l", 0));
+	ut_assert_skip_to_line("   5        ide              ide_bootdev");
+	ut_assert_nextline("   2     *  mmc              mmc_bootdev");
 	ut_assert_skip_to_line("(total hunters: 8)");
 	ut_assert_console_end();
 
 	/* Scan all hunters */
 	sandbox_set_eth_enable(false);
-
+	test_set_skip_delays(true);
 	ut_assertok(run_command("bootdev hunt", 0));
 	ut_assert_nextline("Hunting with: ethernet");
 	ut_assert_nextline("Hunting with: ide");
 	ut_assert_nextline("Bus 0: not available  ");
-	ut_assert_nextline("Hunting with: mmc");
+
+	/* mmc hunter has already been used so should not run again */
+
 	ut_assert_nextline("Hunting with: nvme");
 	ut_assert_nextline("Hunting with: scsi");
 	ut_assert_nextline("scanning bus for devices...");
@@ -309,14 +320,14 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
 	ut_assertok(run_command("bootdev hunt -l", 0));
 	ut_assert_nextlinen("Prio");
 	ut_assert_nextlinen("----");
-	ut_assert_nextline("  50     *  ethernet         eth_bootdev");
-	ut_assert_nextline("  40     *  ide              ide_bootdev");
-	ut_assert_nextline("  10     *  mmc              mmc_bootdev");
-	ut_assert_nextline("  30     *  nvme             nvme_bootdev");
-	ut_assert_nextline("  30     *  scsi             scsi_bootdev");
-	ut_assert_nextline("  30     *  spi_flash        sf_bootdev");
-	ut_assert_nextline("  40     *  usb              usb_bootdev");
-	ut_assert_nextline("  30     *  virtio           virtio_bootdev");
+	ut_assert_nextline("   6     *  ethernet         eth_bootdev");
+	ut_assert_nextline("   5     *  ide              ide_bootdev");
+	ut_assert_nextline("   2     *  mmc              mmc_bootdev");
+	ut_assert_nextline("   4     *  nvme             nvme_bootdev");
+	ut_assert_nextline("   4     *  scsi             scsi_bootdev");
+	ut_assert_nextline("   4     *  spi_flash        sf_bootdev");
+	ut_assert_nextline("   5     *  usb              usb_bootdev");
+	ut_assert_nextline("   4     *  virtio           virtio_bootdev");
 	ut_assert_nextline("(total hunters: 8)");
 	ut_assert_console_end();
 
@@ -370,14 +381,14 @@ static int bootdev_test_hunt_prio(struct unit_test_state *uts)
 	test_set_skip_delays(true);
 
 	console_record_reset_enable();
-	ut_assertok(bootdev_hunt_prio(BOOTDEVP_2_SCAN_FAST, false));
+	ut_assertok(bootdev_hunt_prio(BOOTDEVP_4_SCAN_FAST, false));
 	ut_assert_nextline("scanning bus for devices...");
 	ut_assert_skip_to_line("            Type: Hard Disk");
 	ut_assert_nextlinen("            Capacity:");
 	ut_assert_console_end();
 
 	/* now try a different priority, verbosely */
-	ut_assertok(bootdev_hunt_prio(BOOTDEVP_3_SCAN_SLOW, true));
+	ut_assertok(bootdev_hunt_prio(BOOTDEVP_5_SCAN_SLOW, true));
 	ut_assert_nextline("Hunting with: ide");
 	ut_assert_nextline("Bus 0: not available  ");
 	ut_assert_nextline("Hunting with: usb");
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 60/71] bootstd: Allow hunting for a bootdev by label
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (58 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 59/71] bootstd: Add a new pre-scan priority for bootdevs Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 61/71] bootstd: Allow iterating to the next label in a list Simon Glass
                   ` (11 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

Add a function to hunt for a bootdev label and find the bootdev produced
by the hunter (or already present).

Add a few extra flags so that we can distinguish between "mmc1", "mmc" and
"1" which all need to be handled differently.

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

(no changes since v1)

 boot/bootdev-uclass.c      |  27 ++++++++-
 include/bootdev.h          |  17 ++++++
 include/bootflow.h         |  14 ++++-
 test/boot/bootdev.c        | 115 ++++++++++++++++++++++++++++++++++++-
 test/boot/bootstd_common.c |  19 ++++++
 test/boot/bootstd_common.h |   8 +++
 6 files changed, 195 insertions(+), 5 deletions(-)

diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c
index 5ed310c554f..dcaed4c2692 100644
--- a/boot/bootdev-uclass.c
+++ b/boot/bootdev-uclass.c
@@ -442,6 +442,13 @@ int bootdev_find_by_label(const char *label, struct udevice **devp,
 		if (!ret) {
 			log_debug("- found %s\n", bdev->name);
 			*devp = bdev;
+
+			/*
+			 * if no sequence number was provided, we must scan all
+			 * bootdevs for this media uclass
+			 */
+			if (IS_ENABLED(CONFIG_BOOTSTD_FULL) && seq == -1)
+				method_flags |= BOOTFLOW_METHF_SINGLE_UCLASS;
 			if (method_flagsp)
 				*method_flagsp = method_flags;
 			return 0;
@@ -458,7 +465,7 @@ int bootdev_find_by_any(const char *name, struct udevice **devp,
 {
 	struct udevice *dev;
 	int method_flags = 0;
-	int ret, seq;
+	int ret = -ENODEV, seq;
 	char *endp;
 
 	seq = simple_strtol(name, &endp, 16);
@@ -480,8 +487,9 @@ int bootdev_find_by_any(const char *name, struct udevice **devp,
 			       ret);
 			return log_msg_ret("pro", ret);
 		}
-	} else {
+	} else if (IS_ENABLED(CONFIG_BOOTSTD_FULL)) {
 		ret = uclass_get_device_by_seq(UCLASS_BOOTDEV, seq, &dev);
+		method_flags |= BOOTFLOW_METHF_SINGLE_DEV;
 	}
 	if (ret) {
 		printf("Cannot find '%s' (err=%d)\n", name, ret);
@@ -495,6 +503,21 @@ int bootdev_find_by_any(const char *name, struct udevice **devp,
 	return 0;
 }
 
+int bootdev_hunt_and_find_by_label(const char *label, struct udevice **devp,
+				   int *method_flagsp)
+{
+	int ret;
+
+	ret = bootdev_hunt(label, false);
+	if (ret)
+		return log_msg_ret("scn", ret);
+	ret = bootdev_find_by_label(label, devp, method_flagsp);
+	if (ret)
+		return log_msg_ret("fnd", ret);
+
+	return 0;
+}
+
 static int default_get_bootflow(struct udevice *dev, struct bootflow_iter *iter,
 				struct bootflow *bflow)
 {
diff --git a/include/bootdev.h b/include/bootdev.h
index 65d14f24686..b1e320a7d8e 100644
--- a/include/bootdev.h
+++ b/include/bootdev.h
@@ -316,6 +316,23 @@ int bootdev_hunt(const char *spec, bool show);
  */
 int bootdev_hunt_prio(enum bootdev_prio_t prio, bool show);
 
+/**
+ * bootdev_hunt_and_find_by_label() - Hunt for bootdevs by label
+ *
+ * Runs the hunter for the label, then tries to find the bootdev, possible
+ * created by the hunter
+ *
+ * @label: Label to look up (e.g. "mmc1" or "mmc0")
+ * @devp: Returns the bootdev device found, or NULL if none (note it does not
+ *	return the media device, but its bootdev child)
+ * @method_flagsp: If non-NULL, returns any flags implied by the label
+ * (enum bootflow_meth_flags_t), 0 if none. Unset if function fails
+ * Return: 0 if OK, -EINVAL if the uclass is not supported by this board,
+ * -ENOENT if there is no device with that number
+ */
+int bootdev_hunt_and_find_by_label(const char *label, struct udevice **devp,
+				   int *method_flagsp);
+
 #if CONFIG_IS_ENABLED(BOOTSTD)
 /**
  * bootdev_setup_for_dev() - Bind a new bootdev device (deprecated)
diff --git a/include/bootflow.h b/include/bootflow.h
index 4012f4b8a82..81dbcd6754b 100644
--- a/include/bootflow.h
+++ b/include/bootflow.h
@@ -99,7 +99,10 @@ struct bootflow {
  * Internal flags:
  * @BOOTFLOWF_SINGLE_DEV: (internal) Just scan one bootdev
  * @BOOTFLOWF_SKIP_GLOBAL: (internal) Don't scan global bootmeths
- * this uclass
+ * @BOOTFLOWF_SINGLE_UCLASS: (internal) Keep scanning through all devices in
+ * this uclass (used with things like "mmc")
+ * @BOOTFLOWF_SINGLE_MEDIA: (internal) Scan one media device in the uclass (used
+ * with things like "mmc1")
  */
 enum bootflow_flags_t {
 	BOOTFLOWF_FIXED		= 1 << 0,
@@ -113,6 +116,8 @@ enum bootflow_flags_t {
 	 */
 	BOOTFLOWF_SINGLE_DEV	= 1 << 16,
 	BOOTFLOWF_SKIP_GLOBAL	= 1 << 17,
+	BOOTFLOWF_SINGLE_UCLASS	= 1 << 18,
+	BOOTFLOWF_SINGLE_MEDIA	= 1 << 19,
 };
 
 /**
@@ -124,10 +129,17 @@ enum bootflow_flags_t {
  *
  * @BOOTFLOW_METHF_DHCP_ONLY: Only use dhcp (scripts and EFI)
  * @BOOTFLOW_METHF_PXE_ONLY: Only use pxe (PXE boot)
+ * @BOOTFLOW_METHF_SINGLE_DEV: Scan only a single bootdev (used for labels like
+ * "3"). This is used if a sequence number is provided instead of a label
+ * @BOOTFLOW_METHF_SINGLE_UCLASS: Scan all bootdevs in this one uclass (used
+ * with things like "mmc"). If this is not set, then the bootdev has an integer
+ * value in the label (like "mmc2")
  */
 enum bootflow_meth_flags_t {
 	BOOTFLOW_METHF_DHCP_ONLY	= 1 << 0,
 	BOOTFLOW_METHF_PXE_ONLY		= 1 << 1,
+	BOOTFLOW_METHF_SINGLE_DEV	= 1 << 2,
+	BOOTFLOW_METHF_SINGLE_UCLASS	= 1 << 3,
 };
 
 /**
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c
index 86607f7695e..1fa0909e893 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -113,9 +113,11 @@ static int bootdev_test_labels(struct unit_test_state *uts)
 
 	/* Check method flags */
 	ut_assertok(bootdev_find_by_label("pxe", &dev, &mflags));
-	ut_asserteq(BOOTFLOW_METHF_PXE_ONLY, mflags);
+	ut_asserteq(BOOTFLOW_METHF_SINGLE_UCLASS | BOOTFLOW_METHF_PXE_ONLY,
+		    mflags);
 	ut_assertok(bootdev_find_by_label("dhcp", &dev, &mflags));
-	ut_asserteq(BOOTFLOW_METHF_DHCP_ONLY, mflags);
+	ut_asserteq(BOOTFLOW_METHF_SINGLE_UCLASS | BOOTFLOW_METHF_DHCP_ONLY,
+		    mflags);
 
 	/* Check invalid uclass */
 	ut_asserteq(-EINVAL, bootdev_find_by_label("fred0", &dev, &mflags));
@@ -128,6 +130,62 @@ static int bootdev_test_labels(struct unit_test_state *uts)
 BOOTSTD_TEST(bootdev_test_labels, UT_TESTF_DM | UT_TESTF_SCAN_FDT |
 	     UT_TESTF_ETH_BOOTDEV);
 
+/* Check bootdev_find_by_any() */
+static int bootdev_test_any(struct unit_test_state *uts)
+{
+	struct udevice *dev, *media;
+	int mflags;
+
+	/*
+	 * with ethernet enabled we have 8 devices ahead of the mmc ones:
+	 *
+	 * ut_assertok(run_command("bootdev list", 0));
+	 * Seq  Probed  Status  Uclass    Name
+	 * ---  ------  ------  --------  ------------------
+	 * 0   [ + ]      OK  ethernet  eth@10002000.bootdev
+	 * 1   [   ]      OK  ethernet  eth@10003000.bootdev
+	 * 2   [   ]      OK  ethernet  sbe5.bootdev
+	 * 3   [   ]      OK  ethernet  eth@10004000.bootdev
+	 * 4   [   ]      OK  ethernet  phy-test-eth.bootdev
+	 * 5   [   ]      OK  ethernet  dsa-test-eth.bootdev
+	 * 6   [   ]      OK  ethernet  dsa-test@0.bootdev
+	 * 7   [   ]      OK  ethernet  dsa-test@1.bootdev
+	 * 8   [   ]      OK  mmc       mmc2.bootdev
+	 * 9   [ + ]      OK  mmc       mmc1.bootdev
+	 * a   [   ]      OK  mmc       mmc0.bootdev
+	 */
+	console_record_reset_enable();
+	ut_assertok(bootdev_find_by_any("8", &dev, &mflags));
+	ut_asserteq(UCLASS_BOOTDEV, device_get_uclass_id(dev));
+	ut_asserteq(BOOTFLOW_METHF_SINGLE_DEV, mflags);
+	media = dev_get_parent(dev);
+	ut_asserteq(UCLASS_MMC, device_get_uclass_id(media));
+	ut_asserteq_str("mmc2", media->name);
+	ut_assert_console_end();
+
+	/* there should not be this many bootdevs */
+	ut_asserteq(-ENODEV, bootdev_find_by_any("50", &dev, &mflags));
+	ut_assert_nextline("Cannot find '50' (err=-19)");
+	ut_assert_console_end();
+
+	/* Check method flags */
+	ut_assertok(bootdev_find_by_any("pxe", &dev, &mflags));
+	ut_asserteq(BOOTFLOW_METHF_SINGLE_UCLASS | BOOTFLOW_METHF_PXE_ONLY,
+		    mflags);
+
+	/* Check invalid uclass */
+	mflags = 123;
+	ut_asserteq(-EINVAL, bootdev_find_by_any("fred0", &dev, &mflags));
+	ut_assert_nextline("Unknown uclass 'fred0' in label");
+	ut_assert_nextline("Cannot find bootdev 'fred0' (err=-22)");
+	ut_asserteq(123, mflags);
+	ut_assert_console_end();
+
+	return 0;
+}
+BOOTSTD_TEST(bootdev_test_any, UT_TESTF_DM | UT_TESTF_SCAN_FDT |
+	     UT_TESTF_ETH_BOOTDEV);
+
 /* Check bootdev ordering with the bootdev-order property */
 static int bootdev_test_order(struct unit_test_state *uts)
 {
@@ -399,3 +457,56 @@ static int bootdev_test_hunt_prio(struct unit_test_state *uts)
 	return 0;
 }
 BOOTSTD_TEST(bootdev_test_hunt_prio, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
+
+/* Check hunting for bootdevs with a particular label */
+static int bootdev_test_hunt_label(struct unit_test_state *uts)
+{
+	struct udevice *dev, *old;
+	struct bootstd_priv *std;
+	int mflags;
+
+	/* get access to the used hunters */
+	ut_assertok(bootstd_get_priv(&std));
+
+	/* scan an unknown uclass */
+	console_record_reset_enable();
+	old = (void *)&mflags;   /* arbitrary pointer to check against dev */
+	dev = old;
+	mflags = 123;
+	ut_asserteq(-EINVAL,
+		    bootdev_hunt_and_find_by_label("fred", &dev, &mflags));
+	ut_assert_nextline("Unknown uclass 'fred' in label");
+	ut_asserteq_ptr(old, dev);
+	ut_asserteq(123, mflags);
+	ut_assert_console_end();
+	ut_asserteq(0, std->hunters_used);
+
+	/* scan an invalid mmc controllers */
+	ut_asserteq(-ENOENT,
+		    bootdev_hunt_and_find_by_label("mmc4", &dev, &mflags));
+	ut_asserteq_ptr(old, dev);
+	ut_asserteq(123, mflags);
+	ut_assert_nextline("Unknown seq 4 for label 'mmc4'");
+	ut_assert_console_end();
+
+	ut_assertok(bootstd_test_check_mmc_hunter(uts));
+
+	/* scan for a particular mmc controller */
+	ut_assertok(bootdev_hunt_and_find_by_label("mmc1", &dev, &mflags));
+	ut_assertnonnull(dev);
+	ut_asserteq_str("mmc1.bootdev", dev->name);
+	ut_asserteq(0, mflags);
+	ut_assert_console_end();
+
+	/* scan all of usb */
+	test_set_skip_delays(true);
+	ut_assertok(bootdev_hunt_and_find_by_label("usb", &dev, &mflags));
+	ut_assertnonnull(dev);
+	ut_asserteq_str("usb_mass_storage.lun0.bootdev", dev->name);
+	ut_asserteq(BOOTFLOW_METHF_SINGLE_UCLASS, mflags);
+	ut_assert_nextlinen("Bus usb@1: scanning bus usb@1");
+	ut_assert_console_end();
+
+	return 0;
+}
+BOOTSTD_TEST(bootdev_test_hunt_label, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
diff --git a/test/boot/bootstd_common.c b/test/boot/bootstd_common.c
index 7a40836507a..e71a2975c53 100644
--- a/test/boot/bootstd_common.c
+++ b/test/boot/bootstd_common.c
@@ -7,6 +7,7 @@
  */
 
 #include <common.h>
+#include <bootdev.h>
 #include <bootstd.h>
 #include <dm.h>
 #include <memalign.h>
@@ -67,6 +68,24 @@ int bootstd_test_drop_bootdev_order(struct unit_test_state *uts)
 	return 0;
 }
 
+int bootstd_test_check_mmc_hunter(struct unit_test_state *uts)
+{
+	struct bootdev_hunter *start, *mmc;
+	struct bootstd_priv *std;
+	uint seq;
+
+	/* get access to the used hunters */
+	ut_assertok(bootstd_get_priv(&std));
+
+	/* check that the hunter was used */
+	start = ll_entry_start(struct bootdev_hunter, bootdev_hunter);
+	mmc = BOOTDEV_HUNTER_GET(mmc_bootdev_hunter);
+	seq = mmc - start;
+	ut_asserteq(BIT(seq), std->hunters_used);
+
+	return 0;
+}
+
 int do_ut_bootstd(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
 {
 	struct unit_test *tests = UNIT_TEST_SUITE_START(bootstd_test);
diff --git a/test/boot/bootstd_common.h b/test/boot/bootstd_common.h
index c5e0fd1ceab..0eb48fa1537 100644
--- a/test/boot/bootstd_common.h
+++ b/test/boot/bootstd_common.h
@@ -40,4 +40,12 @@ int bootstd_test_drop_bootdev_order(struct unit_test_state *uts);
  */
 int bootstd_setup_for_tests(void);
 
+/**
+ * bootstd_test_check_mmc_hunter() - Check that the mmc bootdev hunter was used
+ *
+ * @uts: Unit test state to use for ut_assert...() functions
+ * Returns: 0 if OK (used), other value on error (not used)
+ */
+int bootstd_test_check_mmc_hunter(struct unit_test_state *uts);
+
 #endif
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 61/71] bootstd: Allow iterating to the next label in a list
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (59 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 60/71] bootstd: Allow hunting for a bootdev by label Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 63/71] extension: Refactor to allow non-command usage Simon Glass
                   ` (10 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

Add a function which moves to the next label in a list of labels. This
allows processing the boot_targets environment variable.

This works using a new label list in the bootflow iterator. The logic to
set this up is included in a subsequent commit.

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

(no changes since v1)

 boot/bootdev-uclass.c | 26 ++++++++++++--
 include/bootdev.h     | 16 +++++++++
 include/bootflow.h    |  4 +++
 test/boot/bootdev.c   | 80 ++++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 123 insertions(+), 3 deletions(-)

diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c
index dcaed4c2692..ae08430ca8c 100644
--- a/boot/bootdev-uclass.c
+++ b/boot/bootdev-uclass.c
@@ -566,6 +566,25 @@ void bootdev_clear_bootflows(struct udevice *dev)
 	}
 }
 
+int bootdev_next_label(struct bootflow_iter *iter, struct udevice **devp,
+		       int *method_flagsp)
+{
+	struct udevice *dev;
+
+	log_debug("next\n");
+	for (dev = NULL; !dev && iter->labels[++iter->cur_label];) {
+		log_debug("Scanning: %s\n", iter->labels[iter->cur_label]);
+		bootdev_hunt_and_find_by_label(iter->labels[iter->cur_label],
+					       &dev, method_flagsp);
+	}
+
+	if (!dev)
+		return log_msg_ret("fin", -ENODEV);
+	*devp = dev;
+
+	return 0;
+}
+
 /**
  * h_cmp_bootdev() - Compare two bootdevs to find out which should go first
  *
@@ -763,8 +782,11 @@ int bootdev_hunt(const char *spec, bool show)
 
 		log_debug("looking at %.*s for %s\n",
 			  (int)max(strlen(name), len), spec, name);
-		if (spec && strncmp(spec, name, max(strlen(name), len)))
-			continue;
+		if (spec && strncmp(spec, name, max(strlen(name), len))) {
+			if (info->uclass != UCLASS_ETH ||
+			    (strcmp("dhcp", spec) && strcmp("pxe", spec)))
+				continue;
+		}
 		ret = bootdev_hunt_drv(info, i, show);
 		if (ret)
 			result = ret;
diff --git a/include/bootdev.h b/include/bootdev.h
index b1e320a7d8e..300bc736427 100644
--- a/include/bootdev.h
+++ b/include/bootdev.h
@@ -333,6 +333,22 @@ int bootdev_hunt_prio(enum bootdev_prio_t prio, bool show);
 int bootdev_hunt_and_find_by_label(const char *label, struct udevice **devp,
 				   int *method_flagsp);
 
+/**
+ * bootdev_next_label() - Move to the next bootdev in the label sequence
+ *
+ * Looks through the remaining labels until it finds one that matches a bootdev.
+ * Bootdev scanners are used as needed. For example a label "mmc1" results in
+ * running the "mmc" bootdrv.
+ *
+ * @iter: Interation info, containing iter->cur_label
+ * @devp: New bootdev found, if any was found
+ * @method_flagsp: If non-NULL, returns any flags implied by the label
+ * (enum bootflow_meth_flags_t), 0 if none
+ * Returns 0 if OK, -ENODEV if no bootdev was found
+ */
+int bootdev_next_label(struct bootflow_iter *iter, struct udevice **devp,
+		       int *method_flagsp);
+
 #if CONFIG_IS_ENABLED(BOOTSTD)
 /**
  * bootdev_setup_for_dev() - Bind a new bootdev device (deprecated)
diff --git a/include/bootflow.h b/include/bootflow.h
index 81dbcd6754b..8ab32ffd666 100644
--- a/include/bootflow.h
+++ b/include/bootflow.h
@@ -175,6 +175,8 @@ enum bootflow_meth_flags_t {
  * @cur_dev: Current bootdev number, an index into @dev_order[]
  * @dev_order: List of bootdevs to scan, in order of priority. The scan starts
  *	with the first one on the list
+ * @labels: List of labels to scan for bootdevs
+ * @cur_label: Current label being processed
  * @num_methods: Number of bootmeth devices in @method_order
  * @cur_method: Current method number, an index into @method_order
  * @first_glob_method: First global method, if any, else -1
@@ -196,6 +198,8 @@ struct bootflow_iter {
 	int num_devs;
 	int cur_dev;
 	struct udevice **dev_order;
+	const char *const *labels;
+	int cur_label;
 	int num_methods;
 	int cur_method;
 	int first_glob_method;
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c
index 1fa0909e893..608aef15265 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -355,7 +355,7 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
 	ut_assert_console_end();
 
 	/* Scan all hunters */
-	sandbox_set_eth_enable(false);
+	test_set_eth_enable(false);
 	test_set_skip_delays(true);
 	ut_assertok(run_command("bootdev hunt", 0));
 	ut_assert_nextline("Hunting with: ethernet");
@@ -510,3 +510,81 @@ static int bootdev_test_hunt_label(struct unit_test_state *uts)
 	return 0;
 }
 BOOTSTD_TEST(bootdev_test_hunt_label, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
+
+/* Check iterating to the next label in a list */
+static int bootdev_test_next_label(struct unit_test_state *uts)
+{
+	const char *const labels[] = {"mmc0", "scsi", "dhcp", "pxe", NULL};
+	struct bootflow_iter iter;
+	struct bootstd_priv *std;
+	struct bootflow bflow;
+	struct udevice *dev;
+	int mflags;
+
+	test_set_eth_enable(false);
+
+	/* get access to the used hunters */
+	ut_assertok(bootstd_get_priv(&std));
+
+	memset(&iter, '\0', sizeof(iter));
+	memset(&bflow, '\0', sizeof(bflow));
+	iter.part = 0;
+	uclass_first_device(UCLASS_BOOTMETH, &bflow.method);
+	iter.cur_label = -1;
+	iter.labels = labels;
+
+	dev = NULL;
+	mflags = 123;
+	ut_assertok(bootdev_next_label(&iter, &dev, &mflags));
+	console_record_reset_enable();
+	ut_assert_console_end();
+	ut_assertnonnull(dev);
+	ut_asserteq_str("mmc0.bootdev", dev->name);
+	ut_asserteq(0, mflags);
+
+	ut_assertok(bootstd_test_check_mmc_hunter(uts));
+
+	ut_assertok(bootdev_next_label(&iter, &dev, &mflags));
+	ut_assert_nextline("scanning bus for devices...");
+	ut_assert_skip_to_line(
+		"            Capacity: 1.9 MB = 0.0 GB (4095 x 512)");
+	ut_assert_console_end();
+	ut_assertnonnull(dev);
+	ut_asserteq_str("scsi.id0lun0.bootdev", dev->name);
+	ut_asserteq(BOOTFLOW_METHF_SINGLE_UCLASS, mflags);
+
+	/* SCSI is fifth in the list, so bit 4 */
+	ut_asserteq(BIT(2) | BIT(4), std->hunters_used);
+
+	ut_assertok(bootdev_next_label(&iter, &dev, &mflags));
+	ut_assert_console_end();
+	ut_assertnonnull(dev);
+	ut_asserteq_str("eth@10002000.bootdev", dev->name);
+	ut_asserteq(BOOTFLOW_METHF_SINGLE_UCLASS | BOOTFLOW_METHF_DHCP_ONLY,
+		    mflags);
+
+	/* dhcp: Ethernet is first so bit 0 */
+	ut_asserteq(BIT(2) | BIT(4) | BIT(0), std->hunters_used);
+
+	ut_assertok(bootdev_next_label(&iter, &dev, &mflags));
+	ut_assert_console_end();
+	ut_assertnonnull(dev);
+	ut_asserteq_str("eth@10002000.bootdev", dev->name);
+	ut_asserteq(BOOTFLOW_METHF_SINGLE_UCLASS | BOOTFLOW_METHF_PXE_ONLY,
+		    mflags);
+
+	/* pxe: Ethernet is first so bit 0 */
+	ut_asserteq(BIT(2) | BIT(4) | BIT(0), std->hunters_used);
+
+	mflags = 123;
+	ut_asserteq(-ENODEV, bootdev_next_label(&iter, &dev, &mflags));
+	ut_asserteq(123, mflags);
+	ut_assert_console_end();
+
+	/* no change */
+	ut_asserteq(BIT(2) | BIT(4) | BIT(0), std->hunters_used);
+
+	return 0;
+}
+BOOTSTD_TEST(bootdev_test_next_label, UT_TESTF_DM | UT_TESTF_SCAN_FDT |
+	     UT_TESTF_ETH_BOOTDEV | UT_TESTF_SF_BOOTDEV);
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 63/71] extension: Refactor to allow non-command usage
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (60 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 61/71] bootstd: Allow iterating to the next label in a list Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 64/71] bootstd: Add a hunter for the extension feature Simon Glass
                   ` (9 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

The current extension code is designed to be used from commands. We want
to add a boot driver which uses it. To help with this, split the code into
the command processing and a function which actually does the scan.

Really the extension code should be in common/ or use driver model, but
this is a start.

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

(no changes since v1)

 cmd/extension_board.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/cmd/extension_board.c b/cmd/extension_board.c
index f94abd612d5..f7685d47b8b 100644
--- a/cmd/extension_board.c
+++ b/cmd/extension_board.c
@@ -80,8 +80,7 @@ static int do_extension_list(struct cmd_tbl *cmdtp, int flag,
 	return CMD_RET_SUCCESS;
 }
 
-static int do_extension_scan(struct cmd_tbl *cmdtp, int flag,
-			     int argc, char *const argv[])
+static int extension_scan(bool show)
 {
 	struct extension *extension, *next;
 	int extension_num;
@@ -91,12 +90,23 @@ static int do_extension_scan(struct cmd_tbl *cmdtp, int flag,
 		free(extension);
 	}
 	extension_num = extension_board_scan(&extension_list);
+	if (show && extension_num >= 0)
+		printf("Found %d extension board(s).\n", extension_num);
+
+	/* either the number of extensions, or -ve for error */
+	return extension_num;
+}
+
 
+static int do_extension_scan(struct cmd_tbl *cmdtp, int flag,
+			     int argc, char *const argv[])
+{
+	int extension_num;
+
+	extension_num = extension_scan(true);
 	if (extension_num < 0)
 		return CMD_RET_FAILURE;
 
-	printf("Found %d extension board(s).\n", extension_num);
-
 	return CMD_RET_SUCCESS;
 }
 
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 64/71] bootstd: Add a hunter for the extension feature
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (61 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 63/71] extension: Refactor to allow non-command usage Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 65/71] bootstd: Switch bootdev scanning to use labels Simon Glass
                   ` (8 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

This needs to run before any bootdev is used, so add a hunter for it.

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

(no changes since v1)

 cmd/extension_board.c      | 25 +++++++++++++++++++++++++
 test/boot/bootdev.c        | 37 +++++++++++++++++++++++--------------
 test/boot/bootflow.c       | 20 ++++++++++----------
 test/boot/bootstd_common.h |  5 +++++
 4 files changed, 63 insertions(+), 24 deletions(-)

diff --git a/cmd/extension_board.c b/cmd/extension_board.c
index f7685d47b8b..2b672d888c6 100644
--- a/cmd/extension_board.c
+++ b/cmd/extension_board.c
@@ -5,7 +5,9 @@
  */
 
 #include <common.h>
+#include <bootdev.h>
 #include <command.h>
+#include <dm.h>
 #include <malloc.h>
 #include <extension_board.h>
 #include <mapmem.h>
@@ -176,3 +178,26 @@ U_BOOT_CMD(extension, 3, 1, do_extensionops,
 	"extension list - lists available extension(s) board(s)\n"
 	"extension apply <extension number|all> - applies DT overlays corresponding to extension boards\n"
 );
+
+static int extension_bootdev_hunt(struct bootdev_hunter *info, bool show)
+{
+	int ret;
+
+	ret = env_set_hex("extension_overlay_addr",
+			  env_get_hex("fdtoverlay_addr_r", 0));
+	if (ret)
+		return log_msg_ret("env", ret);
+
+	ret = extension_scan(show);
+	if (ret < 0)
+		return log_msg_ret("ext", ret);
+
+	return 0;
+}
+
+/* extensions should have a uclass - for now we use UCLASS_SIMPLE_BUS uclass */
+BOOTDEV_HUNTER(extension_bootdev_hunter) = {
+	.prio		= BOOTDEVP_1_PRE_SCAN,
+	.uclass		= UCLASS_SIMPLE_BUS,
+	.hunt		= extension_bootdev_hunt,
+};
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c
index 1090b92e510..8ebc27a6435 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -306,6 +306,7 @@ static int bootdev_test_hunter(struct unit_test_state *uts)
 	ut_assert_nextline("Prio  Used  Uclass           Hunter");
 	ut_assert_nextlinen("----");
 	ut_assert_nextline("   6        ethernet         eth_bootdev");
+	ut_assert_nextline("   1        simple_bus       (none)");
 	ut_assert_nextline("   5        ide              ide_bootdev");
 	ut_assert_nextline("   2        mmc              mmc_bootdev");
 	ut_assert_nextline("   4        nvme             nvme_bootdev");
@@ -313,7 +314,7 @@ static int bootdev_test_hunter(struct unit_test_state *uts)
 	ut_assert_nextline("   4        spi_flash        sf_bootdev");
 	ut_assert_nextline("   5        usb              usb_bootdev");
 	ut_assert_nextline("   4        virtio           virtio_bootdev");
-	ut_assert_nextline("(total hunters: 8)");
+	ut_assert_nextline("(total hunters: 9)");
 	ut_assert_console_end();
 
 	ut_assertok(bootdev_hunt("usb1", false));
@@ -321,8 +322,8 @@ static int bootdev_test_hunter(struct unit_test_state *uts)
 		"Bus usb@1: scanning bus usb@1 for devices... 5 USB Device(s) found");
 	ut_assert_console_end();
 
-	/* USB is fifth in the list, so bit 6 */
-	ut_asserteq(BIT(6), std->hunters_used);
+	/* USB is sixth in the list, so bit 7 */
+	ut_asserteq(BIT(7), std->hunters_used);
 
 	return 0;
 }
@@ -343,7 +344,7 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
 	ut_assert_nextline("Prio  Used  Uclass           Hunter");
 	ut_assert_nextlinen("----");
 	ut_assert_nextline("   6        ethernet         eth_bootdev");
-	ut_assert_skip_to_line("(total hunters: 8)");
+	ut_assert_skip_to_line("(total hunters: 9)");
 	ut_assert_console_end();
 
 	/* Use the MMC hunter and see that it updates */
@@ -351,7 +352,7 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
 	ut_assertok(run_command("bootdev hunt -l", 0));
 	ut_assert_skip_to_line("   5        ide              ide_bootdev");
 	ut_assert_nextline("   2     *  mmc              mmc_bootdev");
-	ut_assert_skip_to_line("(total hunters: 8)");
+	ut_assert_skip_to_line("(total hunters: 9)");
 	ut_assert_console_end();
 
 	/* Scan all hunters */
@@ -359,6 +360,10 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
 	test_set_skip_delays(true);
 	ut_assertok(run_command("bootdev hunt", 0));
 	ut_assert_nextline("Hunting with: ethernet");
+
+	/* This is the extension feature which has no uclass at present */
+	ut_assert_nextline("Hunting with: simple_bus");
+	ut_assert_nextline("Found 2 extension board(s).");
 	ut_assert_nextline("Hunting with: ide");
 	ut_assert_nextline("Bus 0: not available  ");
 
@@ -379,6 +384,7 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
 	ut_assert_nextlinen("Prio");
 	ut_assert_nextlinen("----");
 	ut_assert_nextline("   6     *  ethernet         eth_bootdev");
+	ut_assert_nextline("   1     *  simple_bus       (none)");
 	ut_assert_nextline("   5     *  ide              ide_bootdev");
 	ut_assert_nextline("   2     *  mmc              mmc_bootdev");
 	ut_assert_nextline("   4     *  nvme             nvme_bootdev");
@@ -386,10 +392,10 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
 	ut_assert_nextline("   4     *  spi_flash        sf_bootdev");
 	ut_assert_nextline("   5     *  usb              usb_bootdev");
 	ut_assert_nextline("   4     *  virtio           virtio_bootdev");
-	ut_assert_nextline("(total hunters: 8)");
+	ut_assert_nextline("(total hunters: 9)");
 	ut_assert_console_end();
 
-	ut_asserteq(GENMASK(7, 0), std->hunters_used);
+	ut_asserteq(GENMASK(MAX_HUNTER, 0), std->hunters_used);
 
 	return 0;
 }
@@ -553,8 +559,8 @@ static int bootdev_test_next_label(struct unit_test_state *uts)
 	ut_asserteq_str("scsi.id0lun0.bootdev", dev->name);
 	ut_asserteq(BOOTFLOW_METHF_SINGLE_UCLASS, mflags);
 
-	/* SCSI is fifth in the list, so bit 4 */
-	ut_asserteq(BIT(2) | BIT(4), std->hunters_used);
+	/* SCSI is sixth in the list, so bit 5 */
+	ut_asserteq(BIT(MMC_HUNTER) | BIT(5), std->hunters_used);
 
 	ut_assertok(bootdev_next_label(&iter, &dev, &mflags));
 	ut_assert_console_end();
@@ -564,7 +570,7 @@ static int bootdev_test_next_label(struct unit_test_state *uts)
 		    mflags);
 
 	/* dhcp: Ethernet is first so bit 0 */
-	ut_asserteq(BIT(2) | BIT(4) | BIT(0), std->hunters_used);
+	ut_asserteq(BIT(MMC_HUNTER) | BIT(5) | BIT(0), std->hunters_used);
 
 	ut_assertok(bootdev_next_label(&iter, &dev, &mflags));
 	ut_assert_console_end();
@@ -574,7 +580,7 @@ static int bootdev_test_next_label(struct unit_test_state *uts)
 		    mflags);
 
 	/* pxe: Ethernet is first so bit 0 */
-	ut_asserteq(BIT(2) | BIT(4) | BIT(0), std->hunters_used);
+	ut_asserteq(BIT(MMC_HUNTER) | BIT(5) | BIT(0), std->hunters_used);
 
 	mflags = 123;
 	ut_asserteq(-ENODEV, bootdev_next_label(&iter, &dev, &mflags));
@@ -582,7 +588,7 @@ static int bootdev_test_next_label(struct unit_test_state *uts)
 	ut_assert_console_end();
 
 	/* no change */
-	ut_asserteq(BIT(2) | BIT(4) | BIT(0), std->hunters_used);
+	ut_asserteq(BIT(MMC_HUNTER) | BIT(5) | BIT(0), std->hunters_used);
 
 	return 0;
 }
@@ -629,10 +635,13 @@ static int bootdev_test_next_prio(struct unit_test_state *uts)
 
 	ut_assertok(bootdev_next_prio(&iter, &dev));
 	ut_asserteq_str("mmc2.bootdev", dev->name);
+	ut_assert_nextline("Hunting with: simple_bus");
+	ut_assert_nextline("Found 2 extension board(s).");
 	ut_assert_nextline("Hunting with: mmc");
 	ut_assert_console_end();
 
-	ut_assertok(bootstd_test_check_mmc_hunter(uts));
+	/* extension in second in the list , so bit 1 */
+	ut_asserteq(BIT(MMC_HUNTER) | BIT(1), std->hunters_used);
 
 	ut_assertok(bootdev_next_prio(&iter, &dev));
 	ut_asserteq_str("mmc1.bootdev", dev->name);
@@ -663,7 +672,7 @@ static int bootdev_test_next_prio(struct unit_test_state *uts)
 	} while (!ret);
 	ut_asserteq(-ENODEV, ret);
 	ut_assertnull(dev);
-	ut_asserteq(GENMASK(7, 0), std->hunters_used);
+	ut_asserteq(GENMASK(MAX_HUNTER, 0), std->hunters_used);
 
 	ut_assert_skip_to_line("Hunting with: ethernet");
 	ut_assert_console_end();
diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c
index b71ec52eb7a..3a65d06696b 100644
--- a/test/boot/bootflow.c
+++ b/test/boot/bootflow.c
@@ -51,7 +51,7 @@ static int bootflow_cmd(struct unit_test_state *uts)
 	console_record_reset_enable();
 	ut_assertok(run_command("bootdev select 1", 0));
 	ut_assert_console_end();
-	ut_assertok(run_command("bootflow scan -l", 0));
+	ut_assertok(run_command("bootflow scan -lH", 0));
 	ut_assert_nextline("Scanning for bootflows in bootdev 'mmc1.bootdev'");
 	ut_assert_nextline("Seq  Method       State   Uclass    Part  Name                      Filename");
 	ut_assert_nextlinen("---");
@@ -77,17 +77,17 @@ BOOTSTD_TEST(bootflow_cmd, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
 static int bootflow_cmd_label(struct unit_test_state *uts)
 {
 	console_record_reset_enable();
-	ut_assertok(run_command("bootflow scan -l mmc1", 0));
+	ut_assertok(run_command("bootflow scan -lH mmc1", 0));
 	ut_assert_nextline("Scanning for bootflows in bootdev 'mmc1.bootdev'");
 	ut_assert_skip_to_line("(1 bootflow, 1 valid)");
 	ut_assert_console_end();
 
-	ut_assertok(run_command("bootflow scan -l mmc0.bootdev", 0));
+	ut_assertok(run_command("bootflow scan -lH mmc0.bootdev", 0));
 	ut_assert_nextline("Scanning for bootflows in bootdev 'mmc0.bootdev'");
 	ut_assert_skip_to_line("(0 bootflows, 0 valid)");
 	ut_assert_console_end();
 
-	ut_assertok(run_command("bootflow scan -l 0", 0));
+	ut_assertok(run_command("bootflow scan -lH 0", 0));
 	ut_assert_nextline("Scanning for bootflows in bootdev 'mmc2.bootdev'");
 	ut_assert_skip_to_line("(0 bootflows, 0 valid)");
 	ut_assert_console_end();
@@ -102,7 +102,7 @@ static int bootflow_cmd_glob(struct unit_test_state *uts)
 	ut_assertok(bootstd_test_drop_bootdev_order(uts));
 
 	console_record_reset_enable();
-	ut_assertok(run_command("bootflow scan -lG", 0));
+	ut_assertok(run_command("bootflow scan -lGH", 0));
 	ut_assert_nextline("Scanning for bootflows in all bootdevs");
 	ut_assert_nextline("Seq  Method       State   Uclass    Part  Name                      Filename");
 	ut_assert_nextlinen("---");
@@ -134,7 +134,7 @@ static int bootflow_cmd_scan_e(struct unit_test_state *uts)
 	ut_assertok(bootstd_test_drop_bootdev_order(uts));
 
 	console_record_reset_enable();
-	ut_assertok(run_command("bootflow scan -aleG", 0));
+	ut_assertok(run_command("bootflow scan -aleGH", 0));
 	ut_assert_nextline("Scanning for bootflows in all bootdevs");
 	ut_assert_nextline("Seq  Method       State   Uclass    Part  Name                      Filename");
 	ut_assert_nextlinen("---");
@@ -352,7 +352,7 @@ static int bootflow_system(struct unit_test_state *uts)
 	/* We should get a single 'bootmgr' method right at the end */
 	bootstd_clear_glob();
 	console_record_reset_enable();
-	ut_assertok(run_command("bootflow scan -l", 0));
+	ut_assertok(run_command("bootflow scan -lH", 0));
 	ut_assert_skip_to_line(
 		"  0  efi_mgr      ready   (none)       0  <NULL>                    <NULL>");
 	ut_assert_skip_to_line("No more bootdevs");
@@ -383,7 +383,7 @@ static int bootflow_iter_disable(struct unit_test_state *uts)
 	bootstd_clear_glob();
 	console_record_reset_enable();
 	ut_assertok(inject_response(uts));
-	ut_assertok(run_command("bootflow scan -lb", 0));
+	ut_assertok(run_command("bootflow scan -lbH", 0));
 
 	/* Try to boot the bootmgr flow, which will fail */
 	console_record_reset_enable();
@@ -419,7 +419,7 @@ static int bootflow_scan_glob_bootmeth(struct unit_test_state *uts)
 	 */
 	console_record_reset_enable();
 	ut_assertok(bootmeth_set_order("efi firmware0"));
-	ut_assertok(run_command("bootflow scan -lG", 0));
+	ut_assertok(run_command("bootflow scan -lGH", 0));
 	ut_assert_nextline("Scanning for bootflows in all bootdevs");
 	ut_assert_nextline(
 		"Seq  Method       State   Uclass    Part  Name                      Filename");
@@ -428,7 +428,7 @@ static int bootflow_scan_glob_bootmeth(struct unit_test_state *uts)
 	ut_assert_nextline("(0 bootflows, 0 valid)");
 	ut_assert_console_end();
 
-	ut_assertok(run_command("bootflow scan -l", 0));
+	ut_assertok(run_command("bootflow scan -lH", 0));
 	ut_assert_nextline("Scanning for bootflows in all bootdevs");
 	ut_assert_nextline(
 		"Seq  Method       State   Uclass    Part  Name                      Filename");
diff --git a/test/boot/bootstd_common.h b/test/boot/bootstd_common.h
index 0eb48fa1537..136a79b5178 100644
--- a/test/boot/bootstd_common.h
+++ b/test/boot/bootstd_common.h
@@ -20,6 +20,11 @@
 #define TEST_VERSION		"U-Boot v2022.04-local2"
 #define TEST_VERNUM		0x00010002
 
+enum {
+	MAX_HUNTER	= 8,
+	MMC_HUNTER	= 3,	/* ID of MMC hunter */
+};
+
 struct unit_test_state;
 
 /**
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 65/71] bootstd: Switch bootdev scanning to use labels
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (62 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 64/71] bootstd: Add a hunter for the extension feature Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 66/71] bootstd: Allow scanning a single bootdev label Simon Glass
                   ` (7 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

At present we set up the bootdev order at the start, then scan the
bootdevs one by one.

However this approach cannot be used with hunters, since the bootdevs may
not exist until the hunter is used. Nor can we just run all the hunters at
the start, since that violate's U-Boot's 'lazy init' requirement. It also
increases boot time.

So we need to adjust the algorithm to scan by labels instead. As a first
step, drop the dev_order[] array in favour of a list of labels. Update the
name of bootdev_setup_iter_order() to better reflect what it does.

Update some related comments and log messages. Also disable a few tests
until a later commit where we can use them.

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

(no changes since v1)

 boot/bootdev-uclass.c | 142 ++++++++----------------------------------
 boot/bootflow.c       |  72 ++++++++++++++++-----
 include/bootdev.h     |  13 ++--
 include/bootflow.h    |   8 +--
 test/boot/bootdev.c   |  22 ++++++-
 test/boot/bootflow.c  |  42 +++++++++++--
 6 files changed, 147 insertions(+), 152 deletions(-)

diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c
index 63005140061..334be7662a1 100644
--- a/boot/bootdev-uclass.c
+++ b/boot/bootdev-uclass.c
@@ -649,96 +649,12 @@ int bootdev_next_prio(struct bootflow_iter *iter, struct udevice **devp)
 	return 0;
 }
 
-/**
- * h_cmp_bootdev() - Compare two bootdevs to find out which should go first
- *
- * @v1: struct udevice * of first bootdev device
- * @v2: struct udevice * of second bootdev device
- * Return: sort order (<0 if dev1 < dev2, ==0 if equal, >0 if dev1 > dev2)
- */
-static int h_cmp_bootdev(const void *v1, const void *v2)
-{
-	const struct udevice *dev1 = *(struct udevice **)v1;
-	const struct udevice *dev2 = *(struct udevice **)v2;
-	const struct bootdev_uc_plat *ucp1 = dev_get_uclass_plat(dev1);
-	const struct bootdev_uc_plat *ucp2 = dev_get_uclass_plat(dev2);
-	int diff;
-
-	/* Use priority first */
-	diff = ucp1->prio - ucp2->prio;
-	if (diff)
-		return diff;
-
-	/* Fall back to seq for devices of the same priority */
-	diff = dev_seq(dev1) - dev_seq(dev2);
-
-	return diff;
-}
-
-/**
- * build_order() - Build the ordered list of bootdevs to use
- *
- * This builds an ordered list of devices by one of three methods:
- * - using the boot_targets environment variable, if non-empty
- * - using the bootdev-order devicetree property, if present
- * - sorted by priority and sequence number
- *
- * @bootstd: BOOTSTD device to use
- * @order: Bootdevs listed in default order
- * @max_count: Number of entries in @order
- * Return: number of bootdevs found in the ordering, or -E2BIG if the
- * boot_targets string is too long, or -EXDEV if the ordering produced 0 results
- */
-static int build_order(struct udevice *bootstd, struct udevice **order,
-		       int max_count)
-{
-	const char *overflow_target = NULL;
-	const char *const *labels;
-	struct udevice *dev;
-	int i, ret, count;
-	bool ok;
-
-	labels = bootstd_get_bootdev_order(bootstd, &ok);
-	if (!ok)
-		return log_msg_ret("ord", -ENOMEM);
-	if (labels) {
-		int upto;
-
-		upto = 0;
-		for (i = 0; labels[i]; i++) {
-			ret = bootdev_find_by_label(labels[i], &dev, NULL);
-			if (!ret) {
-				if (upto == max_count) {
-					overflow_target = labels[i];
-					break;
-				}
-				order[upto++] = dev;
-			}
-		}
-		count = upto;
-	} else {
-		/* sort them into priority order */
-		count = max_count;
-		qsort(order, count, sizeof(struct udevice *), h_cmp_bootdev);
-	}
-
-	if (overflow_target) {
-		log_warning("Expected at most %d bootdevs, but overflowed with boot_target '%s'\n",
-			    max_count, overflow_target);
-	}
-
-	if (!count)
-		return log_msg_ret("targ", -EXDEV);
-
-	return count;
-}
-
-int bootdev_setup_iter_order(struct bootflow_iter *iter, struct udevice **devp)
+int bootdev_setup_iter(struct bootflow_iter *iter, struct udevice **devp,
+		       int *method_flagsp)
 {
-	struct udevice *bootstd, *dev = *devp, **order;
+	struct udevice *bootstd, *dev = *devp;
 	bool show = iter->flags & BOOTFLOWF_SHOW;
-	struct uclass *uc;
-	int count, upto;
+	int method_flags;
 	int ret;
 
 	ret = uclass_first_device_err(UCLASS_BOOTSTD, &bootstd);
@@ -757,39 +673,33 @@ int bootdev_setup_iter_order(struct bootflow_iter *iter, struct udevice **devp)
 	/* Handle scanning a single device */
 	if (dev) {
 		iter->flags |= BOOTFLOWF_SINGLE_DEV;
-		return 0;
-	}
-
-	count = uclass_id_count(UCLASS_BOOTDEV);
-	if (!count)
-		return log_msg_ret("count", -ENOENT);
-
-	order = calloc(count, sizeof(struct udevice *));
-	if (!order)
-		return log_msg_ret("order", -ENOMEM);
-
-	/* Get the list of bootdevs */
-	uclass_id_foreach_dev(UCLASS_BOOTDEV, dev, uc)
-		order[upto++] = dev;
-	log_debug("Found %d bootdevs\n", count);
-	if (upto != count)
-		log_debug("Expected %d bootdevs, found %d using aliases\n",
-			  count, upto);
-
-	ret = build_order(bootstd, order, upto);
-	if (ret < 0) {
-		free(order);
-		return log_msg_ret("build", ret);
+		log_debug("Selected boodev: %s\n", dev->name);
+		method_flags = 0;
+	} else {
+		bool ok;
+
+		/* This either returns a non-empty list or NULL */
+		iter->labels = bootstd_get_bootdev_order(bootstd, &ok);
+		if (!ok)
+			return log_msg_ret("ord", -ENOMEM);
+		log_debug("setup labels %p\n", iter->labels);
+		if (iter->labels) {
+			iter->cur_label = -1;
+			ret = bootdev_next_label(iter, &dev, &method_flags);
+		} else {
+			ret = bootdev_next_prio(iter, &dev);
+			method_flags = 0;
+		}
+		if (!dev)
+			return log_msg_ret("fin", -ENOENT);
+		log_debug("Selected bootdev: %s\n", dev->name);
 	}
 
-	iter->num_devs = ret;
-	iter->dev_order = order;
-	iter->cur_dev = 0;
-
-	dev = *order;
 	ret = device_probe(dev);
 	if (ret)
 		return log_msg_ret("probe", ret);
+	if (method_flagsp)
+		*method_flagsp = method_flags;
 	*devp = dev;
 
 	return 0;
diff --git a/boot/bootflow.c b/boot/bootflow.c
index d2dbc9d4450..32e2aad470d 100644
--- a/boot/bootflow.c
+++ b/boot/bootflow.c
@@ -92,7 +92,6 @@ void bootflow_iter_init(struct bootflow_iter *iter, int flags)
 
 void bootflow_iter_uninit(struct bootflow_iter *iter)
 {
-	free(iter->dev_order);
 	free(iter->method_order);
 }
 
@@ -113,12 +112,25 @@ int bootflow_iter_drop_bootmeth(struct bootflow_iter *iter,
 	return 0;
 }
 
+/**
+ * bootflow_iter_set_dev() - switch to the next bootdev when iterating
+ *
+ * This sets iter->dev, records the device in the dev_used[] list and shows a
+ * message if required
+ *
+ * @iter: Iterator to update
+ * @dev: Bootdev to use, or NULL if there are no more
+ */
 static void bootflow_iter_set_dev(struct bootflow_iter *iter,
-				  struct udevice *dev)
+				  struct udevice *dev, int method_flags)
 {
 	struct bootmeth_uc_plat *ucp = dev_get_uclass_plat(iter->method);
 
+	log_debug("iter: Setting dev to %s, flags %x\n",
+		  dev ? dev->name : "(none)", method_flags);
 	iter->dev = dev;
+	iter->method_flags = method_flags;
+
 	if ((iter->flags & (BOOTFLOWF_SHOW | BOOTFLOWF_SINGLE_DEV)) ==
 	    BOOTFLOWF_SHOW) {
 		if (dev)
@@ -144,6 +156,7 @@ static int iter_incr(struct bootflow_iter *iter)
 	bool global;
 	int ret;
 
+	log_debug("entry: err=%d\n", iter->err);
 	global = iter->doing_global;
 
 	if (iter->err == BF_NO_MORE_DEVICES)
@@ -182,7 +195,7 @@ static int iter_incr(struct bootflow_iter *iter)
 			return 0;
 	}
 
-	/* No more partitions; start at the first one and...*/
+	/* No more partitions; start at the first one and... */
 	iter->part = 0;
 
 	/*
@@ -196,16 +209,32 @@ static int iter_incr(struct bootflow_iter *iter)
 	if (iter->flags & BOOTFLOWF_SINGLE_DEV) {
 		ret = -ENOENT;
 	} else {
-		if (inc_dev)
-			iter->cur_dev++;
-		if (iter->cur_dev == iter->num_devs) {
-			ret = -ENOENT;
-			bootflow_iter_set_dev(iter, NULL);
+		int method_flags;
+
+		ret = 0;
+		dev = iter->dev;
+		log_debug("inc_dev=%d\n", inc_dev);
+		if (!inc_dev) {
+			ret = bootdev_setup_iter(iter, &dev, &method_flags);
+		} else {
+			log_debug("labels %p\n", iter->labels);
+			if (iter->labels) {
+				ret = bootdev_next_label(iter, &dev,
+							 &method_flags);
+			} else {
+				ret = bootdev_next_prio(iter, &dev);
+				method_flags = 0;
+			}
+		}
+		log_debug("ret=%d, dev=%p %s\n", ret, dev,
+			  dev ? dev->name : "none");
+		if (ret) {
+			bootflow_iter_set_dev(iter, NULL, 0);
 		} else {
-			dev = iter->dev_order[iter->cur_dev];
 			ret = device_probe(dev);
+			log_debug("probe %s %d\n", dev->name, ret);
 			if (!log_msg_ret("probe", ret))
-				bootflow_iter_set_dev(iter, dev);
+				bootflow_iter_set_dev(iter, dev, method_flags);
 		}
 	}
 
@@ -230,7 +259,7 @@ static int bootflow_check(struct bootflow_iter *iter, struct bootflow *bflow)
 	int ret;
 
 	if (IS_ENABLED(CONFIG_BOOTMETH_GLOBAL) && iter->doing_global) {
-		bootflow_iter_set_dev(iter, NULL);
+		bootflow_iter_set_dev(iter, NULL, 0);
 		ret = bootmeth_get_bootflow(iter->method, bflow);
 		if (ret)
 			return log_msg_ret("glob", ret);
@@ -274,18 +303,27 @@ int bootflow_scan_bootdev(struct udevice *dev, struct bootflow_iter *iter,
 		flags |= BOOTFLOWF_SKIP_GLOBAL;
 	bootflow_iter_init(iter, flags);
 
-	ret = bootdev_setup_iter_order(iter, &dev);
-	if (ret)
-		return log_msg_ret("obdev", -ENODEV);
-
+	/*
+	 * Set up the ordering of bootmeths. This sets iter->doing_global and
+	 * iter->first_glob_method if we are starting with the global bootmeths
+	 */
 	ret = bootmeth_setup_iter_order(iter, !(flags & BOOTFLOWF_SKIP_GLOBAL));
 	if (ret)
 		return log_msg_ret("obmeth", -ENODEV);
 
 	/* Find the first bootmeth (there must be at least one!) */
 	iter->method = iter->method_order[iter->cur_method];
-	if (!IS_ENABLED(CONFIG_BOOTMETH_GLOBAL) || !iter->doing_global)
-		bootflow_iter_set_dev(iter, dev);
+
+	if (!IS_ENABLED(CONFIG_BOOTMETH_GLOBAL) || !iter->doing_global) {
+		struct udevice *dev = NULL;
+		int method_flags;
+
+		ret = bootdev_setup_iter(iter, &dev, &method_flags);
+		if (ret)
+			return log_msg_ret("obdev", -ENODEV);
+
+		bootflow_iter_set_dev(iter, dev, method_flags);
+	}
 
 	ret = bootflow_check(iter, bflow);
 	if (ret) {
diff --git a/include/bootdev.h b/include/bootdev.h
index 4b6a8eb8d8f..8fa67487c63 100644
--- a/include/bootdev.h
+++ b/include/bootdev.h
@@ -265,21 +265,22 @@ int bootdev_find_by_any(const char *name, struct udevice **devp,
 			int *method_flagsp);
 
 /**
- * bootdev_setup_iter_order() - Set up the ordering of bootdevs to scan
+ * bootdev_setup_iter() - Set up iteration through bootdevs
  *
- * This sets up the ordering information in @iter, based on the priority of each
- * bootdev and the bootdev-order property in the bootstd node
- *
- * If a single device is requested, no ordering is needed
+ * This sets up the an interation, based on the priority of each bootdev, the
+ * bootdev-order property in the bootstd node (or the boot_targets env var).
  *
  * @iter: Iterator to update with the order
  * @devp: On entry, *devp is NULL to scan all, otherwise this is the (single)
  *	device to scan. Returns the first device to use, which is the passed-in
  *	@devp if it was non-NULL
+ * @method_flagsp: If non-NULL, returns any flags implied by the label
+ * (enum bootflow_meth_flags_t), 0 if none
  * Return: 0 if OK, -ENOENT if no bootdevs, -ENOMEM if out of memory, other -ve
  *	on other error
  */
-int bootdev_setup_iter_order(struct bootflow_iter *iter, struct udevice **devp);
+int bootdev_setup_iter(struct bootflow_iter *iter, struct udevice **devp,
+		       int *method_flagsp);
 
 /**
  * bootdev_list_hunters() - List the available bootdev hunters
diff --git a/include/bootflow.h b/include/bootflow.h
index 69ac90483c6..bdb37352ab9 100644
--- a/include/bootflow.h
+++ b/include/bootflow.h
@@ -163,7 +163,8 @@ enum bootflow_meth_flags_t {
  * @flags: Flags to use (see enum bootflow_flags_t). If BOOTFLOWF_GLOBAL_FIRST is
  *	enabled then the global bootmeths are being scanned, otherwise we have
  *	moved onto the bootdevs
- * @dev: Current bootdev, NULL if none
+ * @dev: Current bootdev, NULL if none. This is only ever updated in
+ * bootflow_iter_set_dev()
  * @part: Current partition number (0 for whole device)
  * @method: Current bootmeth
  * @max_part: Maximum hardware partition number in @dev, 0 if there is no
@@ -173,9 +174,6 @@ enum bootflow_meth_flags_t {
  *	forward (e.g. to skip the current partition because it is not valid)
  *	-ESHUTDOWN: try next bootdev
  * @num_devs: Number of bootdevs in @dev_order
- * @cur_dev: Current bootdev number, an index into @dev_order[]
- * @dev_order: List of bootdevs to scan, in order of priority. The scan starts
- *	with the first one on the list
  * @labels: List of labels to scan for bootdevs
  * @cur_label: Current label being processed
  * @num_methods: Number of bootmeth devices in @method_order
@@ -198,8 +196,6 @@ struct bootflow_iter {
 	int first_bootable;
 	int err;
 	int num_devs;
-	int cur_dev;
-	struct udevice **dev_order;
 	const char *const *labels;
 	int cur_label;
 	int num_methods;
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c
index 8ebc27a6435..679ffc4d8df 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -186,6 +186,7 @@ static int bootdev_test_any(struct unit_test_state *uts)
 BOOTSTD_TEST(bootdev_test_any, UT_TESTF_DM | UT_TESTF_SCAN_FDT |
 	     UT_TESTF_ETH_BOOTDEV);
 
+#if 0 /* disable for now */
 /* Check bootdev ordering with the bootdev-order property */
 static int bootdev_test_order(struct unit_test_state *uts)
 {
@@ -290,6 +291,7 @@ static int bootdev_test_prio(struct unit_test_state *uts)
 	return 0;
 }
 BOOTSTD_TEST(bootdev_test_prio, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
+#endif
 
 /* Check listing hunters */
 static int bootdev_test_hunter(struct unit_test_state *uts)
@@ -402,6 +404,25 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
 BOOTSTD_TEST(bootdev_test_cmd_hunt, UT_TESTF_DM | UT_TESTF_SCAN_FDT |
 	     UT_TESTF_ETH_BOOTDEV);
 
+/* Check searching for bootdevs using the hunters */
+static int bootdev_test_hunt_scan(struct unit_test_state *uts)
+{
+	struct bootflow_iter iter;
+	struct bootstd_priv *std;
+	struct bootflow bflow;
+
+	/* get access to the used hunters */
+	ut_assertok(bootstd_get_priv(&std));
+
+	ut_assertok(bootstd_test_drop_bootdev_order(uts));
+	ut_assertok(bootflow_scan_first(&iter, BOOTFLOWF_SHOW | BOOTFLOWF_HUNT |
+					BOOTFLOWF_SKIP_GLOBAL, &bflow));
+	ut_asserteq(BIT(MMC_HUNTER) | BIT(1), std->hunters_used);
+
+	return 0;
+}
+BOOTSTD_TEST(bootdev_test_hunt_scan, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
+
 /* Check that only bootable partitions are processed */
 static int bootdev_test_bootable(struct unit_test_state *uts)
 {
@@ -640,7 +661,6 @@ static int bootdev_test_next_prio(struct unit_test_state *uts)
 	ut_assert_nextline("Hunting with: mmc");
 	ut_assert_console_end();
 
-	/* extension in second in the list , so bit 1 */
 	ut_asserteq(BIT(MMC_HUNTER) | BIT(1), std->hunters_used);
 
 	ut_assertok(bootdev_next_prio(&iter, &dev));
diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c
index 3a65d06696b..1a2c54c1119 100644
--- a/test/boot/bootflow.c
+++ b/test/boot/bootflow.c
@@ -55,7 +55,10 @@ static int bootflow_cmd(struct unit_test_state *uts)
 	ut_assert_nextline("Scanning for bootflows in bootdev 'mmc1.bootdev'");
 	ut_assert_nextline("Seq  Method       State   Uclass    Part  Name                      Filename");
 	ut_assert_nextlinen("---");
+	ut_assert_nextline("Scanning bootdev 'mmc2.bootdev':");
+	ut_assert_nextline("Scanning bootdev 'mmc1.bootdev':");
 	ut_assert_nextline("  0  syslinux     ready   mmc          1  mmc1.bootdev.part_1       /extlinux/extlinux.conf");
+	ut_assert_nextline("No more bootdevs");
 	ut_assert_nextlinen("---");
 	ut_assert_nextline("(1 bootflow, 1 valid)");
 	ut_assert_console_end();
@@ -73,28 +76,55 @@ static int bootflow_cmd(struct unit_test_state *uts)
 }
 BOOTSTD_TEST(bootflow_cmd, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
 
-/* Check 'bootflow scan' with a name / label / seq */
+#if 0 /* disable for now */
+/* Check 'bootflow scan' with a label / seq */
 static int bootflow_cmd_label(struct unit_test_state *uts)
 {
+	test_set_eth_enable(false);
+
 	console_record_reset_enable();
 	ut_assertok(run_command("bootflow scan -lH mmc1", 0));
-	ut_assert_nextline("Scanning for bootflows in bootdev 'mmc1.bootdev'");
+	ut_assert_nextline("Scanning for bootflows with label 'mmc1'");
 	ut_assert_skip_to_line("(1 bootflow, 1 valid)");
 	ut_assert_console_end();
 
-	ut_assertok(run_command("bootflow scan -lH mmc0.bootdev", 0));
-	ut_assert_nextline("Scanning for bootflows in bootdev 'mmc0.bootdev'");
+	ut_assertok(run_command("bootflow scan -lH 0", 0));
+	ut_assert_nextline("Scanning for bootflows with label '0'");
 	ut_assert_skip_to_line("(0 bootflows, 0 valid)");
 	ut_assert_console_end();
 
+	/*
+	 * with ethernet enabled we have 8 devices ahead of the mmc ones:
+	 *
+	 * ut_assertok(run_command("bootdev list", 0));
+	 * Seq  Probed  Status  Uclass    Name
+	 * ---  ------  ------  --------  ------------------
+	 * 0   [ + ]      OK  ethernet  eth@10002000.bootdev
+	 * 1   [   ]      OK  ethernet  eth@10003000.bootdev
+	 * 2   [   ]      OK  ethernet  sbe5.bootdev
+	 * 3   [   ]      OK  ethernet  eth@10004000.bootdev
+	 * 4   [   ]      OK  ethernet  phy-test-eth.bootdev
+	 * 5   [   ]      OK  ethernet  dsa-test-eth.bootdev
+	 * 6   [   ]      OK  ethernet  dsa-test@0.bootdev
+	 * 7   [   ]      OK  ethernet  dsa-test@1.bootdev
+	 * 8   [   ]      OK  mmc       mmc2.bootdev
+	 * 9   [ + ]      OK  mmc       mmc1.bootdev
+	 * a   [   ]      OK  mmc       mmc0.bootdev
+	 */
+	ut_assertok(run_command("bootflow scan -lH 9", 0));
+	ut_assert_nextline("Scanning for bootflows with label '9'");
+	ut_assert_skip_to_line("(1 bootflow, 1 valid)");
+
 	ut_assertok(run_command("bootflow scan -lH 0", 0));
-	ut_assert_nextline("Scanning for bootflows in bootdev 'mmc2.bootdev'");
+	ut_assert_nextline("Scanning for bootflows with label '0'");
 	ut_assert_skip_to_line("(0 bootflows, 0 valid)");
 	ut_assert_console_end();
 
 	return 0;
 }
-BOOTSTD_TEST(bootflow_cmd_label, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
+BOOTSTD_TEST(bootflow_cmd_label, UT_TESTF_DM | UT_TESTF_SCAN_FDT |
+	     UT_TESTF_ETH_BOOTDEV);
+#endif
 
 /* Check 'bootflow scan/list' commands using all bootdevs */
 static int bootflow_cmd_glob(struct unit_test_state *uts)
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 66/71] bootstd: Allow scanning a single bootdev label
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (63 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 65/71] bootstd: Switch bootdev scanning to use labels Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 67/71] bootstd: Drop the old bootflow_scan_first() Simon Glass
                   ` (6 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

We want to support scanning a single label, like 'mmc' or 'usb0'. Add
this feature by plumbing the label through to the iterator, setting a
flag to indicate that only siblings of the initial device should be used.

This means that scanning a bootdev by its name is not supported anymore.
That feature doesn't seem very useful in practice, so it is no great loss.

Add a test for bootdev_find_by_any() while we are here.

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

(no changes since v1)

 boot/bootdev-uclass.c | 28 ++++++++++----
 boot/bootflow.c       | 43 +++++++++++++++++++---
 cmd/bootflow.c        | 86 +++++++++++++++++--------------------------
 include/bootdev.h     | 11 ++++--
 include/bootflow.h    | 10 +++--
 test/boot/bootdev.c   |  2 +-
 test/boot/bootflow.c  | 62 ++++++++++++++++++++++++++++++-
 7 files changed, 166 insertions(+), 76 deletions(-)

diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c
index 334be7662a1..522ecf38eb3 100644
--- a/boot/bootdev-uclass.c
+++ b/boot/bootdev-uclass.c
@@ -649,10 +649,10 @@ int bootdev_next_prio(struct bootflow_iter *iter, struct udevice **devp)
 	return 0;
 }
 
-int bootdev_setup_iter(struct bootflow_iter *iter, struct udevice **devp,
-		       int *method_flagsp)
+int bootdev_setup_iter(struct bootflow_iter *iter, const char *label,
+		       struct udevice **devp, int *method_flagsp)
 {
-	struct udevice *bootstd, *dev = *devp;
+	struct udevice *bootstd, *dev = NULL;
 	bool show = iter->flags & BOOTFLOWF_SHOW;
 	int method_flags;
 	int ret;
@@ -671,10 +671,24 @@ int bootdev_setup_iter(struct bootflow_iter *iter, struct udevice **devp,
 	}
 
 	/* Handle scanning a single device */
-	if (dev) {
-		iter->flags |= BOOTFLOWF_SINGLE_DEV;
-		log_debug("Selected boodev: %s\n", dev->name);
-		method_flags = 0;
+	if (IS_ENABLED(CONFIG_BOOTSTD_FULL) && label) {
+		if (iter->flags & BOOTFLOWF_HUNT) {
+			ret = bootdev_hunt(label, show);
+			if (ret)
+				return log_msg_ret("hun", ret);
+		}
+		ret = bootdev_find_by_any(label, &dev, &method_flags);
+		if (ret)
+			return log_msg_ret("lab", ret);
+
+		log_debug("method_flags: %x\n", method_flags);
+		if (method_flags & BOOTFLOW_METHF_SINGLE_UCLASS)
+			iter->flags |= BOOTFLOWF_SINGLE_UCLASS;
+		else if (method_flags & BOOTFLOW_METHF_SINGLE_DEV)
+			iter->flags |= BOOTFLOWF_SINGLE_DEV;
+		else
+			iter->flags |= BOOTFLOWF_SINGLE_MEDIA;
+		log_debug("Selected label: %s, flags %x\n", label, iter->flags);
 	} else {
 		bool ok;
 
diff --git a/boot/bootflow.c b/boot/bootflow.c
index 32e2aad470d..50d9c2e813a 100644
--- a/boot/bootflow.c
+++ b/boot/bootflow.c
@@ -215,7 +215,37 @@ static int iter_incr(struct bootflow_iter *iter)
 		dev = iter->dev;
 		log_debug("inc_dev=%d\n", inc_dev);
 		if (!inc_dev) {
-			ret = bootdev_setup_iter(iter, &dev, &method_flags);
+			ret = bootdev_setup_iter(iter, NULL, &dev,
+						 &method_flags);
+		} else if (IS_ENABLED(CONFIG_BOOTSTD_FULL) &&
+			   (iter->flags & BOOTFLOWF_SINGLE_UCLASS)) {
+			/* Move to the next bootdev in this uclass */
+			uclass_find_next_device(&dev);
+			if (!dev) {
+				log_debug("finished uclass %s\n",
+					  dev_get_uclass_name(dev));
+				ret = -ENODEV;
+			}
+		} else if (IS_ENABLED(CONFIG_BOOTSTD_FULL) &&
+			   iter->flags & BOOTFLOWF_SINGLE_MEDIA) {
+			log_debug("next in single\n");
+			method_flags = 0;
+			do {
+				/*
+				 * Move to the next bootdev child of this media
+				 * device. This ensures that we cover all the
+				 * available SCSI IDs and LUNs.
+				 */
+				device_find_next_child(&dev);
+				log_debug("- next %s\n",
+					dev ? dev->name : "(none)");
+			} while (dev && device_get_uclass_id(dev) !=
+				UCLASS_BOOTDEV);
+			if (!dev) {
+				log_debug("finished uclass %s\n",
+					  dev_get_uclass_name(dev));
+				ret = -ENODEV;
+			}
 		} else {
 			log_debug("labels %p\n", iter->labels);
 			if (iter->labels) {
@@ -294,12 +324,13 @@ static int bootflow_check(struct bootflow_iter *iter, struct bootflow *bflow)
 	return 0;
 }
 
-int bootflow_scan_bootdev(struct udevice *dev, struct bootflow_iter *iter,
-			  int flags, struct bootflow *bflow)
+int bootflow_scan_bootdev(struct udevice *dev, const char *label,
+			  struct bootflow_iter *iter, int flags,
+			  struct bootflow *bflow)
 {
 	int ret;
 
-	if (dev)
+	if (dev || label)
 		flags |= BOOTFLOWF_SKIP_GLOBAL;
 	bootflow_iter_init(iter, flags);
 
@@ -318,7 +349,7 @@ int bootflow_scan_bootdev(struct udevice *dev, struct bootflow_iter *iter,
 		struct udevice *dev = NULL;
 		int method_flags;
 
-		ret = bootdev_setup_iter(iter, &dev, &method_flags);
+		ret = bootdev_setup_iter(iter, label, &dev, &method_flags);
 		if (ret)
 			return log_msg_ret("obdev", -ENODEV);
 
@@ -345,7 +376,7 @@ int bootflow_scan_first(struct bootflow_iter *iter, int flags,
 {
 	int ret;
 
-	ret = bootflow_scan_bootdev(NULL, iter, flags, bflow);
+	ret = bootflow_scan_bootdev(NULL, NULL, iter, flags, bflow);
 	if (ret)
 		return log_msg_ret("start", ret);
 
diff --git a/cmd/bootflow.c b/cmd/bootflow.c
index fe58de5fa59..72d5a8424e9 100644
--- a/cmd/bootflow.c
+++ b/cmd/bootflow.c
@@ -93,11 +93,12 @@ static int do_bootflow_scan(struct cmd_tbl *cmdtp, int flag, int argc,
 {
 	struct bootstd_priv *std;
 	struct bootflow_iter iter;
-	struct udevice *dev;
+	struct udevice *dev = NULL;
 	struct bootflow bflow;
 	bool all = false, boot = false, errors = false, no_global = false;
 	bool list = false, no_hunter = false;
 	int num_valid = 0;
+	const char *label = NULL;
 	bool has_args;
 	int ret, i;
 	int flags;
@@ -105,7 +106,6 @@ static int do_bootflow_scan(struct cmd_tbl *cmdtp, int flag, int argc,
 	ret = bootstd_get_priv(&std);
 	if (ret)
 		return CMD_RET_FAILURE;
-	dev = std->cur_bootdev;
 
 	has_args = argc > 1 && *argv[1] == '-';
 	if (IS_ENABLED(CONFIG_CMD_BOOTFLOW_FULL)) {
@@ -119,12 +119,10 @@ static int do_bootflow_scan(struct cmd_tbl *cmdtp, int flag, int argc,
 			argc--;
 			argv++;
 		}
-		if (argc > 1) {
-			const char *label = argv[1];
-
-			if (bootdev_find_by_any(label, &dev, NULL))
-				return CMD_RET_FAILURE;
-		}
+		if (argc > 1)
+			label = argv[1];
+		if (!label)
+			dev = std->cur_bootdev;
 	} else {
 		if (has_args) {
 			printf("Flags not supported: enable CONFIG_BOOTFLOW_FULL\n");
@@ -148,54 +146,36 @@ static int do_bootflow_scan(struct cmd_tbl *cmdtp, int flag, int argc,
 	/*
 	 * If we have a device, just scan for bootflows attached to that device
 	 */
-	if (IS_ENABLED(CONFIG_CMD_BOOTFLOW_FULL) && dev) {
-		if (list) {
-			printf("Scanning for bootflows in bootdev '%s'\n",
-			       dev->name);
-			show_header();
-		}
+	if (list) {
+		printf("Scanning for bootflows ");
+		if (dev)
+			printf("in bootdev '%s'\n", dev->name);
+		else if (label)
+			printf("with label '%s'\n", label);
+		else
+			printf("in all bootdevs\n");
+		show_header();
+	}
+	if (dev)
 		bootdev_clear_bootflows(dev);
-		for (i = 0,
-		     ret = bootflow_scan_bootdev(dev, &iter, flags, &bflow);
-		     i < 1000 && ret != -ENODEV;
-		     i++, ret = bootflow_scan_next(&iter, &bflow)) {
-			bflow.err = ret;
-			if (!ret)
-				num_valid++;
-			ret = bootdev_add_bootflow(&bflow);
-			if (ret) {
-				printf("Out of memory\n");
-				return CMD_RET_FAILURE;
-			}
-			if (list)
-				show_bootflow(i, &bflow, errors);
-			if (boot && !bflow.err)
-				bootflow_run_boot(&iter, &bflow);
-		}
-	} else {
-		if (list) {
-			printf("Scanning for bootflows in all bootdevs\n");
-			show_header();
-		}
+	else
 		bootstd_clear_glob();
-
-		for (i = 0,
-		     ret = bootflow_scan_first(&iter, flags, &bflow);
-		     i < 1000 && ret != -ENODEV;
-		     i++, ret = bootflow_scan_next(&iter, &bflow)) {
-			bflow.err = ret;
-			if (!ret)
-				num_valid++;
-			ret = bootdev_add_bootflow(&bflow);
-			if (ret) {
-				printf("Out of memory\n");
-				return CMD_RET_FAILURE;
-			}
-			if (list)
-				show_bootflow(i, &bflow, errors);
-			if (boot && !bflow.err)
-				bootflow_run_boot(&iter, &bflow);
+	for (i = 0,
+	     ret = bootflow_scan_bootdev(dev, label, &iter, flags, &bflow);
+	     i < 1000 && ret != -ENODEV;
+	     i++, ret = bootflow_scan_next(&iter, &bflow)) {
+		bflow.err = ret;
+		if (!ret)
+			num_valid++;
+		ret = bootdev_add_bootflow(&bflow);
+		if (ret) {
+			printf("Out of memory\n");
+			return CMD_RET_FAILURE;
 		}
+		if (list)
+			show_bootflow(i, &bflow, errors);
+		if (boot && !bflow.err)
+			bootflow_run_boot(&iter, &bflow);
 	}
 	bootflow_iter_uninit(&iter);
 	if (list)
diff --git a/include/bootdev.h b/include/bootdev.h
index 8fa67487c63..b92ff4d4f15 100644
--- a/include/bootdev.h
+++ b/include/bootdev.h
@@ -267,10 +267,13 @@ int bootdev_find_by_any(const char *name, struct udevice **devp,
 /**
  * bootdev_setup_iter() - Set up iteration through bootdevs
  *
- * This sets up the an interation, based on the priority of each bootdev, the
- * bootdev-order property in the bootstd node (or the boot_targets env var).
+ * This sets up the an interation, based on the provided device or label. If
+ * neither is provided, the iteration is based on the priority of each bootdev,
+ * the * bootdev-order property in the bootstd node (or the boot_targets env
+ * var).
  *
  * @iter: Iterator to update with the order
+ * @label: label to scan, or NULL to scan all
  * @devp: On entry, *devp is NULL to scan all, otherwise this is the (single)
  *	device to scan. Returns the first device to use, which is the passed-in
  *	@devp if it was non-NULL
@@ -279,8 +282,8 @@ int bootdev_find_by_any(const char *name, struct udevice **devp,
  * Return: 0 if OK, -ENOENT if no bootdevs, -ENOMEM if out of memory, other -ve
  *	on other error
  */
-int bootdev_setup_iter(struct bootflow_iter *iter, struct udevice **devp,
-		       int *method_flagsp);
+int bootdev_setup_iter(struct bootflow_iter *iter, const char *label,
+		       struct udevice **devp, int *method_flagsp);
 
 /**
  * bootdev_list_hunters() - List the available bootdev hunters
diff --git a/include/bootflow.h b/include/bootflow.h
index bdb37352ab9..1b7920a9572 100644
--- a/include/bootflow.h
+++ b/include/bootflow.h
@@ -255,14 +255,18 @@ int bootflow_iter_drop_bootmeth(struct bootflow_iter *iter,
  *
  * @dev:	Boot device to scan, NULL to work through all of them until it
  *	finds one that can supply a bootflow
+ * @label:	Label to control the scan, NULL to work through all devices
+ *	until it finds one that can supply a bootflow
  * @iter:	Place to store private info (inited by this call)
- * @flags:	Flags for iterator (enum bootflow_flags_t)
+ * @flags:	Flags for iterator (enum bootflow_flags_t). Note that if @dev
+ * is NULL, then BOOTFLOWF_SKIP_GLOBAL is set automatically by this function
  * @bflow:	Place to put the bootflow if found
  * Return: 0 if found,  -ENODEV if no device, other -ve on other error
  *	(iteration can continue)
  */
-int bootflow_scan_bootdev(struct udevice *dev, struct bootflow_iter *iter,
-			  int flags, struct bootflow *bflow);
+int bootflow_scan_bootdev(struct udevice *dev, const char *label,
+			  struct bootflow_iter *iter, int flags,
+			  struct bootflow *bflow);
 
 /**
  * bootflow_scan_first() - find the first bootflow
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c
index 679ffc4d8df..1724e34af3e 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -626,7 +626,7 @@ static int bootdev_test_next_prio(struct unit_test_state *uts)
 	struct udevice *dev;
 	int ret;
 
-	sandbox_set_eth_enable(false);
+	test_set_eth_enable(false);
 	test_set_skip_delays(true);
 
 	/* get access to the used hunters */
diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c
index 1a2c54c1119..0b3a2fa6acc 100644
--- a/test/boot/bootflow.c
+++ b/test/boot/bootflow.c
@@ -76,7 +76,6 @@ static int bootflow_cmd(struct unit_test_state *uts)
 }
 BOOTSTD_TEST(bootflow_cmd, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
 
-#if 0 /* disable for now */
 /* Check 'bootflow scan' with a label / seq */
 static int bootflow_cmd_label(struct unit_test_state *uts)
 {
@@ -124,7 +123,6 @@ static int bootflow_cmd_label(struct unit_test_state *uts)
 }
 BOOTSTD_TEST(bootflow_cmd_label, UT_TESTF_DM | UT_TESTF_SCAN_FDT |
 	     UT_TESTF_ETH_BOOTDEV);
-#endif
 
 /* Check 'bootflow scan/list' commands using all bootdevs */
 static int bootflow_cmd_glob(struct unit_test_state *uts)
@@ -564,6 +562,66 @@ static int bootflow_cmd_menu(struct unit_test_state *uts)
 }
 BOOTSTD_TEST(bootflow_cmd_menu, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
 
+/* Check searching for a single bootdev using the hunters */
+static int bootflow_cmd_hunt_single(struct unit_test_state *uts)
+{
+	struct bootstd_priv *std;
+
+	/* get access to the used hunters */
+	ut_assertok(bootstd_get_priv(&std));
+
+	ut_assertok(bootstd_test_drop_bootdev_order(uts));
+
+	console_record_reset_enable();
+	ut_assertok(run_command("bootflow scan -l mmc1", 0));
+	ut_assert_nextline("Scanning for bootflows with label 'mmc1'");
+	ut_assert_skip_to_line("(1 bootflow, 1 valid)");
+	ut_assert_console_end();
+
+	/* check that the hunter was used */
+	ut_asserteq(BIT(MMC_HUNTER) | BIT(1), std->hunters_used);
+
+	return 0;
+}
+BOOTSTD_TEST(bootflow_cmd_hunt_single, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
+
+/* Check searching for a uclass label using the hunters */
+static int bootflow_cmd_hunt_label(struct unit_test_state *uts)
+{
+	struct bootstd_priv *std;
+
+	/* get access to the used hunters */
+	ut_assertok(bootstd_get_priv(&std));
+
+	test_set_skip_delays(true);
+	test_set_eth_enable(false);
+	ut_assertok(bootstd_test_drop_bootdev_order(uts));
+
+	console_record_reset_enable();
+	ut_assertok(run_command("bootflow scan -l mmc", 0));
+
+	/* check that the hunter was used */
+	ut_asserteq(BIT(MMC_HUNTER) | BIT(1), std->hunters_used);
+
+	/* check that we got the mmc1 bootflow */
+	ut_assert_nextline("Scanning for bootflows with label 'mmc'");
+	ut_assert_nextlinen("Seq");
+	ut_assert_nextlinen("---");
+	ut_assert_nextline("Hunting with: simple_bus");
+	ut_assert_nextline("Found 2 extension board(s).");
+	ut_assert_nextline("Hunting with: mmc");
+	ut_assert_nextline("Scanning bootdev 'mmc2.bootdev':");
+	ut_assert_nextline("Scanning bootdev 'mmc1.bootdev':");
+	ut_assert_nextline(
+		"  0  syslinux     ready   mmc          1  mmc1.bootdev.part_1       /extlinux/extlinux.conf");
+	ut_assert_nextline("Scanning bootdev 'mmc0.bootdev':");
+	ut_assert_skip_to_line("(1 bootflow, 1 valid)");
+	ut_assert_console_end();
+
+	return 0;
+}
+BOOTSTD_TEST(bootflow_cmd_hunt_label, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
+
 /**
  * check_font() - Check that the font size for an item matches expectations
  *
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 67/71] bootstd: Drop the old bootflow_scan_first()
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (64 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 66/71] bootstd: Allow scanning a single bootdev label Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 68/71] bootstd: Record the bootdevs used during scanning Simon Glass
                   ` (5 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

This function is not used outside tests. Drop it and rename
bootflow_scan_dev() since it is how we start a scan now.

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

(no changes since v1)

 boot/bootflow.c      | 18 +++---------------
 cmd/bootflow.c       |  2 +-
 include/bootflow.h   | 23 +++--------------------
 test/boot/bootdev.c  | 16 +++++++++-------
 test/boot/bootflow.c |  5 +++--
 5 files changed, 19 insertions(+), 45 deletions(-)

diff --git a/boot/bootflow.c b/boot/bootflow.c
index 50d9c2e813a..750732f7083 100644
--- a/boot/bootflow.c
+++ b/boot/bootflow.c
@@ -324,9 +324,9 @@ static int bootflow_check(struct bootflow_iter *iter, struct bootflow *bflow)
 	return 0;
 }
 
-int bootflow_scan_bootdev(struct udevice *dev, const char *label,
-			  struct bootflow_iter *iter, int flags,
-			  struct bootflow *bflow)
+int bootflow_scan_first(struct udevice *dev, const char *label,
+			struct bootflow_iter *iter, int flags,
+			struct bootflow *bflow)
 {
 	int ret;
 
@@ -371,18 +371,6 @@ int bootflow_scan_bootdev(struct udevice *dev, const char *label,
 	return 0;
 }
 
-int bootflow_scan_first(struct bootflow_iter *iter, int flags,
-			struct bootflow *bflow)
-{
-	int ret;
-
-	ret = bootflow_scan_bootdev(NULL, NULL, iter, flags, bflow);
-	if (ret)
-		return log_msg_ret("start", ret);
-
-	return 0;
-}
-
 int bootflow_scan_next(struct bootflow_iter *iter, struct bootflow *bflow)
 {
 	int ret;
diff --git a/cmd/bootflow.c b/cmd/bootflow.c
index 72d5a8424e9..692bc6d117f 100644
--- a/cmd/bootflow.c
+++ b/cmd/bootflow.c
@@ -161,7 +161,7 @@ static int do_bootflow_scan(struct cmd_tbl *cmdtp, int flag, int argc,
 	else
 		bootstd_clear_glob();
 	for (i = 0,
-	     ret = bootflow_scan_bootdev(dev, label, &iter, flags, &bflow);
+	     ret = bootflow_scan_first(dev, label, &iter, flags, &bflow);
 	     i < 1000 && ret != -ENODEV;
 	     i++, ret = bootflow_scan_next(&iter, &bflow)) {
 		bflow.err = ret;
diff --git a/include/bootflow.h b/include/bootflow.h
index 1b7920a9572..c2368912061 100644
--- a/include/bootflow.h
+++ b/include/bootflow.h
@@ -249,7 +249,7 @@ int bootflow_iter_drop_bootmeth(struct bootflow_iter *iter,
 				const struct udevice *bmeth);
 
 /**
- * bootflow_scan_bootdev() - find the first bootflow in a bootdev
+ * bootflow_scan_first() - find the first bootflow for a device or label
  *
  * If @flags includes BOOTFLOWF_ALL then bootflows with errors are returned too
  *
@@ -264,25 +264,8 @@ int bootflow_iter_drop_bootmeth(struct bootflow_iter *iter,
  * Return: 0 if found,  -ENODEV if no device, other -ve on other error
  *	(iteration can continue)
  */
-int bootflow_scan_bootdev(struct udevice *dev, const char *label,
-			  struct bootflow_iter *iter, int flags,
-			  struct bootflow *bflow);
-
-/**
- * bootflow_scan_first() - find the first bootflow
- *
- * This works through the available bootdev devices until it finds one that
- * can supply a bootflow. It then returns that
- *
- * If @flags includes BOOTFLOWF_ALL then bootflows with errors are returned too
- *
- * @iter:	Place to store private info (inited by this call), with
- * @flags:	Flags for bootdev (enum bootflow_flags_t)
- * @bflow:	Place to put the bootflow if found
- * Return: 0 if found, -ENODEV if no device, other -ve on other error (iteration
- *	can continue)
- */
-int bootflow_scan_first(struct bootflow_iter *iter, int flags,
+int bootflow_scan_first(struct udevice *dev, const char *label,
+			struct bootflow_iter *iter, int flags,
 			struct bootflow *bflow);
 
 /**
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c
index 1724e34af3e..5d5ce7f48cf 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -203,7 +203,7 @@ static int bootdev_test_order(struct unit_test_state *uts)
 	 * mmc2 - nothing connected
 	 */
 	ut_assertok(env_set("boot_targets", NULL));
-	ut_assertok(bootflow_scan_first(&iter, 0, &bflow));
+	ut_assertok(bootflow_scan_first(NULL, NULL, &iter, 0, &bflow));
 	ut_asserteq(2, iter.num_devs);
 	ut_asserteq_str("mmc2.bootdev", iter.dev_order[0]->name);
 	ut_asserteq_str("mmc1.bootdev", iter.dev_order[1]->name);
@@ -211,7 +211,7 @@ static int bootdev_test_order(struct unit_test_state *uts)
 
 	/* Use the environment variable to override it */
 	ut_assertok(env_set("boot_targets", "mmc1 mmc2"));
-	ut_assertok(bootflow_scan_first(&iter, 0, &bflow));
+	ut_assertok(bootflow_scan_first(NULL, NULL, &iter, 0, &bflow));
 	ut_asserteq(2, iter.num_devs);
 	ut_asserteq_str("mmc1.bootdev", iter.dev_order[0]->name);
 	ut_asserteq_str("mmc2.bootdev", iter.dev_order[1]->name);
@@ -224,7 +224,7 @@ static int bootdev_test_order(struct unit_test_state *uts)
 	ut_assertok(env_set("boot_targets", NULL));
 	ut_assertok(bootstd_test_drop_bootdev_order(uts));
 
-	ut_assertok(bootflow_scan_first(&iter, 0, &bflow));
+	ut_assertok(bootflow_scan_first(NULL, NULL, &iter, 0, &bflow));
 	ut_asserteq(3, iter.num_devs);
 	ut_asserteq_str("mmc2.bootdev", iter.dev_order[0]->name);
 	ut_asserteq_str("mmc1.bootdev", iter.dev_order[1]->name);
@@ -239,7 +239,7 @@ static int bootdev_test_order(struct unit_test_state *uts)
 	iter.dev_order[2]->seq_ = 2;
 	bootflow_iter_uninit(&iter);
 
-	ut_assertok(bootflow_scan_first(&iter, 0, &bflow));
+	ut_assertok(bootflow_scan_first(NULL, NULL, &iter, 0, &bflow));
 	ut_asserteq(3, iter.num_devs);
 	ut_asserteq_str("mmc2.bootdev", iter.dev_order[0]->name);
 	ut_asserteq_str("mmc0.bootdev", iter.dev_order[1]->name);
@@ -268,7 +268,7 @@ static int bootdev_test_prio(struct unit_test_state *uts)
 
 	/* 3 MMC and 3 USB bootdevs: MMC should come before USB */
 	console_record_reset_enable();
-	ut_assertok(bootflow_scan_first(&iter, 0, &bflow));
+	ut_assertok(bootflow_scan_first(NULL, NULL, &iter, 0, &bflow));
 	ut_asserteq(6, iter.num_devs);
 	ut_asserteq_str("mmc2.bootdev", iter.dev_order[0]->name);
 	ut_asserteq_str("usb_mass_storage.lun0.bootdev",
@@ -282,7 +282,8 @@ static int bootdev_test_prio(struct unit_test_state *uts)
 	ucp->prio = 1;
 
 	bootflow_iter_uninit(&iter);
-	ut_assertok(bootflow_scan_first(&iter, 0, &bflow));
+	ut_assertok(bootflow_scan_first(NULL, NULL, &iter, BOOTFLOWF_HUNT,
+					&bflow));
 	ut_asserteq(6, iter.num_devs);
 	ut_asserteq_str("usb_mass_storage.lun0.bootdev",
 			iter.dev_order[0]->name);
@@ -415,7 +416,8 @@ static int bootdev_test_hunt_scan(struct unit_test_state *uts)
 	ut_assertok(bootstd_get_priv(&std));
 
 	ut_assertok(bootstd_test_drop_bootdev_order(uts));
-	ut_assertok(bootflow_scan_first(&iter, BOOTFLOWF_SHOW | BOOTFLOWF_HUNT |
+	ut_assertok(bootflow_scan_first(NULL, NULL, &iter,
+					BOOTFLOWF_SHOW | BOOTFLOWF_HUNT |
 					BOOTFLOWF_SKIP_GLOBAL, &bflow));
 	ut_asserteq(BIT(MMC_HUNTER) | BIT(1), std->hunters_used);
 
diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c
index 0b3a2fa6acc..b9284fc464a 100644
--- a/test/boot/bootflow.c
+++ b/test/boot/bootflow.c
@@ -276,7 +276,8 @@ static int bootflow_iter(struct unit_test_state *uts)
 
 	/* The first device is mmc2.bootdev which has no media */
 	ut_asserteq(-EPROTONOSUPPORT,
-		    bootflow_scan_first(&iter, BOOTFLOWF_ALL | BOOTFLOWF_SKIP_GLOBAL, &bflow));
+		    bootflow_scan_first(NULL, NULL, &iter,
+					BOOTFLOWF_ALL | BOOTFLOWF_SKIP_GLOBAL, &bflow));
 	ut_asserteq(2, iter.num_methods);
 	ut_asserteq(0, iter.cur_method);
 	ut_asserteq(0, iter.part);
@@ -415,7 +416,7 @@ static int bootflow_iter_disable(struct unit_test_state *uts)
 
 	/* Try to boot the bootmgr flow, which will fail */
 	console_record_reset_enable();
-	ut_assertok(bootflow_scan_first(&iter, 0, &bflow));
+	ut_assertok(bootflow_scan_first(NULL, NULL, &iter, 0, &bflow));
 	ut_asserteq(3, iter.num_methods);
 	ut_asserteq_str("sandbox", iter.method->name);
 	ut_assertok(inject_response(uts));
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 68/71] bootstd: Record the bootdevs used during scanning
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (65 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 67/71] bootstd: Drop the old bootflow_scan_first() Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 69/71] bootstd: Add a little more logging of bootflows Simon Glass
                   ` (4 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

Add a way to record the bootdevs used when scanning for bootflows. This is
useful for testing.

Enable this only with BOOTSTD_FULL and do the same for the progress
reporting.

Re-enable and update the affected tests now that we have this feature.

For bootdev_test_order_default() there is no-longer any support for using
the bootdev aliases to specify an ordering, so drop that part of the test.

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

(no changes since v1)

 boot/bootflow.c     | 29 +++++++++++++-------
 include/bootflow.h  | 10 ++++++-
 test/boot/bootdev.c | 67 +++++++++++++++++++++++----------------------
 3 files changed, 63 insertions(+), 43 deletions(-)

diff --git a/boot/bootflow.c b/boot/bootflow.c
index 750732f7083..03a180bcddc 100644
--- a/boot/bootflow.c
+++ b/boot/bootflow.c
@@ -88,6 +88,9 @@ void bootflow_iter_init(struct bootflow_iter *iter, int flags)
 	memset(iter, '\0', sizeof(*iter));
 	iter->first_glob_method = -1;
 	iter->flags = flags;
+
+	/* remember the first bootdevs we see */
+	iter->max_devs = BOOTFLOW_MAX_USED_DEVS;
 }
 
 void bootflow_iter_uninit(struct bootflow_iter *iter)
@@ -131,16 +134,22 @@ static void bootflow_iter_set_dev(struct bootflow_iter *iter,
 	iter->dev = dev;
 	iter->method_flags = method_flags;
 
-	if ((iter->flags & (BOOTFLOWF_SHOW | BOOTFLOWF_SINGLE_DEV)) ==
-	    BOOTFLOWF_SHOW) {
-		if (dev)
-			printf("Scanning bootdev '%s':\n", dev->name);
-		else if (IS_ENABLED(CONFIG_BOOTMETH_GLOBAL) &&
-			 ucp->flags & BOOTMETHF_GLOBAL)
-			printf("Scanning global bootmeth '%s':\n",
-			       iter->method->name);
-		else
-			printf("No more bootdevs\n");
+	if (IS_ENABLED(CONFIG_BOOTSTD_FULL)) {
+		/* record the device for later */
+		if (dev && iter->num_devs < iter->max_devs)
+			iter->dev_used[iter->num_devs++] = dev;
+
+		if ((iter->flags & (BOOTFLOWF_SHOW | BOOTFLOWF_SINGLE_DEV)) ==
+		    BOOTFLOWF_SHOW) {
+			if (dev)
+				printf("Scanning bootdev '%s':\n", dev->name);
+			else if (IS_ENABLED(CONFIG_BOOTMETH_GLOBAL) &&
+				ucp->flags & BOOTMETHF_GLOBAL)
+				printf("Scanning global bootmeth '%s':\n",
+				iter->method->name);
+			else
+				printf("No more bootdevs\n");
+		}
 	}
 }
 
diff --git a/include/bootflow.h b/include/bootflow.h
index c2368912061..f516bf8dea4 100644
--- a/include/bootflow.h
+++ b/include/bootflow.h
@@ -14,6 +14,10 @@
 struct bootstd_priv;
 struct expo;
 
+enum {
+	BOOTFLOW_MAX_USED_DEVS	= 16,
+};
+
 /**
  * enum bootflow_state_t - states that a particular bootflow can be in
  *
@@ -173,7 +177,9 @@ enum bootflow_meth_flags_t {
  * @err: Error obtained from checking the last iteration. This is used to skip
  *	forward (e.g. to skip the current partition because it is not valid)
  *	-ESHUTDOWN: try next bootdev
- * @num_devs: Number of bootdevs in @dev_order
+ * @num_devs: Number of bootdevs in @dev_used
+ * @max_devs: Maximum number of entries in @dev_used
+ * @dev_used: List of bootdevs used during iteration
  * @labels: List of labels to scan for bootdevs
  * @cur_label: Current label being processed
  * @num_methods: Number of bootmeth devices in @method_order
@@ -196,6 +202,8 @@ struct bootflow_iter {
 	int first_bootable;
 	int err;
 	int num_devs;
+	int max_devs;
+	struct udevice *dev_used[BOOTFLOW_MAX_USED_DEVS];
 	const char *const *labels;
 	int cur_label;
 	int num_methods;
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c
index 5d5ce7f48cf..ef5215bbcec 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -186,7 +186,6 @@ static int bootdev_test_any(struct unit_test_state *uts)
 BOOTSTD_TEST(bootdev_test_any, UT_TESTF_DM | UT_TESTF_SCAN_FDT |
 	     UT_TESTF_ETH_BOOTDEV);
 
-#if 0 /* disable for now */
 /* Check bootdev ordering with the bootdev-order property */
 static int bootdev_test_order(struct unit_test_state *uts)
 {
@@ -205,18 +204,29 @@ static int bootdev_test_order(struct unit_test_state *uts)
 	ut_assertok(env_set("boot_targets", NULL));
 	ut_assertok(bootflow_scan_first(NULL, NULL, &iter, 0, &bflow));
 	ut_asserteq(2, iter.num_devs);
-	ut_asserteq_str("mmc2.bootdev", iter.dev_order[0]->name);
-	ut_asserteq_str("mmc1.bootdev", iter.dev_order[1]->name);
+	ut_asserteq_str("mmc2.bootdev", iter.dev_used[0]->name);
+	ut_asserteq_str("mmc1.bootdev", iter.dev_used[1]->name);
 	bootflow_iter_uninit(&iter);
 
 	/* Use the environment variable to override it */
 	ut_assertok(env_set("boot_targets", "mmc1 mmc2"));
 	ut_assertok(bootflow_scan_first(NULL, NULL, &iter, 0, &bflow));
+	ut_asserteq(-ENODEV, bootflow_scan_next(&iter, &bflow));
 	ut_asserteq(2, iter.num_devs);
-	ut_asserteq_str("mmc1.bootdev", iter.dev_order[0]->name);
-	ut_asserteq_str("mmc2.bootdev", iter.dev_order[1]->name);
+	ut_asserteq_str("mmc1.bootdev", iter.dev_used[0]->name);
+	ut_asserteq_str("mmc2.bootdev", iter.dev_used[1]->name);
 	bootflow_iter_uninit(&iter);
 
+	return 0;
+}
+BOOTSTD_TEST(bootdev_test_order, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
+
+/* Check default bootdev ordering  */
+static int bootdev_test_order_default(struct unit_test_state *uts)
+{
+	struct bootflow_iter iter;
+	struct bootflow bflow;
+
 	/*
 	 * Now drop both orderings, to check the default (prioriy/sequence)
 	 * ordering
@@ -225,30 +235,18 @@ static int bootdev_test_order(struct unit_test_state *uts)
 	ut_assertok(bootstd_test_drop_bootdev_order(uts));
 
 	ut_assertok(bootflow_scan_first(NULL, NULL, &iter, 0, &bflow));
-	ut_asserteq(3, iter.num_devs);
-	ut_asserteq_str("mmc2.bootdev", iter.dev_order[0]->name);
-	ut_asserteq_str("mmc1.bootdev", iter.dev_order[1]->name);
-	ut_asserteq_str("mmc0.bootdev", iter.dev_order[2]->name);
-
-	/*
-	 * Check that adding aliases for the bootdevs works. We just fake it by
-	 * setting the sequence numbers directly.
-	 */
-	iter.dev_order[0]->seq_ = 0;
-	iter.dev_order[1]->seq_ = 3;
-	iter.dev_order[2]->seq_ = 2;
-	bootflow_iter_uninit(&iter);
+	ut_asserteq(2, iter.num_devs);
+	ut_asserteq_str("mmc2.bootdev", iter.dev_used[0]->name);
+	ut_asserteq_str("mmc1.bootdev", iter.dev_used[1]->name);
 
-	ut_assertok(bootflow_scan_first(NULL, NULL, &iter, 0, &bflow));
+	ut_asserteq(-ENODEV, bootflow_scan_next(&iter, &bflow));
 	ut_asserteq(3, iter.num_devs);
-	ut_asserteq_str("mmc2.bootdev", iter.dev_order[0]->name);
-	ut_asserteq_str("mmc0.bootdev", iter.dev_order[1]->name);
-	ut_asserteq_str("mmc1.bootdev", iter.dev_order[2]->name);
+	ut_asserteq_str("mmc0.bootdev", iter.dev_used[2]->name);
 	bootflow_iter_uninit(&iter);
 
 	return 0;
 }
-BOOTSTD_TEST(bootdev_test_order, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
+BOOTSTD_TEST(bootdev_test_order_default, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
 
 /* Check bootdev ordering with the uclass priority */
 static int bootdev_test_prio(struct unit_test_state *uts)
@@ -260,6 +258,9 @@ static int bootdev_test_prio(struct unit_test_state *uts)
 
 	test_set_skip_delays(true);
 
+	/* disable ethernet since the hunter will run dhcp */
+	test_set_eth_enable(false);
+
 	/* Start up USB which gives us three additional bootdevs */
 	usb_started = false;
 	ut_assertok(run_command("usb start", 0));
@@ -269,30 +270,32 @@ static int bootdev_test_prio(struct unit_test_state *uts)
 	/* 3 MMC and 3 USB bootdevs: MMC should come before USB */
 	console_record_reset_enable();
 	ut_assertok(bootflow_scan_first(NULL, NULL, &iter, 0, &bflow));
+	ut_asserteq(-ENODEV, bootflow_scan_next(&iter, &bflow));
 	ut_asserteq(6, iter.num_devs);
-	ut_asserteq_str("mmc2.bootdev", iter.dev_order[0]->name);
+	ut_asserteq_str("mmc2.bootdev", iter.dev_used[0]->name);
 	ut_asserteq_str("usb_mass_storage.lun0.bootdev",
-			iter.dev_order[3]->name);
+			iter.dev_used[3]->name);
 
-	ut_assertok(bootdev_get_sibling_blk(iter.dev_order[3], &blk));
+	ut_assertok(bootdev_get_sibling_blk(iter.dev_used[3], &blk));
 	ut_asserteq_str("usb_mass_storage.lun0", blk->name);
 
 	/* adjust the priority of the first USB bootdev to the highest */
-	ucp = dev_get_uclass_plat(iter.dev_order[3]);
-	ucp->prio = 1;
+	ucp = dev_get_uclass_plat(iter.dev_used[3]);
+	ucp->prio = BOOTDEVP_1_PRE_SCAN;
 
+	/* try again but enable hunting, which brings in SCSI */
 	bootflow_iter_uninit(&iter);
 	ut_assertok(bootflow_scan_first(NULL, NULL, &iter, BOOTFLOWF_HUNT,
 					&bflow));
-	ut_asserteq(6, iter.num_devs);
+	ut_asserteq(-ENODEV, bootflow_scan_next(&iter, &bflow));
+	ut_asserteq(7, iter.num_devs);
 	ut_asserteq_str("usb_mass_storage.lun0.bootdev",
-			iter.dev_order[0]->name);
-	ut_asserteq_str("mmc2.bootdev", iter.dev_order[1]->name);
+			iter.dev_used[0]->name);
+	ut_asserteq_str("mmc2.bootdev", iter.dev_used[1]->name);
 
 	return 0;
 }
 BOOTSTD_TEST(bootdev_test_prio, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
-#endif
 
 /* Check listing hunters */
 static int bootdev_test_hunter(struct unit_test_state *uts)
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 69/71] bootstd: Add a little more logging of bootflows
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (66 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 68/71] bootstd: Record the bootdevs used during scanning Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 70/71] bootstd: Update documentation for new features Simon Glass
                   ` (3 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

Add some logging to aid debugging of problems with bootflows.

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

(no changes since v1)

 boot/bootdev-uclass.c | 1 +
 boot/bootflow.c       | 4 ++++
 2 files changed, 5 insertions(+)

diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c
index 522ecf38eb3..99ee08e3353 100644
--- a/boot/bootdev-uclass.c
+++ b/boot/bootdev-uclass.c
@@ -546,6 +546,7 @@ int bootdev_get_bootflow(struct udevice *dev, struct bootflow_iter *iter,
 {
 	const struct bootdev_ops *ops = bootdev_get_ops(dev);
 
+	log_debug("->get_bootflow %s=%p\n", dev->name, ops->get_bootflow);
 	bootflow_init(bflow, dev, iter->method);
 	if (!ops->get_bootflow)
 		return default_get_bootflow(dev, iter, bflow);
diff --git a/boot/bootflow.c b/boot/bootflow.c
index 03a180bcddc..dc3f1f0c731 100644
--- a/boot/bootflow.c
+++ b/boot/bootflow.c
@@ -367,6 +367,7 @@ int bootflow_scan_first(struct udevice *dev, const char *label,
 
 	ret = bootflow_check(iter, bflow);
 	if (ret) {
+		log_debug("check - ret=%d\n", ret);
 		if (ret != BF_NO_MORE_PARTS && ret != -ENOSYS) {
 			if (iter->flags & BOOTFLOWF_ALL)
 				return log_msg_ret("all", ret);
@@ -386,11 +387,13 @@ int bootflow_scan_next(struct bootflow_iter *iter, struct bootflow *bflow)
 
 	do {
 		ret = iter_incr(iter);
+		log_debug("iter_incr: ret=%d\n", ret);
 		if (ret == BF_NO_MORE_DEVICES)
 			return log_msg_ret("done", ret);
 
 		if (!ret) {
 			ret = bootflow_check(iter, bflow);
+			log_debug("check - ret=%d\n", ret);
 			if (!ret)
 				return 0;
 			iter->err = ret;
@@ -399,6 +402,7 @@ int bootflow_scan_next(struct bootflow_iter *iter, struct bootflow *bflow)
 					return log_msg_ret("all", ret);
 			}
 		} else {
+			log_debug("incr failed, err=%d\n", ret);
 			iter->err = ret;
 		}
 
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 70/71] bootstd: Update documentation for new features
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (67 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 69/71] bootstd: Add a little more logging of bootflows Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-08  2:50 ` [PATCH v2 71/71] rockchip: Convert rockpro64-rk3399 to use standard boot Simon Glass
                   ` (2 subsequent siblings)
  71 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: U-Boot Custodians, Simon Glass

Document the hunters and the new way that iteration works.

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

(no changes since v1)

 doc/develop/bootstd.rst           | 219 +++++++++++++++++++++---------
 doc/develop/driver-model/nvme.rst |   2 +-
 doc/usage/cmd/bootdev.rst         |  48 ++++++-
 doc/usage/cmd/bootflow.rst        |  17 ++-
 4 files changed, 216 insertions(+), 70 deletions(-)

diff --git a/doc/develop/bootstd.rst b/doc/develop/bootstd.rst
index bfa8cbd7561..281aabf74b2 100644
--- a/doc/develop/bootstd.rst
+++ b/doc/develop/bootstd.rst
@@ -71,8 +71,14 @@ MMC, NVMe). The bootdev accesses the device, including partitions and
 filesystems that might contain things related to an operating system.
 
 For example, an MMC bootdev provides access to the individual partitions on the
-MMC device. It scans through these to find filesystems, then provides a list of
-these for consideration.
+MMC device. It scans through these to find filesystems with the boot flag set,
+then provides a list of these for consideration.
+
+Some bootdevs are not visible until a bus is enumerated, e.g. flash sticks
+attached via USB. To deal with this, each bootdev has an associated 'hunter'
+which can hunt for bootdevs of a particular uclass type. For example, the SCSI
+bootdev scans the SCSI bus looking for devices, creating a bootdev for each
+Logical Unit Number (LUN) that it finds.
 
 
 Bootmeth
@@ -175,7 +181,10 @@ reading from, but each is responsible for returning a valid bootflow if
 available.
 
 A helper called `bootdev_find_in_blk()` makes it fairly easy to implement this
-function for each media device uclass, in a few lines of code.
+function for each media device uclass, in a few lines of code. For many types
+ot bootdevs, the `get_bootflow` member can be NULL, indicating that the default
+handler is used. This is called `default_get_bootflow()` and it only works with
+block devices.
 
 
 Bootdev drivers
@@ -183,30 +192,6 @@ Bootdev drivers
 
 A bootdev driver is typically fairly simple. Here is one for mmc::
 
-    static int mmc_get_bootflow(struct udevice *dev, struct bootflow_iter *iter,
-                    struct bootflow *bflow)
-    {
-        struct udevice *mmc_dev = dev_get_parent(dev);
-        struct udevice *blk;
-        int ret;
-
-        ret = mmc_get_blk(mmc_dev, &blk);
-        /*
-         * If there is no media, indicate that no more partitions should be
-         * checked
-         */
-        if (ret == -EOPNOTSUPP)
-            ret = -ESHUTDOWN;
-        if (ret)
-            return log_msg_ret("blk", ret);
-        assert(blk);
-        ret = bootdev_find_in_blk(dev, blk, iter, bflow);
-        if (ret)
-            return log_msg_ret("find", ret);
-
-        return 0;
-    }
-
     static int mmc_bootdev_bind(struct udevice *dev)
     {
         struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
@@ -217,7 +202,6 @@ A bootdev driver is typically fairly simple. Here is one for mmc::
     }
 
     struct bootdev_ops mmc_bootdev_ops = {
-        .get_bootflow    = mmc_get_bootflow,
     };
 
     static const struct udevice_id mmc_bootdev_ids[] = {
@@ -233,15 +217,77 @@ A bootdev driver is typically fairly simple. Here is one for mmc::
         .of_match    = mmc_bootdev_ids,
     };
 
-The implementation of the `get_bootflow()` method is simply to obtain the
-block device and call a bootdev helper function to do the rest. The
+You may notice that the `get_bootflow` memory is not provided, so is NULL. This
+means that `default_get_bootflow()` is used. This simply obtains the
+block device and calls a bootdev helper function to do the rest. The
 implementation of `bootdev_find_in_blk()` checks the partition table, and
 attempts to read a file from a filesystem on the partition number given by the
-`@iter->part` parameter.
+`@iter->part` parameter. If there are any bootable partitions in the table,
+then only bootable partitions are considered.
+
+Each bootdev has a priority, which indicates the order in which it is used,
+if `boot_targets` is not used. Faster bootdevs are used first, since they are
+more likely to be able to boot the device quickly.
+
+
+Environment Variables
+---------------------
+
+Various environment variables are used by standard boot. These allow the board
+to control where things are placed when booting the OS. You should ensure that
+your boards sets values for these.
+
+fdtfile
+    Name of the flattened device tree (FDT) file to load, e.g.
+    "rockchip/rk3399-rockpro64.dtb"
+
+fdtaddr_addr_r
+    Address at which to load the FDT, e.g. 0x01f00000
+
+fdtoverlay_addr_r (needed if overlays are used)
+    Address at which to load the overlay for the FDT, e.g. 0x02000000
+
+kernel_addr_r
+    Address at which to load the kernel, e.g. 0x02080000
+
+kernel_comp_addr_r
+    Address to which to decompress the kernel, e.g. 0x08000000
+
+kernel_comp_size
+    Size of available space for decompressed kernel, e.g. 0x2000000
+
+pxefile_addr_r
+    Address at which to load the PXE file, e.g. 0x00600000
+
+ramdisk_addr_r
+    Address at which to load the ramdisk, e.g. 0x06000000
+
+scriptaddr
+    Address at which to load the U-Boot script, e.g. 0x00500000
+
+script_offset_f
+    SPI flash offset from which to load the U-Boot script, e.g. 0xffe000
 
-Each bootdev has a priority, which indicates the order in which it is used.
-Faster bootdevs are used first, since they are more likely to be able to boot
-the device quickly.
+script_size_f
+    Size of the script to load, e.g. 0x2000
+
+Some variables are set by script bootmeth:
+
+devtype
+    Device type being used for boot, e.g. mmc
+
+devnum
+    Device number being used for boot, e.g. 1
+
+distro_bootpart
+    Partition being used for boot, e.g. 2
+
+prefix
+    Directory containing the script
+
+mmc_bootdev
+    Device number being used for boot (e.g. 1). This is only used by MMC on
+    sunxi boards.
 
 
 Device hierarchy
@@ -259,13 +305,22 @@ media device::
     bootdev       1  [   ]   mmc_bootdev           |   |   `-- sdhci@7e300000.bootdev
 
 The bootdev device is typically created automatically in the media uclass'
-`post_bind()` method by calling `bootdev_setup_for_dev()`. The code typically
-something like this::
+`post_bind()` method by calling `bootdev_setup_for_dev()` or
+`bootdev_setup_sibling_blk()`. The code typically something like this::
 
+    /* dev is the Ethernet device */
     ret = bootdev_setup_for_dev(dev, "eth_bootdev");
     if (ret)
         return log_msg_ret("bootdev", ret);
 
+or::
+
+    /* blk is the block device (child of MMC device)
+    ret = bootdev_setup_sibling_blk(blk, "mmc_bootdev");
+    if (ret)
+        return log_msg_ret("bootdev", ret);
+
+
 Here, `eth_bootdev` is the name of the Ethernet bootdev driver and `dev`
 is the ethernet device. This function is safe to call even if standard boot is
 not enabled, since it does nothing in that case. It can be added to all uclasses
@@ -337,6 +392,10 @@ Standard boot is enabled with `CONFIG_BOOTSTD`. Each bootmeth has its own CONFIG
 option also. For example, `CONFIG_BOOTMETH_DISTRO` enables support for distro
 boot from a disk.
 
+To enable all feature sof standard boot, use `CONFIG_BOOTSTD_FULL`. This
+includes the full set of commands, more error messages when things go wrong and
+bootmeth ordering with the bootmeths environment variable.
+
 
 Available bootmeth drivers
 --------------------------
@@ -345,7 +404,8 @@ Bootmeth drivers are provided for:
 
    - distro boot from a disk (syslinux)
    - distro boot from a network (PXE)
-   - EFI boot using bootefi
+   - U-Boot scripts from disk, network or SPI flash
+   - EFI boot using bootefi from disk
    - VBE
    - EFI boot using boot manager
 
@@ -412,26 +472,49 @@ those bootdevs. So, all up, we need a single bootstd device, one or more bootdev
 devices and one or more bootmeth devices.
 
 Once these are ready, typically a `bootflow scan` command is issued. This kicks
-of the iteration process, which involves looking through the bootdevs and their
-partitions one by one to find bootflows.
+of the iteration process, which involves hunting for bootdevs and looking
+through the bootdevs and their partitions one by one to find bootflows.
 
-Iteration is kicked off using `bootflow_scan_first()`, which calls
-`bootflow_scan_bootdev()`.
+Iteration is kicked off using `bootflow_scan_first()`.
 
 The iterator is set up with `bootflow_iter_init()`. This simply creates an
 empty one with the given flags. Flags are used to control whether each
 iteration is displayed, whether to return iterations even if they did not result
 in a valid bootflow, whether to iterate through just a single bootdev, etc.
 
-Then the ordering of bootdevs is determined, by `bootdev_setup_iter_order()`. By
-default, the bootdevs are used in the order specified by the `boot_targets`
-environment variable (e.g. "mmc2 mmc0 usb"). If that is missing then their
-sequence order is used, as determined by the `/aliases` node, or failing that
-their order in the devicetree. For BOOTSTD_FULL, if there is a `bootdev-order`
-property in the bootstd node, then this is used as a final fallback. In any
-case, the iterator ends up with a `dev_order` array containing the bootdevs that
-are going to be used, with `num_devs` set to the number of bootdevs and
-`cur_dev` starting at 0.
+Then the iterator is set up to according to the parameters given:
+
+- When `dev` is provided, then a single bootdev is scanned. In this case,
+  `BOOTFLOWF_SKIP_GLOBAL` and `BOOTFLOWF_SINGLE_DEV` are set. No hunters are
+  used in this case
+
+- Otherwise, when `label` is provided, then a single label or named bootdev is
+  scanned. In this case `BOOTFLOWF_SKIP_GLOBAL` is set and there are three
+  options (with an effect on the `iter_incr()` function described later):
+
+  - If `label` indicates a numeric bootdev number (e.g. "2") then
+    `BOOTFLOW_METHF_SINGLE_DEV` is set. In this case, moving to the next bootdev
+    simple stops, since there is only one. No hunters are used.
+  - If `label` indicates a particular media device (e.g. "mmc1") then
+    `BOOTFLOWF_SINGLE_MEDIA` is set. In this case, moving to the next bootdev
+    processes just the children of the media device. Hunters are used, in this
+    example just the "mmc" hunter.
+  - If `label` indicates a media uclass (e.g. "mmc") then
+    `BOOTFLOWF_SINGLE_UCLASS` is set. In this case, all bootdevs in that uclass
+    are used. Hunters are used, in this example just the "mmc" hunter
+
+- Otherwise, none of the above flags is set and iteration is set up to work
+  through `boot_targets` environment variable (or `bootdev-order` device tree
+  property) in order, running the relevant hunter first. In this case
+  `cur_label` is used to indicate the label being processed. If there is no list
+  of labels, then all bootdevs are processed in order of priority, running the
+  hunters as it goes.
+
+With the above it is therefore possible to iterate in a variety of ways.
+
+No attempt is made to determine the ordering of bootdevs, since this cannot be
+known in advance if we are using the hunters. Any hunter might discover a new
+bootdev and disturb the original ordering.
 
 Next, the ordering of bootmeths is determined, by `bootmeth_setup_iter_order()`.
 By default the ordering is again by sequence number, i.e. the `/aliases` node,
@@ -446,21 +529,21 @@ present, `cur_method` is set to the first one, so that global bootmeths are done
 first. Once all have been used, these bootmeths are dropped from the iteration.
 When there are no global bootmeths, `cur_method` is set to 0.
 
-At this point the iterator is ready to use, with the first bootdev and bootmeth
-selected. Most of the other fields are 0. This means that the current partition
+At this point the iterator is ready to use, with the first bootmeth selected.
+Most of the other fields are 0. This means that the current partition
 is 0, which is taken to mean the whole device, since partition numbers start at
 1. It also means that `max_part` is 0, i.e. the maximum partition number we know
 about is 0, meaning that, as far as we know, there is no partition table on this
 bootdev.
 
-With the iterator ready, `bootflow_scan_bootdev()` checks whether the current
+With the iterator ready, `bootflow_scan_first()` checks whether the current
 settings produce a valid bootflow. This is handled by `bootflow_check()`, which
 either returns 0 (if it got something) or an error if not (more on that later).
 If the `BOOTFLOWF_ALL` iterator flag is set, even errors are returned as
 incomplete bootflows, but normally an error results in moving onto the next
 iteration.
 
-Note that `bootflow_check()` handles global bootmeths explicitly, but calling
+Note that `bootflow_check()` handles global bootmeths explicitly, by calling
 `bootmeth_get_bootflow()` on each one. The `doing_global` flag indicates when
 the iterator is in that state.
 
@@ -468,7 +551,7 @@ The `bootflow_scan_next()` function handles moving onto the next iteration and
 checking it. In fact it sits in a loop doing that repeatedly until it finds
 something it wants to return.
 
-The actual 'moving on' part is implemented in `iter_incr()`. This is a very
+The actual 'moving on' part is implemented in `iter_incr()`. This is a fairly
 simple function. It increments the first counter. If that hits its maximum, it
 sets it to zero and increments the second counter. You can think of all the
 counters together as a number with three digits which increment in order, with
@@ -522,6 +605,12 @@ like this:
 The changeover of the value of `doing_global` from true to false is handled in
 `iter_incr()` as well.
 
+Note that the value in the `bootdev` column above is not actually stored - it is
+just for illustration. In practice, `iter_incr()` uses the flags to determine
+whether to move to the next bootdev in the uclass, the next child of the media
+device, the next label, or the next priority level, depending on the flag
+settings (see `BOOTFLOW_METHF_SINGLE_DEV`, etc. above).
+
 There is no expectation that iteration will actually finish. Quite often a
 valid bootflow is found early on. With `bootflow scan -b`, that causes the
 bootflow to be immediately booted. Assuming it is successful, the iteration never
@@ -567,9 +656,9 @@ global bootmeth). Each one can adopt its own approach.
 
 Going down a level, what does the bootdev do in its `get_bootflow()` method?
 Let us consider the MMC bootdev. In that case the call to
-`bootdev_get_bootflow()` ends up in `mmc_get_bootflow()`. It locates the parent
-device of the bootdev, i.e. the `UCLASS_MMC` device itself, then finds the block
-device associated with it. It then calls the helper function
+`bootdev_get_bootflow()` ends up in `default_get_bootflow()`. It locates the
+parent device of the bootdev, i.e. the `UCLASS_MMC` device itself, then finds
+the block device associated with it. It then calls the helper function
 `bootdev_find_in_blk()` to do all the work. This is common with just about any
 bootdev that is based on a media device.
 
@@ -586,7 +675,9 @@ calls the bootmeth device once more, this time to read the bootflow.
 
 Note: At present a filesystem is needed for the bootmeth to be called on block
 devices, simply because we don't have any examples where this is not the case.
-This feature can be added as needed.
+This feature can be added as needed. Note that sandbox is a special case, since
+in that case the host filesystem can be accessed even though the block device
+is NULL.
 
 If we take the example of the `bootmeth_distro` driver, this call ends up at
 `distro_read_bootflow()`. It has the filesystem ready, so tries various
@@ -594,9 +685,9 @@ filenames to try to find the `extlinux.conf` file, reading it if possible. If
 all goes well the bootflow ends up in the `BOOTFLOWST_READY` state.
 
 At this point, we fall back from the bootmeth driver, to
-`bootdev_find_in_blk()`, then back to `mmc_get_bootflow()`, then to
+`bootdev_find_in_blk()`, then back to `default_get_bootflow()`, then to
 `bootdev_get_bootflow()`, then to `bootflow_check()` and finally to its caller,
-either `bootflow_scan_bootdev()` or `bootflow_scan_next()`. In either case,
+either `bootflow_scan_first()` or `bootflow_scan_next()`. In either case,
 the bootflow is returned as the result of this iteration, assuming it made it to
 the  `BOOTFLOWST_READY` state.
 
@@ -625,9 +716,9 @@ Tests are located in `test/boot` and cover the core functionality as well as
 the commands. All tests use sandbox so can be run on a standard Linux computer
 and in U-Boot's CI.
 
-For testing, a DOS-formatted disk image is used with a single FAT partition on
-it. This is created in `setup_bootflow_image()`, with a canned one from the
-source tree used if it cannot be created (e.g. in CI).
+For testing, a DOS-formatted disk image is used with a FAT partition on it and
+a second unused partition. This is created in `setup_bootflow_image()`, with a
+canned one from the source tree used if it cannot be created (e.g. in CI).
 
 
 Bootflow internals
diff --git a/doc/develop/driver-model/nvme.rst b/doc/develop/driver-model/nvme.rst
index fd0c0f00d2d..75518133121 100644
--- a/doc/develop/driver-model/nvme.rst
+++ b/doc/develop/driver-model/nvme.rst
@@ -27,7 +27,7 @@ How it works
 ------------
 There is an NVMe uclass driver (driver name "nvme"), an NVMe host controller
 driver (driver name "nvme") and an NVMe namespace block driver (driver name
-"nvme-blk"). The host controller driver is supposed to probe the hardware and
+"nvme_blk"). The host controller driver is supposed to probe the hardware and
 do necessary initialization to put the controller into a ready state at which
 it is able to scan all available namespaces attached to it. Scanning namespace
 is triggered by the NVMe uclass driver and the actual work is done in the NVMe
diff --git a/doc/usage/cmd/bootdev.rst b/doc/usage/cmd/bootdev.rst
index 5e02e32c514..6c68d0bf840 100644
--- a/doc/usage/cmd/bootdev.rst
+++ b/doc/usage/cmd/bootdev.rst
@@ -8,9 +8,10 @@ Synopis
 
 ::
 
-    bootdev list [-p]      - list all available bootdevs (-p to probe)\n"
-    bootdev select <bm>    - select a bootdev by name\n"
-    bootdev info [-p]      - show information about a bootdev";
+    bootdev list [-p]        - list all available bootdevs (-p to probe)
+    bootdev hunt [-l|<spec>] - use hunt drivers to find bootdevs
+    bootdev select <bm>      - select a bootdev by name
+    bootdev info [-p]        - show information about a bootdev
 
 Description
 -----------
@@ -63,6 +64,17 @@ Name:
     with `.bootdev`
 
 
+bootdev hunt
+~~~~~~~~~~~~
+
+This hunts for new bootdevs, or shows a list of hunters.
+
+Use `-l` to list the available bootdev hunters.
+
+To run hunters, specify the name of the hunter to run, e.g. "mmc". If no
+name is provided, all hunters are run.
+
+
 bootdev select
 ~~~~~~~~~~~~~~~~~
 
@@ -83,7 +95,7 @@ This shows information on the current bootdev, with the format looking like
 this:
 
 =========  =======================
-Name       mmc@7e202000.bootdev
+Name       `mmc@7e202000.bootdev`
 Sequence   0
 Status     Probed
 Uclass     mmc
@@ -128,6 +140,34 @@ one of them::
    Uclass:    mmc
    Bootflows: 1 (1 valid)
 
+This shows using one of the available hunters, then listing them::
+
+    => bootdev hunt usb
+    Hunting with: usb
+    Bus usb@1: scanning bus usb@1 for devices...
+    3 USB Device(s) found
+    => bootdev hunt -l
+    Prio  Used  Uclass           Hunter
+    ----  ----  ---------------  ---------------
+    6        ethernet         eth_bootdev
+    1        simple_bus       (none)
+    5        ide              ide_bootdev
+    2        mmc              mmc_bootdev
+    4        nvme             nvme_bootdev
+    4        scsi             scsi_bootdev
+    4        spi_flash        sf_bootdev
+    5     *  usb              usb_bootdev
+    4        virtio           virtio_bootdev
+    (total hunters: 9)
+    => usb stor
+    Device 0: Vendor: sandbox Rev: 1.0 Prod: flash
+                Type: Hard Disk
+                Capacity: 4.0 MB = 0.0 GB (8192 x 512)
+    Device 1: Vendor: sandbox Rev: 1.0 Prod: flash
+                Type: Hard Disk
+                Capacity: 0.0 MB = 0.0 GB (1 x 512)
+    =>
+
 
 Return value
 ------------
diff --git a/doc/usage/cmd/bootflow.rst b/doc/usage/cmd/bootflow.rst
index aa12dc2e3ab..cad09bbec9a 100644
--- a/doc/usage/cmd/bootflow.rst
+++ b/doc/usage/cmd/bootflow.rst
@@ -8,7 +8,7 @@ Synopis
 
 ::
 
-    bootflow scan [-abel] [bootdev]
+    bootflow scan [-abelGH] [bootdev]
     bootflow list [-e]
     bootflow select [<num|name>]
     bootflow info [-d]
@@ -57,6 +57,16 @@ Flags are:
     is happening during scanning. Use it with the `-b` flag to see which
     bootdev and bootflows are being tried.
 
+-G
+    Skip global bootmeths when scanning. By default these are tried first, but
+    this flag disables them.
+
+-H
+    Don't use bootdev hunters. By default these are used before each boot
+    priority or label is tried, to see if more bootdevs can be discovered, but
+    this flag disables that process.
+
+
 The optional argument specifies a particular bootdev to scan. This can either be
 the name of a bootdev or its sequence number (both shown with `bootdev list`).
 Alternatively a convenience label can be used, like `mmc0`, which is the type of
@@ -145,6 +155,7 @@ Subdir     (none)
 Filename   /extlinux/extlinux.conf
 Buffer     3db7ad48
 Size       232 (562 bytes)
+FDT:       <NULL>
 Error      0
 =========  ===============================
 
@@ -169,6 +180,10 @@ Buffer
 Size
     Size of the bootflow file
 
+FDT:
+    Filename of the device tree, if supported. The EFI bootmeth uses this to
+    remember the filename to load. If `<NULL>` then there is none.
+
 Error
     Error number returned from scanning for the bootflow. This is 0 if the
     bootflow is in the 'loaded' state, or a negative error value on error. You
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* [PATCH v2 71/71] rockchip: Convert rockpro64-rk3399 to use standard boot
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (68 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 70/71] bootstd: Update documentation for new features Simon Glass
@ 2023-01-08  2:50 ` Simon Glass
  2023-01-16  9:54   ` Kever Yang
  2023-01-13 19:54 ` [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Heinrich Schuchardt
  2023-01-17 13:57 ` Tom Rini
  71 siblings, 1 reply; 87+ messages in thread
From: Simon Glass @ 2023-01-08  2:50 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: U-Boot Custodians, Simon Glass, Jeffy Chen, Kever Yang,
	Philipp Tomsich, huang lin

Drop the use of scripts and rely on standard boot for all operation.

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

Changes in v2:
- Rebase to -next

 include/configs/rk3399_common.h   | 5 +----
 include/configs/rockchip-common.h | 2 ++
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/include/configs/rk3399_common.h b/include/configs/rk3399_common.h
index f0a9ab8f83c..daa8803bbf4 100644
--- a/include/configs/rk3399_common.h
+++ b/include/configs/rk3399_common.h
@@ -58,15 +58,12 @@
 #define ROCKCHIP_DEVICE_SETTINGS
 #endif
 
-#include <config_distro_bootcmd.h>
-#include <environment/distro/sf.h>
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	ENV_MEM_LAYOUT_SETTINGS \
 	"fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" \
 	"partitions=" PARTS_DEFAULT \
 	ROCKCHIP_DEVICE_SETTINGS \
-	BOOTENV \
-	BOOTENV_SF \
+	"boot_targets=" BOOT_TARGETS "\0" \
 	"altbootcmd=" \
 		"setenv boot_syslinux_conf extlinux/extlinux-rollback.conf;" \
 		"run distro_bootcmd\0"
diff --git a/include/configs/rockchip-common.h b/include/configs/rockchip-common.h
index 4c964cc3770..5a06365c760 100644
--- a/include/configs/rockchip-common.h
+++ b/include/configs/rockchip-common.h
@@ -67,12 +67,14 @@
 	BOOT_TARGET_PXE(func) \
 	BOOT_TARGET_DHCP(func) \
 	BOOT_TARGET_SF(func)
+#define BOOT_TARGETS	"mmc1 mmc0 nvme scsi usb pxe dhcp spi"
 #else
 #define BOOT_TARGET_DEVICES(func) \
 	BOOT_TARGET_MMC(func) \
 	BOOT_TARGET_USB(func) \
 	BOOT_TARGET_PXE(func) \
 	BOOT_TARGET_DHCP(func)
+#define BOOT_TARGETS	"mmc1 mmc0 usb pxe dhcp"
 #endif
 
 #ifdef CONFIG_ARM64
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[flat|nested] 87+ messages in thread

* Re: [PATCH v2 48/71] bootstd: Support reading the device tree with EFI
  2023-01-08  2:50 ` [PATCH v2 48/71] bootstd: Support reading the device tree with EFI Simon Glass
@ 2023-01-08 10:25   ` Mark Kettenis
  2023-01-13 18:00     ` Simon Glass
  0 siblings, 1 reply; 87+ messages in thread
From: Mark Kettenis @ 2023-01-08 10:25 UTC (permalink / raw)
  To: Simon Glass; +Cc: u-boot, u-boot-custodians, sjg

> From: Simon Glass <sjg@chromium.org>
> Date: Sat,  7 Jan 2023 19:50:24 -0700
> 
> With EFI booting the device tree is required but is not actually specified
> in any way. The normal method is to use a fdtfile environment variable to
> get the filename, then look for that file on the media.
> 
> Implement this in the bootmeth.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---

Hi Simon,

The distroboot scripts also reads dtb files from the root directory of
the ESP (so without the "dtb/" prefix).  This code needs to do that as
well otherwise some folks will run with a different device tree after
switching to bootstd.

The construction of a fallback dtb filename based on soc, board and
boardver is only done for (32-bit) arm and not for arm64.  It isn't
done for riscv either.  That feels to me like someone recognized that
was a bit of a mistake and shouldn't be done for modern targets.  So I
think that code should be under the same

   #if defined(CONFIG_ARM) && !defined(CONFIG_ARM64)

as it is now in config_distro_bootcmd.h.

Cheers,

Mark

> (no changes since v1)
> 
>  boot/bootmeth_efi.c | 105 +++++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 99 insertions(+), 6 deletions(-)
> 
> diff --git a/boot/bootmeth_efi.c b/boot/bootmeth_efi.c
> index 77b4ba22470..53a0489b93c 100644
> --- a/boot/bootmeth_efi.c
> +++ b/boot/bootmeth_efi.c
> @@ -143,10 +143,32 @@ static int distro_efi_check(struct udevice *dev, struct bootflow_iter *iter)
>  	return 0;
>  }
>  
> +static void distro_efi_get_fdt_name(char *fname, int size)
> +{
> +	const char *fdt_fname;
> +
> +	fdt_fname = env_get("fdtfile");
> +	if (fdt_fname) {
> +		snprintf(fname, size, "dtb/%s", fdt_fname);
> +		log_debug("Using device tree: %s\n", fname);
> +	} else {
> +		const char *soc = env_get("soc");
> +		const char *board = env_get("board");
> +		const char *boardver = env_get("boardver");
> +
> +		/* cf the code in label_boot() which seems very complex */
> +		snprintf(fname, size, "dtb/%s%s%s%s.dtb",
> +			 soc ? soc : "", soc ? "-" : "", board ? board : "",
> +			 boardver ? boardver : "");
> +		log_debug("Using default device tree: %s\n", fname);
> +	}
> +}
> +
>  static int distro_efi_read_bootflow_file(struct udevice *dev,
>  					 struct bootflow *bflow)
>  {
>  	struct blk_desc *desc = NULL;
> +	ulong fdt_addr, size;
>  	char fname[256];
>  	int ret;
>  
> @@ -170,15 +192,43 @@ static int distro_efi_read_bootflow_file(struct udevice *dev,
>  	if (ret)
>  		return log_msg_ret("read", -EINVAL);
>  
> +	distro_efi_get_fdt_name(fname, sizeof(fname));
> +	bflow->fdt_fname = strdup(fname);
> +	if (!bflow->fdt_fname)
> +		return log_msg_ret("fil", -ENOMEM);
> +
> +	fdt_addr = env_get_hex("fdt_addr_r", 0);
> +	ret = bootmeth_common_read_file(dev, bflow, fname, fdt_addr, &size);
> +	if (!ret) {
> +		bflow->fdt_size = size;
> +		bflow->fdt_addr = fdt_addr;
> +
> +		/*
> +		 * TODO: Apply extension overlay
> +		 *
> +		 * Here we need to load and apply the extension overlay. This is
> +		 * not implemented. See do_extension_apply(). The extension
> +		 * stuff needs an implementation in boot/extension.c so it is
> +		 * separate from the command code. Really the extension stuff
> +		 * should use the device tree and a uclass / driver interface
> +		 * rather than implementing its own list
> +		 */
> +	} else {
> +		log_debug("No device tree available\n");
> +	}
> +
>  	return 0;
>  }
>  
>  static int distro_efi_read_bootflow_net(struct bootflow *bflow)
>  {
> -	const char *addr_str;
> +	char file_addr[17], fname[256];
> +	char *tftp_argv[] = {"tftp", file_addr, fname, NULL};
> +	struct cmd_tbl cmdtp = {};	/* dummy */
> +	const char *addr_str, *fdt_addr_str;
>  	int ret, arch, size;
> +	ulong addr, fdt_addr;
>  	char str[36];
> -	ulong addr;
>  
>  	ret = get_efi_pxe_vci(str, sizeof(str));
>  	if (ret)
> @@ -216,6 +266,25 @@ static int distro_efi_read_bootflow_net(struct bootflow *bflow)
>  	efi_set_bootdev("Net", "", bflow->fname, map_sysmem(addr, 0),
>  			bflow->size);
>  
> +	/* read the DT file also */
> +	fdt_addr_str = env_get("fdt_addr_r");
> +	if (!fdt_addr_str)
> +		return log_msg_ret("fdt", -EINVAL);
> +	fdt_addr = hextoul(fdt_addr_str, NULL);
> +	sprintf(file_addr, "%lx", fdt_addr);
> +
> +	distro_efi_get_fdt_name(fname, sizeof(fname));
> +	bflow->fdt_fname = strdup(fname);
> +	if (!bflow->fdt_fname)
> +		return log_msg_ret("fil", -ENOMEM);
> +
> +	if (!do_tftpb(&cmdtp, 0, 3, tftp_argv)) {
> +		bflow->fdt_size = env_get_hex("filesize", 0);
> +		bflow->fdt_addr = fdt_addr;
> +	} else {
> +		log_debug("No device tree available\n");
> +	}
> +
>  	bflow->state = BOOTFLOWST_READY;
>  
>  	return 0;
> @@ -243,15 +312,39 @@ static int distro_efi_read_bootflow(struct udevice *dev, struct bootflow *bflow)
>  
>  int distro_efi_boot(struct udevice *dev, struct bootflow *bflow)
>  {
> +	ulong kernel, fdt;
>  	char cmd[50];
>  
> +	/* A non-zero buffer indicates the kernel is there */
> +	if (bflow->buf) {
> +		kernel = (ulong)map_to_sysmem(bflow->buf);
> +
> +		/*
> +		 * use the provided device tree if available, else fall back to
> +		 * the control FDT
> +		 */
> +		if (bflow->fdt_fname)
> +			fdt = bflow->fdt_addr;
> +		else
> +			fdt = (ulong)map_to_sysmem(gd->fdt_blob);
> +	} else {
> +		/*
> +		 * This doesn't actually work for network devices:
> +		 *
> +		 * do_bootefi_image() No UEFI binary known at 0x02080000
> +		 *
> +		 * But this is the same behaviour for distro boot, so it can be
> +		 * fixed here.
> +		 */
> +		kernel = env_get_hex("kernel_addr_r", 0);
> +		fdt = env_get_hex("fdt_addr_r", 0);
> +	}
> +
>  	/*
>  	 * At some point we can add a real interface to bootefi so we can call
> -	 * this directly. For now, go through the CLI like distro boot.
> +	 * this directly. For now, go through the CLI, like distro boot.
>  	 */
> -	snprintf(cmd, sizeof(cmd), "bootefi %lx %lx",
> -		 (ulong)map_to_sysmem(bflow->buf),
> -		 (ulong)map_to_sysmem(gd->fdt_blob));
> +	snprintf(cmd, sizeof(cmd), "bootefi %lx %lx", kernel, fdt);
>  	if (run_command(cmd, 0))
>  		return log_msg_ret("run", -EINVAL);
>  
> -- 
> 2.39.0.314.g84b9a713c41-goog
> 
> 

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH v2 30/71] net: Add a function to run dhcp
  2023-01-08  2:50 ` [PATCH v2 30/71] net: Add a function to run dhcp Simon Glass
@ 2023-01-10 17:03   ` Ramon Fried
  0 siblings, 0 replies; 87+ messages in thread
From: Ramon Fried @ 2023-01-10 17:03 UTC (permalink / raw)
  To: Simon Glass; +Cc: U-Boot Mailing List, U-Boot Custodians, Joe Hershberger

On Sun, Jan 8, 2023 at 4:58 AM Simon Glass <sjg@chromium.org> wrote:
>
> At present this must be done by executing the command. Also it involves
> fiddling with the environment to determine the correct autoload behaviour.
>
> Ideally it should be possible to run network operations without even
> having the command line present (CONFIG_CMDLINE).
>
> For now, add a function to handle DHCP, so it can be called from a bootdev
> more easily.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> (no changes since v1)
>
>  cmd/net.c     | 35 +++++++++++++++++++++++++++++++++++
>  include/net.h | 15 +++++++++++++++
>  2 files changed, 50 insertions(+)
>
> diff --git a/cmd/net.c b/cmd/net.c
> index 0e9f200ca97..6b3774bfe7c 100644
> --- a/cmd/net.c
> +++ b/cmd/net.c
> @@ -4,6 +4,8 @@
>   * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
>   */
>
> +#define LOG_CATEGORY   UCLASS_ETH
> +
>  /*
>   * Boot support
>   */
> @@ -13,6 +15,7 @@
>  #include <dm.h>
>  #include <env.h>
>  #include <image.h>
> +#include <log.h>
>  #include <net.h>
>  #include <net6.h>
>  #include <net/udp.h>
> @@ -120,6 +123,38 @@ U_BOOT_CMD(
>         "boot image via network using DHCP/TFTP protocol",
>         "[loadAddress] [[hostIPaddr:]bootfilename]"
>  );
> +
> +int dhcp_run(ulong addr, const char *fname, bool autoload)
> +{
> +       char *dhcp_argv[] = {"dhcp", NULL, (char *)fname, NULL};
> +       struct cmd_tbl cmdtp = {};      /* dummy */
> +       char file_addr[17];
> +       int old_autoload;
> +       int ret, result;
> +
> +       log_debug("addr=%lx, fname=%s, autoload=%d\n", addr, fname, autoload);
> +       old_autoload = env_get_yesno("autoload");
> +       ret = env_set("autoload", autoload ? "y" : "n");
> +       if (ret)
> +               return log_msg_ret("en1", -EINVAL);
> +
> +       if (autoload) {
> +               sprintf(file_addr, "%lx", addr);
> +               dhcp_argv[1] = file_addr;
> +       }
> +
> +       result = do_dhcp(&cmdtp, 0, !autoload ? 1 : fname ? 3 : 2, dhcp_argv);
> +
> +       ret = env_set("autoload", old_autoload == -1 ? NULL :
> +                     old_autoload ? "y" : "n");
> +       if (ret)
> +               return log_msg_ret("en2", -EINVAL);
> +
> +       if (result)
> +               return log_msg_ret("res", -ENOENT);
> +
> +       return 0;
> +}
>  #endif
>
>  #if defined(CONFIG_CMD_NFS)
> diff --git a/include/net.h b/include/net.h
> index 749f20fa967..c296d06c266 100644
> --- a/include/net.h
> +++ b/include/net.h
> @@ -65,6 +65,21 @@ struct in_addr {
>   */
>  int do_tftpb(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
>
> +/**
> + * dhcp_run() - Run DHCP on the current ethernet device
> + *
> + * This sets the autoload variable, then puts it back to similar to its original
> + * state (y, n or unset).
> + *
> + * @addr: Address to load the file into (0 if @autoload is false)
> + * @fname: Filename of file to load (NULL if @autoload is false or to use the
> + * default filename)
> + * @autoload: true to load the file, false to just get the network IP
> + * @return 0 if OK, -EINVAL if the environment failed, -ENOENT if ant file was
> + * not found
> + */
> +int dhcp_run(ulong addr, const char *fname, bool autoload);
> +
>  /**
>   * An incoming packet handler.
>   * @param pkt    pointer to the application packet
> --
> 2.39.0.314.g84b9a713c41-goog
>
Reviewed-by: Ramon Fried <rfried.dev@gmail.com>

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH v2 48/71] bootstd: Support reading the device tree with EFI
  2023-01-08 10:25   ` Mark Kettenis
@ 2023-01-13 18:00     ` Simon Glass
  0 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-13 18:00 UTC (permalink / raw)
  To: Mark Kettenis; +Cc: u-boot, u-boot-custodians

Hi Mark,

On Sun, 8 Jan 2023 at 03:25, Mark Kettenis <mark.kettenis@xs4all.nl> wrote:
>
> > From: Simon Glass <sjg@chromium.org>
> > Date: Sat,  7 Jan 2023 19:50:24 -0700
> >
> > With EFI booting the device tree is required but is not actually specified
> > in any way. The normal method is to use a fdtfile environment variable to
> > get the filename, then look for that file on the media.
> >
> > Implement this in the bootmeth.
> >
> > Signed-off-by: Simon Glass <sjg@chromium.org>
> > ---
>
> Hi Simon,
>
> The distroboot scripts also reads dtb files from the root directory of
> the ESP (so without the "dtb/" prefix).  This code needs to do that as
> well otherwise some folks will run with a different device tree after
> switching to bootstd.
>
> The construction of a fallback dtb filename based on soc, board and
> boardver is only done for (32-bit) arm and not for arm64.  It isn't
> done for riscv either.  That feels to me like someone recognized that
> was a bit of a mistake and shouldn't be done for modern targets.  So I
> think that code should be under the same
>
>    #if defined(CONFIG_ARM) && !defined(CONFIG_ARM64)
>
> as it is now in config_distro_bootcmd.h.

OK, thanks for that. Yes I deliberately dropped that in the hope that
we can have one standard.

I will send a patch to add that.

Regards,
Simon

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (69 preceding siblings ...)
  2023-01-08  2:50 ` [PATCH v2 71/71] rockchip: Convert rockpro64-rk3399 to use standard boot Simon Glass
@ 2023-01-13 19:54 ` Heinrich Schuchardt
  2023-01-13 20:32   ` Mark Kettenis
  2023-01-13 20:47   ` Tom Rini
  2023-01-17 13:57 ` Tom Rini
  71 siblings, 2 replies; 87+ messages in thread
From: Heinrich Schuchardt @ 2023-01-13 19:54 UTC (permalink / raw)
  To: Simon Glass
  Cc: U-Boot Custodians, Jaehoon Chung, Jeffy Chen, Joe Hershberger,
	Kever Yang, Marek Vasut, Pavel Herrmann, Peng Fan,
	Philipp Tomsich, Rob Herring, huang lin, U-Boot Mailing List,
	Aurelien Jarno

On 1/8/23 03:49, Simon Glass wrote:
> So far, standard boot does not replicate all the of the functionality
> of the distro_bootcmd scripts. In particular it lacks some bootdevs and
> some of the bootmeths are incomplete.
>
> Also there is currently no internal mechanism to enumerate buses in order
> to discover bootdevs, e.g. with USB.
>
> This series addresses these shortcomings:
>
> - Adds the concept of a 'bootdev hunter' to enumerate buses, etc. in an
>    effort to find bootdevs of a certain priority
> - Adds bootdevs for SCSI, IDE, NVMe, virtio, SPI flash
> - Handles PXE and DHCP properly
> - Supports reading the device tree with EFI and reading scripts from the
>    network
>
> It also tidies up label processing, so it is possible to use:
>
>     bootflow scan mmc2
>
> to scan just one MMC device (with BOOTSTD_FULL).
>
> As before this implementation still relies on CONFIG_CMDLINE being
> enabled, mostly for the network stack. Further work would be required to
> disentangle that.
>
> Quite a few tests are added but there are some gaps:
>
> - SPI flash bootdev
> - EFI FDT loading
>
> Note that SATA works via SCSI (CONFIG_SCSI_AHCI) and does not use
> driver model. Only pogo_v4 seems to be affected. Probably all thats is
> needed is to call bootdev_setup_sibling_blk() in the Marvell SATA driver.
>
> Also, while it would be possible to init MMC in a bootdev hunter, there is
> no point since U-Boot always inits MMC on startup, if present.
>
> With this series it should be possible to migrate boards to standard boot
> by removing the inclusion of config_distro_bootcmd.h and instead adding
> a suitable value for boot_targets to the environment, e.g.:
>
>     boot_targets=mmc1 mmc0 nvme scsi usb pxe dhcp spi

Does nvme mean all nvme drives? Would mmc mean all mmc block devices?

doc/develop/bootstd.rst should describe the syntax.

On generic boards it does not make much sense to restrict scanning to
one instance of a block device type.

Cf.
[PATCH] board: sifive: unmatched: enable booting on a second NVME device
https://lore.kernel.org/all/20230107223239.2387940-1-aurelien@aurel32.net/

Best regards

Heinrich

>
> Thus it is possible to boot automatically without scripts and boards can
> use a text-based environment instead of the config.h files.
>
> To demonstrate this, rockpro64-rk3399 is migrated to standard boot in this
> series. Full migration could probably be automated using a script, similar
> in concept to moveconfig:
>
>     - obtain the board environment via 'make u-boot-initial-env'
>     - get the value of "boot_targets"
>     - drop config_distro_bootcmd.h from the config.h file
>     - rebuild again to get the environment without distro scripts
>     - write the environment (adding boot_targets) to board.env
>     - remove CONFIG_EXTRA_ENV_SETTINGS from the config.h file
>
> This series is based on top of the boot menu series v3 [1].
> The tree is available at u-boot-dm/dis-working
>
> [1] https://patchwork.ozlabs.org/project/uboot/list/?series=335364
>
> Changes in v2:
> - Rebase to -next
>
> Simon Glass (71):
>    dm: core: Correct ordering of uclasses IDs
>    dm: core: Support sorting devices with dm tree
>    dm: test: Correct assertion in dm_test_part()
>    lib: Add a function to split a string into substrings
>    bootstd: Remove special-case code for boot_targets
>    bootstd: Simplify locating existing bootdevs
>    test: Fix the help for the ut command
>    test: Drop duplicate restore of DM state
>    sandbox: mmc: Start off with a zeroed file
>    vbe: Avoid a build failure when bloblist is not enabled
>    vbe: sandbox: Drop VBE node in chosen
>    dm: part: Update test to use mmc2
>    dm: test: Correct ordering of DM setup
>    ide: Drop non-DM code for BLK
>    dm: mmc: Use bootdev_setup_sibling_blk()
>    bootstd: Add a default method to get bootflows
>    sandbox: Allow ethernet to be disabled at runtime
>    sandbox: Allow ethernet bootdevs to be disabled for tests
>    sandbox: Enable the Ethernet bootdev
>    lib: Support printing an error string
>    event: Correct duplicate log message in event_notify()
>    efi: Improve logging in efi_disk
>    bootstd: Add the concept of a bootdev hunter
>    bootstd: Support running bootdev hunters
>    dm: usb: Drop some dead code
>    dm: usb: Mark the device name as alloced when binding
>    test: Add a generic function to skip delays
>    bootstd: Add a USB hunter
>    bootstd: Add an MMC hunter
>    net: Add a function to run dhcp
>    bootstd: Add a hunter for ethernet
>    part: Add a function to find the first bootable partition
>    bootstd: Only scan bootable partitions
>    scsi: Correct allocation of block-device name
>    scsi: Remove all children of SCSI devices before rescanning
>    bootstd: Add a SCSI bootdev
>    bootstd: Add an IDE bootdev
>    bootstd: Add an NVMe bootdev
>    virtio: Avoid repeating a long expression
>    virtio: Fix returning -ENODEV
>    virtio: Avoid strange behaviour on removal
>    virtio: Add a block device
>    bootstd: Add a virtio bootdev
>    ata: Don't try to use non-existent ports
>    bootstd: Rename bootdev checkers
>    bootstd: Allow reading an EFI file from the network
>    bootstd: Include the device tree in the bootflow
>    bootstd: Support reading the device tree with EFI
>    bootstd: Set the distro_bootpart env var with scripts
>    bootstd: Update docs on bootmeth_try_file() for sandbox
>    bootstd: Move label parsing into its own function
>    bootstd: Add a new bootmeth method to set the bootflow
>    sandbox: Allow SPI flash bootdevs to be disabled for tests
>    bootstd: Add a SPI flash bootdev
>    bootstd: Support reading a script from network or SPI flash
>    bootstd: Treat DHCP and PXE as bootdev labels
>    bootstd: Use hunters when scanning for bootflows
>    bootstd: Allow hunting for bootdevs of a given priority
>    bootstd: Add a new pre-scan priority for bootdevs
>    bootstd: Allow hunting for a bootdev by label
>    bootstd: Allow iterating to the next label in a list
>    bootstd: Allow iterating to the next bootdev priortiy
>    extension: Refactor to allow non-command usage
>    bootstd: Add a hunter for the extension feature
>    bootstd: Switch bootdev scanning to use labels
>    bootstd: Allow scanning a single bootdev label
>    bootstd: Drop the old bootflow_scan_first()
>    bootstd: Record the bootdevs used during scanning
>    bootstd: Add a little more logging of bootflows
>    bootstd: Update documentation for new features
>    rockchip: Convert rockpro64-rk3399 to use standard boot
>
>   arch/sandbox/cpu/state.c           |  30 ++
>   arch/sandbox/dts/sandbox.dtsi      |  13 -
>   arch/sandbox/dts/test.dts          |   6 +
>   arch/sandbox/include/asm/state.h   |   2 +
>   arch/sandbox/include/asm/test.h    |  30 ++
>   boot/bootdev-uclass.c              | 551 +++++++++++++++++++---------
>   boot/bootflow.c                    | 173 ++++++---
>   boot/bootmeth-uclass.c             |  11 +
>   boot/bootmeth_distro.c             |   2 +-
>   boot/bootmeth_efi.c                | 220 ++++++++++-
>   boot/bootmeth_efi_mgr.c            |   2 +-
>   boot/bootmeth_pxe.c                |   5 +-
>   boot/bootmeth_script.c             |  98 ++++-
>   boot/bootstd-uclass.c              |  17 +-
>   boot/vbe_simple_fw.c               |   2 +-
>   cmd/bootdev.c                      |  42 ++-
>   cmd/bootflow.c                     |  97 +++--
>   cmd/dm.c                           |  10 +-
>   cmd/extension_board.c              |  43 ++-
>   cmd/net.c                          |  35 ++
>   cmd/vbe.c                          |   7 +-
>   common/event.c                     |   2 +-
>   configs/sandbox_defconfig          |   2 +-
>   configs/sandbox_flattree_defconfig |  10 +-
>   disk/part.c                        |  16 +
>   doc/develop/bootstd.rst            | 221 +++++++----
>   doc/develop/driver-model/nvme.rst  |   2 +-
>   doc/usage/cmd/bootdev.rst          |  48 ++-
>   doc/usage/cmd/bootflow.rst         |  17 +-
>   doc/usage/cmd/dm.rst               |   5 +-
>   drivers/ata/ahci.c                 |   6 +
>   drivers/block/ide.c                |  86 ++---
>   drivers/core/dump.c                |  65 +++-
>   drivers/mmc/mmc-uclass.c           |   2 +-
>   drivers/mmc/mmc_bootdev.c          |  33 +-
>   drivers/mmc/sandbox_mmc.c          |   2 +-
>   drivers/mtd/spi/Kconfig            |   8 +
>   drivers/mtd/spi/Makefile           |   1 +
>   drivers/mtd/spi/sf-uclass.c        |  11 +
>   drivers/mtd/spi/sf_bootdev.c       |  82 +++++
>   drivers/nvme/nvme-uclass.c         |  54 +++
>   drivers/nvme/nvme.c                |   5 +
>   drivers/scsi/Makefile              |   7 +
>   drivers/scsi/scsi.c                |  32 +-
>   drivers/scsi/scsi_bootdev.c        |  62 ++++
>   drivers/usb/host/usb-uclass.c      |  45 +--
>   drivers/usb/host/usb_bootdev.c     |  38 +-
>   drivers/virtio/virtio-uclass.c     |  62 +++-
>   drivers/virtio/virtio_sandbox.c    |  16 +-
>   include/bootdev.h                  | 206 ++++++++++-
>   include/bootflow.h                 | 134 +++++--
>   include/bootmeth.h                 |  35 +-
>   include/bootstd.h                  |  17 +-
>   include/configs/rk3399_common.h    |   5 +-
>   include/configs/rockchip-common.h  |   2 +
>   include/dm/uclass-id.h             |   4 +-
>   include/dm/util.h                  |   8 +-
>   include/net.h                      |  31 ++
>   include/part.h                     |   8 +
>   include/test/test.h                |  72 ++++
>   include/vsprintf.h                 |  24 ++
>   lib/efi_loader/efi_disk.c          |  30 +-
>   lib/strto.c                        |  41 +++
>   lib/vsprintf.c                     |  12 +
>   net/eth-uclass.c                   |  14 +-
>   net/eth_bootdev.c                  |  68 ++--
>   net/net.c                          |   4 +
>   test/boot/bootdev.c                | 563 +++++++++++++++++++++++++++--
>   test/boot/bootflow.c               | 138 +++++--
>   test/boot/bootstd_common.c         |  19 +
>   test/boot/bootstd_common.h         |  13 +
>   test/cmd_ut.c                      |   2 +-
>   test/dm/part.c                     |  37 +-
>   test/dm/virtio_device.c            |   3 +
>   test/py/tests/bootstd/mmc1.img.xz  | Bin 4448 -> 4480 bytes
>   test/py/tests/test_dm.py           |  38 ++
>   test/py/tests/test_ut.py           |  13 +-
>   test/str_ut.c                      |  82 +++++
>   test/test-main.c                   |  24 +-
>   79 files changed, 3225 insertions(+), 758 deletions(-)
>   create mode 100644 drivers/mtd/spi/sf_bootdev.c
>   create mode 100644 drivers/scsi/scsi_bootdev.c
>


^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts
  2023-01-13 19:54 ` [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Heinrich Schuchardt
@ 2023-01-13 20:32   ` Mark Kettenis
  2023-01-13 21:05     ` Simon Glass
  2023-01-13 20:47   ` Tom Rini
  1 sibling, 1 reply; 87+ messages in thread
From: Mark Kettenis @ 2023-01-13 20:32 UTC (permalink / raw)
  To: Heinrich Schuchardt
  Cc: sjg, u-boot-custodians, jh80.chung, jeffy.chen, joe.hershberger,
	kever.yang, marex, morpheus.ibis, peng.fan, philipp.tomsich,
	rob.herring, hl, u-boot, aurelien

> Date: Fri, 13 Jan 2023 20:54:06 +0100
> From: Heinrich Schuchardt <xypron.glpk@gmx.de>
> 
> On 1/8/23 03:49, Simon Glass wrote:
> > So far, standard boot does not replicate all the of the functionality
> > of the distro_bootcmd scripts. In particular it lacks some bootdevs and
> > some of the bootmeths are incomplete.
> >
> > Also there is currently no internal mechanism to enumerate buses in order
> > to discover bootdevs, e.g. with USB.
> >
> > This series addresses these shortcomings:
> >
> > - Adds the concept of a 'bootdev hunter' to enumerate buses, etc. in an
> >    effort to find bootdevs of a certain priority
> > - Adds bootdevs for SCSI, IDE, NVMe, virtio, SPI flash
> > - Handles PXE and DHCP properly
> > - Supports reading the device tree with EFI and reading scripts from the
> >    network
> >
> > It also tidies up label processing, so it is possible to use:
> >
> >     bootflow scan mmc2
> >
> > to scan just one MMC device (with BOOTSTD_FULL).
> >
> > As before this implementation still relies on CONFIG_CMDLINE being
> > enabled, mostly for the network stack. Further work would be required to
> > disentangle that.
> >
> > Quite a few tests are added but there are some gaps:
> >
> > - SPI flash bootdev
> > - EFI FDT loading
> >
> > Note that SATA works via SCSI (CONFIG_SCSI_AHCI) and does not use
> > driver model. Only pogo_v4 seems to be affected. Probably all thats is
> > needed is to call bootdev_setup_sibling_blk() in the Marvell SATA driver.
> >
> > Also, while it would be possible to init MMC in a bootdev hunter, there is
> > no point since U-Boot always inits MMC on startup, if present.
> >
> > With this series it should be possible to migrate boards to standard boot
> > by removing the inclusion of config_distro_bootcmd.h and instead adding
> > a suitable value for boot_targets to the environment, e.g.:
> >
> >     boot_targets=mmc1 mmc0 nvme scsi usb pxe dhcp spi
> 
> Does nvme mean all nvme drives? Would mmc mean all mmc block devices?
> 
> doc/develop/bootstd.rst should describe the syntax.
> 
> On generic boards it does not make much sense to restrict scanning to
> one instance of a block device type.
> 
> Cf.
> [PATCH] board: sifive: unmatched: enable booting on a second NVME device
> https://lore.kernel.org/all/20230107223239.2387940-1-aurelien@aurel32.net/

But it would still make sense to be able to specify the order in which
those instances are scanned.

> > Thus it is possible to boot automatically without scripts and boards can
> > use a text-based environment instead of the config.h files.
> >
> > To demonstrate this, rockpro64-rk3399 is migrated to standard boot in this
> > series. Full migration could probably be automated using a script, similar
> > in concept to moveconfig:
> >
> >     - obtain the board environment via 'make u-boot-initial-env'
> >     - get the value of "boot_targets"
> >     - drop config_distro_bootcmd.h from the config.h file
> >     - rebuild again to get the environment without distro scripts
> >     - write the environment (adding boot_targets) to board.env
> >     - remove CONFIG_EXTRA_ENV_SETTINGS from the config.h file
> >
> > This series is based on top of the boot menu series v3 [1].
> > The tree is available at u-boot-dm/dis-working
> >
> > [1] https://patchwork.ozlabs.org/project/uboot/list/?series=335364
> >
> > Changes in v2:
> > - Rebase to -next
> >
> > Simon Glass (71):
> >    dm: core: Correct ordering of uclasses IDs
> >    dm: core: Support sorting devices with dm tree
> >    dm: test: Correct assertion in dm_test_part()
> >    lib: Add a function to split a string into substrings
> >    bootstd: Remove special-case code for boot_targets
> >    bootstd: Simplify locating existing bootdevs
> >    test: Fix the help for the ut command
> >    test: Drop duplicate restore of DM state
> >    sandbox: mmc: Start off with a zeroed file
> >    vbe: Avoid a build failure when bloblist is not enabled
> >    vbe: sandbox: Drop VBE node in chosen
> >    dm: part: Update test to use mmc2
> >    dm: test: Correct ordering of DM setup
> >    ide: Drop non-DM code for BLK
> >    dm: mmc: Use bootdev_setup_sibling_blk()
> >    bootstd: Add a default method to get bootflows
> >    sandbox: Allow ethernet to be disabled at runtime
> >    sandbox: Allow ethernet bootdevs to be disabled for tests
> >    sandbox: Enable the Ethernet bootdev
> >    lib: Support printing an error string
> >    event: Correct duplicate log message in event_notify()
> >    efi: Improve logging in efi_disk
> >    bootstd: Add the concept of a bootdev hunter
> >    bootstd: Support running bootdev hunters
> >    dm: usb: Drop some dead code
> >    dm: usb: Mark the device name as alloced when binding
> >    test: Add a generic function to skip delays
> >    bootstd: Add a USB hunter
> >    bootstd: Add an MMC hunter
> >    net: Add a function to run dhcp
> >    bootstd: Add a hunter for ethernet
> >    part: Add a function to find the first bootable partition
> >    bootstd: Only scan bootable partitions
> >    scsi: Correct allocation of block-device name
> >    scsi: Remove all children of SCSI devices before rescanning
> >    bootstd: Add a SCSI bootdev
> >    bootstd: Add an IDE bootdev
> >    bootstd: Add an NVMe bootdev
> >    virtio: Avoid repeating a long expression
> >    virtio: Fix returning -ENODEV
> >    virtio: Avoid strange behaviour on removal
> >    virtio: Add a block device
> >    bootstd: Add a virtio bootdev
> >    ata: Don't try to use non-existent ports
> >    bootstd: Rename bootdev checkers
> >    bootstd: Allow reading an EFI file from the network
> >    bootstd: Include the device tree in the bootflow
> >    bootstd: Support reading the device tree with EFI
> >    bootstd: Set the distro_bootpart env var with scripts
> >    bootstd: Update docs on bootmeth_try_file() for sandbox
> >    bootstd: Move label parsing into its own function
> >    bootstd: Add a new bootmeth method to set the bootflow
> >    sandbox: Allow SPI flash bootdevs to be disabled for tests
> >    bootstd: Add a SPI flash bootdev
> >    bootstd: Support reading a script from network or SPI flash
> >    bootstd: Treat DHCP and PXE as bootdev labels
> >    bootstd: Use hunters when scanning for bootflows
> >    bootstd: Allow hunting for bootdevs of a given priority
> >    bootstd: Add a new pre-scan priority for bootdevs
> >    bootstd: Allow hunting for a bootdev by label
> >    bootstd: Allow iterating to the next label in a list
> >    bootstd: Allow iterating to the next bootdev priortiy
> >    extension: Refactor to allow non-command usage
> >    bootstd: Add a hunter for the extension feature
> >    bootstd: Switch bootdev scanning to use labels
> >    bootstd: Allow scanning a single bootdev label
> >    bootstd: Drop the old bootflow_scan_first()
> >    bootstd: Record the bootdevs used during scanning
> >    bootstd: Add a little more logging of bootflows
> >    bootstd: Update documentation for new features
> >    rockchip: Convert rockpro64-rk3399 to use standard boot
> >
> >   arch/sandbox/cpu/state.c           |  30 ++
> >   arch/sandbox/dts/sandbox.dtsi      |  13 -
> >   arch/sandbox/dts/test.dts          |   6 +
> >   arch/sandbox/include/asm/state.h   |   2 +
> >   arch/sandbox/include/asm/test.h    |  30 ++
> >   boot/bootdev-uclass.c              | 551 +++++++++++++++++++---------
> >   boot/bootflow.c                    | 173 ++++++---
> >   boot/bootmeth-uclass.c             |  11 +
> >   boot/bootmeth_distro.c             |   2 +-
> >   boot/bootmeth_efi.c                | 220 ++++++++++-
> >   boot/bootmeth_efi_mgr.c            |   2 +-
> >   boot/bootmeth_pxe.c                |   5 +-
> >   boot/bootmeth_script.c             |  98 ++++-
> >   boot/bootstd-uclass.c              |  17 +-
> >   boot/vbe_simple_fw.c               |   2 +-
> >   cmd/bootdev.c                      |  42 ++-
> >   cmd/bootflow.c                     |  97 +++--
> >   cmd/dm.c                           |  10 +-
> >   cmd/extension_board.c              |  43 ++-
> >   cmd/net.c                          |  35 ++
> >   cmd/vbe.c                          |   7 +-
> >   common/event.c                     |   2 +-
> >   configs/sandbox_defconfig          |   2 +-
> >   configs/sandbox_flattree_defconfig |  10 +-
> >   disk/part.c                        |  16 +
> >   doc/develop/bootstd.rst            | 221 +++++++----
> >   doc/develop/driver-model/nvme.rst  |   2 +-
> >   doc/usage/cmd/bootdev.rst          |  48 ++-
> >   doc/usage/cmd/bootflow.rst         |  17 +-
> >   doc/usage/cmd/dm.rst               |   5 +-
> >   drivers/ata/ahci.c                 |   6 +
> >   drivers/block/ide.c                |  86 ++---
> >   drivers/core/dump.c                |  65 +++-
> >   drivers/mmc/mmc-uclass.c           |   2 +-
> >   drivers/mmc/mmc_bootdev.c          |  33 +-
> >   drivers/mmc/sandbox_mmc.c          |   2 +-
> >   drivers/mtd/spi/Kconfig            |   8 +
> >   drivers/mtd/spi/Makefile           |   1 +
> >   drivers/mtd/spi/sf-uclass.c        |  11 +
> >   drivers/mtd/spi/sf_bootdev.c       |  82 +++++
> >   drivers/nvme/nvme-uclass.c         |  54 +++
> >   drivers/nvme/nvme.c                |   5 +
> >   drivers/scsi/Makefile              |   7 +
> >   drivers/scsi/scsi.c                |  32 +-
> >   drivers/scsi/scsi_bootdev.c        |  62 ++++
> >   drivers/usb/host/usb-uclass.c      |  45 +--
> >   drivers/usb/host/usb_bootdev.c     |  38 +-
> >   drivers/virtio/virtio-uclass.c     |  62 +++-
> >   drivers/virtio/virtio_sandbox.c    |  16 +-
> >   include/bootdev.h                  | 206 ++++++++++-
> >   include/bootflow.h                 | 134 +++++--
> >   include/bootmeth.h                 |  35 +-
> >   include/bootstd.h                  |  17 +-
> >   include/configs/rk3399_common.h    |   5 +-
> >   include/configs/rockchip-common.h  |   2 +
> >   include/dm/uclass-id.h             |   4 +-
> >   include/dm/util.h                  |   8 +-
> >   include/net.h                      |  31 ++
> >   include/part.h                     |   8 +
> >   include/test/test.h                |  72 ++++
> >   include/vsprintf.h                 |  24 ++
> >   lib/efi_loader/efi_disk.c          |  30 +-
> >   lib/strto.c                        |  41 +++
> >   lib/vsprintf.c                     |  12 +
> >   net/eth-uclass.c                   |  14 +-
> >   net/eth_bootdev.c                  |  68 ++--
> >   net/net.c                          |   4 +
> >   test/boot/bootdev.c                | 563 +++++++++++++++++++++++++++--
> >   test/boot/bootflow.c               | 138 +++++--
> >   test/boot/bootstd_common.c         |  19 +
> >   test/boot/bootstd_common.h         |  13 +
> >   test/cmd_ut.c                      |   2 +-
> >   test/dm/part.c                     |  37 +-
> >   test/dm/virtio_device.c            |   3 +
> >   test/py/tests/bootstd/mmc1.img.xz  | Bin 4448 -> 4480 bytes
> >   test/py/tests/test_dm.py           |  38 ++
> >   test/py/tests/test_ut.py           |  13 +-
> >   test/str_ut.c                      |  82 +++++
> >   test/test-main.c                   |  24 +-
> >   79 files changed, 3225 insertions(+), 758 deletions(-)
> >   create mode 100644 drivers/mtd/spi/sf_bootdev.c
> >   create mode 100644 drivers/scsi/scsi_bootdev.c
> >
> 
> 

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH v2 22/71] efi: Improve logging in efi_disk
  2023-01-08  2:49 ` [PATCH v2 22/71] efi: Improve logging in efi_disk Simon Glass
@ 2023-01-13 20:35   ` Heinrich Schuchardt
  2023-01-13 20:40     ` Tom Rini
  0 siblings, 1 reply; 87+ messages in thread
From: Heinrich Schuchardt @ 2023-01-13 20:35 UTC (permalink / raw)
  To: Simon Glass; +Cc: U-Boot Custodians, U-Boot Mailing List

On 1/8/23 03:49, Simon Glass wrote:
> When this fails it can be time-consuming to debug. Add some debugging
> to help with this. Also try to return error codes instead of just using
> -1.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> (no changes since v1)
>
>   lib/efi_loader/efi_disk.c | 30 +++++++++++++++++++++---------
>   1 file changed, 21 insertions(+), 9 deletions(-)
>
> diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
> index 7ea0334083f..37123dd2474 100644
> --- a/lib/efi_loader/efi_disk.c
> +++ b/lib/efi_loader/efi_disk.c
> @@ -421,13 +421,16 @@ static efi_status_t efi_disk_add_dev(
>
>   		if (!node) {
>   			ret = EFI_OUT_OF_RESOURCES;
> +			log_debug("no node\n");

Please, provide a descriptive message. I would not know what "no node"
might mean if I were to read it.

There is a reason why we set ret = EFI_OUT_OF_RESOURCES?

The caller should know what this means.

>   			goto error;
>   		}
>
>   		/* Parent must expose EFI_BLOCK_IO_PROTOCOL */
>   		ret = efi_search_protocol(parent, &efi_block_io_guid, &handler);
> -		if (ret != EFI_SUCCESS)
> +		if (ret != EFI_SUCCESS) {
> +			log_debug("search failed\n");

This message text is not descriptive enough.

>   			goto error;
> +		}
>
>   		/*
>   		 * Link the partition (child controller) to the block device
> @@ -436,8 +439,10 @@ static efi_status_t efi_disk_add_dev(
>   		ret = efi_protocol_open(handler, &protocol_interface, NULL,
>   					&diskobj->header,
>   					EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER);
> -		if (ret != EFI_SUCCESS)
> -				goto error;
> +		if (ret != EFI_SUCCESS) {
> +			log_debug("prot open failed\n");

ditto

> +			goto error;
> +		}
>
>   		diskobj->dp = efi_dp_append_node(dp_parent, node);
>   		efi_free_pool(node);
> @@ -468,8 +473,10 @@ static efi_status_t efi_disk_add_dev(
>   					 */
>   					esp_guid, NULL,
>   					NULL);
> -	if (ret != EFI_SUCCESS)
> +	if (ret != EFI_SUCCESS) {
> +		log_debug("install failed %lx\n", ret);

ditto

>   		goto error;
> +	}
>
>   	/*
>   	 * On partitions or whole disks without partitions install the
> @@ -482,8 +489,10 @@ static efi_status_t efi_disk_add_dev(
>   		ret = efi_add_protocol(&diskobj->header,
>   				       &efi_simple_file_system_protocol_guid,
>   				       diskobj->volume);
> -		if (ret != EFI_SUCCESS)
> +		if (ret != EFI_SUCCESS) {
> +			log_debug("simple FS failed\n");

It is not the the simple file system protocol that failed.

Assuming that you don't provide invalid parameters the error can only
occur if we are out of resources and ret will convey that message.

Did you really ever miss any of these messages?
All of these relate to internal errors and I would not find out what is
going wrong without debugging.

>   			return ret;
> +		}
>   	}
>   	diskobj->ops = block_io_disk_template;
>   	diskobj->dev_index = dev_index;
> @@ -552,18 +561,21 @@ static int efi_disk_create_raw(struct udevice *dev)
>   	ret = efi_disk_add_dev(NULL, NULL, desc,
>   			       diskid, NULL, 0, &disk);
>   	if (ret != EFI_SUCCESS) {
> -		if (ret == EFI_NOT_READY)
> +		if (ret == EFI_NOT_READY) {
>   			log_notice("Disk %s not ready\n", dev->name);
> -		else
> +			ret = -EBUSY;

Don't reuse variable ret which is of type efi_status_t. Use a separate
variable of type int instead.

> +		} else {
>   			log_err("Adding disk for %s failed (err=%ld/%#lx)\n", dev->name, ret, ret);
> +			ret = -ENOENT;

ditto

> +		}
>
> -		return -1;
> +		return ret;

ditto

>   	}
>   	if (efi_link_dev(&disk->header, dev)) {
>   		efi_free_pool(disk->dp);
>   		efi_delete_handle(&disk->header);
>
> -		return -1;
> +		return -EINVAL;

The caller will convert any of these return values to -1.
So this change seems superfluous.

Best regards

Heinrich

>   	}
>
>   	return 0;


^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH v2 22/71] efi: Improve logging in efi_disk
  2023-01-13 20:35   ` Heinrich Schuchardt
@ 2023-01-13 20:40     ` Tom Rini
  2023-01-13 20:49       ` Heinrich Schuchardt
  2023-01-13 22:40       ` Simon Glass
  0 siblings, 2 replies; 87+ messages in thread
From: Tom Rini @ 2023-01-13 20:40 UTC (permalink / raw)
  To: Heinrich Schuchardt; +Cc: Simon Glass, U-Boot Custodians, U-Boot Mailing List

[-- Attachment #1: Type: text/plain, Size: 1281 bytes --]

On Fri, Jan 13, 2023 at 09:35:36PM +0100, Heinrich Schuchardt wrote:
> On 1/8/23 03:49, Simon Glass wrote:
> > When this fails it can be time-consuming to debug. Add some debugging
> > to help with this. Also try to return error codes instead of just using
> > -1.
> > 
> > Signed-off-by: Simon Glass <sjg@chromium.org>
> > ---
> > 
> > (no changes since v1)
> > 
> >   lib/efi_loader/efi_disk.c | 30 +++++++++++++++++++++---------
> >   1 file changed, 21 insertions(+), 9 deletions(-)
> > 
> > diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
> > index 7ea0334083f..37123dd2474 100644
> > --- a/lib/efi_loader/efi_disk.c
> > +++ b/lib/efi_loader/efi_disk.c
> > @@ -421,13 +421,16 @@ static efi_status_t efi_disk_add_dev(
> > 
> >   		if (!node) {
> >   			ret = EFI_OUT_OF_RESOURCES;
> > +			log_debug("no node\n");
> 
> Please, provide a descriptive message. I would not know what "no node"
> might mean if I were to read it.
> 
> There is a reason why we set ret = EFI_OUT_OF_RESOURCES?
> 
> The caller should know what this means.

There's a fine balance to be struck here. An error message should be
grep'd through in the code, for debug messages. With CONFIG_LOG we're
already getting file, line and function.

-- 
Tom

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts
  2023-01-13 19:54 ` [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Heinrich Schuchardt
  2023-01-13 20:32   ` Mark Kettenis
@ 2023-01-13 20:47   ` Tom Rini
  1 sibling, 0 replies; 87+ messages in thread
From: Tom Rini @ 2023-01-13 20:47 UTC (permalink / raw)
  To: Heinrich Schuchardt
  Cc: Simon Glass, U-Boot Custodians, Jaehoon Chung, Jeffy Chen,
	Joe Hershberger, Kever Yang, Marek Vasut, Pavel Herrmann,
	Peng Fan, Philipp Tomsich, Rob Herring, huang lin,
	U-Boot Mailing List, Aurelien Jarno

[-- Attachment #1: Type: text/plain, Size: 2756 bytes --]

On Fri, Jan 13, 2023 at 08:54:06PM +0100, Heinrich Schuchardt wrote:
> On 1/8/23 03:49, Simon Glass wrote:
> > So far, standard boot does not replicate all the of the functionality
> > of the distro_bootcmd scripts. In particular it lacks some bootdevs and
> > some of the bootmeths are incomplete.
> > 
> > Also there is currently no internal mechanism to enumerate buses in order
> > to discover bootdevs, e.g. with USB.
> > 
> > This series addresses these shortcomings:
> > 
> > - Adds the concept of a 'bootdev hunter' to enumerate buses, etc. in an
> >    effort to find bootdevs of a certain priority
> > - Adds bootdevs for SCSI, IDE, NVMe, virtio, SPI flash
> > - Handles PXE and DHCP properly
> > - Supports reading the device tree with EFI and reading scripts from the
> >    network
> > 
> > It also tidies up label processing, so it is possible to use:
> > 
> >     bootflow scan mmc2
> > 
> > to scan just one MMC device (with BOOTSTD_FULL).
> > 
> > As before this implementation still relies on CONFIG_CMDLINE being
> > enabled, mostly for the network stack. Further work would be required to
> > disentangle that.
> > 
> > Quite a few tests are added but there are some gaps:
> > 
> > - SPI flash bootdev
> > - EFI FDT loading
> > 
> > Note that SATA works via SCSI (CONFIG_SCSI_AHCI) and does not use
> > driver model. Only pogo_v4 seems to be affected. Probably all thats is
> > needed is to call bootdev_setup_sibling_blk() in the Marvell SATA driver.
> > 
> > Also, while it would be possible to init MMC in a bootdev hunter, there is
> > no point since U-Boot always inits MMC on startup, if present.
> > 
> > With this series it should be possible to migrate boards to standard boot
> > by removing the inclusion of config_distro_bootcmd.h and instead adding
> > a suitable value for boot_targets to the environment, e.g.:
> > 
> >     boot_targets=mmc1 mmc0 nvme scsi usb pxe dhcp spi
> 
> Does nvme mean all nvme drives? Would mmc mean all mmc block devices?
> 
> doc/develop/bootstd.rst should describe the syntax.
> 
> On generic boards it does not make much sense to restrict scanning to
> one instance of a block device type.
> 
> Cf.
> [PATCH] board: sifive: unmatched: enable booting on a second NVME device
> https://lore.kernel.org/all/20230107223239.2387940-1-aurelien@aurel32.net/

I think there's room for improvement on top of
https://patchwork.ozlabs.org/project/uboot/patch/20230108025047.522240-71-sjg@chromium.org/
with more examples / documentation on how to handle a storage type which
can have more than one location. But since this leverages DM, it's not
restricted to a single NVMe, since our uclass isn't restricted to a
single NVMe.

-- 
Tom

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH v2 22/71] efi: Improve logging in efi_disk
  2023-01-13 20:40     ` Tom Rini
@ 2023-01-13 20:49       ` Heinrich Schuchardt
  2023-01-13 22:40       ` Simon Glass
  1 sibling, 0 replies; 87+ messages in thread
From: Heinrich Schuchardt @ 2023-01-13 20:49 UTC (permalink / raw)
  To: Tom Rini; +Cc: Simon Glass, U-Boot Custodians, U-Boot Mailing List

On 1/13/23 21:40, Tom Rini wrote:
> On Fri, Jan 13, 2023 at 09:35:36PM +0100, Heinrich Schuchardt wrote:
>> On 1/8/23 03:49, Simon Glass wrote:
>>> When this fails it can be time-consuming to debug. Add some debugging
>>> to help with this. Also try to return error codes instead of just using
>>> -1.
>>>
>>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>> ---
>>>
>>> (no changes since v1)
>>>
>>>    lib/efi_loader/efi_disk.c | 30 +++++++++++++++++++++---------
>>>    1 file changed, 21 insertions(+), 9 deletions(-)
>>>
>>> diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
>>> index 7ea0334083f..37123dd2474 100644
>>> --- a/lib/efi_loader/efi_disk.c
>>> +++ b/lib/efi_loader/efi_disk.c
>>> @@ -421,13 +421,16 @@ static efi_status_t efi_disk_add_dev(
>>>
>>>    		if (!node) {
>>>    			ret = EFI_OUT_OF_RESOURCES;
>>> +			log_debug("no node\n");
>>
>> Please, provide a descriptive message. I would not know what "no node"
>> might mean if I were to read it.
>>
>> There is a reason why we set ret = EFI_OUT_OF_RESOURCES?
>>
>> The caller should know what this means.
>
> There's a fine balance to be struck here. An error message should be
> grep'd through in the code, for debug messages. With CONFIG_LOG we're
> already getting file, line and function.
>

CONFIG_LOG is of by default. So we are talking about a developer build.

If instead of "no node" I would see "out of resources", this would be
more helpful to me.

Best regards

Heinrich

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts
  2023-01-13 20:32   ` Mark Kettenis
@ 2023-01-13 21:05     ` Simon Glass
  2023-01-14  1:58       ` Peter Robinson
  0 siblings, 1 reply; 87+ messages in thread
From: Simon Glass @ 2023-01-13 21:05 UTC (permalink / raw)
  To: Mark Kettenis
  Cc: Heinrich Schuchardt, u-boot-custodians, jh80.chung, jeffy.chen,
	joe.hershberger, kever.yang, marex, morpheus.ibis, peng.fan,
	philipp.tomsich, rob.herring, hl, u-boot, aurelien

Hi Mark, Heinrich,

On Fri, 13 Jan 2023 at 13:32, Mark Kettenis <mark.kettenis@xs4all.nl> wrote:
>
> > Date: Fri, 13 Jan 2023 20:54:06 +0100
> > From: Heinrich Schuchardt <xypron.glpk@gmx.de>
> >
> > On 1/8/23 03:49, Simon Glass wrote:
> > > So far, standard boot does not replicate all the of the functionality
> > > of the distro_bootcmd scripts. In particular it lacks some bootdevs and
> > > some of the bootmeths are incomplete.
> > >
> > > Also there is currently no internal mechanism to enumerate buses in order
> > > to discover bootdevs, e.g. with USB.
> > >
> > > This series addresses these shortcomings:
> > >
> > > - Adds the concept of a 'bootdev hunter' to enumerate buses, etc. in an
> > >    effort to find bootdevs of a certain priority
> > > - Adds bootdevs for SCSI, IDE, NVMe, virtio, SPI flash
> > > - Handles PXE and DHCP properly
> > > - Supports reading the device tree with EFI and reading scripts from the
> > >    network
> > >
> > > It also tidies up label processing, so it is possible to use:
> > >
> > >     bootflow scan mmc2
> > >
> > > to scan just one MMC device (with BOOTSTD_FULL).
> > >
> > > As before this implementation still relies on CONFIG_CMDLINE being
> > > enabled, mostly for the network stack. Further work would be required to
> > > disentangle that.
> > >
> > > Quite a few tests are added but there are some gaps:
> > >
> > > - SPI flash bootdev
> > > - EFI FDT loading
> > >
> > > Note that SATA works via SCSI (CONFIG_SCSI_AHCI) and does not use
> > > driver model. Only pogo_v4 seems to be affected. Probably all thats is
> > > needed is to call bootdev_setup_sibling_blk() in the Marvell SATA driver.
> > >
> > > Also, while it would be possible to init MMC in a bootdev hunter, there is
> > > no point since U-Boot always inits MMC on startup, if present.
> > >
> > > With this series it should be possible to migrate boards to standard boot
> > > by removing the inclusion of config_distro_bootcmd.h and instead adding
> > > a suitable value for boot_targets to the environment, e.g.:
> > >
> > >     boot_targets=mmc1 mmc0 nvme scsi usb pxe dhcp spi
> >
> > Does nvme mean all nvme drives? Would mmc mean all mmc block devices?
> >

Yes it means to scan all. It is controlled by flags:

 * @BOOTFLOWF_SINGLE_UCLASS: (internal) Keep scanning through all devices in
 * this uclass (used with things like "mmc")
 * @BOOTFLOWF_SINGLE_MEDIA: (internal) Scan one media device in the uclass (used
 * with things like "mmc1")

> > doc/develop/bootstd.rst should describe the syntax.
> >
> > On generic boards it does not make much sense to restrict scanning to
> > one instance of a block device type.
> >
> > Cf.
> > [PATCH] board: sifive: unmatched: enable booting on a second NVME device
> > https://lore.kernel.org/all/20230107223239.2387940-1-aurelien@aurel32.net/
>
> But it would still make sense to be able to specify the order in which
> those instances are scanned.

I hope that the internal/external stuff will help with this, at least
to provide a sensible default, e.g. we normally scan internal mmc
before external SD card. But that is not yet fully implemented.

Regards,
Simon

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH v2 22/71] efi: Improve logging in efi_disk
  2023-01-13 20:40     ` Tom Rini
  2023-01-13 20:49       ` Heinrich Schuchardt
@ 2023-01-13 22:40       ` Simon Glass
  2023-01-13 22:52         ` Heinrich Schuchardt
  1 sibling, 1 reply; 87+ messages in thread
From: Simon Glass @ 2023-01-13 22:40 UTC (permalink / raw)
  To: Tom Rini; +Cc: Heinrich Schuchardt, U-Boot Custodians, U-Boot Mailing List

Hi Tom, Heinrich,

On Fri, 13 Jan 2023 at 13:40, Tom Rini <trini@konsulko.com> wrote:
>
> On Fri, Jan 13, 2023 at 09:35:36PM +0100, Heinrich Schuchardt wrote:
> > On 1/8/23 03:49, Simon Glass wrote:
> > > When this fails it can be time-consuming to debug. Add some debugging
> > > to help with this. Also try to return error codes instead of just using
> > > -1.
> > >
> > > Signed-off-by: Simon Glass <sjg@chromium.org>
> > > ---
> > >
> > > (no changes since v1)
> > >
> > >   lib/efi_loader/efi_disk.c | 30 +++++++++++++++++++++---------
> > >   1 file changed, 21 insertions(+), 9 deletions(-)
> > >
> > > diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
> > > index 7ea0334083f..37123dd2474 100644
> > > --- a/lib/efi_loader/efi_disk.c
> > > +++ b/lib/efi_loader/efi_disk.c
> > > @@ -421,13 +421,16 @@ static efi_status_t efi_disk_add_dev(
> > >
> > >             if (!node) {
> > >                     ret = EFI_OUT_OF_RESOURCES;
> > > +                   log_debug("no node\n");
> >
> > Please, provide a descriptive message. I would not know what "no node"
> > might mean if I were to read it.
> >
> > There is a reason why we set ret = EFI_OUT_OF_RESOURCES?
> >
> > The caller should know what this means.
>
> There's a fine balance to be struck here. An error message should be
> grep'd through in the code, for debug messages. With CONFIG_LOG we're
> already getting file, line and function.
>

Yes, and people need to read the code to figure out what went wrong. I
did this patch because the EFI code returns the same error message for
lots of situations and logging helped me work out what was wrong.

But feel free to drop it if is isn't needed.

Regards,
Simon

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH v2 22/71] efi: Improve logging in efi_disk
  2023-01-13 22:40       ` Simon Glass
@ 2023-01-13 22:52         ` Heinrich Schuchardt
  0 siblings, 0 replies; 87+ messages in thread
From: Heinrich Schuchardt @ 2023-01-13 22:52 UTC (permalink / raw)
  To: Simon Glass; +Cc: U-Boot Custodians, U-Boot Mailing List, Tom Rini

On 1/13/23 23:40, Simon Glass wrote:
> Hi Tom, Heinrich,
>
> On Fri, 13 Jan 2023 at 13:40, Tom Rini <trini@konsulko.com> wrote:
>>
>> On Fri, Jan 13, 2023 at 09:35:36PM +0100, Heinrich Schuchardt wrote:
>>> On 1/8/23 03:49, Simon Glass wrote:
>>>> When this fails it can be time-consuming to debug. Add some debugging
>>>> to help with this. Also try to return error codes instead of just using
>>>> -1.
>>>>
>>>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>>> ---
>>>>
>>>> (no changes since v1)
>>>>
>>>>    lib/efi_loader/efi_disk.c | 30 +++++++++++++++++++++---------
>>>>    1 file changed, 21 insertions(+), 9 deletions(-)
>>>>
>>>> diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
>>>> index 7ea0334083f..37123dd2474 100644
>>>> --- a/lib/efi_loader/efi_disk.c
>>>> +++ b/lib/efi_loader/efi_disk.c
>>>> @@ -421,13 +421,16 @@ static efi_status_t efi_disk_add_dev(
>>>>
>>>>              if (!node) {
>>>>                      ret = EFI_OUT_OF_RESOURCES;
>>>> +                   log_debug("no node\n");
>>>
>>> Please, provide a descriptive message. I would not know what "no node"
>>> might mean if I were to read it.
>>>
>>> There is a reason why we set ret = EFI_OUT_OF_RESOURCES?
>>>
>>> The caller should know what this means.
>>
>> There's a fine balance to be struck here. An error message should be
>> grep'd through in the code, for debug messages. With CONFIG_LOG we're
>> already getting file, line and function.
>>
>
> Yes, and people need to read the code to figure out what went wrong. I
> did this patch because the EFI code returns the same error message for
> lots of situations and logging helped me work out what was wrong.
>
> But feel free to drop it if is isn't needed.

The patch is orthogonal to the rest of the series. I have set it to
"Changes requested", "Archived"

Best regards

Heinrich

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts
  2023-01-13 21:05     ` Simon Glass
@ 2023-01-14  1:58       ` Peter Robinson
  0 siblings, 0 replies; 87+ messages in thread
From: Peter Robinson @ 2023-01-14  1:58 UTC (permalink / raw)
  To: Simon Glass
  Cc: Mark Kettenis, Heinrich Schuchardt, u-boot-custodians,
	jh80.chung, jeffy.chen, joe.hershberger, kever.yang, marex,
	morpheus.ibis, peng.fan, philipp.tomsich, rob.herring, hl,
	u-boot, aurelien

On Fri, Jan 13, 2023 at 9:05 PM Simon Glass <sjg@chromium.org> wrote:
>
> Hi Mark, Heinrich,
>
> On Fri, 13 Jan 2023 at 13:32, Mark Kettenis <mark.kettenis@xs4all.nl> wrote:
> >
> > > Date: Fri, 13 Jan 2023 20:54:06 +0100
> > > From: Heinrich Schuchardt <xypron.glpk@gmx.de>
> > >
> > > On 1/8/23 03:49, Simon Glass wrote:
> > > > So far, standard boot does not replicate all the of the functionality
> > > > of the distro_bootcmd scripts. In particular it lacks some bootdevs and
> > > > some of the bootmeths are incomplete.
> > > >
> > > > Also there is currently no internal mechanism to enumerate buses in order
> > > > to discover bootdevs, e.g. with USB.
> > > >
> > > > This series addresses these shortcomings:
> > > >
> > > > - Adds the concept of a 'bootdev hunter' to enumerate buses, etc. in an
> > > >    effort to find bootdevs of a certain priority
> > > > - Adds bootdevs for SCSI, IDE, NVMe, virtio, SPI flash
> > > > - Handles PXE and DHCP properly
> > > > - Supports reading the device tree with EFI and reading scripts from the
> > > >    network
> > > >
> > > > It also tidies up label processing, so it is possible to use:
> > > >
> > > >     bootflow scan mmc2
> > > >
> > > > to scan just one MMC device (with BOOTSTD_FULL).
> > > >
> > > > As before this implementation still relies on CONFIG_CMDLINE being
> > > > enabled, mostly for the network stack. Further work would be required to
> > > > disentangle that.
> > > >
> > > > Quite a few tests are added but there are some gaps:
> > > >
> > > > - SPI flash bootdev
> > > > - EFI FDT loading
> > > >
> > > > Note that SATA works via SCSI (CONFIG_SCSI_AHCI) and does not use
> > > > driver model. Only pogo_v4 seems to be affected. Probably all thats is
> > > > needed is to call bootdev_setup_sibling_blk() in the Marvell SATA driver.
> > > >
> > > > Also, while it would be possible to init MMC in a bootdev hunter, there is
> > > > no point since U-Boot always inits MMC on startup, if present.
> > > >
> > > > With this series it should be possible to migrate boards to standard boot
> > > > by removing the inclusion of config_distro_bootcmd.h and instead adding
> > > > a suitable value for boot_targets to the environment, e.g.:
> > > >
> > > >     boot_targets=mmc1 mmc0 nvme scsi usb pxe dhcp spi
> > >
> > > Does nvme mean all nvme drives? Would mmc mean all mmc block devices?
> > >
>
> Yes it means to scan all. It is controlled by flags:
>
>  * @BOOTFLOWF_SINGLE_UCLASS: (internal) Keep scanning through all devices in
>  * this uclass (used with things like "mmc")
>  * @BOOTFLOWF_SINGLE_MEDIA: (internal) Scan one media device in the uclass (used
>  * with things like "mmc1")
>
> > > doc/develop/bootstd.rst should describe the syntax.
> > >
> > > On generic boards it does not make much sense to restrict scanning to
> > > one instance of a block device type.
> > >
> > > Cf.
> > > [PATCH] board: sifive: unmatched: enable booting on a second NVME device
> > > https://lore.kernel.org/all/20230107223239.2387940-1-aurelien@aurel32.net/
> >
> > But it would still make sense to be able to specify the order in which
> > those instances are scanned.
>
> I hope that the internal/external stuff will help with this, at least
> to provide a sensible default, e.g. we normally scan internal mmc
> before external SD card. But that is not yet fully implemented.

I would have thought you'd scan external first as you might have a
situation where you want to boot off external as a priority if say the
internal boot was broken.

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH v2 71/71] rockchip: Convert rockpro64-rk3399 to use standard boot
  2023-01-08  2:50 ` [PATCH v2 71/71] rockchip: Convert rockpro64-rk3399 to use standard boot Simon Glass
@ 2023-01-16  9:54   ` Kever Yang
  0 siblings, 0 replies; 87+ messages in thread
From: Kever Yang @ 2023-01-16  9:54 UTC (permalink / raw)
  To: Simon Glass, U-Boot Mailing List
  Cc: U-Boot Custodians, Jeffy Chen, Philipp Tomsich, huang lin


On 2023/1/8 10:50, Simon Glass wrote:
> Drop the use of scripts and rely on standard boot for all operation.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>

Thanks,
- Kever
> ---
>
> Changes in v2:
> - Rebase to -next
>
>   include/configs/rk3399_common.h   | 5 +----
>   include/configs/rockchip-common.h | 2 ++
>   2 files changed, 3 insertions(+), 4 deletions(-)
>
> diff --git a/include/configs/rk3399_common.h b/include/configs/rk3399_common.h
> index f0a9ab8f83c..daa8803bbf4 100644
> --- a/include/configs/rk3399_common.h
> +++ b/include/configs/rk3399_common.h
> @@ -58,15 +58,12 @@
>   #define ROCKCHIP_DEVICE_SETTINGS
>   #endif
>   
> -#include <config_distro_bootcmd.h>
> -#include <environment/distro/sf.h>
>   #define CONFIG_EXTRA_ENV_SETTINGS \
>   	ENV_MEM_LAYOUT_SETTINGS \
>   	"fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" \
>   	"partitions=" PARTS_DEFAULT \
>   	ROCKCHIP_DEVICE_SETTINGS \
> -	BOOTENV \
> -	BOOTENV_SF \
> +	"boot_targets=" BOOT_TARGETS "\0" \
>   	"altbootcmd=" \
>   		"setenv boot_syslinux_conf extlinux/extlinux-rollback.conf;" \
>   		"run distro_bootcmd\0"
> diff --git a/include/configs/rockchip-common.h b/include/configs/rockchip-common.h
> index 4c964cc3770..5a06365c760 100644
> --- a/include/configs/rockchip-common.h
> +++ b/include/configs/rockchip-common.h
> @@ -67,12 +67,14 @@
>   	BOOT_TARGET_PXE(func) \
>   	BOOT_TARGET_DHCP(func) \
>   	BOOT_TARGET_SF(func)
> +#define BOOT_TARGETS	"mmc1 mmc0 nvme scsi usb pxe dhcp spi"
>   #else
>   #define BOOT_TARGET_DEVICES(func) \
>   	BOOT_TARGET_MMC(func) \
>   	BOOT_TARGET_USB(func) \
>   	BOOT_TARGET_PXE(func) \
>   	BOOT_TARGET_DHCP(func)
> +#define BOOT_TARGETS	"mmc1 mmc0 usb pxe dhcp"
>   #endif
>   
>   #ifdef CONFIG_ARM64

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts
  2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
                   ` (70 preceding siblings ...)
  2023-01-13 19:54 ` [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Heinrich Schuchardt
@ 2023-01-17 13:57 ` Tom Rini
  2023-01-17 16:07   ` Simon Glass
  71 siblings, 1 reply; 87+ messages in thread
From: Tom Rini @ 2023-01-17 13:57 UTC (permalink / raw)
  To: Simon Glass
  Cc: U-Boot Mailing List, U-Boot Custodians, Jaehoon Chung,
	Jeffy Chen, Joe Hershberger, Kever Yang, Marek Vasut,
	Pavel Herrmann, Peng Fan, Philipp Tomsich, Rob Herring,
	huang lin

[-- Attachment #1: Type: text/plain, Size: 3116 bytes --]

On Sat, Jan 07, 2023 at 07:49:36PM -0700, Simon Glass wrote:

> So far, standard boot does not replicate all the of the functionality
> of the distro_bootcmd scripts. In particular it lacks some bootdevs and
> some of the bootmeths are incomplete.
> 
> Also there is currently no internal mechanism to enumerate buses in order
> to discover bootdevs, e.g. with USB.
> 
> This series addresses these shortcomings:
> 
> - Adds the concept of a 'bootdev hunter' to enumerate buses, etc. in an
>   effort to find bootdevs of a certain priority
> - Adds bootdevs for SCSI, IDE, NVMe, virtio, SPI flash
> - Handles PXE and DHCP properly
> - Supports reading the device tree with EFI and reading scripts from the
>   network
> 
> It also tidies up label processing, so it is possible to use:
> 
>    bootflow scan mmc2
> 
> to scan just one MMC device (with BOOTSTD_FULL).
> 
> As before this implementation still relies on CONFIG_CMDLINE being
> enabled, mostly for the network stack. Further work would be required to
> disentangle that.
> 
> Quite a few tests are added but there are some gaps:
> 
> - SPI flash bootdev
> - EFI FDT loading
> 
> Note that SATA works via SCSI (CONFIG_SCSI_AHCI) and does not use
> driver model. Only pogo_v4 seems to be affected. Probably all thats is
> needed is to call bootdev_setup_sibling_blk() in the Marvell SATA driver.
> 
> Also, while it would be possible to init MMC in a bootdev hunter, there is
> no point since U-Boot always inits MMC on startup, if present.
> 
> With this series it should be possible to migrate boards to standard boot
> by removing the inclusion of config_distro_bootcmd.h and instead adding
> a suitable value for boot_targets to the environment, e.g.:
> 
>    boot_targets=mmc1 mmc0 nvme scsi usb pxe dhcp spi
> 
> Thus it is possible to boot automatically without scripts and boards can
> use a text-based environment instead of the config.h files.
> 
> To demonstrate this, rockpro64-rk3399 is migrated to standard boot in this
> series. Full migration could probably be automated using a script, similar
> in concept to moveconfig:
> 
>    - obtain the board environment via 'make u-boot-initial-env'
>    - get the value of "boot_targets"
>    - drop config_distro_bootcmd.h from the config.h file
>    - rebuild again to get the environment without distro scripts
>    - write the environment (adding boot_targets) to board.env
>    - remove CONFIG_EXTRA_ENV_SETTINGS from the config.h file
> 
> This series is based on top of the boot menu series v3 [1].
> The tree is available at u-boot-dm/dis-working
> 
> [1] https://patchwork.ozlabs.org/project/uboot/list/?series=335364
> 
> Changes in v2:
> - Rebase to -next

A small problem is that patch 62 was missing, but I could rebase v1
easily enough. A number of other patches needed to be rebased on top of
Sean's source command updates for confs in FIT images to be used. I
thought I got this part done right as well, but most of the new tests
then failed. Please rebase again on top of current master, sorry.

-- 
Tom

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts
  2023-01-17 13:57 ` Tom Rini
@ 2023-01-17 16:07   ` Simon Glass
  0 siblings, 0 replies; 87+ messages in thread
From: Simon Glass @ 2023-01-17 16:07 UTC (permalink / raw)
  To: Tom Rini
  Cc: U-Boot Mailing List, U-Boot Custodians, Jaehoon Chung,
	Jeffy Chen, Joe Hershberger, Kever Yang, Marek Vasut,
	Pavel Herrmann, Peng Fan, Philipp Tomsich, Rob Herring,
	huang lin

Hi Tom,

On Tue, 17 Jan 2023 at 06:57, Tom Rini <trini@konsulko.com> wrote:
>
> On Sat, Jan 07, 2023 at 07:49:36PM -0700, Simon Glass wrote:
>
> > So far, standard boot does not replicate all the of the functionality
> > of the distro_bootcmd scripts. In particular it lacks some bootdevs and
> > some of the bootmeths are incomplete.
> >
> > Also there is currently no internal mechanism to enumerate buses in order
> > to discover bootdevs, e.g. with USB.
> >
> > This series addresses these shortcomings:
> >
> > - Adds the concept of a 'bootdev hunter' to enumerate buses, etc. in an
> >   effort to find bootdevs of a certain priority
> > - Adds bootdevs for SCSI, IDE, NVMe, virtio, SPI flash
> > - Handles PXE and DHCP properly
> > - Supports reading the device tree with EFI and reading scripts from the
> >   network
> >
> > It also tidies up label processing, so it is possible to use:
> >
> >    bootflow scan mmc2
> >
> > to scan just one MMC device (with BOOTSTD_FULL).
> >
> > As before this implementation still relies on CONFIG_CMDLINE being
> > enabled, mostly for the network stack. Further work would be required to
> > disentangle that.
> >
> > Quite a few tests are added but there are some gaps:
> >
> > - SPI flash bootdev
> > - EFI FDT loading
> >
> > Note that SATA works via SCSI (CONFIG_SCSI_AHCI) and does not use
> > driver model. Only pogo_v4 seems to be affected. Probably all thats is
> > needed is to call bootdev_setup_sibling_blk() in the Marvell SATA driver.
> >
> > Also, while it would be possible to init MMC in a bootdev hunter, there is
> > no point since U-Boot always inits MMC on startup, if present.
> >
> > With this series it should be possible to migrate boards to standard boot
> > by removing the inclusion of config_distro_bootcmd.h and instead adding
> > a suitable value for boot_targets to the environment, e.g.:
> >
> >    boot_targets=mmc1 mmc0 nvme scsi usb pxe dhcp spi
> >
> > Thus it is possible to boot automatically without scripts and boards can
> > use a text-based environment instead of the config.h files.
> >
> > To demonstrate this, rockpro64-rk3399 is migrated to standard boot in this
> > series. Full migration could probably be automated using a script, similar
> > in concept to moveconfig:
> >
> >    - obtain the board environment via 'make u-boot-initial-env'
> >    - get the value of "boot_targets"
> >    - drop config_distro_bootcmd.h from the config.h file
> >    - rebuild again to get the environment without distro scripts
> >    - write the environment (adding boot_targets) to board.env
> >    - remove CONFIG_EXTRA_ENV_SETTINGS from the config.h file
> >
> > This series is based on top of the boot menu series v3 [1].
> > The tree is available at u-boot-dm/dis-working
> >
> > [1] https://patchwork.ozlabs.org/project/uboot/list/?series=335364
> >
> > Changes in v2:
> > - Rebase to -next
>
> A small problem is that patch 62 was missing, but I could rebase v1
> easily enough. A number of other patches needed to be rebased on top of
> Sean's source command updates for confs in FIT images to be used. I
> thought I got this part done right as well, but most of the new tests
> then failed. Please rebase again on top of current master, sorry.

OK, thanks, testing now and will resend when done.

Regards,
Simon

^ permalink raw reply	[flat|nested] 87+ messages in thread

end of thread, other threads:[~2023-01-17 16:08 UTC | newest]

Thread overview: 87+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-08  2:49 [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Simon Glass
2023-01-08  2:49 ` [PATCH v2 01/71] dm: core: Correct ordering of uclasses IDs Simon Glass
2023-01-08  2:49 ` [PATCH v2 02/71] dm: core: Support sorting devices with dm tree Simon Glass
2023-01-08  2:49 ` [PATCH v2 03/71] dm: test: Correct assertion in dm_test_part() Simon Glass
2023-01-08  2:49 ` [PATCH v2 04/71] lib: Add a function to split a string into substrings Simon Glass
2023-01-08  2:49 ` [PATCH v2 05/71] bootstd: Remove special-case code for boot_targets Simon Glass
2023-01-08  2:49 ` [PATCH v2 06/71] bootstd: Simplify locating existing bootdevs Simon Glass
2023-01-08  2:49 ` [PATCH v2 07/71] test: Fix the help for the ut command Simon Glass
2023-01-08  2:49 ` [PATCH v2 08/71] test: Drop duplicate restore of DM state Simon Glass
2023-01-08  2:49 ` [PATCH v2 09/71] sandbox: mmc: Start off with a zeroed file Simon Glass
2023-01-08  2:49 ` [PATCH v2 10/71] vbe: Avoid a build failure when bloblist is not enabled Simon Glass
2023-01-08  2:49 ` [PATCH v2 11/71] vbe: sandbox: Drop VBE node in chosen Simon Glass
2023-01-08  2:49 ` [PATCH v2 12/71] dm: part: Update test to use mmc2 Simon Glass
2023-01-08  2:49 ` [PATCH v2 13/71] dm: test: Correct ordering of DM setup Simon Glass
2023-01-08  2:49 ` [PATCH v2 14/71] ide: Drop non-DM code for BLK Simon Glass
2023-01-08  2:49 ` [PATCH v2 15/71] dm: mmc: Use bootdev_setup_sibling_blk() Simon Glass
2023-01-08  2:49 ` [PATCH v2 16/71] bootstd: Add a default method to get bootflows Simon Glass
2023-01-08  2:49 ` [PATCH v2 17/71] sandbox: Allow ethernet to be disabled at runtime Simon Glass
2023-01-08  2:49 ` [PATCH v2 18/71] sandbox: Allow ethernet bootdevs to be disabled for tests Simon Glass
2023-01-08  2:49 ` [PATCH v2 19/71] sandbox: Enable the Ethernet bootdev Simon Glass
2023-01-08  2:49 ` [PATCH v2 20/71] lib: Support printing an error string Simon Glass
2023-01-08  2:49 ` [PATCH v2 21/71] event: Correct duplicate log message in event_notify() Simon Glass
2023-01-08  2:49 ` [PATCH v2 22/71] efi: Improve logging in efi_disk Simon Glass
2023-01-13 20:35   ` Heinrich Schuchardt
2023-01-13 20:40     ` Tom Rini
2023-01-13 20:49       ` Heinrich Schuchardt
2023-01-13 22:40       ` Simon Glass
2023-01-13 22:52         ` Heinrich Schuchardt
2023-01-08  2:49 ` [PATCH v2 23/71] bootstd: Add the concept of a bootdev hunter Simon Glass
2023-01-08  2:50 ` [PATCH v2 24/71] bootstd: Support running bootdev hunters Simon Glass
2023-01-08  2:50 ` [PATCH v2 25/71] dm: usb: Drop some dead code Simon Glass
2023-01-08  2:50 ` [PATCH v2 26/71] dm: usb: Mark the device name as alloced when binding Simon Glass
2023-01-08  2:50 ` [PATCH v2 27/71] test: Add a generic function to skip delays Simon Glass
2023-01-08  2:50 ` [PATCH v2 28/71] bootstd: Add a USB hunter Simon Glass
2023-01-08  2:50 ` [PATCH v2 29/71] bootstd: Add an MMC hunter Simon Glass
2023-01-08  2:50 ` [PATCH v2 30/71] net: Add a function to run dhcp Simon Glass
2023-01-10 17:03   ` Ramon Fried
2023-01-08  2:50 ` [PATCH v2 31/71] bootstd: Add a hunter for ethernet Simon Glass
2023-01-08  2:50 ` [PATCH v2 32/71] part: Add a function to find the first bootable partition Simon Glass
2023-01-08  2:50 ` [PATCH v2 33/71] bootstd: Only scan bootable partitions Simon Glass
2023-01-08  2:50 ` [PATCH v2 34/71] scsi: Correct allocation of block-device name Simon Glass
2023-01-08  2:50 ` [PATCH v2 35/71] scsi: Remove all children of SCSI devices before rescanning Simon Glass
2023-01-08  2:50 ` [PATCH v2 36/71] bootstd: Add a SCSI bootdev Simon Glass
2023-01-08  2:50 ` [PATCH v2 37/71] bootstd: Add an IDE bootdev Simon Glass
2023-01-08  2:50 ` [PATCH v2 38/71] bootstd: Add an NVMe bootdev Simon Glass
2023-01-08  2:50 ` [PATCH v2 39/71] virtio: Avoid repeating a long expression Simon Glass
2023-01-08  2:50 ` [PATCH v2 40/71] virtio: Fix returning -ENODEV Simon Glass
2023-01-08  2:50 ` [PATCH v2 41/71] virtio: Avoid strange behaviour on removal Simon Glass
2023-01-08  2:50 ` [PATCH v2 42/71] virtio: Add a block device Simon Glass
2023-01-08  2:50 ` [PATCH v2 43/71] bootstd: Add a virtio bootdev Simon Glass
2023-01-08  2:50 ` [PATCH v2 44/71] ata: Don't try to use non-existent ports Simon Glass
2023-01-08  2:50 ` [PATCH v2 45/71] bootstd: Rename bootdev checkers Simon Glass
2023-01-08  2:50 ` [PATCH v2 46/71] bootstd: Allow reading an EFI file from the network Simon Glass
2023-01-08  2:50 ` [PATCH v2 47/71] bootstd: Include the device tree in the bootflow Simon Glass
2023-01-08  2:50 ` [PATCH v2 48/71] bootstd: Support reading the device tree with EFI Simon Glass
2023-01-08 10:25   ` Mark Kettenis
2023-01-13 18:00     ` Simon Glass
2023-01-08  2:50 ` [PATCH v2 49/71] bootstd: Set the distro_bootpart env var with scripts Simon Glass
2023-01-08  2:50 ` [PATCH v2 50/71] bootstd: Update docs on bootmeth_try_file() for sandbox Simon Glass
2023-01-08  2:50 ` [PATCH v2 51/71] bootstd: Move label parsing into its own function Simon Glass
2023-01-08  2:50 ` [PATCH v2 52/71] bootstd: Add a new bootmeth method to set the bootflow Simon Glass
2023-01-08  2:50 ` [PATCH v2 53/71] sandbox: Allow SPI flash bootdevs to be disabled for tests Simon Glass
2023-01-08  2:50 ` [PATCH v2 54/71] bootstd: Add a SPI flash bootdev Simon Glass
2023-01-08  2:50 ` [PATCH v2 55/71] bootstd: Support reading a script from network or SPI flash Simon Glass
2023-01-08  2:50 ` [PATCH v2 56/71] bootstd: Treat DHCP and PXE as bootdev labels Simon Glass
2023-01-08  2:50 ` [PATCH v2 57/71] bootstd: Use hunters when scanning for bootflows Simon Glass
2023-01-08  2:50 ` [PATCH v2 58/71] bootstd: Allow hunting for bootdevs of a given priority Simon Glass
2023-01-08  2:50 ` [PATCH v2 59/71] bootstd: Add a new pre-scan priority for bootdevs Simon Glass
2023-01-08  2:50 ` [PATCH v2 60/71] bootstd: Allow hunting for a bootdev by label Simon Glass
2023-01-08  2:50 ` [PATCH v2 61/71] bootstd: Allow iterating to the next label in a list Simon Glass
2023-01-08  2:50 ` [PATCH v2 63/71] extension: Refactor to allow non-command usage Simon Glass
2023-01-08  2:50 ` [PATCH v2 64/71] bootstd: Add a hunter for the extension feature Simon Glass
2023-01-08  2:50 ` [PATCH v2 65/71] bootstd: Switch bootdev scanning to use labels Simon Glass
2023-01-08  2:50 ` [PATCH v2 66/71] bootstd: Allow scanning a single bootdev label Simon Glass
2023-01-08  2:50 ` [PATCH v2 67/71] bootstd: Drop the old bootflow_scan_first() Simon Glass
2023-01-08  2:50 ` [PATCH v2 68/71] bootstd: Record the bootdevs used during scanning Simon Glass
2023-01-08  2:50 ` [PATCH v2 69/71] bootstd: Add a little more logging of bootflows Simon Glass
2023-01-08  2:50 ` [PATCH v2 70/71] bootstd: Update documentation for new features Simon Glass
2023-01-08  2:50 ` [PATCH v2 71/71] rockchip: Convert rockpro64-rk3399 to use standard boot Simon Glass
2023-01-16  9:54   ` Kever Yang
2023-01-13 19:54 ` [PATCH v2 00/71] bootstd: Allow migration from distro_bootcmd scripts Heinrich Schuchardt
2023-01-13 20:32   ` Mark Kettenis
2023-01-13 21:05     ` Simon Glass
2023-01-14  1:58       ` Peter Robinson
2023-01-13 20:47   ` Tom Rini
2023-01-17 13:57 ` Tom Rini
2023-01-17 16:07   ` Simon Glass

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.