1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (c) 2013 Google, Inc 4 */ 5 6 #include <common.h> 7 #include <dm.h> 8 #include <errno.h> 9 #include <fdtdec.h> 10 #include <malloc.h> 11 #include <asm/io.h> 12 #include <dm/test.h> 13 #include <dm/root.h> 14 #include <dm/device-internal.h> 15 #include <dm/uclass-internal.h> 16 #include <dm/util.h> 17 #include <dm/lists.h> 18 #include <dm/of_access.h> 19 #include <test/ut.h> 20 21 DECLARE_GLOBAL_DATA_PTR; 22 23 static int testfdt_drv_ping(struct udevice *dev, int pingval, int *pingret) 24 { 25 const struct dm_test_pdata *pdata = dev->platdata; 26 struct dm_test_priv *priv = dev_get_priv(dev); 27 28 *pingret = pingval + pdata->ping_add; 29 priv->ping_total += *pingret; 30 31 return 0; 32 } 33 34 static const struct test_ops test_ops = { 35 .ping = testfdt_drv_ping, 36 }; 37 38 static int testfdt_ofdata_to_platdata(struct udevice *dev) 39 { 40 struct dm_test_pdata *pdata = dev_get_platdata(dev); 41 42 pdata->ping_add = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), 43 "ping-add", -1); 44 pdata->base = fdtdec_get_addr(gd->fdt_blob, dev_of_offset(dev), 45 "ping-expect"); 46 47 return 0; 48 } 49 50 static int testfdt_drv_probe(struct udevice *dev) 51 { 52 struct dm_test_priv *priv = dev_get_priv(dev); 53 54 priv->ping_total += DM_TEST_START_TOTAL; 55 56 /* 57 * If this device is on a bus, the uclass_flag will be set before 58 * calling this function. This is used by 59 * dm_test_bus_child_pre_probe_uclass(). 60 */ 61 priv->uclass_total += priv->uclass_flag; 62 63 return 0; 64 } 65 66 static const struct udevice_id testfdt_ids[] = { 67 { 68 .compatible = "denx,u-boot-fdt-test", 69 .data = DM_TEST_TYPE_FIRST }, 70 { 71 .compatible = "google,another-fdt-test", 72 .data = DM_TEST_TYPE_SECOND }, 73 { } 74 }; 75 76 U_BOOT_DRIVER(testfdt_drv) = { 77 .name = "testfdt_drv", 78 .of_match = testfdt_ids, 79 .id = UCLASS_TEST_FDT, 80 .ofdata_to_platdata = testfdt_ofdata_to_platdata, 81 .probe = testfdt_drv_probe, 82 .ops = &test_ops, 83 .priv_auto_alloc_size = sizeof(struct dm_test_priv), 84 .platdata_auto_alloc_size = sizeof(struct dm_test_pdata), 85 }; 86 87 static const struct udevice_id testfdt1_ids[] = { 88 { 89 .compatible = "denx,u-boot-fdt-test1", 90 .data = DM_TEST_TYPE_FIRST }, 91 { } 92 }; 93 94 U_BOOT_DRIVER(testfdt1_drv) = { 95 .name = "testfdt1_drv", 96 .of_match = testfdt1_ids, 97 .id = UCLASS_TEST_FDT, 98 .ofdata_to_platdata = testfdt_ofdata_to_platdata, 99 .probe = testfdt_drv_probe, 100 .ops = &test_ops, 101 .priv_auto_alloc_size = sizeof(struct dm_test_priv), 102 .platdata_auto_alloc_size = sizeof(struct dm_test_pdata), 103 .flags = DM_FLAG_PRE_RELOC, 104 }; 105 106 /* From here is the testfdt uclass code */ 107 int testfdt_ping(struct udevice *dev, int pingval, int *pingret) 108 { 109 const struct test_ops *ops = device_get_ops(dev); 110 111 if (!ops->ping) 112 return -ENOSYS; 113 114 return ops->ping(dev, pingval, pingret); 115 } 116 117 UCLASS_DRIVER(testfdt) = { 118 .name = "testfdt", 119 .id = UCLASS_TEST_FDT, 120 .flags = DM_UC_FLAG_SEQ_ALIAS, 121 }; 122 123 struct dm_testprobe_pdata { 124 int probe_err; 125 }; 126 127 static int testprobe_drv_probe(struct udevice *dev) 128 { 129 struct dm_testprobe_pdata *pdata = dev_get_platdata(dev); 130 131 return pdata->probe_err; 132 } 133 134 static const struct udevice_id testprobe_ids[] = { 135 { .compatible = "denx,u-boot-probe-test" }, 136 { } 137 }; 138 139 U_BOOT_DRIVER(testprobe_drv) = { 140 .name = "testprobe_drv", 141 .of_match = testprobe_ids, 142 .id = UCLASS_TEST_PROBE, 143 .probe = testprobe_drv_probe, 144 .platdata_auto_alloc_size = sizeof(struct dm_testprobe_pdata), 145 }; 146 147 UCLASS_DRIVER(testprobe) = { 148 .name = "testprobe", 149 .id = UCLASS_TEST_PROBE, 150 .flags = DM_UC_FLAG_SEQ_ALIAS, 151 }; 152 153 int dm_check_devices(struct unit_test_state *uts, int num_devices) 154 { 155 struct udevice *dev; 156 int ret; 157 int i; 158 159 /* 160 * Now check that the ping adds are what we expect. This is using the 161 * ping-add property in each node. 162 */ 163 for (i = 0; i < num_devices; i++) { 164 uint32_t base; 165 166 ret = uclass_get_device(UCLASS_TEST_FDT, i, &dev); 167 ut_assert(!ret); 168 169 /* 170 * Get the 'ping-expect' property, which tells us what the 171 * ping add should be. We don't use the platdata because we 172 * want to test the code that sets that up 173 * (testfdt_drv_probe()). 174 */ 175 base = fdtdec_get_addr(gd->fdt_blob, dev_of_offset(dev), 176 "ping-expect"); 177 debug("dev=%d, base=%d: %s\n", i, base, 178 fdt_get_name(gd->fdt_blob, dev_of_offset(dev), NULL)); 179 180 ut_assert(!dm_check_operations(uts, dev, base, 181 dev_get_priv(dev))); 182 } 183 184 return 0; 185 } 186 187 /* Test that FDT-based binding works correctly */ 188 static int dm_test_fdt(struct unit_test_state *uts) 189 { 190 const int num_devices = 8; 191 struct udevice *dev; 192 struct uclass *uc; 193 int ret; 194 int i; 195 196 ret = dm_scan_fdt(gd->fdt_blob, false); 197 ut_assert(!ret); 198 199 ret = uclass_get(UCLASS_TEST_FDT, &uc); 200 ut_assert(!ret); 201 202 /* These are num_devices compatible root-level device tree nodes */ 203 ut_asserteq(num_devices, list_count_items(&uc->dev_head)); 204 205 /* Each should have platform data but no private data */ 206 for (i = 0; i < num_devices; i++) { 207 ret = uclass_find_device(UCLASS_TEST_FDT, i, &dev); 208 ut_assert(!ret); 209 ut_assert(!dev_get_priv(dev)); 210 ut_assert(dev->platdata); 211 } 212 213 ut_assertok(dm_check_devices(uts, num_devices)); 214 215 return 0; 216 } 217 DM_TEST(dm_test_fdt, 0); 218 219 static int dm_test_fdt_pre_reloc(struct unit_test_state *uts) 220 { 221 struct uclass *uc; 222 int ret; 223 224 ret = dm_scan_fdt(gd->fdt_blob, true); 225 ut_assert(!ret); 226 227 ret = uclass_get(UCLASS_TEST_FDT, &uc); 228 ut_assert(!ret); 229 230 /* 231 * These are 2 pre-reloc devices: 232 * one with "u-boot,dm-pre-reloc" property (a-test node), and the other 233 * one whose driver marked with DM_FLAG_PRE_RELOC flag (h-test node). 234 */ 235 ut_asserteq(2, list_count_items(&uc->dev_head)); 236 237 return 0; 238 } 239 DM_TEST(dm_test_fdt_pre_reloc, 0); 240 241 /* Test that sequence numbers are allocated properly */ 242 static int dm_test_fdt_uclass_seq(struct unit_test_state *uts) 243 { 244 struct udevice *dev; 245 246 /* A few basic santiy tests */ 247 ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_FDT, 3, true, &dev)); 248 ut_asserteq_str("b-test", dev->name); 249 250 ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_FDT, 8, true, &dev)); 251 ut_asserteq_str("a-test", dev->name); 252 253 ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_TEST_FDT, 5, 254 true, &dev)); 255 ut_asserteq_ptr(NULL, dev); 256 257 /* Test aliases */ 258 ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 6, &dev)); 259 ut_asserteq_str("e-test", dev->name); 260 261 ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_TEST_FDT, 7, 262 true, &dev)); 263 264 /* 265 * Note that c-test nodes are not probed since it is not a top-level 266 * node 267 */ 268 ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 3, &dev)); 269 ut_asserteq_str("b-test", dev->name); 270 271 /* 272 * d-test wants sequence number 3 also, but it can't have it because 273 * b-test gets it first. 274 */ 275 ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 2, &dev)); 276 ut_asserteq_str("d-test", dev->name); 277 278 /* d-test actually gets 0 */ 279 ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 0, &dev)); 280 ut_asserteq_str("d-test", dev->name); 281 282 /* initially no one wants seq 1 */ 283 ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_TEST_FDT, 1, 284 &dev)); 285 ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev)); 286 ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 4, &dev)); 287 288 /* But now that it is probed, we can find it */ 289 ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 1, &dev)); 290 ut_asserteq_str("f-test", dev->name); 291 292 return 0; 293 } 294 DM_TEST(dm_test_fdt_uclass_seq, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 295 296 /* Test that we can find a device by device tree offset */ 297 static int dm_test_fdt_offset(struct unit_test_state *uts) 298 { 299 const void *blob = gd->fdt_blob; 300 struct udevice *dev; 301 int node; 302 303 node = fdt_path_offset(blob, "/e-test"); 304 ut_assert(node > 0); 305 ut_assertok(uclass_get_device_by_of_offset(UCLASS_TEST_FDT, node, 306 &dev)); 307 ut_asserteq_str("e-test", dev->name); 308 309 /* This node should not be bound */ 310 node = fdt_path_offset(blob, "/junk"); 311 ut_assert(node > 0); 312 ut_asserteq(-ENODEV, uclass_get_device_by_of_offset(UCLASS_TEST_FDT, 313 node, &dev)); 314 315 /* This is not a top level node so should not be probed */ 316 node = fdt_path_offset(blob, "/some-bus/c-test@5"); 317 ut_assert(node > 0); 318 ut_asserteq(-ENODEV, uclass_get_device_by_of_offset(UCLASS_TEST_FDT, 319 node, &dev)); 320 321 return 0; 322 } 323 DM_TEST(dm_test_fdt_offset, 324 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT | DM_TESTF_FLAT_TREE); 325 326 /** 327 * Test various error conditions with uclass_first_device() and 328 * uclass_next_device() 329 */ 330 static int dm_test_first_next_device(struct unit_test_state *uts) 331 { 332 struct dm_testprobe_pdata *pdata; 333 struct udevice *dev, *parent = NULL; 334 int count; 335 int ret; 336 337 /* There should be 4 devices */ 338 for (ret = uclass_first_device(UCLASS_TEST_PROBE, &dev), count = 0; 339 dev; 340 ret = uclass_next_device(&dev)) { 341 count++; 342 parent = dev_get_parent(dev); 343 } 344 ut_assertok(ret); 345 ut_asserteq(4, count); 346 347 /* Remove them and try again, with an error on the second one */ 348 ut_assertok(uclass_get_device(UCLASS_TEST_PROBE, 1, &dev)); 349 pdata = dev_get_platdata(dev); 350 pdata->probe_err = -ENOMEM; 351 device_remove(parent, DM_REMOVE_NORMAL); 352 ut_assertok(uclass_first_device(UCLASS_TEST_PROBE, &dev)); 353 ut_asserteq(-ENOMEM, uclass_next_device(&dev)); 354 ut_asserteq_ptr(dev, NULL); 355 356 /* Now an error on the first one */ 357 ut_assertok(uclass_get_device(UCLASS_TEST_PROBE, 0, &dev)); 358 pdata = dev_get_platdata(dev); 359 pdata->probe_err = -ENOENT; 360 device_remove(parent, DM_REMOVE_NORMAL); 361 ut_asserteq(-ENOENT, uclass_first_device(UCLASS_TEST_PROBE, &dev)); 362 363 return 0; 364 } 365 DM_TEST(dm_test_first_next_device, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 366 367 /** 368 * check_devices() - Check return values and pointers 369 * 370 * This runs through a full sequence of uclass_first_device_check()... 371 * uclass_next_device_check() checking that the return values and devices 372 * are correct. 373 * 374 * @uts: Test state 375 * @devlist: List of expected devices 376 * @mask: Indicates which devices should return an error. Device n should 377 * return error (-NOENT - n) if bit n is set, or no error (i.e. 0) if 378 * bit n is clear. 379 */ 380 static int check_devices(struct unit_test_state *uts, 381 struct udevice *devlist[], int mask) 382 { 383 int expected_ret; 384 struct udevice *dev; 385 int i; 386 387 expected_ret = (mask & 1) ? -ENOENT : 0; 388 mask >>= 1; 389 ut_asserteq(expected_ret, 390 uclass_first_device_check(UCLASS_TEST_PROBE, &dev)); 391 for (i = 0; i < 4; i++) { 392 ut_asserteq_ptr(devlist[i], dev); 393 expected_ret = (mask & 1) ? -ENOENT - (i + 1) : 0; 394 mask >>= 1; 395 ut_asserteq(expected_ret, uclass_next_device_check(&dev)); 396 } 397 ut_asserteq_ptr(NULL, dev); 398 399 return 0; 400 } 401 402 /* Test uclass_first_device_check() and uclass_next_device_check() */ 403 static int dm_test_first_next_ok_device(struct unit_test_state *uts) 404 { 405 struct dm_testprobe_pdata *pdata; 406 struct udevice *dev, *parent = NULL, *devlist[4]; 407 int count; 408 int ret; 409 410 /* There should be 4 devices */ 411 count = 0; 412 for (ret = uclass_first_device_check(UCLASS_TEST_PROBE, &dev); 413 dev; 414 ret = uclass_next_device_check(&dev)) { 415 ut_assertok(ret); 416 devlist[count++] = dev; 417 parent = dev_get_parent(dev); 418 } 419 ut_asserteq(4, count); 420 ut_assertok(uclass_first_device_check(UCLASS_TEST_PROBE, &dev)); 421 ut_assertok(check_devices(uts, devlist, 0)); 422 423 /* Remove them and try again, with an error on the second one */ 424 pdata = dev_get_platdata(devlist[1]); 425 pdata->probe_err = -ENOENT - 1; 426 device_remove(parent, DM_REMOVE_NORMAL); 427 ut_assertok(check_devices(uts, devlist, 1 << 1)); 428 429 /* Now an error on the first one */ 430 pdata = dev_get_platdata(devlist[0]); 431 pdata->probe_err = -ENOENT - 0; 432 device_remove(parent, DM_REMOVE_NORMAL); 433 ut_assertok(check_devices(uts, devlist, 3 << 0)); 434 435 /* Now errors on all */ 436 pdata = dev_get_platdata(devlist[2]); 437 pdata->probe_err = -ENOENT - 2; 438 pdata = dev_get_platdata(devlist[3]); 439 pdata->probe_err = -ENOENT - 3; 440 device_remove(parent, DM_REMOVE_NORMAL); 441 ut_assertok(check_devices(uts, devlist, 0xf << 0)); 442 443 return 0; 444 } 445 DM_TEST(dm_test_first_next_ok_device, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 446 447 static const struct udevice_id fdt_dummy_ids[] = { 448 { .compatible = "denx,u-boot-fdt-dummy", }, 449 { } 450 }; 451 452 UCLASS_DRIVER(fdt_dummy) = { 453 .name = "fdt-dummy", 454 .id = UCLASS_TEST_DUMMY, 455 .flags = DM_UC_FLAG_SEQ_ALIAS, 456 }; 457 458 U_BOOT_DRIVER(fdt_dummy_drv) = { 459 .name = "fdt_dummy_drv", 460 .of_match = fdt_dummy_ids, 461 .id = UCLASS_TEST_DUMMY, 462 }; 463 464 static int dm_test_fdt_translation(struct unit_test_state *uts) 465 { 466 struct udevice *dev; 467 468 /* Some simple translations */ 469 ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, true, &dev)); 470 ut_asserteq_str("dev@0,0", dev->name); 471 ut_asserteq(0x8000, dev_read_addr(dev)); 472 473 ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 1, true, &dev)); 474 ut_asserteq_str("dev@1,100", dev->name); 475 ut_asserteq(0x9000, dev_read_addr(dev)); 476 477 ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 2, true, &dev)); 478 ut_asserteq_str("dev@2,200", dev->name); 479 ut_asserteq(0xA000, dev_read_addr(dev)); 480 481 /* No translation for busses with #size-cells == 0 */ 482 ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 3, true, &dev)); 483 ut_asserteq_str("dev@42", dev->name); 484 ut_asserteq(0x42, dev_read_addr(dev)); 485 486 return 0; 487 } 488 DM_TEST(dm_test_fdt_translation, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 489 490 /* Test devfdt_remap_addr_index() */ 491 static int dm_test_fdt_remap_addr_flat(struct unit_test_state *uts) 492 { 493 struct udevice *dev; 494 fdt_addr_t addr; 495 void *paddr; 496 497 ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, true, &dev)); 498 499 addr = devfdt_get_addr(dev); 500 ut_asserteq(0x8000, addr); 501 502 paddr = map_physmem(addr, 0, MAP_NOCACHE); 503 ut_assertnonnull(paddr); 504 ut_asserteq_ptr(paddr, devfdt_remap_addr(dev)); 505 506 return 0; 507 } 508 DM_TEST(dm_test_fdt_remap_addr_flat, 509 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT | DM_TESTF_FLAT_TREE); 510 511 /* Test dev_remap_addr_index() */ 512 static int dm_test_fdt_remap_addr_live(struct unit_test_state *uts) 513 { 514 struct udevice *dev; 515 fdt_addr_t addr; 516 void *paddr; 517 518 ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, true, &dev)); 519 520 addr = dev_read_addr(dev); 521 ut_asserteq(0x8000, addr); 522 523 paddr = map_physmem(addr, 0, MAP_NOCACHE); 524 ut_assertnonnull(paddr); 525 ut_asserteq_ptr(paddr, dev_remap_addr(dev)); 526 527 return 0; 528 } 529 DM_TEST(dm_test_fdt_remap_addr_live, 530 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 531 532 static int dm_test_fdt_livetree_writing(struct unit_test_state *uts) 533 { 534 struct udevice *dev; 535 ofnode node; 536 537 if (!of_live_active()) { 538 printf("Live tree not active; ignore test\n"); 539 return 0; 540 } 541 542 /* Test enabling devices */ 543 544 node = ofnode_path("/usb@2"); 545 546 ut_assert(!of_device_is_available(ofnode_to_np(node))); 547 ofnode_set_enabled(node, true); 548 ut_assert(of_device_is_available(ofnode_to_np(node))); 549 550 device_bind_driver_to_node(dm_root(), "usb_sandbox", "usb@2", node, 551 &dev); 552 ut_assertok(uclass_find_device_by_seq(UCLASS_USB, 2, true, &dev)); 553 554 /* Test string property setting */ 555 556 ut_assert(device_is_compatible(dev, "sandbox,usb")); 557 ofnode_write_string(node, "compatible", "gdsys,super-usb"); 558 ut_assert(device_is_compatible(dev, "gdsys,super-usb")); 559 ofnode_write_string(node, "compatible", "sandbox,usb"); 560 ut_assert(device_is_compatible(dev, "sandbox,usb")); 561 562 /* Test setting generic properties */ 563 564 /* Non-existent in DTB */ 565 ut_asserteq(FDT_ADDR_T_NONE, dev_read_addr(dev)); 566 /* reg = 0x42, size = 0x100 */ 567 ut_assertok(ofnode_write_prop(node, "reg", 8, 568 "\x00\x00\x00\x42\x00\x00\x01\x00")); 569 ut_asserteq(0x42, dev_read_addr(dev)); 570 571 /* Test disabling devices */ 572 573 device_remove(dev, DM_REMOVE_NORMAL); 574 device_unbind(dev); 575 576 ut_assert(of_device_is_available(ofnode_to_np(node))); 577 ofnode_set_enabled(node, false); 578 ut_assert(!of_device_is_available(ofnode_to_np(node))); 579 580 return 0; 581 } 582 DM_TEST(dm_test_fdt_livetree_writing, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 583 584 static int dm_test_fdt_disable_enable_by_path(struct unit_test_state *uts) 585 { 586 ofnode node; 587 588 if (!of_live_active()) { 589 printf("Live tree not active; ignore test\n"); 590 return 0; 591 } 592 593 node = ofnode_path("/usb@2"); 594 595 /* Test enabling devices */ 596 597 ut_assert(!of_device_is_available(ofnode_to_np(node))); 598 dev_enable_by_path("/usb@2"); 599 ut_assert(of_device_is_available(ofnode_to_np(node))); 600 601 /* Test disabling devices */ 602 603 ut_assert(of_device_is_available(ofnode_to_np(node))); 604 dev_disable_by_path("/usb@2"); 605 ut_assert(!of_device_is_available(ofnode_to_np(node))); 606 607 return 0; 608 } 609 DM_TEST(dm_test_fdt_disable_enable_by_path, DM_TESTF_SCAN_PDATA | 610 DM_TESTF_SCAN_FDT); 611