"Das U-Boot" Source Tree
at master 773 lines 25 kB view raw
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Test for bootdev functions. All start with 'bootdev' 4 * 5 * Copyright 2021 Google LLC 6 * Written by Simon Glass <sjg@chromium.org> 7 */ 8 9#include <bootstd.h> 10#include <dm.h> 11#include <bootdev.h> 12#include <bootflow.h> 13#include <mapmem.h> 14#include <os.h> 15#include <test/suites.h> 16#include <test/ut.h> 17#include "bootstd_common.h" 18 19/* Check 'bootdev list' command */ 20static int bootdev_test_cmd_list(struct unit_test_state *uts) 21{ 22 int probed; 23 24 for (probed = 0; probed < 2; probed++) { 25 int probe_ch = probed ? '+' : ' '; 26 27 ut_assertok(run_command(probed ? "bootdev list -p" : 28 "bootdev list", 0)); 29 ut_assert_nextline("Seq Probed Status Uclass Name"); 30 ut_assert_nextlinen("---"); 31 ut_assert_nextline("%3x [ %c ] %6s %-8s %s", 0, probe_ch, "OK", 32 "mmc", "mmc2.bootdev"); 33 ut_assert_nextline("%3x [ %c ] %6s %-8s %s", 1, probe_ch, "OK", 34 "mmc", "mmc1.bootdev"); 35 ut_assert_nextline("%3x [ %c ] %6s %-8s %s", 2, probe_ch, "OK", 36 "mmc", "mmc0.bootdev"); 37 ut_assert_nextlinen("---"); 38 ut_assert_nextline("(3 bootdevs)"); 39 ut_assert_console_end(); 40 } 41 42 return 0; 43} 44BOOTSTD_TEST(bootdev_test_cmd_list, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE); 45 46/* Check 'bootdev select' and 'info' commands */ 47static int bootdev_test_cmd_select(struct unit_test_state *uts) 48{ 49 struct bootstd_priv *std; 50 51 /* get access to the CLI's cur_bootdev */ 52 ut_assertok(bootstd_get_priv(&std)); 53 54 ut_asserteq(1, run_command("bootdev info", 0)); 55 ut_assert_nextlinen("Please use"); 56 ut_assert_console_end(); 57 58 /* select by sequence */ 59 ut_assertok(run_command("bootdev select 0", 0)); 60 ut_assert_console_end(); 61 62 ut_assertok(run_command("bootdev info", 0)); 63 ut_assert_nextline("Name: mmc2.bootdev"); 64 ut_assert_nextline("Sequence: 0"); 65 ut_assert_nextline("Status: Probed"); 66 ut_assert_nextline("Uclass: mmc"); 67 ut_assert_nextline("Bootflows: 0 (0 valid)"); 68 ut_assert_console_end(); 69 70 /* select by bootdev name */ 71 ut_assertok(run_command("bootdev select mmc1.bootdev", 0)); 72 ut_assert_console_end(); 73 ut_assertnonnull(std->cur_bootdev); 74 ut_asserteq_str("mmc1.bootdev", std->cur_bootdev->name); 75 76 /* select by bootdev label*/ 77 ut_assertok(run_command("bootdev select mmc1", 0)); 78 ut_assert_console_end(); 79 ut_assertnonnull(std->cur_bootdev); 80 ut_asserteq_str("mmc1.bootdev", std->cur_bootdev->name); 81 82 /* deselect */ 83 ut_assertok(run_command("bootdev select", 0)); 84 ut_assert_console_end(); 85 ut_assertnull(std->cur_bootdev); 86 87 ut_asserteq(1, run_command("bootdev info", 0)); 88 ut_assert_nextlinen("Please use"); 89 ut_assert_console_end(); 90 91 return 0; 92} 93BOOTSTD_TEST(bootdev_test_cmd_select, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE); 94 95/* Check bootdev labels */ 96static int bootdev_test_labels(struct unit_test_state *uts) 97{ 98 struct udevice *dev, *media; 99 int mflags = 0; 100 101 ut_assertok(bootdev_find_by_label("mmc2", &dev, &mflags)); 102 ut_asserteq(UCLASS_BOOTDEV, device_get_uclass_id(dev)); 103 ut_asserteq(0, mflags); 104 media = dev_get_parent(dev); 105 ut_asserteq(UCLASS_MMC, device_get_uclass_id(media)); 106 ut_asserteq_str("mmc2", media->name); 107 108 /* Check method flags */ 109 ut_assertok(bootdev_find_by_label("pxe", &dev, &mflags)); 110 ut_asserteq(BOOTFLOW_METHF_SINGLE_UCLASS | BOOTFLOW_METHF_PXE_ONLY, 111 mflags); 112 ut_assertok(bootdev_find_by_label("dhcp", &dev, &mflags)); 113 ut_asserteq(BOOTFLOW_METHF_SINGLE_UCLASS | BOOTFLOW_METHF_DHCP_ONLY, 114 mflags); 115 116 /* Check invalid uclass */ 117 ut_asserteq(-EPFNOSUPPORT, 118 bootdev_find_by_label("fred0", &dev, &mflags)); 119 120 /* Check unknown sequence number */ 121 ut_asserteq(-ENOENT, bootdev_find_by_label("mmc6", &dev, &mflags)); 122 123 return 0; 124} 125BOOTSTD_TEST(bootdev_test_labels, UTF_DM | UTF_SCAN_FDT | UTF_ETH_BOOTDEV); 126 127/* Check bootdev_find_by_any() */ 128static int bootdev_test_any(struct unit_test_state *uts) 129{ 130 struct udevice *dev, *media; 131 char *seq; 132 int mflags; 133 134 /* 135 * with ethernet enabled we have 8 devices ahead of the mmc ones: 136 * 137 * ut_assertok(run_command("bootdev list", 0)); 138 * Seq Probed Status Uclass Name 139 * --- ------ ------ -------- ------------------ 140 * 0 [ + ] OK ethernet eth@10002000.bootdev 141 * 1 [ ] OK ethernet eth@10003000.bootdev 142 * 2 [ ] OK ethernet sbe5.bootdev 143 * 3 [ ] OK ethernet eth@10004000.bootdev 144 * 4 [ ] OK ethernet phy-test-eth.bootdev 145 * 5 [ ] OK ethernet dsa-test-eth.bootdev 146 * 6 [ ] OK ethernet dsa-test@0.bootdev 147 * 7 [ ] OK ethernet dsa-test@1.bootdev 148 * 8 [ ] OK mmc mmc2.bootdev 149 * 9 [ + ] OK mmc mmc1.bootdev 150 * a [ ] OK mmc mmc0.bootdev 151 * 152 * However if DSA_SANDBOX is disabled the dsa-test@{0,1} devices 153 * are not there. 154 */ 155 if (CONFIG_IS_ENABLED(DSA_SANDBOX)) 156 seq = "8"; 157 else 158 seq = "6"; 159 160 ut_assertok(bootdev_find_by_any(seq, &dev, &mflags)); 161 ut_asserteq(UCLASS_BOOTDEV, device_get_uclass_id(dev)); 162 ut_asserteq(BOOTFLOW_METHF_SINGLE_DEV, mflags); 163 media = dev_get_parent(dev); 164 ut_asserteq(UCLASS_MMC, device_get_uclass_id(media)); 165 ut_asserteq_str("mmc2", media->name); 166 ut_assert_console_end(); 167 168 /* there should not be this many bootdevs */ 169 ut_asserteq(-ENODEV, bootdev_find_by_any("50", &dev, &mflags)); 170 ut_assert_nextline("Cannot find '50' (err=-19)"); 171 ut_assert_console_end(); 172 173 /* Check method flags */ 174 ut_assertok(bootdev_find_by_any("pxe", &dev, &mflags)); 175 ut_asserteq(BOOTFLOW_METHF_SINGLE_UCLASS | BOOTFLOW_METHF_PXE_ONLY, 176 mflags); 177 178 /* Check invalid uclass */ 179 mflags = 123; 180 ut_asserteq(-EPFNOSUPPORT, bootdev_find_by_any("fred0", &dev, &mflags)); 181 ut_assert_nextline("Cannot find bootdev 'fred0' (err=-96)"); 182 ut_asserteq(123, mflags); 183 ut_assert_console_end(); 184 185 return 0; 186} 187BOOTSTD_TEST(bootdev_test_any, UTF_DM | UTF_SCAN_FDT | UTF_ETH_BOOTDEV | 188 UTF_CONSOLE); 189 190/* 191 * Check bootdev ordering with the bootdev-order property and boot_targets 192 * environment variable 193 */ 194static int bootdev_test_order(struct unit_test_state *uts) 195{ 196 struct bootflow_iter iter; 197 struct bootflow bflow; 198 199 test_set_skip_delays(true); 200 201 /* Start up USB which gives us three additional bootdevs */ 202 bootstd_reset_usb(); 203 ut_assertok(run_command("usb start", 0)); 204 205 /* 206 * First try the order set by the bootdev-order property 207 * Like all sandbox unit tests this relies on the devicetree setting up 208 * the required devices: 209 * 210 * mmc0 - nothing connected 211 * mmc1 - connected to mmc1.img file 212 * mmc2 - nothing connected 213 */ 214 ut_assertok(env_set("boot_targets", NULL)); 215 ut_assertok(bootflow_scan_first(NULL, NULL, &iter, 0, &bflow)); 216 ut_asserteq(2, iter.num_devs); 217 ut_asserteq_str("mmc2.bootdev", iter.dev_used[0]->name); 218 ut_asserteq_str("mmc1.bootdev", iter.dev_used[1]->name); 219 bootflow_iter_uninit(&iter); 220 221 /* Use the environment variable to override it */ 222 ut_assertok(env_set("boot_targets", "mmc1 mmc2 usb")); 223 ut_assertok(bootflow_scan_first(NULL, NULL, &iter, 0, &bflow)); 224 225 /* get the usb device which has a backing file (flash1.img) */ 226 ut_asserteq(0, bootflow_scan_next(&iter, &bflow)); 227 228 ut_asserteq(-ENODEV, bootflow_scan_next(&iter, &bflow)); 229 ut_asserteq(5, iter.num_devs); 230 ut_asserteq_str("mmc1.bootdev", iter.dev_used[0]->name); 231 ut_asserteq_str("mmc2.bootdev", iter.dev_used[1]->name); 232 ut_asserteq_str("usb_mass_storage.lun0.bootdev", 233 iter.dev_used[2]->name); 234 bootflow_iter_uninit(&iter); 235 236 /* Try a single uclass */ 237 ut_assertok(env_set("boot_targets", NULL)); 238 ut_assertok(bootflow_scan_first(NULL, "mmc", &iter, 0, &bflow)); 239 ut_asserteq(2, iter.num_devs); 240 241 /* Now scan past mmc1 and make sure that only mmc0 shows up */ 242 ut_asserteq(-ENODEV, bootflow_scan_next(&iter, &bflow)); 243 ut_asserteq(3, iter.num_devs); 244 ut_asserteq_str("mmc2.bootdev", iter.dev_used[0]->name); 245 ut_asserteq_str("mmc1.bootdev", iter.dev_used[1]->name); 246 ut_asserteq_str("mmc0.bootdev", iter.dev_used[2]->name); 247 bootflow_iter_uninit(&iter); 248 249 /* Try a single uclass with boot_targets */ 250 ut_assertok(env_set("boot_targets", "mmc")); 251 ut_assertok(bootflow_scan_first(NULL, NULL, &iter, 0, &bflow)); 252 ut_asserteq(2, iter.num_devs); 253 254 /* Now scan past mmc1 and make sure that only mmc0 shows up */ 255 ut_asserteq(-ENODEV, bootflow_scan_next(&iter, &bflow)); 256 ut_asserteq(3, iter.num_devs); 257 ut_asserteq_str("mmc2.bootdev", iter.dev_used[0]->name); 258 ut_asserteq_str("mmc1.bootdev", iter.dev_used[1]->name); 259 ut_asserteq_str("mmc0.bootdev", iter.dev_used[2]->name); 260 bootflow_iter_uninit(&iter); 261 262 /* Try a single uclass with boot_targets */ 263 ut_assertok(env_set("boot_targets", "mmc usb")); 264 ut_assertok(bootflow_scan_first(NULL, NULL, &iter, 0, &bflow)); 265 ut_asserteq(2, iter.num_devs); 266 267 /* 268 * Now scan past mmc1 and make sure that the 3 USB devices show up. The 269 * first one has a backing file so returns success 270 */ 271 ut_asserteq(0, bootflow_scan_next(&iter, &bflow)); 272 ut_asserteq(-ENODEV, bootflow_scan_next(&iter, &bflow)); 273 ut_asserteq(6, iter.num_devs); 274 ut_asserteq_str("mmc2.bootdev", iter.dev_used[0]->name); 275 ut_asserteq_str("mmc1.bootdev", iter.dev_used[1]->name); 276 ut_asserteq_str("mmc0.bootdev", iter.dev_used[2]->name); 277 ut_asserteq_str("usb_mass_storage.lun0.bootdev", 278 iter.dev_used[3]->name); 279 bootflow_iter_uninit(&iter); 280 281 return 0; 282} 283BOOTSTD_TEST(bootdev_test_order, UTF_DM | UTF_SCAN_FDT); 284 285/* Check default bootdev ordering */ 286static int bootdev_test_order_default(struct unit_test_state *uts) 287{ 288 struct bootflow_iter iter; 289 struct bootflow bflow; 290 291 /* 292 * Now drop both orderings, to check the default (prioriy/sequence) 293 * ordering 294 */ 295 ut_assertok(env_set("boot_targets", NULL)); 296 ut_assertok(bootstd_test_drop_bootdev_order(uts)); 297 298 ut_assertok(bootflow_scan_first(NULL, NULL, &iter, 0, &bflow)); 299 ut_asserteq(2, iter.num_devs); 300 ut_asserteq_str("mmc2.bootdev", iter.dev_used[0]->name); 301 ut_asserteq_str("mmc1.bootdev", iter.dev_used[1]->name); 302 303 ut_asserteq(-ENODEV, bootflow_scan_next(&iter, &bflow)); 304 ut_asserteq(3, iter.num_devs); 305 ut_asserteq_str("mmc0.bootdev", iter.dev_used[2]->name); 306 bootflow_iter_uninit(&iter); 307 308 return 0; 309} 310BOOTSTD_TEST(bootdev_test_order_default, UTF_DM | UTF_SCAN_FDT); 311 312/* Check bootdev ordering with the uclass priority */ 313static int bootdev_test_prio(struct unit_test_state *uts) 314{ 315 struct bootdev_uc_plat *ucp; 316 struct bootflow_iter iter; 317 struct bootflow bflow; 318 struct udevice *blk; 319 320 test_set_skip_delays(true); 321 322 /* disable ethernet since the hunter will run dhcp */ 323 test_set_eth_enable(false); 324 325 /* Start up USB which gives us three additional bootdevs */ 326 bootstd_reset_usb(); 327 ut_assertok(run_command("usb start", 0)); 328 329 ut_assertok(bootstd_test_drop_bootdev_order(uts)); 330 331 /* 3 MMC and 3 USB bootdevs: MMC should come before USB */ 332 ut_assertok(bootflow_scan_first(NULL, NULL, &iter, 0, &bflow)); 333 334 /* get the usb device which has a backing file (flash1.img) */ 335 ut_asserteq(0, bootflow_scan_next(&iter, &bflow)); 336 337 ut_asserteq(-ENODEV, bootflow_scan_next(&iter, &bflow)); 338 ut_asserteq(6, iter.num_devs); 339 ut_asserteq_str("mmc2.bootdev", iter.dev_used[0]->name); 340 ut_asserteq_str("usb_mass_storage.lun0.bootdev", 341 iter.dev_used[3]->name); 342 343 ut_assertok(bootdev_get_sibling_blk(iter.dev_used[3], &blk)); 344 ut_asserteq_str("usb_mass_storage.lun0", blk->name); 345 346 /* adjust the priority of the first USB bootdev to the highest */ 347 ucp = dev_get_uclass_plat(iter.dev_used[3]); 348 ucp->prio = BOOTDEVP_1_PRE_SCAN; 349 350 /* try again but enable hunting, which brings in SCSI */ 351 bootflow_iter_uninit(&iter); 352 ut_assertok(bootflow_scan_first(NULL, NULL, &iter, BOOTFLOWIF_HUNT, 353 &bflow)); 354 355 /* get the usb device which has a backing file (flash1.img) */ 356 ut_asserteq(0, bootflow_scan_next(&iter, &bflow)); 357 358 ut_asserteq(-ENODEV, bootflow_scan_next(&iter, &bflow)); 359 ut_asserteq(7, iter.num_devs); 360 ut_asserteq_str("usb_mass_storage.lun0.bootdev", 361 iter.dev_used[0]->name); 362 ut_asserteq_str("mmc2.bootdev", iter.dev_used[1]->name); 363 364 return 0; 365} 366BOOTSTD_TEST(bootdev_test_prio, UTF_DM | UTF_SCAN_FDT); 367 368/* Check listing hunters */ 369static int bootdev_test_hunter(struct unit_test_state *uts) 370{ 371 struct bootstd_priv *std; 372 373 bootstd_reset_usb(); 374 test_set_skip_delays(true); 375 376 /* get access to the used hunters */ 377 ut_assertok(bootstd_get_priv(&std)); 378 379 bootdev_list_hunters(std); 380 ut_assert_nextline("Prio Used Uclass Hunter"); 381 ut_assert_nextlinen("----"); 382 ut_assert_nextline(" 6 ethernet eth_bootdev"); 383 ut_assert_nextline(" 1 simple_bus (none)"); 384 ut_assert_nextline(" 5 ide ide_bootdev"); 385 ut_assert_nextline(" 2 mmc mmc_bootdev"); 386 ut_assert_nextline(" 4 nvme nvme_bootdev"); 387 ut_assert_nextline(" 4 qfw qfw_bootdev"); 388 ut_assert_nextline(" 4 scsi scsi_bootdev"); 389 ut_assert_nextline(" 4 spi_flash sf_bootdev"); 390 ut_assert_nextline(" 5 usb usb_bootdev"); 391 ut_assert_nextline(" 4 virtio virtio_bootdev"); 392 ut_assert_nextline("(total hunters: 10)"); 393 ut_assert_console_end(); 394 395 ut_assertok(bootdev_hunt("usb1", false)); 396 ut_assert_nextline( 397 "Bus usb@1: scanning bus usb@1 for devices... 5 USB Device(s) found"); 398 ut_assert_console_end(); 399 400 /* USB is 7th in the list, so bit 8 */ 401 ut_asserteq(BIT(8), std->hunters_used); 402 403 return 0; 404} 405BOOTSTD_TEST(bootdev_test_hunter, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE); 406 407/* Check 'bootdev hunt' command */ 408static int bootdev_test_cmd_hunt(struct unit_test_state *uts) 409{ 410 struct bootstd_priv *std; 411 412 test_set_skip_delays(true); 413 bootstd_reset_usb(); 414 415 /* get access to the used hunters */ 416 ut_assertok(bootstd_get_priv(&std)); 417 418 ut_assertok(run_command("bootdev hunt -l", 0)); 419 ut_assert_nextline("Prio Used Uclass Hunter"); 420 ut_assert_nextlinen("----"); 421 ut_assert_nextline(" 6 ethernet eth_bootdev"); 422 ut_assert_skip_to_line("(total hunters: 10)"); 423 ut_assert_console_end(); 424 425 /* Use the MMC hunter and see that it updates */ 426 ut_assertok(run_command("bootdev hunt mmc", 0)); 427 ut_assertok(run_command("bootdev hunt -l", 0)); 428 ut_assert_skip_to_line(" 5 ide ide_bootdev"); 429 ut_assert_nextline(" 2 * mmc mmc_bootdev"); 430 ut_assert_skip_to_line("(total hunters: 10)"); 431 ut_assert_console_end(); 432 433 /* Scan all hunters */ 434 test_set_eth_enable(false); 435 test_set_skip_delays(true); 436 ut_assertok(run_command("bootdev hunt", 0)); 437 ut_assert_nextline("Hunting with: ethernet"); 438 439 /* This is the extension feature which has no uclass at present */ 440 ut_assert_nextline("Hunting with: simple_bus"); 441 ut_assert_nextline("Found 2 extension board(s)."); 442 ut_assert_nextline("Hunting with: ide"); 443 444 /* mmc hunter has already been used so should not run again */ 445 446 ut_assert_nextline("Hunting with: nvme"); 447 ut_assert_nextline("Hunting with: qfw"); 448 ut_assert_nextline("Hunting with: scsi"); 449 ut_assert_nextline("scanning bus for devices..."); 450 ut_assert_skip_to_line("Hunting with: spi_flash"); 451 ut_assert_nextline("Hunting with: usb"); 452 ut_assert_nextline( 453 "Bus usb@1: scanning bus usb@1 for devices... 5 USB Device(s) found"); 454 ut_assert_nextline("Hunting with: virtio"); 455 ut_assert_console_end(); 456 457 /* List available hunters */ 458 ut_assertok(run_command("bootdev hunt -l", 0)); 459 ut_assert_nextlinen("Prio"); 460 ut_assert_nextlinen("----"); 461 ut_assert_nextline(" 6 * ethernet eth_bootdev"); 462 ut_assert_nextline(" 1 * simple_bus (none)"); 463 ut_assert_nextline(" 5 * ide ide_bootdev"); 464 ut_assert_nextline(" 2 * mmc mmc_bootdev"); 465 ut_assert_nextline(" 4 * nvme nvme_bootdev"); 466 ut_assert_nextline(" 4 * qfw qfw_bootdev"); 467 ut_assert_nextline(" 4 * scsi scsi_bootdev"); 468 ut_assert_nextline(" 4 * spi_flash sf_bootdev"); 469 ut_assert_nextline(" 5 * usb usb_bootdev"); 470 ut_assert_nextline(" 4 * virtio virtio_bootdev"); 471 ut_assert_nextline("(total hunters: 10)"); 472 ut_assert_console_end(); 473 474 ut_asserteq(GENMASK(MAX_HUNTER, 0), std->hunters_used); 475 476 return 0; 477} 478BOOTSTD_TEST(bootdev_test_cmd_hunt, UTF_DM | UTF_SCAN_FDT | UTF_ETH_BOOTDEV | 479 UTF_CONSOLE); 480 481/* Check searching for bootdevs using the hunters */ 482static int bootdev_test_hunt_scan(struct unit_test_state *uts) 483{ 484 struct bootflow_iter iter; 485 struct bootstd_priv *std; 486 struct bootflow bflow; 487 488 /* get access to the used hunters */ 489 ut_assertok(bootstd_get_priv(&std)); 490 491 ut_assertok(bootstd_test_drop_bootdev_order(uts)); 492 ut_assertok(bootflow_scan_first(NULL, NULL, &iter, 493 BOOTFLOWIF_SHOW | BOOTFLOWIF_HUNT | 494 BOOTFLOWIF_SKIP_GLOBAL, &bflow)); 495 ut_asserteq(BIT(MMC_HUNTER) | BIT(1), std->hunters_used); 496 497 return 0; 498} 499BOOTSTD_TEST(bootdev_test_hunt_scan, UTF_DM | UTF_SCAN_FDT); 500 501/* Check that only bootable partitions are processed */ 502static int bootdev_test_bootable(struct unit_test_state *uts) 503{ 504 struct bootflow_iter iter; 505 struct bootflow bflow; 506 struct udevice *blk; 507 508 memset(&iter, '\0', sizeof(iter)); 509 memset(&bflow, '\0', sizeof(bflow)); 510 iter.part = 0; 511 ut_assertok(uclass_get_device_by_name(UCLASS_BLK, "mmc1.blk", &blk)); 512 iter.dev = blk; 513 ut_assertok(device_find_next_child(&iter.dev)); 514 uclass_first_device(UCLASS_BOOTMETH, &bflow.method); 515 516 /* 517 * initially we don't have any knowledge of which partitions are 518 * bootable, but mmc1 has two partitions, with the first one being 519 * bootable 520 */ 521 iter.part = 2; 522 ut_asserteq(-EINVAL, bootdev_find_in_blk(iter.dev, blk, &iter, &bflow)); 523 ut_asserteq(0, iter.first_bootable); 524 525 /* scan with part == 0 to get the partition info */ 526 iter.part = 0; 527 ut_asserteq(-ENOENT, bootdev_find_in_blk(iter.dev, blk, &iter, &bflow)); 528 ut_asserteq(1, iter.first_bootable); 529 530 /* now it will refuse to use non-bootable partitions */ 531 iter.part = 2; 532 ut_asserteq(-EINVAL, bootdev_find_in_blk(iter.dev, blk, &iter, &bflow)); 533 534 return 0; 535} 536BOOTSTD_TEST(bootdev_test_bootable, UTF_DM | UTF_SCAN_FDT); 537 538/* Check hunting for bootdev of a particular priority */ 539static int bootdev_test_hunt_prio(struct unit_test_state *uts) 540{ 541 bootstd_reset_usb(); 542 test_set_skip_delays(true); 543 544 ut_assertok(bootdev_hunt_prio(BOOTDEVP_4_SCAN_FAST, false)); 545 ut_assert_nextline("scanning bus for devices..."); 546 ut_assert_skip_to_line(" Type: Hard Disk"); 547 ut_assert_nextlinen(" Capacity:"); 548 ut_assert_console_end(); 549 550 /* now try a different priority, verbosely */ 551 ut_assertok(bootdev_hunt_prio(BOOTDEVP_5_SCAN_SLOW, true)); 552 ut_assert_nextline("Hunting with: ide"); 553 ut_assert_nextline("Hunting with: usb"); 554 ut_assert_nextline( 555 "Bus usb@1: scanning bus usb@1 for devices... 5 USB Device(s) found"); 556 ut_assert_console_end(); 557 558 return 0; 559} 560BOOTSTD_TEST(bootdev_test_hunt_prio, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE); 561 562/* Check hunting for bootdevs with a particular label */ 563static int bootdev_test_hunt_label(struct unit_test_state *uts) 564{ 565 struct udevice *dev, *old; 566 struct bootstd_priv *std; 567 int mflags; 568 569 bootstd_reset_usb(); 570 571 /* get access to the used hunters */ 572 ut_assertok(bootstd_get_priv(&std)); 573 574 /* scan an unknown uclass */ 575 old = (void *)&mflags; /* arbitrary pointer to check against dev */ 576 dev = old; 577 mflags = 123; 578 ut_asserteq(-EPFNOSUPPORT, 579 bootdev_hunt_and_find_by_label("fred", &dev, &mflags)); 580 ut_asserteq_ptr(old, dev); 581 ut_asserteq(123, mflags); 582 ut_assert_console_end(); 583 ut_asserteq(0, std->hunters_used); 584 585 /* scan an invalid mmc controllers */ 586 ut_asserteq(-ENOENT, 587 bootdev_hunt_and_find_by_label("mmc4", &dev, &mflags)); 588 ut_asserteq_ptr(old, dev); 589 ut_asserteq(123, mflags); 590 ut_assert_console_end(); 591 592 ut_assertok(bootstd_test_check_mmc_hunter(uts)); 593 594 /* scan for a particular mmc controller */ 595 ut_assertok(bootdev_hunt_and_find_by_label("mmc1", &dev, &mflags)); 596 ut_assertnonnull(dev); 597 ut_asserteq_str("mmc1.bootdev", dev->name); 598 ut_asserteq(0, mflags); 599 ut_assert_console_end(); 600 601 /* scan all of usb */ 602 test_set_skip_delays(true); 603 ut_assertok(bootdev_hunt_and_find_by_label("usb", &dev, &mflags)); 604 ut_assertnonnull(dev); 605 ut_asserteq_str("usb_mass_storage.lun0.bootdev", dev->name); 606 ut_asserteq(BOOTFLOW_METHF_SINGLE_UCLASS, mflags); 607 ut_assert_nextlinen("Bus usb@1: scanning bus usb@1"); 608 ut_assert_console_end(); 609 610 return 0; 611} 612BOOTSTD_TEST(bootdev_test_hunt_label, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE); 613 614/* Check iterating to the next label in a list */ 615static int bootdev_test_next_label(struct unit_test_state *uts) 616{ 617 const char *const labels[] = {"mmc0", "scsi", "dhcp", "pxe", NULL}; 618 struct bootflow_iter iter; 619 struct bootstd_priv *std; 620 struct bootflow bflow; 621 struct udevice *dev; 622 int mflags; 623 624 test_set_eth_enable(false); 625 626 /* get access to the used hunters */ 627 ut_assertok(bootstd_get_priv(&std)); 628 629 memset(&iter, '\0', sizeof(iter)); 630 memset(&bflow, '\0', sizeof(bflow)); 631 iter.part = 0; 632 uclass_first_device(UCLASS_BOOTMETH, &bflow.method); 633 iter.cur_label = -1; 634 iter.labels = labels; 635 636 dev = NULL; 637 mflags = 123; 638 ut_assertok(bootdev_next_label(&iter, &dev, &mflags)); 639 ut_assert_console_end(); 640 ut_assertnonnull(dev); 641 ut_asserteq_str("mmc0.bootdev", dev->name); 642 ut_asserteq(0, mflags); 643 644 ut_assertok(bootstd_test_check_mmc_hunter(uts)); 645 646 ut_assertok(bootdev_next_label(&iter, &dev, &mflags)); 647 ut_assert_nextline("scanning bus for devices..."); 648 ut_assert_skip_to_line( 649 " Capacity: 2.0 MB = 0.0 GB (4096 x 512)"); 650 ut_assert_console_end(); 651 ut_assertnonnull(dev); 652 ut_asserteq_str("scsi.id0lun0.bootdev", dev->name); 653 ut_asserteq(BOOTFLOW_METHF_SINGLE_UCLASS, mflags); 654 655 /* SCSI is 7th in the list, so bit 6 */ 656 ut_asserteq(BIT(MMC_HUNTER) | BIT(6), std->hunters_used); 657 658 ut_assertok(bootdev_next_label(&iter, &dev, &mflags)); 659 ut_assert_console_end(); 660 ut_assertnonnull(dev); 661 ut_asserteq_str("eth@10002000.bootdev", dev->name); 662 ut_asserteq(BOOTFLOW_METHF_SINGLE_UCLASS | BOOTFLOW_METHF_DHCP_ONLY, 663 mflags); 664 665 /* dhcp: Ethernet is first so bit 0 */ 666 ut_asserteq(BIT(MMC_HUNTER) | BIT(6) | BIT(0), std->hunters_used); 667 668 ut_assertok(bootdev_next_label(&iter, &dev, &mflags)); 669 ut_assert_console_end(); 670 ut_assertnonnull(dev); 671 ut_asserteq_str("eth@10002000.bootdev", dev->name); 672 ut_asserteq(BOOTFLOW_METHF_SINGLE_UCLASS | BOOTFLOW_METHF_PXE_ONLY, 673 mflags); 674 675 /* pxe: Ethernet is first so bit 0 */ 676 ut_asserteq(BIT(MMC_HUNTER) | BIT(6) | BIT(0), std->hunters_used); 677 678 mflags = 123; 679 ut_asserteq(-ENODEV, bootdev_next_label(&iter, &dev, &mflags)); 680 ut_asserteq(123, mflags); 681 ut_assert_console_end(); 682 683 /* no change */ 684 ut_asserteq(BIT(MMC_HUNTER) | BIT(6) | BIT(0), std->hunters_used); 685 686 return 0; 687} 688BOOTSTD_TEST(bootdev_test_next_label, UTF_DM | UTF_SCAN_FDT | UTF_ETH_BOOTDEV | 689 UTF_SF_BOOTDEV | UTF_CONSOLE); 690 691/* Check iterating to the next prioirty in a list */ 692static int bootdev_test_next_prio(struct unit_test_state *uts) 693{ 694 struct bootflow_iter iter; 695 struct bootstd_priv *std; 696 struct bootflow bflow; 697 struct udevice *dev; 698 int ret; 699 700 test_set_eth_enable(false); 701 test_set_skip_delays(true); 702 703 /* get access to the used hunters */ 704 ut_assertok(bootstd_get_priv(&std)); 705 706 memset(&iter, '\0', sizeof(iter)); 707 memset(&bflow, '\0', sizeof(bflow)); 708 iter.part = 0; 709 uclass_first_device(UCLASS_BOOTMETH, &bflow.method); 710 iter.cur_prio = 0; 711 iter.flags = BOOTFLOWIF_SHOW; 712 713 dev = NULL; 714 ut_assertok(bootdev_next_prio(&iter, &dev)); 715 ut_assertnonnull(dev); 716 ut_asserteq_str("mmc2.bootdev", dev->name); 717 718 /* hunt flag not set, so this should not use any hunters */ 719 ut_asserteq(0, std->hunters_used); 720 ut_assert_console_end(); 721 722 /* now try again with hunting enabled */ 723 iter.flags = BOOTFLOWIF_SHOW | BOOTFLOWIF_HUNT; 724 iter.cur_prio = 0; 725 iter.part = 0; 726 727 ut_assertok(bootdev_next_prio(&iter, &dev)); 728 ut_asserteq_str("mmc2.bootdev", dev->name); 729 ut_assert_nextline("Hunting with: simple_bus"); 730 ut_assert_nextline("Found 2 extension board(s)."); 731 ut_assert_nextline("Hunting with: mmc"); 732 ut_assert_console_end(); 733 734 ut_asserteq(BIT(MMC_HUNTER) | BIT(1), std->hunters_used); 735 736 ut_assertok(bootdev_next_prio(&iter, &dev)); 737 ut_asserteq_str("mmc1.bootdev", dev->name); 738 739 ut_assertok(bootdev_next_prio(&iter, &dev)); 740 ut_asserteq_str("mmc0.bootdev", dev->name); 741 ut_assert_console_end(); 742 743 ut_assertok(bootdev_next_prio(&iter, &dev)); 744 ut_asserteq_str("spi.bin@0.bootdev", dev->name); 745 ut_assert_skip_to_line("Hunting with: spi_flash"); 746 747 /* 748 * this scans all bootdevs of priority BOOTDEVP_4_SCAN_FAST before it 749 * starts looking at the devices, so we se virtio as well 750 */ 751 ut_assert_nextline("Hunting with: virtio"); 752 ut_assert_nextlinen("SF: Detected m25p16"); 753 754 ut_assertok(bootdev_next_prio(&iter, &dev)); 755 ut_asserteq_str("spi.bin@1.bootdev", dev->name); 756 ut_assert_nextlinen("SF: Detected m25p16"); 757 ut_assert_console_end(); 758 759 /* keep going until there are no more bootdevs */ 760 do { 761 ret = bootdev_next_prio(&iter, &dev); 762 } while (!ret); 763 ut_asserteq(-ENODEV, ret); 764 ut_assertnull(dev); 765 ut_asserteq(GENMASK(MAX_HUNTER, 0), std->hunters_used); 766 767 ut_assert_skip_to_line("Hunting with: ethernet"); 768 ut_assert_console_end(); 769 770 return 0; 771} 772BOOTSTD_TEST(bootdev_test_next_prio, UTF_DM | UTF_SCAN_FDT | UTF_SF_BOOTDEV | 773 UTF_CONSOLE);