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