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