1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright 2022 Google LLC 4 * 5 * There are two types of tests in this file: 6 * - normal ones which act on the control FDT (gd->fdt_blob or gd->of_root) 7 * - 'other' ones which act on the 'other' FDT (other.dts) 8 * 9 * The 'other' ones have an _ot suffix. 10 * 11 * The latter are used to check behaviour with multiple device trees, 12 * particularly with flat tree, where a tree ID is included in ofnode as part of 13 * the node offset. These tests are typically just for making sure that the 14 * offset makes it to libfdt correctly and that the resulting return value is 15 * correctly turned into an ofnode. The 'other' tests do not fully check the 16 * behaviour of each ofnode function, since that is done by the normal ones. 17 */ 18 19#include <common.h> 20#include <abuf.h> 21#include <dm.h> 22#include <log.h> 23#include <of_live.h> 24#include <dm/device-internal.h> 25#include <dm/lists.h> 26#include <dm/of_extra.h> 27#include <dm/root.h> 28#include <dm/test.h> 29#include <dm/uclass-internal.h> 30#include <linux/sizes.h> 31#include <test/test.h> 32#include <test/ut.h> 33 34/** 35 * get_other_oftree() - Convert a flat tree into an oftree object 36 * 37 * @uts: Test state 38 * @return: oftree object for the 'other' FDT (see sandbox' other.dts) 39 */ 40oftree get_other_oftree(struct unit_test_state *uts) 41{ 42 oftree tree; 43 44 if (of_live_active()) 45 tree = oftree_from_np(uts->of_other); 46 else 47 tree = oftree_from_fdt(uts->other_fdt); 48 49 /* An invalid tree may cause failure or crashes */ 50 if (!oftree_valid(tree)) 51 ut_reportf("test needs the UT_TESTF_OTHER_FDT flag"); 52 53 return tree; 54} 55 56/** 57 * get_oftree() - Convert a flat tree into an oftree object 58 * 59 * @uts: Test state 60 * @fdt: Pointer to flat tree 61 * @treep: Returns the tree, on success 62 * Return: 0 if OK, 1 if the tree failed to unflatten, -EOVERFLOW if there are 63 * too many flat trees to allow another one to be registers (see 64 * oftree_ensure()) 65 */ 66int get_oftree(struct unit_test_state *uts, void *fdt, oftree *treep) 67{ 68 oftree tree; 69 70 if (of_live_active()) { 71 struct device_node *root; 72 73 ut_assertok(unflatten_device_tree(fdt, &root)); 74 tree = oftree_from_np(root); 75 } else { 76 tree = oftree_from_fdt(fdt); 77 if (!oftree_valid(tree)) 78 return -EOVERFLOW; 79 } 80 *treep = tree; 81 82 return 0; 83} 84 85/** 86 * free_oftree() - Free memory used by get_oftree() 87 * 88 * @tree: Tree to free 89 */ 90void free_oftree(oftree tree) 91{ 92 if (of_live_active()) 93 free(tree.np); 94} 95 96/* test ofnode_device_is_compatible() */ 97static int dm_test_ofnode_compatible(struct unit_test_state *uts) 98{ 99 ofnode root_node = ofnode_path("/"); 100 101 ut_assert(ofnode_valid(root_node)); 102 ut_assert(ofnode_device_is_compatible(root_node, "sandbox")); 103 104 return 0; 105} 106DM_TEST(dm_test_ofnode_compatible, 107 UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); 108 109/* check ofnode_device_is_compatible() with the 'other' FDT */ 110static int dm_test_ofnode_compatible_ot(struct unit_test_state *uts) 111{ 112 oftree otree = get_other_oftree(uts); 113 ofnode oroot = oftree_root(otree); 114 115 ut_assert(ofnode_valid(oroot)); 116 ut_assert(ofnode_device_is_compatible(oroot, "sandbox-other")); 117 118 return 0; 119} 120DM_TEST(dm_test_ofnode_compatible_ot, UT_TESTF_SCAN_FDT | UT_TESTF_OTHER_FDT); 121 122static int dm_test_ofnode_get_by_phandle(struct unit_test_state *uts) 123{ 124 /* test invalid phandle */ 125 ut_assert(!ofnode_valid(ofnode_get_by_phandle(0))); 126 ut_assert(!ofnode_valid(ofnode_get_by_phandle(-1))); 127 128 /* test first valid phandle */ 129 ut_assert(ofnode_valid(ofnode_get_by_phandle(1))); 130 131 /* test unknown phandle */ 132 ut_assert(!ofnode_valid(ofnode_get_by_phandle(0x1000000))); 133 134 ut_assert(ofnode_valid(oftree_get_by_phandle(oftree_default(), 1))); 135 136 return 0; 137} 138DM_TEST(dm_test_ofnode_get_by_phandle, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); 139 140/* test oftree_get_by_phandle() with a the 'other' oftree */ 141static int dm_test_ofnode_get_by_phandle_ot(struct unit_test_state *uts) 142{ 143 oftree otree = get_other_oftree(uts); 144 ofnode node; 145 146 ut_assert(ofnode_valid(oftree_get_by_phandle(oftree_default(), 1))); 147 node = oftree_get_by_phandle(otree, 1); 148 ut_assert(ofnode_valid(node)); 149 ut_asserteq_str("target", ofnode_get_name(node)); 150 151 return 0; 152} 153DM_TEST(dm_test_ofnode_get_by_phandle_ot, 154 UT_TESTF_SCAN_FDT | UT_TESTF_OTHER_FDT); 155 156static int check_prop_values(struct unit_test_state *uts, ofnode start, 157 const char *propname, const char *propval, 158 int expect_count) 159{ 160 int proplen = strlen(propval) + 1; 161 const char *str; 162 ofnode node; 163 int count; 164 165 /* Find first matching node, there should be at least one */ 166 node = ofnode_by_prop_value(start, propname, propval, proplen); 167 ut_assert(ofnode_valid(node)); 168 str = ofnode_read_string(node, propname); 169 ut_assert(str && !strcmp(str, propval)); 170 171 /* Find the rest of the matching nodes */ 172 count = 1; 173 while (true) { 174 node = ofnode_by_prop_value(node, propname, propval, proplen); 175 if (!ofnode_valid(node)) 176 break; 177 str = ofnode_read_string(node, propname); 178 ut_asserteq_str(propval, str); 179 count++; 180 } 181 ut_asserteq(expect_count, count); 182 183 return 0; 184} 185 186static int dm_test_ofnode_by_prop_value(struct unit_test_state *uts) 187{ 188 ut_assertok(check_prop_values(uts, ofnode_null(), "compatible", 189 "denx,u-boot-fdt-test", 11)); 190 191 return 0; 192} 193DM_TEST(dm_test_ofnode_by_prop_value, UT_TESTF_SCAN_FDT); 194 195/* test ofnode_by_prop_value() with a the 'other' oftree */ 196static int dm_test_ofnode_by_prop_value_ot(struct unit_test_state *uts) 197{ 198 oftree otree = get_other_oftree(uts); 199 200 ut_assertok(check_prop_values(uts, oftree_root(otree), "str-prop", 201 "other", 2)); 202 203 return 0; 204} 205DM_TEST(dm_test_ofnode_by_prop_value_ot, 206 UT_TESTF_SCAN_FDT | UT_TESTF_OTHER_FDT); 207 208/* test ofnode_read_fmap_entry() */ 209static int dm_test_ofnode_fmap(struct unit_test_state *uts) 210{ 211 struct fmap_entry entry; 212 ofnode node; 213 214 node = ofnode_path("/cros-ec/flash"); 215 ut_assert(ofnode_valid(node)); 216 ut_assertok(ofnode_read_fmap_entry(node, &entry)); 217 ut_asserteq(0x08000000, entry.offset); 218 ut_asserteq(0x20000, entry.length); 219 220 return 0; 221} 222DM_TEST(dm_test_ofnode_fmap, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); 223 224/* test ofnode_read_prop() */ 225static int dm_test_ofnode_read(struct unit_test_state *uts) 226{ 227 const u32 *val; 228 ofnode node; 229 int size; 230 231 node = oftree_path(oftree_default(), "/"); 232 ut_assert(ofnode_valid(node)); 233 234 node = ofnode_path("/a-test"); 235 ut_assert(ofnode_valid(node)); 236 237 val = ofnode_read_prop(node, "int-value", &size); 238 ut_assertnonnull(val); 239 ut_asserteq(4, size); 240 ut_asserteq(1234, fdt32_to_cpu(val[0])); 241 242 val = ofnode_read_prop(node, "missing", &size); 243 ut_assertnull(val); 244 ut_asserteq(-FDT_ERR_NOTFOUND, size); 245 246 /* Check it works without a size parameter */ 247 val = ofnode_read_prop(node, "missing", NULL); 248 ut_assertnull(val); 249 250 return 0; 251} 252DM_TEST(dm_test_ofnode_read, UT_TESTF_SCAN_FDT); 253 254/* test ofnode_read_prop() with the 'other' tree */ 255static int dm_test_ofnode_read_ot(struct unit_test_state *uts) 256{ 257 oftree otree = get_other_oftree(uts); 258 const char *val; 259 ofnode node; 260 int size; 261 262 node = oftree_path(otree, "/"); 263 ut_assert(ofnode_valid(node)); 264 265 node = oftree_path(otree, "/node/subnode"); 266 ut_assert(ofnode_valid(node)); 267 268 val = ofnode_read_prop(node, "str-prop", &size); 269 ut_assertnonnull(val); 270 ut_asserteq_str("other", val); 271 ut_asserteq(6, size); 272 273 return 0; 274} 275DM_TEST(dm_test_ofnode_read_ot, UT_TESTF_SCAN_FDT | UT_TESTF_OTHER_FDT); 276 277/* test ofnode_count_/parse_phandle_with_args() */ 278static int dm_test_ofnode_phandle(struct unit_test_state *uts) 279{ 280 struct ofnode_phandle_args args; 281 ofnode node; 282 int ret; 283 const char prop[] = "test-gpios"; 284 const char cell[] = "#gpio-cells"; 285 const char prop2[] = "phandle-value"; 286 287 node = ofnode_path("/a-test"); 288 ut_assert(ofnode_valid(node)); 289 290 /* Test ofnode_count_phandle_with_args with cell name */ 291 ret = ofnode_count_phandle_with_args(node, "missing", cell, 0); 292 ut_asserteq(-ENOENT, ret); 293 ret = ofnode_count_phandle_with_args(node, prop, "#invalid", 0); 294 ut_asserteq(-EINVAL, ret); 295 ret = ofnode_count_phandle_with_args(node, prop, cell, 0); 296 ut_asserteq(5, ret); 297 298 /* Test ofnode_parse_phandle_with_args with cell name */ 299 ret = ofnode_parse_phandle_with_args(node, "missing", cell, 0, 0, 300 &args); 301 ut_asserteq(-ENOENT, ret); 302 ret = ofnode_parse_phandle_with_args(node, prop, "#invalid", 0, 0, 303 &args); 304 ut_asserteq(-EINVAL, ret); 305 ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 0, &args); 306 ut_assertok(ret); 307 ut_asserteq(1, args.args_count); 308 ut_asserteq(1, args.args[0]); 309 ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 1, &args); 310 ut_assertok(ret); 311 ut_asserteq(1, args.args_count); 312 ut_asserteq(4, args.args[0]); 313 ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 2, &args); 314 ut_assertok(ret); 315 ut_asserteq(5, args.args_count); 316 ut_asserteq(5, args.args[0]); 317 ut_asserteq(1, args.args[4]); 318 ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 3, &args); 319 ut_asserteq(-ENOENT, ret); 320 ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 4, &args); 321 ut_assertok(ret); 322 ut_asserteq(1, args.args_count); 323 ut_asserteq(12, args.args[0]); 324 ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 5, &args); 325 ut_asserteq(-ENOENT, ret); 326 327 /* Test ofnode_count_phandle_with_args with cell count */ 328 ret = ofnode_count_phandle_with_args(node, "missing", NULL, 2); 329 ut_asserteq(-ENOENT, ret); 330 ret = ofnode_count_phandle_with_args(node, prop2, NULL, 1); 331 ut_asserteq(3, ret); 332 333 /* Test ofnode_parse_phandle_with_args with cell count */ 334 ret = ofnode_parse_phandle_with_args(node, prop2, NULL, 1, 0, &args); 335 ut_assertok(ret); 336 ut_asserteq(1, ofnode_valid(args.node)); 337 ut_asserteq(1, args.args_count); 338 ut_asserteq(10, args.args[0]); 339 ret = ofnode_parse_phandle_with_args(node, prop2, NULL, 1, 1, &args); 340 ut_asserteq(-EINVAL, ret); 341 ret = ofnode_parse_phandle_with_args(node, prop2, NULL, 1, 2, &args); 342 ut_assertok(ret); 343 ut_asserteq(1, ofnode_valid(args.node)); 344 ut_asserteq(1, args.args_count); 345 ut_asserteq(30, args.args[0]); 346 ret = ofnode_parse_phandle_with_args(node, prop2, NULL, 1, 3, &args); 347 ut_asserteq(-ENOENT, ret); 348 349 return 0; 350} 351DM_TEST(dm_test_ofnode_phandle, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); 352 353/* test ofnode_count_/parse_phandle_with_args() with 'other' tree */ 354static int dm_test_ofnode_phandle_ot(struct unit_test_state *uts) 355{ 356 oftree otree = get_other_oftree(uts); 357 struct ofnode_phandle_args args; 358 ofnode node; 359 int ret; 360 361 node = oftree_path(otree, "/node"); 362 363 /* Test ofnode_count_phandle_with_args with cell name */ 364 ret = ofnode_count_phandle_with_args(node, "missing", "#gpio-cells", 0); 365 ut_asserteq(-ENOENT, ret); 366 ret = ofnode_count_phandle_with_args(node, "target", "#invalid", 0); 367 ut_asserteq(-EINVAL, ret); 368 ret = ofnode_count_phandle_with_args(node, "target", "#gpio-cells", 0); 369 ut_asserteq(1, ret); 370 371 ret = ofnode_parse_phandle_with_args(node, "target", "#gpio-cells", 0, 372 0, &args); 373 ut_assertok(ret); 374 ut_asserteq(2, args.args_count); 375 ut_asserteq(3, args.args[0]); 376 ut_asserteq(4, args.args[1]); 377 378 return 0; 379} 380DM_TEST(dm_test_ofnode_phandle_ot, UT_TESTF_OTHER_FDT); 381 382/* test ofnode_read_chosen_string/node/prop() */ 383static int dm_test_ofnode_read_chosen(struct unit_test_state *uts) 384{ 385 const char *str; 386 const u32 *val; 387 ofnode node; 388 int size; 389 390 str = ofnode_read_chosen_string("setting"); 391 ut_assertnonnull(str); 392 ut_asserteq_str("sunrise ohoka", str); 393 ut_asserteq_ptr(NULL, ofnode_read_chosen_string("no-setting")); 394 395 node = ofnode_get_chosen_node("other-node"); 396 ut_assert(ofnode_valid(node)); 397 ut_asserteq_str("c-test@5", ofnode_get_name(node)); 398 399 node = ofnode_get_chosen_node("setting"); 400 ut_assert(!ofnode_valid(node)); 401 402 val = ofnode_read_chosen_prop("int-values", &size); 403 ut_assertnonnull(val); 404 ut_asserteq(8, size); 405 ut_asserteq(0x1937, fdt32_to_cpu(val[0])); 406 ut_asserteq(72993, fdt32_to_cpu(val[1])); 407 408 return 0; 409} 410DM_TEST(dm_test_ofnode_read_chosen, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); 411 412/* test ofnode_get_aliases_node/prop() */ 413static int dm_test_ofnode_read_aliases(struct unit_test_state *uts) 414{ 415 const void *val; 416 ofnode node; 417 int size; 418 419 node = ofnode_get_aliases_node("ethernet3"); 420 ut_assert(ofnode_valid(node)); 421 ut_asserteq_str("sbe5", ofnode_get_name(node)); 422 423 node = ofnode_get_aliases_node("unknown"); 424 ut_assert(!ofnode_valid(node)); 425 426 val = ofnode_read_aliases_prop("spi0", &size); 427 ut_assertnonnull(val); 428 ut_asserteq(7, size); 429 ut_asserteq_str("/spi@0", (const char *)val); 430 431 return 0; 432} 433DM_TEST(dm_test_ofnode_read_aliases, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); 434 435static int dm_test_ofnode_get_child_count(struct unit_test_state *uts) 436{ 437 ofnode node, child_node; 438 u32 val; 439 440 node = ofnode_path("/i-test"); 441 ut_assert(ofnode_valid(node)); 442 443 val = ofnode_get_child_count(node); 444 ut_asserteq(3, val); 445 446 child_node = ofnode_first_subnode(node); 447 ut_assert(ofnode_valid(child_node)); 448 val = ofnode_get_child_count(child_node); 449 ut_asserteq(0, val); 450 451 return 0; 452} 453DM_TEST(dm_test_ofnode_get_child_count, 454 UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); 455 456/* test ofnode_get_child_count() with 'other' tree */ 457static int dm_test_ofnode_get_child_count_ot(struct unit_test_state *uts) 458{ 459 oftree otree = get_other_oftree(uts); 460 ofnode node, child_node; 461 u32 val; 462 463 node = oftree_path(otree, "/node"); 464 ut_assert(ofnode_valid(node)); 465 466 val = ofnode_get_child_count(node); 467 ut_asserteq(2, val); 468 469 child_node = ofnode_first_subnode(node); 470 ut_assert(ofnode_valid(child_node)); 471 val = ofnode_get_child_count(child_node); 472 ut_asserteq(0, val); 473 474 return 0; 475} 476DM_TEST(dm_test_ofnode_get_child_count_ot, 477 UT_TESTF_SCAN_FDT | UT_TESTF_OTHER_FDT); 478 479static int dm_test_ofnode_is_enabled(struct unit_test_state *uts) 480{ 481 ofnode root_node = ofnode_path("/"); 482 ofnode node = ofnode_path("/usb@0"); 483 484 ut_assert(ofnode_is_enabled(root_node)); 485 ut_assert(!ofnode_is_enabled(node)); 486 487 return 0; 488} 489DM_TEST(dm_test_ofnode_is_enabled, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); 490 491/* test ofnode_is_enabled() with 'other' tree */ 492static int dm_test_ofnode_is_enabled_ot(struct unit_test_state *uts) 493{ 494 oftree otree = get_other_oftree(uts); 495 ofnode root_node = oftree_root(otree); 496 ofnode node = oftree_path(otree, "/target"); 497 498 ut_assert(ofnode_is_enabled(root_node)); 499 ut_assert(!ofnode_is_enabled(node)); 500 501 return 0; 502} 503DM_TEST(dm_test_ofnode_is_enabled_ot, UT_TESTF_OTHER_FDT); 504 505/* test ofnode_get_addr/size() */ 506static int dm_test_ofnode_get_reg(struct unit_test_state *uts) 507{ 508 ofnode node; 509 fdt_addr_t addr; 510 fdt_size_t size; 511 512 node = ofnode_path("/translation-test@8000"); 513 ut_assert(ofnode_valid(node)); 514 addr = ofnode_get_addr(node); 515 size = ofnode_get_size(node); 516 ut_asserteq(0x8000, addr); 517 ut_asserteq(0x4000, size); 518 519 node = ofnode_path("/translation-test@8000/dev@1,100"); 520 ut_assert(ofnode_valid(node)); 521 addr = ofnode_get_addr(node); 522 size = ofnode_get_size(node); 523 ut_asserteq(0x9000, addr); 524 ut_asserteq(0x1000, size); 525 526 node = ofnode_path("/emul-mux-controller"); 527 ut_assert(ofnode_valid(node)); 528 addr = ofnode_get_addr(node); 529 size = ofnode_get_size(node); 530 ut_asserteq_64(FDT_ADDR_T_NONE, addr); 531 ut_asserteq(FDT_SIZE_T_NONE, size); 532 533 node = ofnode_path("/translation-test@8000/noxlatebus@3,300/dev@42"); 534 ut_assert(ofnode_valid(node)); 535 addr = ofnode_get_addr_size_index_notrans(node, 0, &size); 536 ut_asserteq_64(0x42, addr); 537 538 return 0; 539} 540DM_TEST(dm_test_ofnode_get_reg, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); 541 542/* test ofnode_get_addr() with 'other' tree */ 543static int dm_test_ofnode_get_reg_ot(struct unit_test_state *uts) 544{ 545 oftree otree = get_other_oftree(uts); 546 ofnode node = oftree_path(otree, "/target"); 547 fdt_addr_t addr; 548 549 addr = ofnode_get_addr(node); 550 ut_asserteq(0x8000, addr); 551 552 return 0; 553} 554DM_TEST(dm_test_ofnode_get_reg_ot, UT_TESTF_SCAN_FDT | UT_TESTF_OTHER_FDT); 555 556static int dm_test_ofnode_get_path(struct unit_test_state *uts) 557{ 558 const char *path = "/translation-test@8000/noxlatebus@3,300/dev@42"; 559 char buf[64]; 560 ofnode node; 561 562 node = ofnode_path(path); 563 ut_assert(ofnode_valid(node)); 564 565 ut_assertok(ofnode_get_path(node, buf, sizeof(buf))); 566 ut_asserteq_str(path, buf); 567 568 ut_asserteq(-ENOSPC, ofnode_get_path(node, buf, 32)); 569 570 ut_assertok(ofnode_get_path(ofnode_root(), buf, 32)); 571 ut_asserteq_str("/", buf); 572 573 return 0; 574} 575DM_TEST(dm_test_ofnode_get_path, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); 576 577/* test ofnode_get_path() with 'other' tree */ 578static int dm_test_ofnode_get_path_ot(struct unit_test_state *uts) 579{ 580 oftree otree = get_other_oftree(uts); 581 const char *path = "/node/subnode"; 582 ofnode node = oftree_path(otree, path); 583 char buf[64]; 584 585 ut_assert(ofnode_valid(node)); 586 587 ut_assertok(ofnode_get_path(node, buf, sizeof(buf))); 588 ut_asserteq_str(path, buf); 589 590 ut_assertok(ofnode_get_path(oftree_root(otree), buf, 32)); 591 ut_asserteq_str("/", buf); 592 593 return 0; 594} 595DM_TEST(dm_test_ofnode_get_path_ot, UT_TESTF_SCAN_FDT | UT_TESTF_OTHER_FDT); 596 597/* test ofnode_conf_read_bool/int/str() */ 598static int dm_test_ofnode_conf(struct unit_test_state *uts) 599{ 600 ut_assert(!ofnode_conf_read_bool("missing")); 601 ut_assert(ofnode_conf_read_bool("testing-bool")); 602 603 ut_asserteq(123, ofnode_conf_read_int("testing-int", 0)); 604 ut_asserteq(6, ofnode_conf_read_int("missing", 6)); 605 606 ut_assertnull(ofnode_conf_read_str("missing")); 607 ut_asserteq_str("testing", ofnode_conf_read_str("testing-str")); 608 609 return 0; 610} 611DM_TEST(dm_test_ofnode_conf, UT_TESTF_SCAN_FDT); 612 613static int dm_test_ofnode_options(struct unit_test_state *uts) 614{ 615 u64 bootscr_address, bootscr_offset; 616 u64 bootscr_flash_offset, bootscr_flash_size; 617 618 ut_assertok(ofnode_read_bootscript_address(&bootscr_address, 619 &bootscr_offset)); 620 ut_asserteq_64(0, bootscr_address); 621 ut_asserteq_64(0x12345678, bootscr_offset); 622 623 ut_assertok(ofnode_read_bootscript_flash(&bootscr_flash_offset, 624 &bootscr_flash_size)); 625 ut_asserteq_64(0, bootscr_flash_offset); 626 ut_asserteq_64(0x2000, bootscr_flash_size); 627 628 return 0; 629} 630DM_TEST(dm_test_ofnode_options, 0); 631 632static int dm_test_ofnode_for_each_compatible_node(struct unit_test_state *uts) 633{ 634 const char compatible[] = "denx,u-boot-fdt-test"; 635 bool found = false; 636 ofnode node; 637 638 ofnode_for_each_compatible_node(node, compatible) { 639 ut_assert(ofnode_device_is_compatible(node, compatible)); 640 found = true; 641 } 642 643 /* There should be at least one matching node */ 644 ut_assert(found); 645 646 return 0; 647} 648DM_TEST(dm_test_ofnode_for_each_compatible_node, UT_TESTF_SCAN_FDT); 649 650/* test dm_test_ofnode_string_count/index/list() */ 651static int dm_test_ofnode_string(struct unit_test_state *uts) 652{ 653 const char **val; 654 const char *out; 655 ofnode node; 656 657 node = ofnode_path("/a-test"); 658 ut_assert(ofnode_valid(node)); 659 660 /* single string */ 661 ut_asserteq(1, ofnode_read_string_count(node, "str-value")); 662 ut_assertok(ofnode_read_string_index(node, "str-value", 0, &out)); 663 ut_asserteq_str("test string", out); 664 ut_asserteq(0, ofnode_stringlist_search(node, "str-value", 665 "test string")); 666 ut_asserteq(1, ofnode_read_string_list(node, "str-value", &val)); 667 ut_asserteq_str("test string", val[0]); 668 ut_assertnull(val[1]); 669 free(val); 670 671 /* list of strings */ 672 ut_asserteq(5, ofnode_read_string_count(node, "mux-control-names")); 673 ut_assertok(ofnode_read_string_index(node, "mux-control-names", 0, 674 &out)); 675 ut_asserteq_str("mux0", out); 676 ut_asserteq(0, ofnode_stringlist_search(node, "mux-control-names", 677 "mux0")); 678 ut_asserteq(5, ofnode_read_string_list(node, "mux-control-names", 679 &val)); 680 ut_asserteq_str("mux0", val[0]); 681 ut_asserteq_str("mux1", val[1]); 682 ut_asserteq_str("mux2", val[2]); 683 ut_asserteq_str("mux3", val[3]); 684 ut_asserteq_str("mux4", val[4]); 685 ut_assertnull(val[5]); 686 free(val); 687 688 ut_assertok(ofnode_read_string_index(node, "mux-control-names", 4, 689 &out)); 690 ut_asserteq_str("mux4", out); 691 ut_asserteq(4, ofnode_stringlist_search(node, "mux-control-names", 692 "mux4")); 693 694 return 0; 695} 696DM_TEST(dm_test_ofnode_string, UT_TESTF_SCAN_FDT); 697 698/* test error returns from ofnode_read_string_count/index/list() */ 699static int dm_test_ofnode_string_err(struct unit_test_state *uts) 700{ 701 const char **val; 702 const char *out; 703 ofnode node; 704 705 /* 706 * Test error codes only on livetree, as they are different with 707 * flattree 708 */ 709 node = ofnode_path("/a-test"); 710 ut_assert(ofnode_valid(node)); 711 712 /* non-existent property */ 713 ut_asserteq(-EINVAL, ofnode_read_string_count(node, "missing")); 714 ut_asserteq(-EINVAL, ofnode_read_string_index(node, "missing", 0, 715 &out)); 716 ut_asserteq(-EINVAL, ofnode_read_string_list(node, "missing", &val)); 717 718 /* empty property */ 719 ut_asserteq(-ENODATA, ofnode_read_string_count(node, "bool-value")); 720 ut_asserteq(-ENODATA, ofnode_read_string_index(node, "bool-value", 0, 721 &out)); 722 ut_asserteq(-ENODATA, ofnode_read_string_list(node, "bool-value", 723 &val)); 724 725 /* badly formatted string list */ 726 ut_asserteq(-EILSEQ, ofnode_read_string_count(node, "int64-value")); 727 ut_asserteq(-EILSEQ, ofnode_read_string_index(node, "int64-value", 0, 728 &out)); 729 ut_asserteq(-EILSEQ, ofnode_read_string_list(node, "int64-value", 730 &val)); 731 732 /* out of range / not found */ 733 ut_asserteq(-ENODATA, ofnode_read_string_index(node, "str-value", 1, 734 &out)); 735 ut_asserteq(-ENODATA, ofnode_stringlist_search(node, "str-value", 736 "other")); 737 738 /* negative value for index is not allowed, so don't test for that */ 739 740 ut_asserteq(-ENODATA, ofnode_read_string_index(node, 741 "mux-control-names", 5, 742 &out)); 743 744 return 0; 745} 746DM_TEST(dm_test_ofnode_string_err, UT_TESTF_LIVE_TREE); 747 748static int dm_test_ofnode_read_phy_mode(struct unit_test_state *uts) 749{ 750 ofnode eth_node, phy_node; 751 phy_interface_t mode; 752 u32 reg; 753 754 eth_node = ofnode_path("/phy-test-eth"); 755 ut_assert(ofnode_valid(eth_node)); 756 757 mode = ofnode_read_phy_mode(eth_node); 758 ut_assert(mode == PHY_INTERFACE_MODE_2500BASEX); 759 760 phy_node = ofnode_get_phy_node(eth_node); 761 ut_assert(ofnode_valid(phy_node)); 762 763 reg = ofnode_read_u32_default(phy_node, "reg", -1U); 764 ut_asserteq_64(0x1, reg); 765 766 return 0; 767} 768DM_TEST(dm_test_ofnode_read_phy_mode, UT_TESTF_SCAN_FDT); 769 770/** 771 * make_ofnode_fdt() - Create an FDT for testing with ofnode 772 * 773 * The size is set to the minimum needed 774 * 775 * @uts: Test state 776 * @fdt: Place to write FDT 777 * @size: Maximum size of space for fdt 778 * @id: id value to add to the tree ('id' property in root node) 779 */ 780static int make_ofnode_fdt(struct unit_test_state *uts, void *fdt, int size, 781 int id) 782{ 783 ut_assertok(fdt_create(fdt, size)); 784 ut_assertok(fdt_finish_reservemap(fdt)); 785 ut_assert(fdt_begin_node(fdt, "") >= 0); 786 787 ut_assertok(fdt_property_u32(fdt, "id", id)); 788 789 ut_assert(fdt_begin_node(fdt, "aliases") >= 0); 790 ut_assertok(fdt_property_string(fdt, "mmc0", "/new-mmc")); 791 ut_assertok(fdt_end_node(fdt)); 792 793 ut_assert(fdt_begin_node(fdt, "new-mmc") >= 0); 794 ut_assertok(fdt_end_node(fdt)); 795 796 ut_assertok(fdt_end_node(fdt)); 797 ut_assertok(fdt_finish(fdt)); 798 799 return 0; 800} 801 802/* Check that aliases work on the control FDT */ 803static int dm_test_ofnode_aliases(struct unit_test_state *uts) 804{ 805 ofnode node; 806 807 node = ofnode_get_aliases_node("ethernet3"); 808 ut_assert(ofnode_valid(node)); 809 ut_asserteq_str("sbe5", ofnode_get_name(node)); 810 811 ut_assert(!oftree_valid(oftree_null())); 812 813 return 0; 814} 815DM_TEST(dm_test_ofnode_aliases, UT_TESTF_SCAN_FDT); 816 817/** 818 * dm_test_ofnode_root_mult() - Check aliaes on control and 'other' tree 819 * 820 * Check that aliases work only with the control FDT, not with 'other' tree. 821 * This is not actually the desired behaviour. If aliases are implemented for 822 * any tree, then this test should be changed. 823 */ 824static int dm_test_ofnode_root_mult(struct unit_test_state *uts) 825{ 826 char fdt[256]; 827 oftree tree; 828 ofnode node; 829 830 /* skip this test if multiple FDTs are not supported */ 831 if (!IS_ENABLED(CONFIG_OFNODE_MULTI_TREE)) 832 return -EAGAIN; 833 834 ut_assertok(make_ofnode_fdt(uts, fdt, sizeof(fdt), 0)); 835 ut_assertok(get_oftree(uts, fdt, &tree)); 836 ut_assert(oftree_valid(tree)); 837 838 /* Make sure they don't work on this new tree */ 839 node = oftree_path(tree, "mmc0"); 840 ut_assert(!ofnode_valid(node)); 841 842 /* It should appear in the new tree */ 843 node = oftree_path(tree, "/new-mmc"); 844 ut_assert(ofnode_valid(node)); 845 846 /* ...and not in the control FDT */ 847 node = oftree_path(oftree_default(), "/new-mmc"); 848 ut_assert(!ofnode_valid(node)); 849 850 free_oftree(tree); 851 852 return 0; 853} 854DM_TEST(dm_test_ofnode_root_mult, UT_TESTF_SCAN_FDT); 855 856/* test ofnode_set_enabled(), ofnode_write_prop() on a livetree */ 857static int dm_test_ofnode_livetree_writing(struct unit_test_state *uts) 858{ 859 struct udevice *dev; 860 ofnode node; 861 862 /* Test enabling devices */ 863 node = ofnode_path("/usb@2"); 864 865 ut_assert(!ofnode_is_enabled(node)); 866 ut_assertok(ofnode_set_enabled(node, true)); 867 ut_asserteq(true, ofnode_is_enabled(node)); 868 869 device_bind_driver_to_node(dm_root(), "usb_sandbox", "usb@2", node, 870 &dev); 871 ut_assertok(uclass_find_device_by_seq(UCLASS_USB, 2, &dev)); 872 873 /* Test string property setting */ 874 ut_assert(device_is_compatible(dev, "sandbox,usb")); 875 ofnode_write_string(node, "compatible", "gdsys,super-usb"); 876 ut_assert(device_is_compatible(dev, "gdsys,super-usb")); 877 ofnode_write_string(node, "compatible", "sandbox,usb"); 878 ut_assert(device_is_compatible(dev, "sandbox,usb")); 879 880 /* Test setting generic properties */ 881 882 /* Non-existent in DTB */ 883 ut_asserteq_64(FDT_ADDR_T_NONE, dev_read_addr(dev)); 884 /* reg = 0x42, size = 0x100 */ 885 ut_assertok(ofnode_write_prop(node, "reg", 886 "\x00\x00\x00\x42\x00\x00\x01\x00", 8, 887 false)); 888 ut_asserteq(0x42, dev_read_addr(dev)); 889 890 /* Test disabling devices */ 891 device_remove(dev, DM_REMOVE_NORMAL); 892 device_unbind(dev); 893 894 ut_assert(ofnode_is_enabled(node)); 895 ut_assertok(ofnode_set_enabled(node, false)); 896 ut_assert(!ofnode_is_enabled(node)); 897 898 return 0; 899} 900DM_TEST(dm_test_ofnode_livetree_writing, 901 UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); 902 903static int check_write_prop(struct unit_test_state *uts, ofnode node) 904{ 905 char prop[] = "middle-name"; 906 char name[10]; 907 int len; 908 909 strcpy(name, "cecil"); 910 len = strlen(name) + 1; 911 ut_assertok(ofnode_write_prop(node, prop, name, len, false)); 912 ut_asserteq_str(name, ofnode_read_string(node, prop)); 913 914 /* change the underlying value, this should mess up the live tree */ 915 strcpy(name, "tony"); 916 if (of_live_active()) { 917 ut_asserteq_str(name, ofnode_read_string(node, prop)); 918 } else { 919 ut_asserteq_str("cecil", ofnode_read_string(node, prop)); 920 } 921 922 /* try again, this time copying the property */ 923 strcpy(name, "mary"); 924 ut_assertok(ofnode_write_prop(node, prop, name, len, true)); 925 ut_asserteq_str(name, ofnode_read_string(node, prop)); 926 strcpy(name, "leah"); 927 928 /* both flattree and livetree behave the same */ 929 ut_asserteq_str("mary", ofnode_read_string(node, prop)); 930 931 return 0; 932} 933 934/* writing the tree with and without copying the property */ 935static int dm_test_ofnode_write_copy(struct unit_test_state *uts) 936{ 937 ofnode node; 938 939 node = ofnode_path("/a-test"); 940 ut_assertok(check_write_prop(uts, node)); 941 942 return 0; 943} 944DM_TEST(dm_test_ofnode_write_copy, UT_TESTF_SCAN_FDT); 945 946/* test writing a property to the 'other' tree */ 947static int dm_test_ofnode_write_copy_ot(struct unit_test_state *uts) 948{ 949 oftree otree = get_other_oftree(uts); 950 ofnode node, check_node; 951 952 node = oftree_path(otree, "/node"); 953 ut_assertok(check_write_prop(uts, node)); 954 955 /* make sure the control FDT is not touched */ 956 check_node = ofnode_path("/node"); 957 ut_assertnull(ofnode_read_string(check_node, "middle-name")); 958 959 return 0; 960} 961DM_TEST(dm_test_ofnode_write_copy_ot, UT_TESTF_SCAN_FDT | UT_TESTF_OTHER_FDT); 962 963/* test ofnode_read_u32_index/default() */ 964static int dm_test_ofnode_u32(struct unit_test_state *uts) 965{ 966 ofnode node; 967 u32 val; 968 969 node = ofnode_path("/lcd"); 970 ut_assert(ofnode_valid(node)); 971 ut_asserteq(1366, ofnode_read_u32_default(node, "xres", 123)); 972 ut_assertok(ofnode_write_u32(node, "xres", 1367)); 973 ut_asserteq(1367, ofnode_read_u32_default(node, "xres", 123)); 974 ut_assertok(ofnode_write_u32(node, "xres", 1366)); 975 976 node = ofnode_path("/backlight"); 977 ut_assertok(ofnode_read_u32_index(node, "brightness-levels", 0, &val)); 978 ut_asserteq(0, val); 979 ut_assertok(ofnode_read_u32_index(node, "brightness-levels", 1, &val)); 980 ut_asserteq(16, val); 981 ut_assertok(ofnode_read_u32_index(node, "brightness-levels", 8, &val)); 982 ut_asserteq(255, val); 983 ut_asserteq(-EOVERFLOW, 984 ofnode_read_u32_index(node, "brightness-levels", 9, &val)); 985 ut_asserteq(-EINVAL, ofnode_read_u32_index(node, "missing", 0, &val)); 986 987 return 0; 988} 989DM_TEST(dm_test_ofnode_u32, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); 990 991/* test ofnode_read_u32_array() */ 992static int dm_test_ofnode_u32_array(struct unit_test_state *uts) 993{ 994 ofnode node; 995 u32 val[10]; 996 997 node = ofnode_path("/a-test"); 998 ut_assert(ofnode_valid(node)); 999 ut_assertok(ofnode_read_u32_array(node, "int-value", val, 1)); 1000 ut_asserteq(-EINVAL, ofnode_read_u32_array(node, "missing", val, 1)); 1001 ut_asserteq(-EOVERFLOW, ofnode_read_u32_array(node, "bool-value", val, 1002 1)); 1003 1004 memset(val, '\0', sizeof(val)); 1005 ut_assertok(ofnode_read_u32_array(node, "int-array", val + 1, 3)); 1006 ut_asserteq(0, val[0]); 1007 ut_asserteq(5678, val[1]); 1008 ut_asserteq(9123, val[2]); 1009 ut_asserteq(4567, val[3]); 1010 ut_asserteq(0, val[4]); 1011 ut_asserteq(-EOVERFLOW, ofnode_read_u32_array(node, "int-array", val, 1012 4)); 1013 1014 return 0; 1015} 1016DM_TEST(dm_test_ofnode_u32_array, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); 1017 1018/* test ofnode_read_u64() and ofnode_write_u64() */ 1019static int dm_test_ofnode_u64(struct unit_test_state *uts) 1020{ 1021 ofnode node; 1022 u64 val; 1023 1024 node = ofnode_path("/a-test"); 1025 ut_assert(ofnode_valid(node)); 1026 ut_assertok(ofnode_read_u64(node, "int64-value", &val)); 1027 ut_asserteq_64(0x1111222233334444, val); 1028 ut_assertok(ofnode_write_u64(node, "new-int64-value", 0x9876543210)); 1029 ut_assertok(ofnode_read_u64(node, "new-int64-value", &val)); 1030 ut_asserteq_64(0x9876543210, val); 1031 1032 ut_asserteq(-EINVAL, ofnode_read_u64(node, "missing", &val)); 1033 1034 ut_assertok(ofnode_read_u64_index(node, "int64-array", 0, &val)); 1035 ut_asserteq_64(0x1111222233334444, val); 1036 ut_assertok(ofnode_read_u64_index(node, "int64-array", 1, &val)); 1037 ut_asserteq_64(0x4444333322221111, val); 1038 ut_asserteq(-EOVERFLOW, 1039 ofnode_read_u64_index(node, "int64-array", 2, &val)); 1040 ut_asserteq(-EINVAL, ofnode_read_u64_index(node, "missing", 0, &val)); 1041 1042 ut_assertok(ofnode_write_u64(node, "int64-array", 0x9876543210)); 1043 ut_assertok(ofnode_read_u64_index(node, "int64-array", 0, &val)); 1044 ut_asserteq_64(0x9876543210, val); 1045 ut_asserteq(-EOVERFLOW, 1046 ofnode_read_u64_index(node, "int64-array", 1, &val)); 1047 1048 return 0; 1049} 1050DM_TEST(dm_test_ofnode_u64, UT_TESTF_SCAN_FDT); 1051 1052static int dm_test_ofnode_add_subnode(struct unit_test_state *uts) 1053{ 1054 ofnode node, check, subnode; 1055 char buf[128]; 1056 1057 node = ofnode_path("/lcd"); 1058 ut_assert(ofnode_valid(node)); 1059 ut_assertok(ofnode_add_subnode(node, "edmund", &subnode)); 1060 check = ofnode_path("/lcd/edmund"); 1061 ut_asserteq(subnode.of_offset, check.of_offset); 1062 ut_assertok(ofnode_get_path(subnode, buf, sizeof(buf))); 1063 ut_asserteq_str("/lcd/edmund", buf); 1064 1065 if (of_live_active()) { 1066 struct device_node *child; 1067 1068 ut_assertok(of_add_subnode((void *)ofnode_to_np(node), "edmund", 1069 2, &child)); 1070 ut_asserteq_str("ed", child->name); 1071 ut_asserteq_str("/lcd/ed", child->full_name); 1072 check = ofnode_path("/lcd/ed"); 1073 ut_asserteq_ptr(child, check.np); 1074 ut_assertok(ofnode_get_path(np_to_ofnode(child), buf, 1075 sizeof(buf))); 1076 ut_asserteq_str("/lcd/ed", buf); 1077 } 1078 1079 /* An existing node should be returned with -EEXIST */ 1080 ut_asserteq(-EEXIST, ofnode_add_subnode(node, "edmund", &check)); 1081 ut_asserteq(subnode.of_offset, check.of_offset); 1082 1083 /* add a root node */ 1084 node = ofnode_path("/"); 1085 ut_assert(ofnode_valid(node)); 1086 ut_assertok(ofnode_add_subnode(node, "lcd2", &subnode)); 1087 check = ofnode_path("/lcd2"); 1088 ut_asserteq(subnode.of_offset, check.of_offset); 1089 ut_assertok(ofnode_get_path(subnode, buf, sizeof(buf))); 1090 ut_asserteq_str("/lcd2", buf); 1091 1092 if (of_live_active()) { 1093 ulong start; 1094 int i; 1095 1096 /* 1097 * Make sure each of the three malloc()checks in 1098 * of_add_subnode() work 1099 */ 1100 for (i = 0; i < 3; i++) { 1101 malloc_enable_testing(i); 1102 start = ut_check_free(); 1103 ut_asserteq(-ENOMEM, ofnode_add_subnode(node, "anthony", 1104 &check)); 1105 ut_assertok(ut_check_delta(start)); 1106 } 1107 1108 /* This should pass since we allow 3 allocations */ 1109 malloc_enable_testing(3); 1110 ut_assertok(ofnode_add_subnode(node, "anthony", &check)); 1111 malloc_disable_testing(); 1112 } 1113 1114 /* write to the empty node */ 1115 ut_assertok(ofnode_write_string(subnode, "example", "text")); 1116 1117 return 0; 1118} 1119DM_TEST(dm_test_ofnode_add_subnode, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); 1120 1121static int dm_test_ofnode_for_each_prop(struct unit_test_state *uts) 1122{ 1123 ofnode node, subnode; 1124 struct ofprop prop; 1125 int count; 1126 1127 node = ofnode_path("/ofnode-foreach"); 1128 count = 0; 1129 1130 /* we expect "compatible" for each node */ 1131 ofnode_for_each_prop(prop, node) 1132 count++; 1133 ut_asserteq(1, count); 1134 1135 /* there are two nodes, each with 2 properties */ 1136 ofnode_for_each_subnode(subnode, node) 1137 ofnode_for_each_prop(prop, subnode) 1138 count++; 1139 ut_asserteq(5, count); 1140 1141 return 0; 1142} 1143DM_TEST(dm_test_ofnode_for_each_prop, UT_TESTF_SCAN_FDT); 1144 1145static int dm_test_ofnode_by_compatible(struct unit_test_state *uts) 1146{ 1147 const char *compat = "denx,u-boot-fdt-test"; 1148 ofnode node; 1149 int count; 1150 1151 count = 0; 1152 for (node = ofnode_null(); 1153 node = ofnode_by_compatible(node, compat), ofnode_valid(node);) 1154 count++; 1155 ut_asserteq(11, count); 1156 1157 return 0; 1158} 1159DM_TEST(dm_test_ofnode_by_compatible, UT_TESTF_SCAN_FDT); 1160 1161/* check ofnode_by_compatible() on the 'other' tree */ 1162static int dm_test_ofnode_by_compatible_ot(struct unit_test_state *uts) 1163{ 1164 const char *compat = "sandbox-other2"; 1165 oftree otree = get_other_oftree(uts); 1166 ofnode node; 1167 int count; 1168 1169 count = 0; 1170 for (node = oftree_root(otree); 1171 node = ofnode_by_compatible(node, compat), ofnode_valid(node);) 1172 count++; 1173 ut_asserteq(2, count); 1174 1175 return 0; 1176} 1177DM_TEST(dm_test_ofnode_by_compatible_ot, UT_TESTF_SCAN_FDT | UT_TESTF_OTHER_FDT); 1178 1179static int dm_test_ofnode_find_subnode(struct unit_test_state *uts) 1180{ 1181 ofnode node, subnode; 1182 1183 node = ofnode_path("/buttons"); 1184 1185 subnode = ofnode_find_subnode(node, "btn1"); 1186 ut_assert(ofnode_valid(subnode)); 1187 ut_asserteq_str("btn1", ofnode_get_name(subnode)); 1188 1189 subnode = ofnode_find_subnode(node, "btn"); 1190 ut_assert(!ofnode_valid(subnode)); 1191 1192 return 0; 1193} 1194DM_TEST(dm_test_ofnode_find_subnode, UT_TESTF_SCAN_FDT); 1195 1196/* test ofnode_find_subnode() on the 'other' tree */ 1197static int dm_test_ofnode_find_subnode_ot(struct unit_test_state *uts) 1198{ 1199 oftree otree = get_other_oftree(uts); 1200 ofnode node, subnode; 1201 1202 node = oftree_path(otree, "/node"); 1203 1204 subnode = ofnode_find_subnode(node, "subnode"); 1205 ut_assert(ofnode_valid(subnode)); 1206 ut_asserteq_str("subnode", ofnode_get_name(subnode)); 1207 1208 subnode = ofnode_find_subnode(node, "btn"); 1209 ut_assert(!ofnode_valid(subnode)); 1210 1211 return 0; 1212} 1213DM_TEST(dm_test_ofnode_find_subnode_ot, UT_TESTF_OTHER_FDT); 1214 1215static int dm_test_ofnode_get_name(struct unit_test_state *uts) 1216{ 1217 ofnode node; 1218 1219 node = ofnode_path("/buttons"); 1220 ut_assert(ofnode_valid(node)); 1221 ut_asserteq_str("buttons", ofnode_get_name(node)); 1222 ut_asserteq_str("", ofnode_get_name(ofnode_root())); 1223 1224 return 0; 1225} 1226DM_TEST(dm_test_ofnode_get_name, UT_TESTF_SCAN_FDT); 1227 1228/* try to access more FDTs than is supported */ 1229static int dm_test_ofnode_too_many(struct unit_test_state *uts) 1230{ 1231 const int max_trees = CONFIG_IS_ENABLED(OFNODE_MULTI_TREE, 1232 (CONFIG_OFNODE_MULTI_TREE_MAX), (1)); 1233 const int fdt_size = 256; 1234 const int num_trees = max_trees + 1; 1235 char fdt[num_trees][fdt_size]; 1236 int i; 1237 1238 for (i = 0; i < num_trees; i++) { 1239 oftree tree; 1240 int ret; 1241 1242 ut_assertok(make_ofnode_fdt(uts, fdt[i], fdt_size, i)); 1243 ret = get_oftree(uts, fdt[i], &tree); 1244 1245 /* 1246 * With flat tree we have the control FDT using one slot. Live 1247 * tree has no limit since it uses pointers, not integer tree 1248 * IDs 1249 */ 1250 if (of_live_active() || i < max_trees - 1) { 1251 ut_assertok(ret); 1252 } else { 1253 /* 1254 * tree should be invalid when we try to register too 1255 * many trees 1256 */ 1257 ut_asserteq(-EOVERFLOW, ret); 1258 } 1259 } 1260 1261 return 0; 1262} 1263DM_TEST(dm_test_ofnode_too_many, UT_TESTF_SCAN_FDT); 1264 1265static int check_copy_props(struct unit_test_state *uts, ofnode dst, ofnode src) 1266{ 1267 u32 reg[2], val; 1268 1269 ut_assertok(ofnode_copy_props(dst, src)); 1270 1271 ut_assertok(ofnode_read_u32(dst, "ping-expect", &val)); 1272 ut_asserteq(3, val); 1273 1274 ut_asserteq_str("denx,u-boot-fdt-test", 1275 ofnode_read_string(dst, "compatible")); 1276 1277 /* check that a property with the same name is overwritten */ 1278 ut_assertok(ofnode_read_u32_array(dst, "reg", reg, ARRAY_SIZE(reg))); 1279 ut_asserteq(3, reg[0]); 1280 ut_asserteq(1, reg[1]); 1281 1282 /* reset the compatible so the live tree does not change */ 1283 ut_assertok(ofnode_write_string(dst, "compatible", "nothing")); 1284 1285 return 0; 1286} 1287 1288static int dm_test_ofnode_copy_props(struct unit_test_state *uts) 1289{ 1290 ofnode src, dst; 1291 1292 /* 1293 * These nodes are chosen so that the src node is before the destination 1294 * node in the tree. This doesn't matter with livetree, but with 1295 * flattree any attempt to insert a property earlier in the tree will 1296 * mess up the offsets after it. 1297 */ 1298 src = ofnode_path("/b-test"); 1299 dst = ofnode_path("/some-bus"); 1300 1301 ut_assertok(check_copy_props(uts, dst, src)); 1302 1303 /* check a property that is in the destination already */ 1304 ut_asserteq_str("mux0", ofnode_read_string(dst, "mux-control-names")); 1305 1306 return 0; 1307} 1308DM_TEST(dm_test_ofnode_copy_props, UT_TESTF_SCAN_FDT); 1309 1310/* test ofnode_copy_props() with the 'other' tree */ 1311static int dm_test_ofnode_copy_props_ot(struct unit_test_state *uts) 1312{ 1313 ofnode src, dst; 1314 oftree otree = get_other_oftree(uts); 1315 1316 src = ofnode_path("/b-test"); 1317 dst = oftree_path(otree, "/node/subnode2"); 1318 ut_assertok(check_copy_props(uts, dst, src)); 1319 1320 return 0; 1321} 1322DM_TEST(dm_test_ofnode_copy_props_ot, UT_TESTF_SCAN_FDT | UT_TESTF_OTHER_FDT); 1323 1324/* check that the livetree is aligned to a structure boundary */ 1325static int dm_test_livetree_align(struct unit_test_state *uts) 1326{ 1327 const int align = __alignof__(struct unit_test_state); 1328 struct device_node *node; 1329 u32 *sentinel; 1330 ulong start; 1331 1332 start = (ulong)gd_of_root(); 1333 ut_asserteq(start, ALIGN(start, align)); 1334 1335 node = gd_of_root(); 1336 sentinel = (void *)node - sizeof(u32); 1337 1338 /* 1339 * The sentinel should be overwritten with the root node. If it isn't, 1340 * then the root node is not at the very start of the livetree memory 1341 * area, and free(root) will fail to free the memory used by the 1342 * livetree. 1343 */ 1344 ut_assert(*sentinel != BAD_OF_ROOT); 1345 1346 return 0; 1347} 1348DM_TEST(dm_test_livetree_align, UT_TESTF_SCAN_FDT | UT_TESTF_LIVE_TREE); 1349 1350/* check that it is possible to load an arbitrary livetree */ 1351static int dm_test_livetree_ensure(struct unit_test_state *uts) 1352{ 1353 oftree tree; 1354 ofnode node; 1355 1356 /* read from other.dtb */ 1357 ut_assertok(test_load_other_fdt(uts)); 1358 tree = oftree_from_fdt(uts->other_fdt); 1359 ut_assert(oftree_valid(tree)); 1360 node = oftree_path(tree, "/node/subnode"); 1361 ut_assert(ofnode_valid(node)); 1362 ut_asserteq_str("sandbox-other2", 1363 ofnode_read_string(node, "compatible")); 1364 1365 return 0; 1366} 1367DM_TEST(dm_test_livetree_ensure, UT_TESTF_SCAN_FDT); 1368 1369static int dm_test_oftree_new(struct unit_test_state *uts) 1370{ 1371 ofnode node, subnode, check; 1372 oftree tree; 1373 1374 ut_assertok(oftree_new(&tree)); 1375 node = oftree_root(tree); 1376 ut_assert(ofnode_valid(node)); 1377 ut_assertok(ofnode_add_subnode(node, "edmund", &subnode)); 1378 check = ofnode_find_subnode(node, "edmund"); 1379 ut_asserteq(check.of_offset, subnode.of_offset); 1380 1381 return 0; 1382} 1383DM_TEST(dm_test_oftree_new, UT_TESTF_SCAN_FDT); 1384 1385static int check_copy_node(struct unit_test_state *uts, ofnode dst, ofnode src, 1386 ofnode *nodep) 1387{ 1388 u32 reg[2], val; 1389 ofnode node; 1390 1391 ut_assertok(ofnode_copy_node(dst, "copy-test", src, &node)); 1392 1393 ut_assertok(ofnode_read_u32(node, "ping-expect", &val)); 1394 ut_asserteq(3, val); 1395 1396 ut_asserteq_str("denx,u-boot-fdt-test", 1397 ofnode_read_string(node, "compatible")); 1398 1399 /* check that a property with the same name is overwritten */ 1400 ut_assertok(ofnode_read_u32_array(node, "reg", reg, ARRAY_SIZE(reg))); 1401 ut_asserteq(3, reg[0]); 1402 ut_asserteq(1, reg[1]); 1403 1404 /* reset the compatible so the live tree does not change */ 1405 ut_assertok(ofnode_write_string(node, "compatible", "nothing")); 1406 *nodep = node; 1407 1408 return 0; 1409} 1410 1411static int dm_test_ofnode_copy_node(struct unit_test_state *uts) 1412{ 1413 ofnode src, dst, node, try; 1414 1415 /* 1416 * These nodes are chosen so that the src node is before the destination 1417 * node in the tree. This doesn't matter with livetree, but with 1418 * flattree any attempt to insert a property earlier in the tree will 1419 * mess up the offsets after it. 1420 */ 1421 src = ofnode_path("/b-test"); 1422 dst = ofnode_path("/some-bus"); 1423 1424 ut_assertok(check_copy_node(uts, dst, src, &node)); 1425 1426 /* check trying to copy over an existing node */ 1427 ut_asserteq(-EEXIST, ofnode_copy_node(dst, "copy-test", src, &try)); 1428 ut_asserteq(try.of_offset, node.of_offset); 1429 1430 return 0; 1431} 1432DM_TEST(dm_test_ofnode_copy_node, UT_TESTF_SCAN_FDT); 1433 1434/* test ofnode_copy_node() with the 'other' tree */ 1435static int dm_test_ofnode_copy_node_ot(struct unit_test_state *uts) 1436{ 1437 oftree otree = get_other_oftree(uts); 1438 ofnode src, dst, node; 1439 1440 src = ofnode_path("/b-test"); 1441 dst = oftree_path(otree, "/node/subnode2"); 1442 ut_assertok(check_copy_node(uts, dst, src, &node)); 1443 1444 return 0; 1445} 1446DM_TEST(dm_test_ofnode_copy_node_ot, UT_TESTF_SCAN_FDT | UT_TESTF_OTHER_FDT); 1447 1448static int dm_test_ofnode_delete(struct unit_test_state *uts) 1449{ 1450 ofnode node; 1451 1452 /* 1453 * At present the livetree is not restored after changes made in tests. 1454 * See test_pre_run() for how this is done with the other FDT and 1455 * dm_test_pre_run() where it sets up the root-tree pointer. So use 1456 * nodes which don't matter to other tests. 1457 * 1458 * We could fix this by detecting livetree changes and regenerating it 1459 * before the next test if needed. 1460 */ 1461 node = ofnode_path("/leds/iracibble"); 1462 ut_assert(ofnode_valid(node)); 1463 ut_assertok(ofnode_delete(&node)); 1464 ut_assert(!ofnode_valid(node)); 1465 ut_assert(!ofnode_valid(ofnode_path("/leds/iracibble"))); 1466 1467 node = ofnode_path("/leds/default_on"); 1468 ut_assert(ofnode_valid(node)); 1469 ut_assertok(ofnode_delete(&node)); 1470 ut_assert(!ofnode_valid(node)); 1471 ut_assert(!ofnode_valid(ofnode_path("/leds/default_on"))); 1472 1473 ut_asserteq(2, ofnode_get_child_count(ofnode_path("/leds"))); 1474 1475 return 0; 1476} 1477DM_TEST(dm_test_ofnode_delete, UT_TESTF_SCAN_FDT); 1478 1479static int dm_test_oftree_to_fdt(struct unit_test_state *uts) 1480{ 1481 oftree tree, check; 1482 struct abuf buf, buf2; 1483 1484 tree = oftree_default(); 1485 ut_assertok(oftree_to_fdt(tree, &buf)); 1486 ut_assert(abuf_size(&buf) > SZ_16K); 1487 1488 /* convert it back to a tree and see if it looks OK */ 1489 check = oftree_from_fdt(abuf_data(&buf)); 1490 ut_assert(oftree_valid(check)); 1491 1492 ut_assertok(oftree_to_fdt(check, &buf2)); 1493 ut_assert(abuf_size(&buf2) > SZ_16K); 1494 ut_asserteq(abuf_size(&buf), abuf_size(&buf2)); 1495 ut_asserteq_mem(abuf_data(&buf), abuf_data(&buf2), abuf_size(&buf)); 1496 1497 return 0; 1498} 1499DM_TEST(dm_test_oftree_to_fdt, UT_TESTF_SCAN_FDT); 1500 1501/* test ofnode_read_bool() and ofnode_write_bool() */ 1502static int dm_test_bool(struct unit_test_state *uts) 1503{ 1504 const char *propname = "missing-bool-value"; 1505 ofnode node; 1506 1507 node = ofnode_path("/a-test"); 1508 ut_assert(ofnode_read_bool(node, "bool-value")); 1509 ut_assert(!ofnode_read_bool(node, propname)); 1510 ut_assert(!ofnode_has_property(node, propname)); 1511 1512 ut_assertok(ofnode_write_bool(node, propname, true)); 1513 ut_assert(ofnode_read_bool(node, propname)); 1514 ut_assert(ofnode_has_property(node, propname)); 1515 ut_assert(ofnode_read_bool(node, "bool-value")); 1516 1517 ut_assertok(ofnode_write_bool(node, propname, false)); 1518 ut_assert(!ofnode_read_bool(node, propname)); 1519 ut_assert(!ofnode_has_property(node, propname)); 1520 ut_assert(ofnode_read_bool(node, "bool-value")); 1521 1522 return 0; 1523} 1524DM_TEST(dm_test_bool, UT_TESTF_SCAN_FDT); 1525