1/* $NetBSD: checks.c,v 1.1.1.3 2019/12/22 12:34:02 skrll Exp $ */ 2 3// SPDX-License-Identifier: GPL-2.0-or-later 4/* 5 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2007. 6 */ 7 8#include "dtc.h" 9#include "srcpos.h" 10 11#ifdef TRACE_CHECKS 12#define TRACE(c, ...) \ 13 do { \ 14 fprintf(stderr, "=== %s: ", (c)->name); \ 15 fprintf(stderr, __VA_ARGS__); \ 16 fprintf(stderr, "\n"); \ 17 } while (0) 18#else 19#define TRACE(c, fmt, ...) do { } while (0) 20#endif 21 22enum checkstatus { 23 UNCHECKED = 0, 24 PREREQ, 25 PASSED, 26 FAILED, 27}; 28 29struct check; 30 31typedef void (*check_fn)(struct check *c, struct dt_info *dti, struct node *node); 32 33struct check { 34 const char *name; 35 check_fn fn; 36 void *data; 37 bool warn, error; 38 enum checkstatus status; 39 bool inprogress; 40 int num_prereqs; 41 struct check **prereq; 42}; 43 44#define CHECK_ENTRY(nm_, fn_, d_, w_, e_, ...) \ 45 static struct check *nm_##_prereqs[] = { __VA_ARGS__ }; \ 46 static struct check nm_ = { \ 47 .name = #nm_, \ 48 .fn = (fn_), \ 49 .data = (d_), \ 50 .warn = (w_), \ 51 .error = (e_), \ 52 .status = UNCHECKED, \ 53 .num_prereqs = ARRAY_SIZE(nm_##_prereqs), \ 54 .prereq = nm_##_prereqs, \ 55 }; 56#define WARNING(nm_, fn_, d_, ...) \ 57 CHECK_ENTRY(nm_, fn_, d_, true, false, __VA_ARGS__) 58#define ERROR(nm_, fn_, d_, ...) \ 59 CHECK_ENTRY(nm_, fn_, d_, false, true, __VA_ARGS__) 60#define CHECK(nm_, fn_, d_, ...) \ 61 CHECK_ENTRY(nm_, fn_, d_, false, false, __VA_ARGS__) 62 63static inline void PRINTF(5, 6) check_msg(struct check *c, struct dt_info *dti, 64 struct node *node, 65 struct property *prop, 66 const char *fmt, ...) 67{ 68 va_list ap; 69 char *str = NULL; 70 struct srcpos *pos = NULL; 71 char *file_str; 72 73 if (!(c->warn && (quiet < 1)) && !(c->error && (quiet < 2))) 74 return; 75 76 if (prop && prop->srcpos) 77 pos = prop->srcpos; 78 else if (node && node->srcpos) 79 pos = node->srcpos; 80 81 if (pos) { 82 file_str = srcpos_string(pos); 83 xasprintf(&str, "%s", file_str); 84 free(file_str); 85 } else if (streq(dti->outname, "-")) { 86 xasprintf(&str, "<stdout>"); 87 } else { 88 xasprintf(&str, "%s", dti->outname); 89 } 90 91 xasprintf_append(&str, ": %s (%s): ", 92 (c->error) ? "ERROR" : "Warning", c->name); 93 94 if (node) { 95 if (prop) 96 xasprintf_append(&str, "%s:%s: ", node->fullpath, prop->name); 97 else 98 xasprintf_append(&str, "%s: ", node->fullpath); 99 } 100 101 va_start(ap, fmt); 102 xavsprintf_append(&str, fmt, ap); 103 va_end(ap); 104 105 xasprintf_append(&str, "\n"); 106 107 if (!prop && pos) { 108 pos = node->srcpos; 109 while (pos->next) { 110 pos = pos->next; 111 112 file_str = srcpos_string(pos); 113 xasprintf_append(&str, " also defined at %s\n", file_str); 114 free(file_str); 115 } 116 } 117 118 fputs(str, stderr); 119} 120 121#define FAIL(c, dti, node, ...) \ 122 do { \ 123 TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \ 124 (c)->status = FAILED; \ 125 check_msg((c), dti, node, NULL, __VA_ARGS__); \ 126 } while (0) 127 128#define FAIL_PROP(c, dti, node, prop, ...) \ 129 do { \ 130 TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \ 131 (c)->status = FAILED; \ 132 check_msg((c), dti, node, prop, __VA_ARGS__); \ 133 } while (0) 134 135 136static void check_nodes_props(struct check *c, struct dt_info *dti, struct node *node) 137{ 138 struct node *child; 139 140 TRACE(c, "%s", node->fullpath); 141 if (c->fn) 142 c->fn(c, dti, node); 143 144 for_each_child(node, child) 145 check_nodes_props(c, dti, child); 146} 147 148static bool run_check(struct check *c, struct dt_info *dti) 149{ 150 struct node *dt = dti->dt; 151 bool error = false; 152 int i; 153 154 assert(!c->inprogress); 155 156 if (c->status != UNCHECKED) 157 goto out; 158 159 c->inprogress = true; 160 161 for (i = 0; i < c->num_prereqs; i++) { 162 struct check *prq = c->prereq[i]; 163 error = error || run_check(prq, dti); 164 if (prq->status != PASSED) { 165 c->status = PREREQ; 166 check_msg(c, dti, NULL, NULL, "Failed prerequisite '%s'", 167 c->prereq[i]->name); 168 } 169 } 170 171 if (c->status != UNCHECKED) 172 goto out; 173 174 check_nodes_props(c, dti, dt); 175 176 if (c->status == UNCHECKED) 177 c->status = PASSED; 178 179 TRACE(c, "\tCompleted, status %d", c->status); 180 181out: 182 c->inprogress = false; 183 if ((c->status != PASSED) && (c->error)) 184 error = true; 185 return error; 186} 187 188/* 189 * Utility check functions 190 */ 191 192/* A check which always fails, for testing purposes only */ 193static inline void check_always_fail(struct check *c, struct dt_info *dti, 194 struct node *node) 195{ 196 FAIL(c, dti, node, "always_fail check"); 197} 198CHECK(always_fail, check_always_fail, NULL); 199 200static void check_is_string(struct check *c, struct dt_info *dti, 201 struct node *node) 202{ 203 struct property *prop; 204 char *propname = c->data; 205 206 prop = get_property(node, propname); 207 if (!prop) 208 return; /* Not present, assumed ok */ 209 210 if (!data_is_one_string(prop->val)) 211 FAIL_PROP(c, dti, node, prop, "property is not a string"); 212} 213#define WARNING_IF_NOT_STRING(nm, propname) \ 214 WARNING(nm, check_is_string, (propname)) 215#define ERROR_IF_NOT_STRING(nm, propname) \ 216 ERROR(nm, check_is_string, (propname)) 217 218static void check_is_string_list(struct check *c, struct dt_info *dti, 219 struct node *node) 220{ 221 int rem, l; 222 struct property *prop; 223 char *propname = c->data; 224 char *str; 225 226 prop = get_property(node, propname); 227 if (!prop) 228 return; /* Not present, assumed ok */ 229 230 str = prop->val.val; 231 rem = prop->val.len; 232 while (rem > 0) { 233 l = strnlen(str, rem); 234 if (l == rem) { 235 FAIL_PROP(c, dti, node, prop, "property is not a string list"); 236 break; 237 } 238 rem -= l + 1; 239 str += l + 1; 240 } 241} 242#define WARNING_IF_NOT_STRING_LIST(nm, propname) \ 243 WARNING(nm, check_is_string_list, (propname)) 244#define ERROR_IF_NOT_STRING_LIST(nm, propname) \ 245 ERROR(nm, check_is_string_list, (propname)) 246 247static void check_is_cell(struct check *c, struct dt_info *dti, 248 struct node *node) 249{ 250 struct property *prop; 251 char *propname = c->data; 252 253 prop = get_property(node, propname); 254 if (!prop) 255 return; /* Not present, assumed ok */ 256 257 if (prop->val.len != sizeof(cell_t)) 258 FAIL_PROP(c, dti, node, prop, "property is not a single cell"); 259} 260#define WARNING_IF_NOT_CELL(nm, propname) \ 261 WARNING(nm, check_is_cell, (propname)) 262#define ERROR_IF_NOT_CELL(nm, propname) \ 263 ERROR(nm, check_is_cell, (propname)) 264 265/* 266 * Structural check functions 267 */ 268 269static void check_duplicate_node_names(struct check *c, struct dt_info *dti, 270 struct node *node) 271{ 272 struct node *child, *child2; 273 274 for_each_child(node, child) 275 for (child2 = child->next_sibling; 276 child2; 277 child2 = child2->next_sibling) 278 if (streq(child->name, child2->name)) 279 FAIL(c, dti, child2, "Duplicate node name"); 280} 281ERROR(duplicate_node_names, check_duplicate_node_names, NULL); 282 283static void check_duplicate_property_names(struct check *c, struct dt_info *dti, 284 struct node *node) 285{ 286 struct property *prop, *prop2; 287 288 for_each_property(node, prop) { 289 for (prop2 = prop->next; prop2; prop2 = prop2->next) { 290 if (prop2->deleted) 291 continue; 292 if (streq(prop->name, prop2->name)) 293 FAIL_PROP(c, dti, node, prop, "Duplicate property name"); 294 } 295 } 296} 297ERROR(duplicate_property_names, check_duplicate_property_names, NULL); 298 299#define LOWERCASE "abcdefghijklmnopqrstuvwxyz" 300#define UPPERCASE "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 301#define DIGITS "0123456789" 302#define PROPNODECHARS LOWERCASE UPPERCASE DIGITS ",._+*#?-" 303#define PROPNODECHARSSTRICT LOWERCASE UPPERCASE DIGITS ",-" 304 305static void check_node_name_chars(struct check *c, struct dt_info *dti, 306 struct node *node) 307{ 308 int n = strspn(node->name, c->data); 309 310 if (n < strlen(node->name)) 311 FAIL(c, dti, node, "Bad character '%c' in node name", 312 node->name[n]); 313} 314ERROR(node_name_chars, check_node_name_chars, PROPNODECHARS "@"); 315 316static void check_node_name_chars_strict(struct check *c, struct dt_info *dti, 317 struct node *node) 318{ 319 int n = strspn(node->name, c->data); 320 321 if (n < node->basenamelen) 322 FAIL(c, dti, node, "Character '%c' not recommended in node name", 323 node->name[n]); 324} 325CHECK(node_name_chars_strict, check_node_name_chars_strict, PROPNODECHARSSTRICT); 326 327static void check_node_name_format(struct check *c, struct dt_info *dti, 328 struct node *node) 329{ 330 if (strchr(get_unitname(node), '@')) 331 FAIL(c, dti, node, "multiple '@' characters in node name"); 332} 333ERROR(node_name_format, check_node_name_format, NULL, &node_name_chars); 334 335static void check_unit_address_vs_reg(struct check *c, struct dt_info *dti, 336 struct node *node) 337{ 338 const char *unitname = get_unitname(node); 339 struct property *prop = get_property(node, "reg"); 340 341 if (get_subnode(node, "__overlay__")) { 342 /* HACK: Overlay fragments are a special case */ 343 return; 344 } 345 346 if (!prop) { 347 prop = get_property(node, "ranges"); 348 if (prop && !prop->val.len) 349 prop = NULL; 350 } 351 352 if (prop) { 353 if (!unitname[0]) 354 FAIL(c, dti, node, "node has a reg or ranges property, but no unit name"); 355 } else { 356 if (unitname[0]) 357 FAIL(c, dti, node, "node has a unit name, but no reg property"); 358 } 359} 360WARNING(unit_address_vs_reg, check_unit_address_vs_reg, NULL); 361 362static void check_property_name_chars(struct check *c, struct dt_info *dti, 363 struct node *node) 364{ 365 struct property *prop; 366 367 for_each_property(node, prop) { 368 int n = strspn(prop->name, c->data); 369 370 if (n < strlen(prop->name)) 371 FAIL_PROP(c, dti, node, prop, "Bad character '%c' in property name", 372 prop->name[n]); 373 } 374} 375ERROR(property_name_chars, check_property_name_chars, PROPNODECHARS); 376 377static void check_property_name_chars_strict(struct check *c, 378 struct dt_info *dti, 379 struct node *node) 380{ 381 struct property *prop; 382 383 for_each_property(node, prop) { 384 const char *name = prop->name; 385 int n = strspn(name, c->data); 386 387 if (n == strlen(prop->name)) 388 continue; 389 390 /* Certain names are whitelisted */ 391 if (streq(name, "device_type")) 392 continue; 393 394 /* 395 * # is only allowed at the beginning of property names not counting 396 * the vendor prefix. 397 */ 398 if (name[n] == '#' && ((n == 0) || (name[n-1] == ','))) { 399 name += n + 1; 400 n = strspn(name, c->data); 401 } 402 if (n < strlen(name)) 403 FAIL_PROP(c, dti, node, prop, "Character '%c' not recommended in property name", 404 name[n]); 405 } 406} 407CHECK(property_name_chars_strict, check_property_name_chars_strict, PROPNODECHARSSTRICT); 408 409#define DESCLABEL_FMT "%s%s%s%s%s" 410#define DESCLABEL_ARGS(node,prop,mark) \ 411 ((mark) ? "value of " : ""), \ 412 ((prop) ? "'" : ""), \ 413 ((prop) ? (prop)->name : ""), \ 414 ((prop) ? "' in " : ""), (node)->fullpath 415 416static void check_duplicate_label(struct check *c, struct dt_info *dti, 417 const char *label, struct node *node, 418 struct property *prop, struct marker *mark) 419{ 420 struct node *dt = dti->dt; 421 struct node *othernode = NULL; 422 struct property *otherprop = NULL; 423 struct marker *othermark = NULL; 424 425 othernode = get_node_by_label(dt, label); 426 427 if (!othernode) 428 otherprop = get_property_by_label(dt, label, &othernode); 429 if (!othernode) 430 othermark = get_marker_label(dt, label, &othernode, 431 &otherprop); 432 433 if (!othernode) 434 return; 435 436 if ((othernode != node) || (otherprop != prop) || (othermark != mark)) 437 FAIL(c, dti, node, "Duplicate label '%s' on " DESCLABEL_FMT 438 " and " DESCLABEL_FMT, 439 label, DESCLABEL_ARGS(node, prop, mark), 440 DESCLABEL_ARGS(othernode, otherprop, othermark)); 441} 442 443static void check_duplicate_label_node(struct check *c, struct dt_info *dti, 444 struct node *node) 445{ 446 struct label *l; 447 struct property *prop; 448 449 for_each_label(node->labels, l) 450 check_duplicate_label(c, dti, l->label, node, NULL, NULL); 451 452 for_each_property(node, prop) { 453 struct marker *m = prop->val.markers; 454 455 for_each_label(prop->labels, l) 456 check_duplicate_label(c, dti, l->label, node, prop, NULL); 457 458 for_each_marker_of_type(m, LABEL) 459 check_duplicate_label(c, dti, m->ref, node, prop, m); 460 } 461} 462ERROR(duplicate_label, check_duplicate_label_node, NULL); 463 464static cell_t check_phandle_prop(struct check *c, struct dt_info *dti, 465 struct node *node, const char *propname) 466{ 467 struct node *root = dti->dt; 468 struct property *prop; 469 struct marker *m; 470 cell_t phandle; 471 472 prop = get_property(node, propname); 473 if (!prop) 474 return 0; 475 476 if (prop->val.len != sizeof(cell_t)) { 477 FAIL_PROP(c, dti, node, prop, "bad length (%d) %s property", 478 prop->val.len, prop->name); 479 return 0; 480 } 481 482 m = prop->val.markers; 483 for_each_marker_of_type(m, REF_PHANDLE) { 484 assert(m->offset == 0); 485 if (node != get_node_by_ref(root, m->ref)) 486 /* "Set this node's phandle equal to some 487 * other node's phandle". That's nonsensical 488 * by construction. */ { 489 FAIL(c, dti, node, "%s is a reference to another node", 490 prop->name); 491 } 492 /* But setting this node's phandle equal to its own 493 * phandle is allowed - that means allocate a unique 494 * phandle for this node, even if it's not otherwise 495 * referenced. The value will be filled in later, so 496 * we treat it as having no phandle data for now. */ 497 return 0; 498 } 499 500 phandle = propval_cell(prop); 501 502 if ((phandle == 0) || (phandle == -1)) { 503 FAIL_PROP(c, dti, node, prop, "bad value (0x%x) in %s property", 504 phandle, prop->name); 505 return 0; 506 } 507 508 return phandle; 509} 510 511static void check_explicit_phandles(struct check *c, struct dt_info *dti, 512 struct node *node) 513{ 514 struct node *root = dti->dt; 515 struct node *other; 516 cell_t phandle, linux_phandle; 517 518 /* Nothing should have assigned phandles yet */ 519 assert(!node->phandle); 520 521 phandle = check_phandle_prop(c, dti, node, "phandle"); 522 523 linux_phandle = check_phandle_prop(c, dti, node, "linux,phandle"); 524 525 if (!phandle && !linux_phandle) 526 /* No valid phandles; nothing further to check */ 527 return; 528 529 if (linux_phandle && phandle && (phandle != linux_phandle)) 530 FAIL(c, dti, node, "mismatching 'phandle' and 'linux,phandle'" 531 " properties"); 532 533 if (linux_phandle && !phandle) 534 phandle = linux_phandle; 535 536 other = get_node_by_phandle(root, phandle); 537 if (other && (other != node)) { 538 FAIL(c, dti, node, "duplicated phandle 0x%x (seen before at %s)", 539 phandle, other->fullpath); 540 return; 541 } 542 543 node->phandle = phandle; 544} 545ERROR(explicit_phandles, check_explicit_phandles, NULL); 546 547static void check_name_properties(struct check *c, struct dt_info *dti, 548 struct node *node) 549{ 550 struct property **pp, *prop = NULL; 551 552 for (pp = &node->proplist; *pp; pp = &((*pp)->next)) 553 if (streq((*pp)->name, "name")) { 554 prop = *pp; 555 break; 556 } 557 558 if (!prop) 559 return; /* No name property, that's fine */ 560 561 if ((prop->val.len != node->basenamelen+1) 562 || (memcmp(prop->val.val, node->name, node->basenamelen) != 0)) { 563 FAIL(c, dti, node, "\"name\" property is incorrect (\"%s\" instead" 564 " of base node name)", prop->val.val); 565 } else { 566 /* The name property is correct, and therefore redundant. 567 * Delete it */ 568 *pp = prop->next; 569 free(prop->name); 570 data_free(prop->val); 571 free(prop); 572 } 573} 574ERROR_IF_NOT_STRING(name_is_string, "name"); 575ERROR(name_properties, check_name_properties, NULL, &name_is_string); 576 577/* 578 * Reference fixup functions 579 */ 580 581static void fixup_phandle_references(struct check *c, struct dt_info *dti, 582 struct node *node) 583{ 584 struct node *dt = dti->dt; 585 struct property *prop; 586 587 for_each_property(node, prop) { 588 struct marker *m = prop->val.markers; 589 struct node *refnode; 590 cell_t phandle; 591 592 for_each_marker_of_type(m, REF_PHANDLE) { 593 assert(m->offset + sizeof(cell_t) <= prop->val.len); 594 595 refnode = get_node_by_ref(dt, m->ref); 596 if (! refnode) { 597 if (!(dti->dtsflags & DTSF_PLUGIN)) 598 FAIL(c, dti, node, "Reference to non-existent node or " 599 "label \"%s\"\n", m->ref); 600 else /* mark the entry as unresolved */ 601 *((fdt32_t *)(prop->val.val + m->offset)) = 602 cpu_to_fdt32(0xffffffff); 603 continue; 604 } 605 606 phandle = get_node_phandle(dt, refnode); 607 *((fdt32_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle); 608 609 reference_node(refnode); 610 } 611 } 612} 613ERROR(phandle_references, fixup_phandle_references, NULL, 614 &duplicate_node_names, &explicit_phandles); 615 616static void fixup_path_references(struct check *c, struct dt_info *dti, 617 struct node *node) 618{ 619 struct node *dt = dti->dt; 620 struct property *prop; 621 622 for_each_property(node, prop) { 623 struct marker *m = prop->val.markers; 624 struct node *refnode; 625 char *path; 626 627 for_each_marker_of_type(m, REF_PATH) { 628 assert(m->offset <= prop->val.len); 629 630 refnode = get_node_by_ref(dt, m->ref); 631 if (!refnode) { 632 FAIL(c, dti, node, "Reference to non-existent node or label \"%s\"\n", 633 m->ref); 634 continue; 635 } 636 637 path = refnode->fullpath; 638 prop->val = data_insert_at_marker(prop->val, m, path, 639 strlen(path) + 1); 640 641 reference_node(refnode); 642 } 643 } 644} 645ERROR(path_references, fixup_path_references, NULL, &duplicate_node_names); 646 647static void fixup_omit_unused_nodes(struct check *c, struct dt_info *dti, 648 struct node *node) 649{ 650 if (generate_symbols && node->labels) 651 return; 652 if (node->omit_if_unused && !node->is_referenced) 653 delete_node(node); 654} 655ERROR(omit_unused_nodes, fixup_omit_unused_nodes, NULL, &phandle_references, &path_references); 656 657/* 658 * Semantic checks 659 */ 660WARNING_IF_NOT_CELL(address_cells_is_cell, "#address-cells"); 661WARNING_IF_NOT_CELL(size_cells_is_cell, "#size-cells"); 662WARNING_IF_NOT_CELL(interrupt_cells_is_cell, "#interrupt-cells"); 663 664WARNING_IF_NOT_STRING(device_type_is_string, "device_type"); 665WARNING_IF_NOT_STRING(model_is_string, "model"); 666WARNING_IF_NOT_STRING(status_is_string, "status"); 667WARNING_IF_NOT_STRING(label_is_string, "label"); 668 669WARNING_IF_NOT_STRING_LIST(compatible_is_string_list, "compatible"); 670 671static void check_names_is_string_list(struct check *c, struct dt_info *dti, 672 struct node *node) 673{ 674 struct property *prop; 675 676 for_each_property(node, prop) { 677 const char *s = strrchr(prop->name, '-'); 678 if (!s || !streq(s, "-names")) 679 continue; 680 681 c->data = prop->name; 682 check_is_string_list(c, dti, node); 683 } 684} 685WARNING(names_is_string_list, check_names_is_string_list, NULL); 686 687static void check_alias_paths(struct check *c, struct dt_info *dti, 688 struct node *node) 689{ 690 struct property *prop; 691 692 if (!streq(node->name, "aliases")) 693 return; 694 695 for_each_property(node, prop) { 696 if (streq(prop->name, "phandle") 697 || streq(prop->name, "linux,phandle")) { 698 continue; 699 } 700 701 if (!prop->val.val || !get_node_by_path(dti->dt, prop->val.val)) { 702 FAIL_PROP(c, dti, node, prop, "aliases property is not a valid node (%s)", 703 prop->val.val); 704 continue; 705 } 706 if (strspn(prop->name, LOWERCASE DIGITS "-") != strlen(prop->name)) 707 FAIL(c, dti, node, "aliases property name must include only lowercase and '-'"); 708 } 709} 710WARNING(alias_paths, check_alias_paths, NULL); 711 712static void fixup_addr_size_cells(struct check *c, struct dt_info *dti, 713 struct node *node) 714{ 715 struct property *prop; 716 717 node->addr_cells = -1; 718 node->size_cells = -1; 719 720 prop = get_property(node, "#address-cells"); 721 if (prop) 722 node->addr_cells = propval_cell(prop); 723 724 prop = get_property(node, "#size-cells"); 725 if (prop) 726 node->size_cells = propval_cell(prop); 727} 728WARNING(addr_size_cells, fixup_addr_size_cells, NULL, 729 &address_cells_is_cell, &size_cells_is_cell); 730 731#define node_addr_cells(n) \ 732 (((n)->addr_cells == -1) ? 2 : (n)->addr_cells) 733#define node_size_cells(n) \ 734 (((n)->size_cells == -1) ? 1 : (n)->size_cells) 735 736static void check_reg_format(struct check *c, struct dt_info *dti, 737 struct node *node) 738{ 739 struct property *prop; 740 int addr_cells, size_cells, entrylen; 741 742 prop = get_property(node, "reg"); 743 if (!prop) 744 return; /* No "reg", that's fine */ 745 746 if (!node->parent) { 747 FAIL(c, dti, node, "Root node has a \"reg\" property"); 748 return; 749 } 750 751 if (prop->val.len == 0) 752 FAIL_PROP(c, dti, node, prop, "property is empty"); 753 754 addr_cells = node_addr_cells(node->parent); 755 size_cells = node_size_cells(node->parent); 756 entrylen = (addr_cells + size_cells) * sizeof(cell_t); 757 758 if (!entrylen || (prop->val.len % entrylen) != 0) 759 FAIL_PROP(c, dti, node, prop, "property has invalid length (%d bytes) " 760 "(#address-cells == %d, #size-cells == %d)", 761 prop->val.len, addr_cells, size_cells); 762} 763WARNING(reg_format, check_reg_format, NULL, &addr_size_cells); 764 765static void check_ranges_format(struct check *c, struct dt_info *dti, 766 struct node *node) 767{ 768 struct property *prop; 769 int c_addr_cells, p_addr_cells, c_size_cells, p_size_cells, entrylen; 770 771 prop = get_property(node, "ranges"); 772 if (!prop) 773 return; 774 775 if (!node->parent) { 776 FAIL_PROP(c, dti, node, prop, "Root node has a \"ranges\" property"); 777 return; 778 } 779 780 p_addr_cells = node_addr_cells(node->parent); 781 p_size_cells = node_size_cells(node->parent); 782 c_addr_cells = node_addr_cells(node); 783 c_size_cells = node_size_cells(node); 784 entrylen = (p_addr_cells + c_addr_cells + c_size_cells) * sizeof(cell_t); 785 786 if (prop->val.len == 0) { 787 if (p_addr_cells != c_addr_cells) 788 FAIL_PROP(c, dti, node, prop, "empty \"ranges\" property but its " 789 "#address-cells (%d) differs from %s (%d)", 790 c_addr_cells, node->parent->fullpath, 791 p_addr_cells); 792 if (p_size_cells != c_size_cells) 793 FAIL_PROP(c, dti, node, prop, "empty \"ranges\" property but its " 794 "#size-cells (%d) differs from %s (%d)", 795 c_size_cells, node->parent->fullpath, 796 p_size_cells); 797 } else if ((prop->val.len % entrylen) != 0) { 798 FAIL_PROP(c, dti, node, prop, "\"ranges\" property has invalid length (%d bytes) " 799 "(parent #address-cells == %d, child #address-cells == %d, " 800 "#size-cells == %d)", prop->val.len, 801 p_addr_cells, c_addr_cells, c_size_cells); 802 } 803} 804WARNING(ranges_format, check_ranges_format, NULL, &addr_size_cells); 805 806static const struct bus_type pci_bus = { 807 .name = "PCI", 808}; 809 810static void check_pci_bridge(struct check *c, struct dt_info *dti, struct node *node) 811{ 812 struct property *prop; 813 cell_t *cells; 814 815 prop = get_property(node, "device_type"); 816 if (!prop || !streq(prop->val.val, "pci")) 817 return; 818 819 node->bus = &pci_bus; 820 821 if (!strprefixeq(node->name, node->basenamelen, "pci") && 822 !strprefixeq(node->name, node->basenamelen, "pcie")) 823 FAIL(c, dti, node, "node name is not \"pci\" or \"pcie\""); 824 825 prop = get_property(node, "ranges"); 826 if (!prop) 827 FAIL(c, dti, node, "missing ranges for PCI bridge (or not a bridge)"); 828 829 if (node_addr_cells(node) != 3) 830 FAIL(c, dti, node, "incorrect #address-cells for PCI bridge"); 831 if (node_size_cells(node) != 2) 832 FAIL(c, dti, node, "incorrect #size-cells for PCI bridge"); 833 834 prop = get_property(node, "bus-range"); 835 if (!prop) 836 return; 837 838 if (prop->val.len != (sizeof(cell_t) * 2)) { 839 FAIL_PROP(c, dti, node, prop, "value must be 2 cells"); 840 return; 841 } 842 cells = (cell_t *)prop->val.val; 843 if (fdt32_to_cpu(cells[0]) > fdt32_to_cpu(cells[1])) 844 FAIL_PROP(c, dti, node, prop, "1st cell must be less than or equal to 2nd cell"); 845 if (fdt32_to_cpu(cells[1]) > 0xff) 846 FAIL_PROP(c, dti, node, prop, "maximum bus number must be less than 256"); 847} 848WARNING(pci_bridge, check_pci_bridge, NULL, 849 &device_type_is_string, &addr_size_cells); 850 851static void check_pci_device_bus_num(struct check *c, struct dt_info *dti, struct node *node) 852{ 853 struct property *prop; 854 unsigned int bus_num, min_bus, max_bus; 855 cell_t *cells; 856 857 if (!node->parent || (node->parent->bus != &pci_bus)) 858 return; 859 860 prop = get_property(node, "reg"); 861 if (!prop) 862 return; 863 864 cells = (cell_t *)prop->val.val; 865 bus_num = (fdt32_to_cpu(cells[0]) & 0x00ff0000) >> 16; 866 867 prop = get_property(node->parent, "bus-range"); 868 if (!prop) { 869 min_bus = max_bus = 0; 870 } else { 871 cells = (cell_t *)prop->val.val; 872 min_bus = fdt32_to_cpu(cells[0]); 873 max_bus = fdt32_to_cpu(cells[0]); 874 } 875 if ((bus_num < min_bus) || (bus_num > max_bus)) 876 FAIL_PROP(c, dti, node, prop, "PCI bus number %d out of range, expected (%d - %d)", 877 bus_num, min_bus, max_bus); 878} 879WARNING(pci_device_bus_num, check_pci_device_bus_num, NULL, ®_format, &pci_bridge); 880 881static void check_pci_device_reg(struct check *c, struct dt_info *dti, struct node *node) 882{ 883 struct property *prop; 884 const char *unitname = get_unitname(node); 885 char unit_addr[5]; 886 unsigned int dev, func, reg; 887 cell_t *cells; 888 889 if (!node->parent || (node->parent->bus != &pci_bus)) 890 return; 891 892 prop = get_property(node, "reg"); 893 if (!prop) { 894 FAIL(c, dti, node, "missing PCI reg property"); 895 return; 896 } 897 898 cells = (cell_t *)prop->val.val; 899 if (cells[1] || cells[2]) 900 FAIL_PROP(c, dti, node, prop, "PCI reg config space address cells 2 and 3 must be 0"); 901 902 reg = fdt32_to_cpu(cells[0]); 903 dev = (reg & 0xf800) >> 11; 904 func = (reg & 0x700) >> 8; 905 906 if (reg & 0xff000000) 907 FAIL_PROP(c, dti, node, prop, "PCI reg address is not configuration space"); 908 if (reg & 0x000000ff) 909 FAIL_PROP(c, dti, node, prop, "PCI reg config space address register number must be 0"); 910 911 if (func == 0) { 912 snprintf(unit_addr, sizeof(unit_addr), "%x", dev); 913 if (streq(unitname, unit_addr)) 914 return; 915 } 916 917 snprintf(unit_addr, sizeof(unit_addr), "%x,%x", dev, func); 918 if (streq(unitname, unit_addr)) 919 return; 920 921 FAIL(c, dti, node, "PCI unit address format error, expected \"%s\"", 922 unit_addr); 923} 924WARNING(pci_device_reg, check_pci_device_reg, NULL, ®_format, &pci_bridge); 925 926static const struct bus_type simple_bus = { 927 .name = "simple-bus", 928}; 929 930static bool node_is_compatible(struct node *node, const char *compat) 931{ 932 struct property *prop; 933 const char *str, *end; 934 935 prop = get_property(node, "compatible"); 936 if (!prop) 937 return false; 938 939 for (str = prop->val.val, end = str + prop->val.len; str < end; 940 str += strnlen(str, end - str) + 1) { 941 if (streq(str, compat)) 942 return true; 943 } 944 return false; 945} 946 947static void check_simple_bus_bridge(struct check *c, struct dt_info *dti, struct node *node) 948{ 949 if (node_is_compatible(node, "simple-bus")) 950 node->bus = &simple_bus; 951} 952WARNING(simple_bus_bridge, check_simple_bus_bridge, NULL, 953 &addr_size_cells, &compatible_is_string_list); 954 955static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct node *node) 956{ 957 struct property *prop; 958 const char *unitname = get_unitname(node); 959 char unit_addr[17]; 960 unsigned int size; 961 uint64_t reg = 0; 962 cell_t *cells = NULL; 963 964 if (!node->parent || (node->parent->bus != &simple_bus)) 965 return; 966 967 prop = get_property(node, "reg"); 968 if (prop) 969 cells = (cell_t *)prop->val.val; 970 else { 971 prop = get_property(node, "ranges"); 972 if (prop && prop->val.len) 973 /* skip of child address */ 974 cells = ((cell_t *)prop->val.val) + node_addr_cells(node); 975 } 976 977 if (!cells) { 978 if (node->parent->parent && !(node->bus == &simple_bus)) 979 FAIL(c, dti, node, "missing or empty reg/ranges property"); 980 return; 981 } 982 983 size = node_addr_cells(node->parent); 984 while (size--) 985 reg = (reg << 32) | fdt32_to_cpu(*(cells++)); 986 987 snprintf(unit_addr, sizeof(unit_addr), "%"PRIx64, reg); 988 if (!streq(unitname, unit_addr)) 989 FAIL(c, dti, node, "simple-bus unit address format error, expected \"%s\"", 990 unit_addr); 991} 992WARNING(simple_bus_reg, check_simple_bus_reg, NULL, ®_format, &simple_bus_bridge); 993 994static const struct bus_type i2c_bus = { 995 .name = "i2c-bus", 996}; 997 998static void check_i2c_bus_bridge(struct check *c, struct dt_info *dti, struct node *node) 999{ 1000 if (strprefixeq(node->name, node->basenamelen, "i2c-bus") || 1001 strprefixeq(node->name, node->basenamelen, "i2c-arb")) { 1002 node->bus = &i2c_bus; 1003 } else if (strprefixeq(node->name, node->basenamelen, "i2c")) { 1004 struct node *child; 1005 for_each_child(node, child) { 1006 if (strprefixeq(child->name, node->basenamelen, "i2c-bus")) 1007 return; 1008 } 1009 node->bus = &i2c_bus; 1010 } else 1011 return; 1012 1013 if (!node->children) 1014 return; 1015 1016 if (node_addr_cells(node) != 1) 1017 FAIL(c, dti, node, "incorrect #address-cells for I2C bus"); 1018 if (node_size_cells(node) != 0) 1019 FAIL(c, dti, node, "incorrect #size-cells for I2C bus"); 1020 1021} 1022WARNING(i2c_bus_bridge, check_i2c_bus_bridge, NULL, &addr_size_cells); 1023 1024static void check_i2c_bus_reg(struct check *c, struct dt_info *dti, struct node *node) 1025{ 1026 struct property *prop; 1027 const char *unitname = get_unitname(node); 1028 char unit_addr[17]; 1029 uint32_t reg = 0; 1030 int len; 1031 cell_t *cells = NULL; 1032 1033 if (!node->parent || (node->parent->bus != &i2c_bus)) 1034 return; 1035 1036 prop = get_property(node, "reg"); 1037 if (prop) 1038 cells = (cell_t *)prop->val.val; 1039 1040 if (!cells) { 1041 FAIL(c, dti, node, "missing or empty reg property"); 1042 return; 1043 } 1044 1045 reg = fdt32_to_cpu(*cells); 1046 snprintf(unit_addr, sizeof(unit_addr), "%x", reg); 1047 if (!streq(unitname, unit_addr)) 1048 FAIL(c, dti, node, "I2C bus unit address format error, expected \"%s\"", 1049 unit_addr); 1050 1051 for (len = prop->val.len; len > 0; len -= 4) { 1052 reg = fdt32_to_cpu(*(cells++)); 1053 if (reg > 0x3ff) 1054 FAIL_PROP(c, dti, node, prop, "I2C address must be less than 10-bits, got \"0x%x\"", 1055 reg); 1056 1057 } 1058} 1059WARNING(i2c_bus_reg, check_i2c_bus_reg, NULL, ®_format, &i2c_bus_bridge); 1060 1061static const struct bus_type spi_bus = { 1062 .name = "spi-bus", 1063}; 1064 1065static void check_spi_bus_bridge(struct check *c, struct dt_info *dti, struct node *node) 1066{ 1067 int spi_addr_cells = 1; 1068 1069 if (strprefixeq(node->name, node->basenamelen, "spi")) { 1070 node->bus = &spi_bus; 1071 } else { 1072 /* Try to detect SPI buses which don't have proper node name */ 1073 struct node *child; 1074 1075 if (node_addr_cells(node) != 1 || node_size_cells(node) != 0) 1076 return; 1077 1078 for_each_child(node, child) { 1079 struct property *prop; 1080 for_each_property(child, prop) { 1081 if (strprefixeq(prop->name, 4, "spi-")) { 1082 node->bus = &spi_bus; 1083 break; 1084 } 1085 } 1086 if (node->bus == &spi_bus) 1087 break; 1088 } 1089 1090 if (node->bus == &spi_bus && get_property(node, "reg")) 1091 FAIL(c, dti, node, "node name for SPI buses should be 'spi'"); 1092 } 1093 if (node->bus != &spi_bus || !node->children) 1094 return; 1095 1096 if (get_property(node, "spi-slave")) 1097 spi_addr_cells = 0; 1098 if (node_addr_cells(node) != spi_addr_cells) 1099 FAIL(c, dti, node, "incorrect #address-cells for SPI bus"); 1100 if (node_size_cells(node) != 0) 1101 FAIL(c, dti, node, "incorrect #size-cells for SPI bus"); 1102 1103} 1104WARNING(spi_bus_bridge, check_spi_bus_bridge, NULL, &addr_size_cells); 1105 1106static void check_spi_bus_reg(struct check *c, struct dt_info *dti, struct node *node) 1107{ 1108 struct property *prop; 1109 const char *unitname = get_unitname(node); 1110 char unit_addr[9]; 1111 uint32_t reg = 0; 1112 cell_t *cells = NULL; 1113 1114 if (!node->parent || (node->parent->bus != &spi_bus)) 1115 return; 1116 1117 if (get_property(node->parent, "spi-slave")) 1118 return; 1119 1120 prop = get_property(node, "reg"); 1121 if (prop) 1122 cells = (cell_t *)prop->val.val; 1123 1124 if (!cells) { 1125 FAIL(c, dti, node, "missing or empty reg property"); 1126 return; 1127 } 1128 1129 reg = fdt32_to_cpu(*cells); 1130 snprintf(unit_addr, sizeof(unit_addr), "%x", reg); 1131 if (!streq(unitname, unit_addr)) 1132 FAIL(c, dti, node, "SPI bus unit address format error, expected \"%s\"", 1133 unit_addr); 1134} 1135WARNING(spi_bus_reg, check_spi_bus_reg, NULL, ®_format, &spi_bus_bridge); 1136 1137static void check_unit_address_format(struct check *c, struct dt_info *dti, 1138 struct node *node) 1139{ 1140 const char *unitname = get_unitname(node); 1141 1142 if (node->parent && node->parent->bus) 1143 return; 1144 1145 if (!unitname[0]) 1146 return; 1147 1148 if (!strncmp(unitname, "0x", 2)) { 1149 FAIL(c, dti, node, "unit name should not have leading \"0x\""); 1150 /* skip over 0x for next test */ 1151 unitname += 2; 1152 } 1153 if (unitname[0] == '0' && isxdigit(unitname[1])) 1154 FAIL(c, dti, node, "unit name should not have leading 0s"); 1155} 1156WARNING(unit_address_format, check_unit_address_format, NULL, 1157 &node_name_format, &pci_bridge, &simple_bus_bridge); 1158 1159/* 1160 * Style checks 1161 */ 1162static void check_avoid_default_addr_size(struct check *c, struct dt_info *dti, 1163 struct node *node) 1164{ 1165 struct property *reg, *ranges; 1166 1167 if (!node->parent) 1168 return; /* Ignore root node */ 1169 1170 reg = get_property(node, "reg"); 1171 ranges = get_property(node, "ranges"); 1172 1173 if (!reg && !ranges) 1174 return; 1175 1176 if (node->parent->addr_cells == -1) 1177 FAIL(c, dti, node, "Relying on default #address-cells value"); 1178 1179 if (node->parent->size_cells == -1) 1180 FAIL(c, dti, node, "Relying on default #size-cells value"); 1181} 1182WARNING(avoid_default_addr_size, check_avoid_default_addr_size, NULL, 1183 &addr_size_cells); 1184 1185static void check_avoid_unnecessary_addr_size(struct check *c, struct dt_info *dti, 1186 struct node *node) 1187{ 1188 struct property *prop; 1189 struct node *child; 1190 bool has_reg = false; 1191 1192 if (!node->parent || node->addr_cells < 0 || node->size_cells < 0) 1193 return; 1194 1195 if (get_property(node, "ranges") || !node->children) 1196 return; 1197 1198 for_each_child(node, child) { 1199 prop = get_property(child, "reg"); 1200 if (prop) 1201 has_reg = true; 1202 } 1203 1204 if (!has_reg) 1205 FAIL(c, dti, node, "unnecessary #address-cells/#size-cells without \"ranges\" or child \"reg\" property"); 1206} 1207WARNING(avoid_unnecessary_addr_size, check_avoid_unnecessary_addr_size, NULL, &avoid_default_addr_size); 1208 1209static bool node_is_disabled(struct node *node) 1210{ 1211 struct property *prop; 1212 1213 prop = get_property(node, "status"); 1214 if (prop) { 1215 char *str = prop->val.val; 1216 if (streq("disabled", str)) 1217 return true; 1218 } 1219 1220 return false; 1221} 1222 1223static void check_unique_unit_address_common(struct check *c, 1224 struct dt_info *dti, 1225 struct node *node, 1226 bool disable_check) 1227{ 1228 struct node *childa; 1229 1230 if (node->addr_cells < 0 || node->size_cells < 0) 1231 return; 1232 1233 if (!node->children) 1234 return; 1235 1236 for_each_child(node, childa) { 1237 struct node *childb; 1238 const char *addr_a = get_unitname(childa); 1239 1240 if (!strlen(addr_a)) 1241 continue; 1242 1243 if (disable_check && node_is_disabled(childa)) 1244 continue; 1245 1246 for_each_child(node, childb) { 1247 const char *addr_b = get_unitname(childb); 1248 if (childa == childb) 1249 break; 1250 1251 if (disable_check && node_is_disabled(childb)) 1252 continue; 1253 1254 if (streq(addr_a, addr_b)) 1255 FAIL(c, dti, childb, "duplicate unit-address (also used in node %s)", childa->fullpath); 1256 } 1257 } 1258} 1259 1260static void check_unique_unit_address(struct check *c, struct dt_info *dti, 1261 struct node *node) 1262{ 1263 check_unique_unit_address_common(c, dti, node, false); 1264} 1265WARNING(unique_unit_address, check_unique_unit_address, NULL, &avoid_default_addr_size); 1266 1267static void check_unique_unit_address_if_enabled(struct check *c, struct dt_info *dti, 1268 struct node *node) 1269{ 1270 check_unique_unit_address_common(c, dti, node, true); 1271} 1272CHECK_ENTRY(unique_unit_address_if_enabled, check_unique_unit_address_if_enabled, 1273 NULL, false, false, &avoid_default_addr_size); 1274 1275static void check_obsolete_chosen_interrupt_controller(struct check *c, 1276 struct dt_info *dti, 1277 struct node *node) 1278{ 1279 struct node *dt = dti->dt; 1280 struct node *chosen; 1281 struct property *prop; 1282 1283 if (node != dt) 1284 return; 1285 1286 1287 chosen = get_node_by_path(dt, "/chosen"); 1288 if (!chosen) 1289 return; 1290 1291 prop = get_property(chosen, "interrupt-controller"); 1292 if (prop) 1293 FAIL_PROP(c, dti, node, prop, 1294 "/chosen has obsolete \"interrupt-controller\" property"); 1295} 1296WARNING(obsolete_chosen_interrupt_controller, 1297 check_obsolete_chosen_interrupt_controller, NULL); 1298 1299static void check_chosen_node_is_root(struct check *c, struct dt_info *dti, 1300 struct node *node) 1301{ 1302 if (!streq(node->name, "chosen")) 1303 return; 1304 1305 if (node->parent != dti->dt) 1306 FAIL(c, dti, node, "chosen node must be at root node"); 1307} 1308WARNING(chosen_node_is_root, check_chosen_node_is_root, NULL); 1309 1310static void check_chosen_node_bootargs(struct check *c, struct dt_info *dti, 1311 struct node *node) 1312{ 1313 struct property *prop; 1314 1315 if (!streq(node->name, "chosen")) 1316 return; 1317 1318 prop = get_property(node, "bootargs"); 1319 if (!prop) 1320 return; 1321 1322 c->data = prop->name; 1323 check_is_string(c, dti, node); 1324} 1325WARNING(chosen_node_bootargs, check_chosen_node_bootargs, NULL); 1326 1327static void check_chosen_node_stdout_path(struct check *c, struct dt_info *dti, 1328 struct node *node) 1329{ 1330 struct property *prop; 1331 1332 if (!streq(node->name, "chosen")) 1333 return; 1334 1335 prop = get_property(node, "stdout-path"); 1336 if (!prop) { 1337 prop = get_property(node, "linux,stdout-path"); 1338 if (!prop) 1339 return; 1340 FAIL_PROP(c, dti, node, prop, "Use 'stdout-path' instead"); 1341 } 1342 1343 c->data = prop->name; 1344 check_is_string(c, dti, node); 1345} 1346WARNING(chosen_node_stdout_path, check_chosen_node_stdout_path, NULL); 1347 1348struct provider { 1349 const char *prop_name; 1350 const char *cell_name; 1351 bool optional; 1352}; 1353 1354static void check_property_phandle_args(struct check *c, 1355 struct dt_info *dti, 1356 struct node *node, 1357 struct property *prop, 1358 const struct provider *provider) 1359{ 1360 struct node *root = dti->dt; 1361 int cell, cellsize = 0; 1362 1363 if (prop->val.len % sizeof(cell_t)) { 1364 FAIL_PROP(c, dti, node, prop, 1365 "property size (%d) is invalid, expected multiple of %zu", 1366 prop->val.len, sizeof(cell_t)); 1367 return; 1368 } 1369 1370 for (cell = 0; cell < prop->val.len / sizeof(cell_t); cell += cellsize + 1) { 1371 struct node *provider_node; 1372 struct property *cellprop; 1373 int phandle; 1374 1375 phandle = propval_cell_n(prop, cell); 1376 /* 1377 * Some bindings use a cell value 0 or -1 to skip over optional 1378 * entries when each index position has a specific definition. 1379 */ 1380 if (phandle == 0 || phandle == -1) { 1381 /* Give up if this is an overlay with external references */ 1382 if (dti->dtsflags & DTSF_PLUGIN) 1383 break; 1384 1385 cellsize = 0; 1386 continue; 1387 } 1388 1389 /* If we have markers, verify the current cell is a phandle */ 1390 if (prop->val.markers) { 1391 struct marker *m = prop->val.markers; 1392 for_each_marker_of_type(m, REF_PHANDLE) { 1393 if (m->offset == (cell * sizeof(cell_t))) 1394 break; 1395 } 1396 if (!m) 1397 FAIL_PROP(c, dti, node, prop, 1398 "cell %d is not a phandle reference", 1399 cell); 1400 } 1401 1402 provider_node = get_node_by_phandle(root, phandle); 1403 if (!provider_node) { 1404 FAIL_PROP(c, dti, node, prop, 1405 "Could not get phandle node for (cell %d)", 1406 cell); 1407 break; 1408 } 1409 1410 cellprop = get_property(provider_node, provider->cell_name); 1411 if (cellprop) { 1412 cellsize = propval_cell(cellprop); 1413 } else if (provider->optional) { 1414 cellsize = 0; 1415 } else { 1416 FAIL(c, dti, node, "Missing property '%s' in node %s or bad phandle (referred from %s[%d])", 1417 provider->cell_name, 1418 provider_node->fullpath, 1419 prop->name, cell); 1420 break; 1421 } 1422 1423 if (prop->val.len < ((cell + cellsize + 1) * sizeof(cell_t))) { 1424 FAIL_PROP(c, dti, node, prop, 1425 "property size (%d) too small for cell size %d", 1426 prop->val.len, cellsize); 1427 } 1428 } 1429} 1430 1431static void check_provider_cells_property(struct check *c, 1432 struct dt_info *dti, 1433 struct node *node) 1434{ 1435 struct provider *provider = c->data; 1436 struct property *prop; 1437 1438 prop = get_property(node, provider->prop_name); 1439 if (!prop) 1440 return; 1441 1442 check_property_phandle_args(c, dti, node, prop, provider); 1443} 1444#define WARNING_PROPERTY_PHANDLE_CELLS(nm, propname, cells_name, ...) \ 1445 static struct provider nm##_provider = { (propname), (cells_name), __VA_ARGS__ }; \ 1446 WARNING(nm##_property, check_provider_cells_property, &nm##_provider, &phandle_references); 1447 1448WARNING_PROPERTY_PHANDLE_CELLS(clocks, "clocks", "#clock-cells"); 1449WARNING_PROPERTY_PHANDLE_CELLS(cooling_device, "cooling-device", "#cooling-cells"); 1450WARNING_PROPERTY_PHANDLE_CELLS(dmas, "dmas", "#dma-cells"); 1451WARNING_PROPERTY_PHANDLE_CELLS(hwlocks, "hwlocks", "#hwlock-cells"); 1452WARNING_PROPERTY_PHANDLE_CELLS(interrupts_extended, "interrupts-extended", "#interrupt-cells"); 1453WARNING_PROPERTY_PHANDLE_CELLS(io_channels, "io-channels", "#io-channel-cells"); 1454WARNING_PROPERTY_PHANDLE_CELLS(iommus, "iommus", "#iommu-cells"); 1455WARNING_PROPERTY_PHANDLE_CELLS(mboxes, "mboxes", "#mbox-cells"); 1456WARNING_PROPERTY_PHANDLE_CELLS(msi_parent, "msi-parent", "#msi-cells", true); 1457WARNING_PROPERTY_PHANDLE_CELLS(mux_controls, "mux-controls", "#mux-control-cells"); 1458WARNING_PROPERTY_PHANDLE_CELLS(phys, "phys", "#phy-cells"); 1459WARNING_PROPERTY_PHANDLE_CELLS(power_domains, "power-domains", "#power-domain-cells"); 1460WARNING_PROPERTY_PHANDLE_CELLS(pwms, "pwms", "#pwm-cells"); 1461WARNING_PROPERTY_PHANDLE_CELLS(resets, "resets", "#reset-cells"); 1462WARNING_PROPERTY_PHANDLE_CELLS(sound_dai, "sound-dai", "#sound-dai-cells"); 1463WARNING_PROPERTY_PHANDLE_CELLS(thermal_sensors, "thermal-sensors", "#thermal-sensor-cells"); 1464 1465static bool prop_is_gpio(struct property *prop) 1466{ 1467 char *str; 1468 1469 /* 1470 * *-gpios and *-gpio can appear in property names, 1471 * so skip over any false matches (only one known ATM) 1472 */ 1473 if (strstr(prop->name, "nr-gpio")) 1474 return false; 1475 1476 str = strrchr(prop->name, '-'); 1477 if (str) 1478 str++; 1479 else 1480 str = prop->name; 1481 if (!(streq(str, "gpios") || streq(str, "gpio"))) 1482 return false; 1483 1484 return true; 1485} 1486 1487static void check_gpios_property(struct check *c, 1488 struct dt_info *dti, 1489 struct node *node) 1490{ 1491 struct property *prop; 1492 1493 /* Skip GPIO hog nodes which have 'gpios' property */ 1494 if (get_property(node, "gpio-hog")) 1495 return; 1496 1497 for_each_property(node, prop) { 1498 struct provider provider; 1499 1500 if (!prop_is_gpio(prop)) 1501 continue; 1502 1503 provider.prop_name = prop->name; 1504 provider.cell_name = "#gpio-cells"; 1505 provider.optional = false; 1506 check_property_phandle_args(c, dti, node, prop, &provider); 1507 } 1508 1509} 1510WARNING(gpios_property, check_gpios_property, NULL, &phandle_references); 1511 1512static void check_deprecated_gpio_property(struct check *c, 1513 struct dt_info *dti, 1514 struct node *node) 1515{ 1516 struct property *prop; 1517 1518 for_each_property(node, prop) { 1519 char *str; 1520 1521 if (!prop_is_gpio(prop)) 1522 continue; 1523 1524 str = strstr(prop->name, "gpio"); 1525 if (!streq(str, "gpio")) 1526 continue; 1527 1528 FAIL_PROP(c, dti, node, prop, 1529 "'[*-]gpio' is deprecated, use '[*-]gpios' instead"); 1530 } 1531 1532} 1533CHECK(deprecated_gpio_property, check_deprecated_gpio_property, NULL); 1534 1535static bool node_is_interrupt_provider(struct node *node) 1536{ 1537 struct property *prop; 1538 1539 prop = get_property(node, "interrupt-controller"); 1540 if (prop) 1541 return true; 1542 1543 prop = get_property(node, "interrupt-map"); 1544 if (prop) 1545 return true; 1546 1547 return false; 1548} 1549static void check_interrupts_property(struct check *c, 1550 struct dt_info *dti, 1551 struct node *node) 1552{ 1553 struct node *root = dti->dt; 1554 struct node *irq_node = NULL, *parent = node; 1555 struct property *irq_prop, *prop = NULL; 1556 int irq_cells, phandle; 1557 1558 irq_prop = get_property(node, "interrupts"); 1559 if (!irq_prop) 1560 return; 1561 1562 if (irq_prop->val.len % sizeof(cell_t)) 1563 FAIL_PROP(c, dti, node, irq_prop, "size (%d) is invalid, expected multiple of %zu", 1564 irq_prop->val.len, sizeof(cell_t)); 1565 1566 while (parent && !prop) { 1567 if (parent != node && node_is_interrupt_provider(parent)) { 1568 irq_node = parent; 1569 break; 1570 } 1571 1572 prop = get_property(parent, "interrupt-parent"); 1573 if (prop) { 1574 phandle = propval_cell(prop); 1575 if ((phandle == 0) || (phandle == -1)) { 1576 /* Give up if this is an overlay with 1577 * external references */ 1578 if (dti->dtsflags & DTSF_PLUGIN) 1579 return; 1580 FAIL_PROP(c, dti, parent, prop, "Invalid phandle"); 1581 continue; 1582 } 1583 1584 irq_node = get_node_by_phandle(root, phandle); 1585 if (!irq_node) { 1586 FAIL_PROP(c, dti, parent, prop, "Bad phandle"); 1587 return; 1588 } 1589 if (!node_is_interrupt_provider(irq_node)) 1590 FAIL(c, dti, irq_node, 1591 "Missing interrupt-controller or interrupt-map property"); 1592 1593 break; 1594 } 1595 1596 parent = parent->parent; 1597 } 1598 1599 if (!irq_node) { 1600 FAIL(c, dti, node, "Missing interrupt-parent"); 1601 return; 1602 } 1603 1604 prop = get_property(irq_node, "#interrupt-cells"); 1605 if (!prop) { 1606 FAIL(c, dti, irq_node, "Missing #interrupt-cells in interrupt-parent"); 1607 return; 1608 } 1609 1610 irq_cells = propval_cell(prop); 1611 if (irq_prop->val.len % (irq_cells * sizeof(cell_t))) { 1612 FAIL_PROP(c, dti, node, prop, 1613 "size is (%d), expected multiple of %d", 1614 irq_prop->val.len, (int)(irq_cells * sizeof(cell_t))); 1615 } 1616} 1617WARNING(interrupts_property, check_interrupts_property, &phandle_references); 1618 1619static const struct bus_type graph_port_bus = { 1620 .name = "graph-port", 1621}; 1622 1623static const struct bus_type graph_ports_bus = { 1624 .name = "graph-ports", 1625}; 1626 1627static void check_graph_nodes(struct check *c, struct dt_info *dti, 1628 struct node *node) 1629{ 1630 struct node *child; 1631 1632 for_each_child(node, child) { 1633 if (!(strprefixeq(child->name, child->basenamelen, "endpoint") || 1634 get_property(child, "remote-endpoint"))) 1635 continue; 1636 1637 node->bus = &graph_port_bus; 1638 1639 /* The parent of 'port' nodes can be either 'ports' or a device */ 1640 if (!node->parent->bus && 1641 (streq(node->parent->name, "ports") || get_property(node, "reg"))) 1642 node->parent->bus = &graph_ports_bus; 1643 1644 break; 1645 } 1646 1647} 1648WARNING(graph_nodes, check_graph_nodes, NULL); 1649 1650static void check_graph_child_address(struct check *c, struct dt_info *dti, 1651 struct node *node) 1652{ 1653 int cnt = 0; 1654 struct node *child; 1655 1656 if (node->bus != &graph_ports_bus && node->bus != &graph_port_bus) 1657 return; 1658 1659 for_each_child(node, child) { 1660 struct property *prop = get_property(child, "reg"); 1661 1662 /* No error if we have any non-zero unit address */ 1663 if (prop && propval_cell(prop) != 0) 1664 return; 1665 1666 cnt++; 1667 } 1668 1669 if (cnt == 1 && node->addr_cells != -1) 1670 FAIL(c, dti, node, "graph node has single child node '%s', #address-cells/#size-cells are not necessary", 1671 node->children->name); 1672} 1673WARNING(graph_child_address, check_graph_child_address, NULL, &graph_nodes); 1674 1675static void check_graph_reg(struct check *c, struct dt_info *dti, 1676 struct node *node) 1677{ 1678 char unit_addr[9]; 1679 const char *unitname = get_unitname(node); 1680 struct property *prop; 1681 1682 prop = get_property(node, "reg"); 1683 if (!prop || !unitname) 1684 return; 1685 1686 if (!(prop->val.val && prop->val.len == sizeof(cell_t))) { 1687 FAIL(c, dti, node, "graph node malformed 'reg' property"); 1688 return; 1689 } 1690 1691 snprintf(unit_addr, sizeof(unit_addr), "%x", propval_cell(prop)); 1692 if (!streq(unitname, unit_addr)) 1693 FAIL(c, dti, node, "graph node unit address error, expected \"%s\"", 1694 unit_addr); 1695 1696 if (node->parent->addr_cells != 1) 1697 FAIL_PROP(c, dti, node, get_property(node, "#address-cells"), 1698 "graph node '#address-cells' is %d, must be 1", 1699 node->parent->addr_cells); 1700 if (node->parent->size_cells != 0) 1701 FAIL_PROP(c, dti, node, get_property(node, "#size-cells"), 1702 "graph node '#size-cells' is %d, must be 0", 1703 node->parent->size_cells); 1704} 1705 1706static void check_graph_port(struct check *c, struct dt_info *dti, 1707 struct node *node) 1708{ 1709 if (node->bus != &graph_port_bus) 1710 return; 1711 1712 if (!strprefixeq(node->name, node->basenamelen, "port")) 1713 FAIL(c, dti, node, "graph port node name should be 'port'"); 1714 1715 check_graph_reg(c, dti, node); 1716} 1717WARNING(graph_port, check_graph_port, NULL, &graph_nodes); 1718 1719static struct node *get_remote_endpoint(struct check *c, struct dt_info *dti, 1720 struct node *endpoint) 1721{ 1722 int phandle; 1723 struct node *node; 1724 struct property *prop; 1725 1726 prop = get_property(endpoint, "remote-endpoint"); 1727 if (!prop) 1728 return NULL; 1729 1730 phandle = propval_cell(prop); 1731 /* Give up if this is an overlay with external references */ 1732 if (phandle == 0 || phandle == -1) 1733 return NULL; 1734 1735 node = get_node_by_phandle(dti->dt, phandle); 1736 if (!node) 1737 FAIL_PROP(c, dti, endpoint, prop, "graph phandle is not valid"); 1738 1739 return node; 1740} 1741 1742static void check_graph_endpoint(struct check *c, struct dt_info *dti, 1743 struct node *node) 1744{ 1745 struct node *remote_node; 1746 1747 if (!node->parent || node->parent->bus != &graph_port_bus) 1748 return; 1749 1750 if (!strprefixeq(node->name, node->basenamelen, "endpoint")) 1751 FAIL(c, dti, node, "graph endpoint node name should be 'endpoint'"); 1752 1753 check_graph_reg(c, dti, node); 1754 1755 remote_node = get_remote_endpoint(c, dti, node); 1756 if (!remote_node) 1757 return; 1758 1759 if (get_remote_endpoint(c, dti, remote_node) != node) 1760 FAIL(c, dti, node, "graph connection to node '%s' is not bidirectional", 1761 remote_node->fullpath); 1762} 1763WARNING(graph_endpoint, check_graph_endpoint, NULL, &graph_nodes); 1764 1765static struct check *check_table[] = { 1766 &duplicate_node_names, &duplicate_property_names, 1767 &node_name_chars, &node_name_format, &property_name_chars, 1768 &name_is_string, &name_properties, 1769 1770 &duplicate_label, 1771 1772 &explicit_phandles, 1773 &phandle_references, &path_references, 1774 &omit_unused_nodes, 1775 1776 &address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell, 1777 &device_type_is_string, &model_is_string, &status_is_string, 1778 &label_is_string, 1779 1780 &compatible_is_string_list, &names_is_string_list, 1781 1782 &property_name_chars_strict, 1783 &node_name_chars_strict, 1784 1785 &addr_size_cells, ®_format, &ranges_format, 1786 1787 &unit_address_vs_reg, 1788 &unit_address_format, 1789 1790 &pci_bridge, 1791 &pci_device_reg, 1792 &pci_device_bus_num, 1793 1794 &simple_bus_bridge, 1795 &simple_bus_reg, 1796 1797 &i2c_bus_bridge, 1798 &i2c_bus_reg, 1799 1800 &spi_bus_bridge, 1801 &spi_bus_reg, 1802 1803 &avoid_default_addr_size, 1804 &avoid_unnecessary_addr_size, 1805 &unique_unit_address, 1806 &unique_unit_address_if_enabled, 1807 &obsolete_chosen_interrupt_controller, 1808 &chosen_node_is_root, &chosen_node_bootargs, &chosen_node_stdout_path, 1809 1810 &clocks_property, 1811 &cooling_device_property, 1812 &dmas_property, 1813 &hwlocks_property, 1814 &interrupts_extended_property, 1815 &io_channels_property, 1816 &iommus_property, 1817 &mboxes_property, 1818 &msi_parent_property, 1819 &mux_controls_property, 1820 &phys_property, 1821 &power_domains_property, 1822 &pwms_property, 1823 &resets_property, 1824 &sound_dai_property, 1825 &thermal_sensors_property, 1826 1827 &deprecated_gpio_property, 1828 &gpios_property, 1829 &interrupts_property, 1830 1831 &alias_paths, 1832 1833 &graph_nodes, &graph_child_address, &graph_port, &graph_endpoint, 1834 1835 &always_fail, 1836}; 1837 1838static void enable_warning_error(struct check *c, bool warn, bool error) 1839{ 1840 int i; 1841 1842 /* Raising level, also raise it for prereqs */ 1843 if ((warn && !c->warn) || (error && !c->error)) 1844 for (i = 0; i < c->num_prereqs; i++) 1845 enable_warning_error(c->prereq[i], warn, error); 1846 1847 c->warn = c->warn || warn; 1848 c->error = c->error || error; 1849} 1850 1851static void disable_warning_error(struct check *c, bool warn, bool error) 1852{ 1853 int i; 1854 1855 /* Lowering level, also lower it for things this is the prereq 1856 * for */ 1857 if ((warn && c->warn) || (error && c->error)) { 1858 for (i = 0; i < ARRAY_SIZE(check_table); i++) { 1859 struct check *cc = check_table[i]; 1860 int j; 1861 1862 for (j = 0; j < cc->num_prereqs; j++) 1863 if (cc->prereq[j] == c) 1864 disable_warning_error(cc, warn, error); 1865 } 1866 } 1867 1868 c->warn = c->warn && !warn; 1869 c->error = c->error && !error; 1870} 1871 1872void parse_checks_option(bool warn, bool error, const char *arg) 1873{ 1874 int i; 1875 const char *name = arg; 1876 bool enable = true; 1877 1878 if ((strncmp(arg, "no-", 3) == 0) 1879 || (strncmp(arg, "no_", 3) == 0)) { 1880 name = arg + 3; 1881 enable = false; 1882 } 1883 1884 for (i = 0; i < ARRAY_SIZE(check_table); i++) { 1885 struct check *c = check_table[i]; 1886 1887 if (streq(c->name, name)) { 1888 if (enable) 1889 enable_warning_error(c, warn, error); 1890 else 1891 disable_warning_error(c, warn, error); 1892 return; 1893 } 1894 } 1895 1896 die("Unrecognized check name \"%s\"\n", name); 1897} 1898 1899void process_checks(bool force, struct dt_info *dti) 1900{ 1901 int i; 1902 int error = 0; 1903 1904 for (i = 0; i < ARRAY_SIZE(check_table); i++) { 1905 struct check *c = check_table[i]; 1906 1907 if (c->warn || c->error) 1908 error = error || run_check(c, dti); 1909 } 1910 1911 if (error) { 1912 if (!force) { 1913 fprintf(stderr, "ERROR: Input tree has errors, aborting " 1914 "(use -f to force output)\n"); 1915 exit(2); 1916 } else if (quiet < 3) { 1917 fprintf(stderr, "Warning: Input tree has errors, " 1918 "output forced\n"); 1919 } 1920 } 1921} 1922