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