From eacc261178b9c8024cb8de89ee4ca6c68d80d96a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 17 Jan 2023 10:48:08 -0700 Subject: [PATCH] bootstd: Add a new pre-scan priority for bootdevs 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 --- 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 e868615..5ed310c 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 1ccc494..bfa8cbd 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 80c8b64..1ad9b6c 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 300208f..b57b8a6 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 2272e85..d6b47b1 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 7a8ff06..f3af6a2 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 2367b33..991013f 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 66d0b6a..32919f9 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 27efac0..91af412 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 b7973fa..65d14f2 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 bcbb35a..13e5fcd 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 f965363..86607f7 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.7.4