[PATCH 68/71] bootstd: Record the bootdevs used during scanning

Simon Glass sjg at chromium.org
Wed Dec 7 09:51:34 CET 2022


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 at chromium.org>
---

 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 61a4f16599c..a351dc5fdf1 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 5b0bdc7e684..d96afc249cf 100644
--- a/include/bootflow.h
+++ b/include/bootflow.h
@@ -10,6 +10,10 @@
 #include <bootdev.h>
 #include <linux/list.h>
 
+enum {
+	BOOTFLOW_MAX_USED_DEVS	= 16,
+};
+
 /**
  * enum bootflow_state_t - states that a particular bootflow can be in
  *
@@ -162,7 +166,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
@@ -185,6 +191,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.rc0.267.gcb52ba06e7-goog



More information about the U-Boot mailing list