mirror of
https://xff.cz/git/u-boot/
synced 2025-09-20 18:12:11 +02:00
bootstd: Record the bootdevs used during scanning
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>
This commit is contained in:
@@ -88,6 +88,9 @@ void bootflow_iter_init(struct bootflow_iter *iter, int flags)
|
|||||||
memset(iter, '\0', sizeof(*iter));
|
memset(iter, '\0', sizeof(*iter));
|
||||||
iter->first_glob_method = -1;
|
iter->first_glob_method = -1;
|
||||||
iter->flags = flags;
|
iter->flags = flags;
|
||||||
|
|
||||||
|
/* remember the first bootdevs we see */
|
||||||
|
iter->max_devs = BOOTFLOW_MAX_USED_DEVS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bootflow_iter_uninit(struct bootflow_iter *iter)
|
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->dev = dev;
|
||||||
iter->method_flags = method_flags;
|
iter->method_flags = method_flags;
|
||||||
|
|
||||||
if ((iter->flags & (BOOTFLOWF_SHOW | BOOTFLOWF_SINGLE_DEV)) ==
|
if (IS_ENABLED(CONFIG_BOOTSTD_FULL)) {
|
||||||
BOOTFLOWF_SHOW) {
|
/* record the device for later */
|
||||||
if (dev)
|
if (dev && iter->num_devs < iter->max_devs)
|
||||||
printf("Scanning bootdev '%s':\n", dev->name);
|
iter->dev_used[iter->num_devs++] = dev;
|
||||||
else if (IS_ENABLED(CONFIG_BOOTMETH_GLOBAL) &&
|
|
||||||
ucp->flags & BOOTMETHF_GLOBAL)
|
if ((iter->flags & (BOOTFLOWF_SHOW | BOOTFLOWF_SINGLE_DEV)) ==
|
||||||
printf("Scanning global bootmeth '%s':\n",
|
BOOTFLOWF_SHOW) {
|
||||||
iter->method->name);
|
if (dev)
|
||||||
else
|
printf("Scanning bootdev '%s':\n", dev->name);
|
||||||
printf("No more bootdevs\n");
|
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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -14,6 +14,10 @@
|
|||||||
struct bootstd_priv;
|
struct bootstd_priv;
|
||||||
struct expo;
|
struct expo;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
BOOTFLOW_MAX_USED_DEVS = 16,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enum bootflow_state_t - states that a particular bootflow can be in
|
* 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
|
* @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)
|
* forward (e.g. to skip the current partition because it is not valid)
|
||||||
* -ESHUTDOWN: try next bootdev
|
* -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
|
* @labels: List of labels to scan for bootdevs
|
||||||
* @cur_label: Current label being processed
|
* @cur_label: Current label being processed
|
||||||
* @num_methods: Number of bootmeth devices in @method_order
|
* @num_methods: Number of bootmeth devices in @method_order
|
||||||
@@ -196,6 +202,8 @@ struct bootflow_iter {
|
|||||||
int first_bootable;
|
int first_bootable;
|
||||||
int err;
|
int err;
|
||||||
int num_devs;
|
int num_devs;
|
||||||
|
int max_devs;
|
||||||
|
struct udevice *dev_used[BOOTFLOW_MAX_USED_DEVS];
|
||||||
const char *const *labels;
|
const char *const *labels;
|
||||||
int cur_label;
|
int cur_label;
|
||||||
int num_methods;
|
int num_methods;
|
||||||
|
@@ -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 |
|
BOOTSTD_TEST(bootdev_test_any, UT_TESTF_DM | UT_TESTF_SCAN_FDT |
|
||||||
UT_TESTF_ETH_BOOTDEV);
|
UT_TESTF_ETH_BOOTDEV);
|
||||||
|
|
||||||
#if 0 /* disable for now */
|
|
||||||
/* Check bootdev ordering with the bootdev-order property */
|
/* Check bootdev ordering with the bootdev-order property */
|
||||||
static int bootdev_test_order(struct unit_test_state *uts)
|
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(env_set("boot_targets", NULL));
|
||||||
ut_assertok(bootflow_scan_first(NULL, NULL, &iter, 0, &bflow));
|
ut_assertok(bootflow_scan_first(NULL, NULL, &iter, 0, &bflow));
|
||||||
ut_asserteq(2, iter.num_devs);
|
ut_asserteq(2, 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("mmc1.bootdev", iter.dev_order[1]->name);
|
ut_asserteq_str("mmc1.bootdev", iter.dev_used[1]->name);
|
||||||
bootflow_iter_uninit(&iter);
|
bootflow_iter_uninit(&iter);
|
||||||
|
|
||||||
/* Use the environment variable to override it */
|
/* Use the environment variable to override it */
|
||||||
ut_assertok(env_set("boot_targets", "mmc1 mmc2"));
|
ut_assertok(env_set("boot_targets", "mmc1 mmc2"));
|
||||||
ut_assertok(bootflow_scan_first(NULL, NULL, &iter, 0, &bflow));
|
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(2, iter.num_devs);
|
||||||
ut_asserteq_str("mmc1.bootdev", iter.dev_order[0]->name);
|
ut_asserteq_str("mmc1.bootdev", iter.dev_used[0]->name);
|
||||||
ut_asserteq_str("mmc2.bootdev", iter.dev_order[1]->name);
|
ut_asserteq_str("mmc2.bootdev", iter.dev_used[1]->name);
|
||||||
bootflow_iter_uninit(&iter);
|
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)
|
* Now drop both orderings, to check the default (prioriy/sequence)
|
||||||
* ordering
|
* 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(bootstd_test_drop_bootdev_order(uts));
|
||||||
|
|
||||||
ut_assertok(bootflow_scan_first(NULL, NULL, &iter, 0, &bflow));
|
ut_assertok(bootflow_scan_first(NULL, NULL, &iter, 0, &bflow));
|
||||||
ut_asserteq(3, iter.num_devs);
|
ut_asserteq(2, 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("mmc1.bootdev", iter.dev_order[1]->name);
|
ut_asserteq_str("mmc1.bootdev", iter.dev_used[1]->name);
|
||||||
ut_asserteq_str("mmc0.bootdev", iter.dev_order[2]->name);
|
|
||||||
|
|
||||||
/*
|
ut_asserteq(-ENODEV, bootflow_scan_next(&iter, &bflow));
|
||||||
* 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_assertok(bootflow_scan_first(NULL, NULL, &iter, 0, &bflow));
|
|
||||||
ut_asserteq(3, iter.num_devs);
|
ut_asserteq(3, iter.num_devs);
|
||||||
ut_asserteq_str("mmc2.bootdev", iter.dev_order[0]->name);
|
ut_asserteq_str("mmc0.bootdev", iter.dev_used[2]->name);
|
||||||
ut_asserteq_str("mmc0.bootdev", iter.dev_order[1]->name);
|
|
||||||
ut_asserteq_str("mmc1.bootdev", iter.dev_order[2]->name);
|
|
||||||
bootflow_iter_uninit(&iter);
|
bootflow_iter_uninit(&iter);
|
||||||
|
|
||||||
return 0;
|
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 */
|
/* Check bootdev ordering with the uclass priority */
|
||||||
static int bootdev_test_prio(struct unit_test_state *uts)
|
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);
|
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 */
|
/* Start up USB which gives us three additional bootdevs */
|
||||||
usb_started = false;
|
usb_started = false;
|
||||||
ut_assertok(run_command("usb start", 0));
|
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 */
|
/* 3 MMC and 3 USB bootdevs: MMC should come before USB */
|
||||||
console_record_reset_enable();
|
console_record_reset_enable();
|
||||||
ut_assertok(bootflow_scan_first(NULL, NULL, &iter, 0, &bflow));
|
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(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",
|
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);
|
ut_asserteq_str("usb_mass_storage.lun0", blk->name);
|
||||||
|
|
||||||
/* adjust the priority of the first USB bootdev to the highest */
|
/* adjust the priority of the first USB bootdev to the highest */
|
||||||
ucp = dev_get_uclass_plat(iter.dev_order[3]);
|
ucp = dev_get_uclass_plat(iter.dev_used[3]);
|
||||||
ucp->prio = 1;
|
ucp->prio = BOOTDEVP_1_PRE_SCAN;
|
||||||
|
|
||||||
|
/* try again but enable hunting, which brings in SCSI */
|
||||||
bootflow_iter_uninit(&iter);
|
bootflow_iter_uninit(&iter);
|
||||||
ut_assertok(bootflow_scan_first(NULL, NULL, &iter, BOOTFLOWF_HUNT,
|
ut_assertok(bootflow_scan_first(NULL, NULL, &iter, BOOTFLOWF_HUNT,
|
||||||
&bflow));
|
&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",
|
ut_asserteq_str("usb_mass_storage.lun0.bootdev",
|
||||||
iter.dev_order[0]->name);
|
iter.dev_used[0]->name);
|
||||||
ut_asserteq_str("mmc2.bootdev", iter.dev_order[1]->name);
|
ut_asserteq_str("mmc2.bootdev", iter.dev_used[1]->name);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
BOOTSTD_TEST(bootdev_test_prio, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
|
BOOTSTD_TEST(bootdev_test_prio, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Check listing hunters */
|
/* Check listing hunters */
|
||||||
static int bootdev_test_hunter(struct unit_test_state *uts)
|
static int bootdev_test_hunter(struct unit_test_state *uts)
|
||||||
|
Reference in New Issue
Block a user