bootstd: Add a hunter for the extension feature

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

Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Simon Glass 2023-01-17 10:48:13 -07:00 committed by Tom Rini
parent 35ce14617e
commit 18552d2a72
4 changed files with 63 additions and 24 deletions

View file

@ -5,7 +5,9 @@
*/ */
#include <common.h> #include <common.h>
#include <bootdev.h>
#include <command.h> #include <command.h>
#include <dm.h>
#include <malloc.h> #include <malloc.h>
#include <extension_board.h> #include <extension_board.h>
#include <mapmem.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 list - lists available extension(s) board(s)\n"
"extension apply <extension number|all> - applies DT overlays corresponding to extension boards\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,
};

View file

@ -306,6 +306,7 @@ static int bootdev_test_hunter(struct unit_test_state *uts)
ut_assert_nextline("Prio Used Uclass Hunter"); ut_assert_nextline("Prio Used Uclass Hunter");
ut_assert_nextlinen("----"); ut_assert_nextlinen("----");
ut_assert_nextline(" 6 ethernet eth_bootdev"); ut_assert_nextline(" 6 ethernet eth_bootdev");
ut_assert_nextline(" 1 simple_bus (none)");
ut_assert_nextline(" 5 ide ide_bootdev"); ut_assert_nextline(" 5 ide ide_bootdev");
ut_assert_nextline(" 2 mmc mmc_bootdev"); ut_assert_nextline(" 2 mmc mmc_bootdev");
ut_assert_nextline(" 4 nvme nvme_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(" 4 spi_flash sf_bootdev");
ut_assert_nextline(" 5 usb usb_bootdev"); ut_assert_nextline(" 5 usb usb_bootdev");
ut_assert_nextline(" 4 virtio virtio_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_assert_console_end();
ut_assertok(bootdev_hunt("usb1", false)); 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"); "Bus usb@1: scanning bus usb@1 for devices... 5 USB Device(s) found");
ut_assert_console_end(); ut_assert_console_end();
/* USB is fifth in the list, so bit 6 */ /* USB is sixth in the list, so bit 7 */
ut_asserteq(BIT(6), std->hunters_used); ut_asserteq(BIT(7), std->hunters_used);
return 0; 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_nextline("Prio Used Uclass Hunter");
ut_assert_nextlinen("----"); ut_assert_nextlinen("----");
ut_assert_nextline(" 6 ethernet eth_bootdev"); 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(); ut_assert_console_end();
/* Use the MMC hunter and see that it updates */ /* 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_assertok(run_command("bootdev hunt -l", 0));
ut_assert_skip_to_line(" 5 ide ide_bootdev"); ut_assert_skip_to_line(" 5 ide ide_bootdev");
ut_assert_nextline(" 2 * mmc mmc_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(); ut_assert_console_end();
/* Scan all hunters */ /* Scan all hunters */
@ -359,6 +360,10 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
test_set_skip_delays(true); test_set_skip_delays(true);
ut_assertok(run_command("bootdev hunt", 0)); ut_assertok(run_command("bootdev hunt", 0));
ut_assert_nextline("Hunting with: ethernet"); 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("Hunting with: ide");
ut_assert_nextline("Bus 0: not available "); 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("Prio");
ut_assert_nextlinen("----"); ut_assert_nextlinen("----");
ut_assert_nextline(" 6 * ethernet eth_bootdev"); ut_assert_nextline(" 6 * ethernet eth_bootdev");
ut_assert_nextline(" 1 * simple_bus (none)");
ut_assert_nextline(" 5 * ide ide_bootdev"); ut_assert_nextline(" 5 * ide ide_bootdev");
ut_assert_nextline(" 2 * mmc mmc_bootdev"); ut_assert_nextline(" 2 * mmc mmc_bootdev");
ut_assert_nextline(" 4 * nvme nvme_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(" 4 * spi_flash sf_bootdev");
ut_assert_nextline(" 5 * usb usb_bootdev"); ut_assert_nextline(" 5 * usb usb_bootdev");
ut_assert_nextline(" 4 * virtio virtio_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_assert_console_end();
ut_asserteq(GENMASK(7, 0), std->hunters_used); ut_asserteq(GENMASK(MAX_HUNTER, 0), std->hunters_used);
return 0; 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_str("scsi.id0lun0.bootdev", dev->name);
ut_asserteq(BOOTFLOW_METHF_SINGLE_UCLASS, mflags); ut_asserteq(BOOTFLOW_METHF_SINGLE_UCLASS, mflags);
/* SCSI is fifth in the list, so bit 4 */ /* SCSI is sixth in the list, so bit 5 */
ut_asserteq(BIT(2) | BIT(4), std->hunters_used); ut_asserteq(BIT(MMC_HUNTER) | BIT(5), std->hunters_used);
ut_assertok(bootdev_next_label(&iter, &dev, &mflags)); ut_assertok(bootdev_next_label(&iter, &dev, &mflags));
ut_assert_console_end(); ut_assert_console_end();
@ -564,7 +570,7 @@ static int bootdev_test_next_label(struct unit_test_state *uts)
mflags); mflags);
/* dhcp: Ethernet is first so bit 0 */ /* 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_assertok(bootdev_next_label(&iter, &dev, &mflags));
ut_assert_console_end(); ut_assert_console_end();
@ -574,7 +580,7 @@ static int bootdev_test_next_label(struct unit_test_state *uts)
mflags); mflags);
/* pxe: Ethernet is first so bit 0 */ /* 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; mflags = 123;
ut_asserteq(-ENODEV, bootdev_next_label(&iter, &dev, &mflags)); 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(); ut_assert_console_end();
/* no change */ /* 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; 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_assertok(bootdev_next_prio(&iter, &dev));
ut_asserteq_str("mmc2.bootdev", dev->name); 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_nextline("Hunting with: mmc");
ut_assert_console_end(); 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_assertok(bootdev_next_prio(&iter, &dev));
ut_asserteq_str("mmc1.bootdev", dev->name); ut_asserteq_str("mmc1.bootdev", dev->name);
@ -663,7 +672,7 @@ static int bootdev_test_next_prio(struct unit_test_state *uts)
} while (!ret); } while (!ret);
ut_asserteq(-ENODEV, ret); ut_asserteq(-ENODEV, ret);
ut_assertnull(dev); 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_skip_to_line("Hunting with: ethernet");
ut_assert_console_end(); ut_assert_console_end();

View file

@ -51,7 +51,7 @@ static int bootflow_cmd(struct unit_test_state *uts)
console_record_reset_enable(); console_record_reset_enable();
ut_assertok(run_command("bootdev select 1", 0)); ut_assertok(run_command("bootdev select 1", 0));
ut_assert_console_end(); 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("Scanning for bootflows in bootdev 'mmc1.bootdev'");
ut_assert_nextline("Seq Method State Uclass Part Name Filename"); ut_assert_nextline("Seq Method State Uclass Part Name Filename");
ut_assert_nextlinen("---"); 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) static int bootflow_cmd_label(struct unit_test_state *uts)
{ {
console_record_reset_enable(); 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_nextline("Scanning for bootflows in bootdev 'mmc1.bootdev'");
ut_assert_skip_to_line("(1 bootflow, 1 valid)"); ut_assert_skip_to_line("(1 bootflow, 1 valid)");
ut_assert_console_end(); 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_nextline("Scanning for bootflows in bootdev 'mmc0.bootdev'");
ut_assert_skip_to_line("(0 bootflows, 0 valid)"); ut_assert_skip_to_line("(0 bootflows, 0 valid)");
ut_assert_console_end(); 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_nextline("Scanning for bootflows in bootdev 'mmc2.bootdev'");
ut_assert_skip_to_line("(0 bootflows, 0 valid)"); ut_assert_skip_to_line("(0 bootflows, 0 valid)");
ut_assert_console_end(); 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)); ut_assertok(bootstd_test_drop_bootdev_order(uts));
console_record_reset_enable(); 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("Scanning for bootflows in all bootdevs");
ut_assert_nextline("Seq Method State Uclass Part Name Filename"); ut_assert_nextline("Seq Method State Uclass Part Name Filename");
ut_assert_nextlinen("---"); 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)); ut_assertok(bootstd_test_drop_bootdev_order(uts));
console_record_reset_enable(); 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("Scanning for bootflows in all bootdevs");
ut_assert_nextline("Seq Method State Uclass Part Name Filename"); ut_assert_nextline("Seq Method State Uclass Part Name Filename");
ut_assert_nextlinen("---"); 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 */ /* We should get a single 'bootmgr' method right at the end */
bootstd_clear_glob(); bootstd_clear_glob();
console_record_reset_enable(); 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( ut_assert_skip_to_line(
" 0 efi_mgr ready (none) 0 <NULL> <NULL>"); " 0 efi_mgr ready (none) 0 <NULL> <NULL>");
ut_assert_skip_to_line("No more bootdevs"); 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(); bootstd_clear_glob();
console_record_reset_enable(); console_record_reset_enable();
ut_assertok(inject_response(uts)); 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 */ /* Try to boot the bootmgr flow, which will fail */
console_record_reset_enable(); console_record_reset_enable();
@ -419,7 +419,7 @@ static int bootflow_scan_glob_bootmeth(struct unit_test_state *uts)
*/ */
console_record_reset_enable(); console_record_reset_enable();
ut_assertok(bootmeth_set_order("efi firmware0")); 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("Scanning for bootflows in all bootdevs");
ut_assert_nextline( ut_assert_nextline(
"Seq Method State Uclass Part Name Filename"); "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_nextline("(0 bootflows, 0 valid)");
ut_assert_console_end(); 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("Scanning for bootflows in all bootdevs");
ut_assert_nextline( ut_assert_nextline(
"Seq Method State Uclass Part Name Filename"); "Seq Method State Uclass Part Name Filename");

View file

@ -20,6 +20,11 @@
#define TEST_VERSION "U-Boot v2022.04-local2" #define TEST_VERSION "U-Boot v2022.04-local2"
#define TEST_VERNUM 0x00010002 #define TEST_VERNUM 0x00010002
enum {
MAX_HUNTER = 8,
MMC_HUNTER = 3, /* ID of MMC hunter */
};
struct unit_test_state; struct unit_test_state;
/** /**