1 /* 2 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2007. 3 * 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License as 7 * published by the Free Software Foundation; either version 2 of the 8 * License, or (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 18 * USA 19 */ 20 21 #include "dtc.h" 22 23 #ifdef TRACE_CHECKS 24 #define TRACE(c, ...) \ 25 do { \ 26 fprintf(stderr, "=== %s: ", (c)->name); \ 27 fprintf(stderr, __VA_ARGS__); \ 28 fprintf(stderr, "\n"); \ 29 } while (0) 30 #else 31 #define TRACE(c, fmt, ...) do { } while (0) 32 #endif 33 34 enum checkstatus { 35 UNCHECKED = 0, 36 PREREQ, 37 PASSED, 38 FAILED, 39 }; 40 41 struct check; 42 43 typedef void (*check_fn)(struct check *c, struct dt_info *dti, struct node *node); 44 45 struct check { 46 const char *name; 47 check_fn fn; 48 void *data; 49 bool warn, error; 50 enum checkstatus status; 51 bool inprogress; 52 int num_prereqs; 53 struct check **prereq; 54 }; 55 56 #define CHECK_ENTRY(_nm, _fn, _d, _w, _e, ...) \ 57 static struct check *_nm##_prereqs[] = { __VA_ARGS__ }; \ 58 static struct check _nm = { \ 59 .name = #_nm, \ 60 .fn = (_fn), \ 61 .data = (_d), \ 62 .warn = (_w), \ 63 .error = (_e), \ 64 .status = UNCHECKED, \ 65 .num_prereqs = ARRAY_SIZE(_nm##_prereqs), \ 66 .prereq = _nm##_prereqs, \ 67 }; 68 #define WARNING(_nm, _fn, _d, ...) \ 69 CHECK_ENTRY(_nm, _fn, _d, true, false, __VA_ARGS__) 70 #define ERROR(_nm, _fn, _d, ...) \ 71 CHECK_ENTRY(_nm, _fn, _d, false, true, __VA_ARGS__) 72 #define CHECK(_nm, _fn, _d, ...) \ 73 CHECK_ENTRY(_nm, _fn, _d, false, false, __VA_ARGS__) 74 75 static inline void PRINTF(3, 4) check_msg(struct check *c, struct dt_info *dti, 76 const char *fmt, ...) 77 { 78 va_list ap; 79 va_start(ap, fmt); 80 81 if ((c->warn && (quiet < 1)) 82 || (c->error && (quiet < 2))) { 83 fprintf(stderr, "%s: %s (%s): ", 84 strcmp(dti->outname, "-") ? dti->outname : "<stdout>", 85 (c->error) ? "ERROR" : "Warning", c->name); 86 vfprintf(stderr, fmt, ap); 87 fprintf(stderr, "\n"); 88 } 89 va_end(ap); 90 } 91 92 #define FAIL(c, dti, ...) \ 93 do { \ 94 TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \ 95 (c)->status = FAILED; \ 96 check_msg((c), dti, __VA_ARGS__); \ 97 } while (0) 98 99 static void check_nodes_props(struct check *c, struct dt_info *dti, struct node *node) 100 { 101 struct node *child; 102 103 TRACE(c, "%s", node->fullpath); 104 if (c->fn) 105 c->fn(c, dti, node); 106 107 for_each_child(node, child) 108 check_nodes_props(c, dti, child); 109 } 110 111 static bool run_check(struct check *c, struct dt_info *dti) 112 { 113 struct node *dt = dti->dt; 114 bool error = false; 115 int i; 116 117 assert(!c->inprogress); 118 119 if (c->status != UNCHECKED) 120 goto out; 121 122 c->inprogress = true; 123 124 for (i = 0; i < c->num_prereqs; i++) { 125 struct check *prq = c->prereq[i]; 126 error = error || run_check(prq, dti); 127 if (prq->status != PASSED) { 128 c->status = PREREQ; 129 check_msg(c, dti, "Failed prerequisite '%s'", 130 c->prereq[i]->name); 131 } 132 } 133 134 if (c->status != UNCHECKED) 135 goto out; 136 137 check_nodes_props(c, dti, dt); 138 139 if (c->status == UNCHECKED) 140 c->status = PASSED; 141 142 TRACE(c, "\tCompleted, status %d", c->status); 143 144 out: 145 c->inprogress = false; 146 if ((c->status != PASSED) && (c->error)) 147 error = true; 148 return error; 149 } 150 151 /* 152 * Utility check functions 153 */ 154 155 /* A check which always fails, for testing purposes only */ 156 static inline void check_always_fail(struct check *c, struct dt_info *dti, 157 struct node *node) 158 { 159 FAIL(c, dti, "always_fail check"); 160 } 161 CHECK(always_fail, check_always_fail, NULL); 162 163 static void check_is_string(struct check *c, struct dt_info *dti, 164 struct node *node) 165 { 166 struct property *prop; 167 char *propname = c->data; 168 169 prop = get_property(node, propname); 170 if (!prop) 171 return; /* Not present, assumed ok */ 172 173 if (!data_is_one_string(prop->val)) 174 FAIL(c, dti, "\"%s\" property in %s is not a string", 175 propname, node->fullpath); 176 } 177 #define WARNING_IF_NOT_STRING(nm, propname) \ 178 WARNING(nm, check_is_string, (propname)) 179 #define ERROR_IF_NOT_STRING(nm, propname) \ 180 ERROR(nm, check_is_string, (propname)) 181 182 static void check_is_cell(struct check *c, struct dt_info *dti, 183 struct node *node) 184 { 185 struct property *prop; 186 char *propname = c->data; 187 188 prop = get_property(node, propname); 189 if (!prop) 190 return; /* Not present, assumed ok */ 191 192 if (prop->val.len != sizeof(cell_t)) 193 FAIL(c, dti, "\"%s\" property in %s is not a single cell", 194 propname, node->fullpath); 195 } 196 #define WARNING_IF_NOT_CELL(nm, propname) \ 197 WARNING(nm, check_is_cell, (propname)) 198 #define ERROR_IF_NOT_CELL(nm, propname) \ 199 ERROR(nm, check_is_cell, (propname)) 200 201 /* 202 * Structural check functions 203 */ 204 205 static void check_duplicate_node_names(struct check *c, struct dt_info *dti, 206 struct node *node) 207 { 208 struct node *child, *child2; 209 210 for_each_child(node, child) 211 for (child2 = child->next_sibling; 212 child2; 213 child2 = child2->next_sibling) 214 if (streq(child->name, child2->name)) 215 FAIL(c, dti, "Duplicate node name %s", 216 child->fullpath); 217 } 218 ERROR(duplicate_node_names, check_duplicate_node_names, NULL); 219 220 static void check_duplicate_property_names(struct check *c, struct dt_info *dti, 221 struct node *node) 222 { 223 struct property *prop, *prop2; 224 225 for_each_property(node, prop) { 226 for (prop2 = prop->next; prop2; prop2 = prop2->next) { 227 if (prop2->deleted) 228 continue; 229 if (streq(prop->name, prop2->name)) 230 FAIL(c, dti, "Duplicate property name %s in %s", 231 prop->name, node->fullpath); 232 } 233 } 234 } 235 ERROR(duplicate_property_names, check_duplicate_property_names, NULL); 236 237 #define LOWERCASE "abcdefghijklmnopqrstuvwxyz" 238 #define UPPERCASE "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 239 #define DIGITS "0123456789" 240 #define PROPNODECHARS LOWERCASE UPPERCASE DIGITS ",._+*#?-" 241 #define PROPNODECHARSSTRICT LOWERCASE UPPERCASE DIGITS ",-" 242 243 static void check_node_name_chars(struct check *c, struct dt_info *dti, 244 struct node *node) 245 { 246 int n = strspn(node->name, c->data); 247 248 if (n < strlen(node->name)) 249 FAIL(c, dti, "Bad character '%c' in node %s", 250 node->name[n], node->fullpath); 251 } 252 ERROR(node_name_chars, check_node_name_chars, PROPNODECHARS "@"); 253 254 static void check_node_name_chars_strict(struct check *c, struct dt_info *dti, 255 struct node *node) 256 { 257 int n = strspn(node->name, c->data); 258 259 if (n < node->basenamelen) 260 FAIL(c, dti, "Character '%c' not recommended in node %s", 261 node->name[n], node->fullpath); 262 } 263 CHECK(node_name_chars_strict, check_node_name_chars_strict, PROPNODECHARSSTRICT); 264 265 static void check_node_name_format(struct check *c, struct dt_info *dti, 266 struct node *node) 267 { 268 if (strchr(get_unitname(node), '@')) 269 FAIL(c, dti, "Node %s has multiple '@' characters in name", 270 node->fullpath); 271 } 272 ERROR(node_name_format, check_node_name_format, NULL, &node_name_chars); 273 274 static void check_unit_address_vs_reg(struct check *c, struct dt_info *dti, 275 struct node *node) 276 { 277 const char *unitname = get_unitname(node); 278 struct property *prop = get_property(node, "reg"); 279 280 if (!prop) { 281 prop = get_property(node, "ranges"); 282 if (prop && !prop->val.len) 283 prop = NULL; 284 } 285 286 if (prop) { 287 if (!unitname[0]) 288 FAIL(c, dti, "Node %s has a reg or ranges property, but no unit name", 289 node->fullpath); 290 } else { 291 if (unitname[0]) 292 FAIL(c, dti, "Node %s has a unit name, but no reg property", 293 node->fullpath); 294 } 295 } 296 WARNING(unit_address_vs_reg, check_unit_address_vs_reg, NULL); 297 298 static void check_property_name_chars(struct check *c, struct dt_info *dti, 299 struct node *node) 300 { 301 struct property *prop; 302 303 for_each_property(node, prop) { 304 int n = strspn(prop->name, c->data); 305 306 if (n < strlen(prop->name)) 307 FAIL(c, dti, "Bad character '%c' in property name \"%s\", node %s", 308 prop->name[n], prop->name, node->fullpath); 309 } 310 } 311 ERROR(property_name_chars, check_property_name_chars, PROPNODECHARS); 312 313 static void check_property_name_chars_strict(struct check *c, 314 struct dt_info *dti, 315 struct node *node) 316 { 317 struct property *prop; 318 319 for_each_property(node, prop) { 320 const char *name = prop->name; 321 int n = strspn(name, c->data); 322 323 if (n == strlen(prop->name)) 324 continue; 325 326 /* Certain names are whitelisted */ 327 if (streq(name, "device_type")) 328 continue; 329 330 /* 331 * # is only allowed at the beginning of property names not counting 332 * the vendor prefix. 333 */ 334 if (name[n] == '#' && ((n == 0) || (name[n-1] == ','))) { 335 name += n + 1; 336 n = strspn(name, c->data); 337 } 338 if (n < strlen(name)) 339 FAIL(c, dti, "Character '%c' not recommended in property name \"%s\", node %s", 340 name[n], prop->name, node->fullpath); 341 } 342 } 343 CHECK(property_name_chars_strict, check_property_name_chars_strict, PROPNODECHARSSTRICT); 344 345 #define DESCLABEL_FMT "%s%s%s%s%s" 346 #define DESCLABEL_ARGS(node,prop,mark) \ 347 ((mark) ? "value of " : ""), \ 348 ((prop) ? "'" : ""), \ 349 ((prop) ? (prop)->name : ""), \ 350 ((prop) ? "' in " : ""), (node)->fullpath 351 352 static void check_duplicate_label(struct check *c, struct dt_info *dti, 353 const char *label, struct node *node, 354 struct property *prop, struct marker *mark) 355 { 356 struct node *dt = dti->dt; 357 struct node *othernode = NULL; 358 struct property *otherprop = NULL; 359 struct marker *othermark = NULL; 360 361 othernode = get_node_by_label(dt, label); 362 363 if (!othernode) 364 otherprop = get_property_by_label(dt, label, &othernode); 365 if (!othernode) 366 othermark = get_marker_label(dt, label, &othernode, 367 &otherprop); 368 369 if (!othernode) 370 return; 371 372 if ((othernode != node) || (otherprop != prop) || (othermark != mark)) 373 FAIL(c, dti, "Duplicate label '%s' on " DESCLABEL_FMT 374 " and " DESCLABEL_FMT, 375 label, DESCLABEL_ARGS(node, prop, mark), 376 DESCLABEL_ARGS(othernode, otherprop, othermark)); 377 } 378 379 static void check_duplicate_label_node(struct check *c, struct dt_info *dti, 380 struct node *node) 381 { 382 struct label *l; 383 struct property *prop; 384 385 for_each_label(node->labels, l) 386 check_duplicate_label(c, dti, l->label, node, NULL, NULL); 387 388 for_each_property(node, prop) { 389 struct marker *m = prop->val.markers; 390 391 for_each_label(prop->labels, l) 392 check_duplicate_label(c, dti, l->label, node, prop, NULL); 393 394 for_each_marker_of_type(m, LABEL) 395 check_duplicate_label(c, dti, m->ref, node, prop, m); 396 } 397 } 398 ERROR(duplicate_label, check_duplicate_label_node, NULL); 399 400 static cell_t check_phandle_prop(struct check *c, struct dt_info *dti, 401 struct node *node, const char *propname) 402 { 403 struct node *root = dti->dt; 404 struct property *prop; 405 struct marker *m; 406 cell_t phandle; 407 408 prop = get_property(node, propname); 409 if (!prop) 410 return 0; 411 412 if (prop->val.len != sizeof(cell_t)) { 413 FAIL(c, dti, "%s has bad length (%d) %s property", 414 node->fullpath, prop->val.len, prop->name); 415 return 0; 416 } 417 418 m = prop->val.markers; 419 for_each_marker_of_type(m, REF_PHANDLE) { 420 assert(m->offset == 0); 421 if (node != get_node_by_ref(root, m->ref)) 422 /* "Set this node's phandle equal to some 423 * other node's phandle". That's nonsensical 424 * by construction. */ { 425 FAIL(c, dti, "%s in %s is a reference to another node", 426 prop->name, node->fullpath); 427 } 428 /* But setting this node's phandle equal to its own 429 * phandle is allowed - that means allocate a unique 430 * phandle for this node, even if it's not otherwise 431 * referenced. The value will be filled in later, so 432 * we treat it as having no phandle data for now. */ 433 return 0; 434 } 435 436 phandle = propval_cell(prop); 437 438 if ((phandle == 0) || (phandle == -1)) { 439 FAIL(c, dti, "%s has bad value (0x%x) in %s property", 440 node->fullpath, phandle, prop->name); 441 return 0; 442 } 443 444 return phandle; 445 } 446 447 static void check_explicit_phandles(struct check *c, struct dt_info *dti, 448 struct node *node) 449 { 450 struct node *root = dti->dt; 451 struct node *other; 452 cell_t phandle, linux_phandle; 453 454 /* Nothing should have assigned phandles yet */ 455 assert(!node->phandle); 456 457 phandle = check_phandle_prop(c, dti, node, "phandle"); 458 459 linux_phandle = check_phandle_prop(c, dti, node, "linux,phandle"); 460 461 if (!phandle && !linux_phandle) 462 /* No valid phandles; nothing further to check */ 463 return; 464 465 if (linux_phandle && phandle && (phandle != linux_phandle)) 466 FAIL(c, dti, "%s has mismatching 'phandle' and 'linux,phandle'" 467 " properties", node->fullpath); 468 469 if (linux_phandle && !phandle) 470 phandle = linux_phandle; 471 472 other = get_node_by_phandle(root, phandle); 473 if (other && (other != node)) { 474 FAIL(c, dti, "%s has duplicated phandle 0x%x (seen before at %s)", 475 node->fullpath, phandle, other->fullpath); 476 return; 477 } 478 479 node->phandle = phandle; 480 } 481 ERROR(explicit_phandles, check_explicit_phandles, NULL); 482 483 static void check_name_properties(struct check *c, struct dt_info *dti, 484 struct node *node) 485 { 486 struct property **pp, *prop = NULL; 487 488 for (pp = &node->proplist; *pp; pp = &((*pp)->next)) 489 if (streq((*pp)->name, "name")) { 490 prop = *pp; 491 break; 492 } 493 494 if (!prop) 495 return; /* No name property, that's fine */ 496 497 if ((prop->val.len != node->basenamelen+1) 498 || (memcmp(prop->val.val, node->name, node->basenamelen) != 0)) { 499 FAIL(c, dti, "\"name\" property in %s is incorrect (\"%s\" instead" 500 " of base node name)", node->fullpath, prop->val.val); 501 } else { 502 /* The name property is correct, and therefore redundant. 503 * Delete it */ 504 *pp = prop->next; 505 free(prop->name); 506 data_free(prop->val); 507 free(prop); 508 } 509 } 510 ERROR_IF_NOT_STRING(name_is_string, "name"); 511 ERROR(name_properties, check_name_properties, NULL, &name_is_string); 512 513 /* 514 * Reference fixup functions 515 */ 516 517 static void fixup_phandle_references(struct check *c, struct dt_info *dti, 518 struct node *node) 519 { 520 struct node *dt = dti->dt; 521 struct property *prop; 522 523 for_each_property(node, prop) { 524 struct marker *m = prop->val.markers; 525 struct node *refnode; 526 cell_t phandle; 527 528 for_each_marker_of_type(m, REF_PHANDLE) { 529 assert(m->offset + sizeof(cell_t) <= prop->val.len); 530 531 refnode = get_node_by_ref(dt, m->ref); 532 if (! refnode) { 533 if (!(dti->dtsflags & DTSF_PLUGIN)) 534 FAIL(c, dti, "Reference to non-existent node or " 535 "label \"%s\"\n", m->ref); 536 else /* mark the entry as unresolved */ 537 *((fdt32_t *)(prop->val.val + m->offset)) = 538 cpu_to_fdt32(0xffffffff); 539 continue; 540 } 541 542 phandle = get_node_phandle(dt, refnode); 543 *((fdt32_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle); 544 } 545 } 546 } 547 ERROR(phandle_references, fixup_phandle_references, NULL, 548 &duplicate_node_names, &explicit_phandles); 549 550 static void fixup_path_references(struct check *c, struct dt_info *dti, 551 struct node *node) 552 { 553 struct node *dt = dti->dt; 554 struct property *prop; 555 556 for_each_property(node, prop) { 557 struct marker *m = prop->val.markers; 558 struct node *refnode; 559 char *path; 560 561 for_each_marker_of_type(m, REF_PATH) { 562 assert(m->offset <= prop->val.len); 563 564 refnode = get_node_by_ref(dt, m->ref); 565 if (!refnode) { 566 FAIL(c, dti, "Reference to non-existent node or label \"%s\"\n", 567 m->ref); 568 continue; 569 } 570 571 path = refnode->fullpath; 572 prop->val = data_insert_at_marker(prop->val, m, path, 573 strlen(path) + 1); 574 } 575 } 576 } 577 ERROR(path_references, fixup_path_references, NULL, &duplicate_node_names); 578 579 /* 580 * Semantic checks 581 */ 582 WARNING_IF_NOT_CELL(address_cells_is_cell, "#address-cells"); 583 WARNING_IF_NOT_CELL(size_cells_is_cell, "#size-cells"); 584 WARNING_IF_NOT_CELL(interrupt_cells_is_cell, "#interrupt-cells"); 585 586 WARNING_IF_NOT_STRING(device_type_is_string, "device_type"); 587 WARNING_IF_NOT_STRING(model_is_string, "model"); 588 WARNING_IF_NOT_STRING(status_is_string, "status"); 589 590 static void fixup_addr_size_cells(struct check *c, struct dt_info *dti, 591 struct node *node) 592 { 593 struct property *prop; 594 595 node->addr_cells = -1; 596 node->size_cells = -1; 597 598 prop = get_property(node, "#address-cells"); 599 if (prop) 600 node->addr_cells = propval_cell(prop); 601 602 prop = get_property(node, "#size-cells"); 603 if (prop) 604 node->size_cells = propval_cell(prop); 605 } 606 WARNING(addr_size_cells, fixup_addr_size_cells, NULL, 607 &address_cells_is_cell, &size_cells_is_cell); 608 609 #define node_addr_cells(n) \ 610 (((n)->addr_cells == -1) ? 2 : (n)->addr_cells) 611 #define node_size_cells(n) \ 612 (((n)->size_cells == -1) ? 1 : (n)->size_cells) 613 614 static void check_reg_format(struct check *c, struct dt_info *dti, 615 struct node *node) 616 { 617 struct property *prop; 618 int addr_cells, size_cells, entrylen; 619 620 prop = get_property(node, "reg"); 621 if (!prop) 622 return; /* No "reg", that's fine */ 623 624 if (!node->parent) { 625 FAIL(c, dti, "Root node has a \"reg\" property"); 626 return; 627 } 628 629 if (prop->val.len == 0) 630 FAIL(c, dti, "\"reg\" property in %s is empty", node->fullpath); 631 632 addr_cells = node_addr_cells(node->parent); 633 size_cells = node_size_cells(node->parent); 634 entrylen = (addr_cells + size_cells) * sizeof(cell_t); 635 636 if (!entrylen || (prop->val.len % entrylen) != 0) 637 FAIL(c, dti, "\"reg\" property in %s has invalid length (%d bytes) " 638 "(#address-cells == %d, #size-cells == %d)", 639 node->fullpath, prop->val.len, addr_cells, size_cells); 640 } 641 WARNING(reg_format, check_reg_format, NULL, &addr_size_cells); 642 643 static void check_ranges_format(struct check *c, struct dt_info *dti, 644 struct node *node) 645 { 646 struct property *prop; 647 int c_addr_cells, p_addr_cells, c_size_cells, p_size_cells, entrylen; 648 649 prop = get_property(node, "ranges"); 650 if (!prop) 651 return; 652 653 if (!node->parent) { 654 FAIL(c, dti, "Root node has a \"ranges\" property"); 655 return; 656 } 657 658 p_addr_cells = node_addr_cells(node->parent); 659 p_size_cells = node_size_cells(node->parent); 660 c_addr_cells = node_addr_cells(node); 661 c_size_cells = node_size_cells(node); 662 entrylen = (p_addr_cells + c_addr_cells + c_size_cells) * sizeof(cell_t); 663 664 if (prop->val.len == 0) { 665 if (p_addr_cells != c_addr_cells) 666 FAIL(c, dti, "%s has empty \"ranges\" property but its " 667 "#address-cells (%d) differs from %s (%d)", 668 node->fullpath, c_addr_cells, node->parent->fullpath, 669 p_addr_cells); 670 if (p_size_cells != c_size_cells) 671 FAIL(c, dti, "%s has empty \"ranges\" property but its " 672 "#size-cells (%d) differs from %s (%d)", 673 node->fullpath, c_size_cells, node->parent->fullpath, 674 p_size_cells); 675 } else if ((prop->val.len % entrylen) != 0) { 676 FAIL(c, dti, "\"ranges\" property in %s has invalid length (%d bytes) " 677 "(parent #address-cells == %d, child #address-cells == %d, " 678 "#size-cells == %d)", node->fullpath, prop->val.len, 679 p_addr_cells, c_addr_cells, c_size_cells); 680 } 681 } 682 WARNING(ranges_format, check_ranges_format, NULL, &addr_size_cells); 683 684 static const struct bus_type pci_bus = { 685 .name = "PCI", 686 }; 687 688 static void check_pci_bridge(struct check *c, struct dt_info *dti, struct node *node) 689 { 690 struct property *prop; 691 cell_t *cells; 692 693 prop = get_property(node, "device_type"); 694 if (!prop || !streq(prop->val.val, "pci")) 695 return; 696 697 node->bus = &pci_bus; 698 699 if (!strneq(node->name, "pci", node->basenamelen) && 700 !strneq(node->name, "pcie", node->basenamelen)) 701 FAIL(c, dti, "Node %s node name is not \"pci\" or \"pcie\"", 702 node->fullpath); 703 704 prop = get_property(node, "ranges"); 705 if (!prop) 706 FAIL(c, dti, "Node %s missing ranges for PCI bridge (or not a bridge)", 707 node->fullpath); 708 709 if (node_addr_cells(node) != 3) 710 FAIL(c, dti, "Node %s incorrect #address-cells for PCI bridge", 711 node->fullpath); 712 if (node_size_cells(node) != 2) 713 FAIL(c, dti, "Node %s incorrect #size-cells for PCI bridge", 714 node->fullpath); 715 716 prop = get_property(node, "bus-range"); 717 if (!prop) { 718 FAIL(c, dti, "Node %s missing bus-range for PCI bridge", 719 node->fullpath); 720 return; 721 } 722 if (prop->val.len != (sizeof(cell_t) * 2)) { 723 FAIL(c, dti, "Node %s bus-range must be 2 cells", 724 node->fullpath); 725 return; 726 } 727 cells = (cell_t *)prop->val.val; 728 if (fdt32_to_cpu(cells[0]) > fdt32_to_cpu(cells[1])) 729 FAIL(c, dti, "Node %s bus-range 1st cell must be less than or equal to 2nd cell", 730 node->fullpath); 731 if (fdt32_to_cpu(cells[1]) > 0xff) 732 FAIL(c, dti, "Node %s bus-range maximum bus number must be less than 256", 733 node->fullpath); 734 } 735 WARNING(pci_bridge, check_pci_bridge, NULL, 736 &device_type_is_string, &addr_size_cells); 737 738 static void check_pci_device_bus_num(struct check *c, struct dt_info *dti, struct node *node) 739 { 740 struct property *prop; 741 unsigned int bus_num, min_bus, max_bus; 742 cell_t *cells; 743 744 if (!node->parent || (node->parent->bus != &pci_bus)) 745 return; 746 747 prop = get_property(node, "reg"); 748 if (!prop) 749 return; 750 751 cells = (cell_t *)prop->val.val; 752 bus_num = (fdt32_to_cpu(cells[0]) & 0x00ff0000) >> 16; 753 754 prop = get_property(node->parent, "bus-range"); 755 if (!prop) { 756 min_bus = max_bus = 0; 757 } else { 758 cells = (cell_t *)prop->val.val; 759 min_bus = fdt32_to_cpu(cells[0]); 760 max_bus = fdt32_to_cpu(cells[0]); 761 } 762 if ((bus_num < min_bus) || (bus_num > max_bus)) 763 FAIL(c, dti, "Node %s PCI bus number %d out of range, expected (%d - %d)", 764 node->fullpath, bus_num, min_bus, max_bus); 765 } 766 WARNING(pci_device_bus_num, check_pci_device_bus_num, NULL, ®_format, &pci_bridge); 767 768 static void check_pci_device_reg(struct check *c, struct dt_info *dti, struct node *node) 769 { 770 struct property *prop; 771 const char *unitname = get_unitname(node); 772 char unit_addr[5]; 773 unsigned int dev, func, reg; 774 cell_t *cells; 775 776 if (!node->parent || (node->parent->bus != &pci_bus)) 777 return; 778 779 prop = get_property(node, "reg"); 780 if (!prop) { 781 FAIL(c, dti, "Node %s missing PCI reg property", node->fullpath); 782 return; 783 } 784 785 cells = (cell_t *)prop->val.val; 786 if (cells[1] || cells[2]) 787 FAIL(c, dti, "Node %s PCI reg config space address cells 2 and 3 must be 0", 788 node->fullpath); 789 790 reg = fdt32_to_cpu(cells[0]); 791 dev = (reg & 0xf800) >> 11; 792 func = (reg & 0x700) >> 8; 793 794 if (reg & 0xff000000) 795 FAIL(c, dti, "Node %s PCI reg address is not configuration space", 796 node->fullpath); 797 if (reg & 0x000000ff) 798 FAIL(c, dti, "Node %s PCI reg config space address register number must be 0", 799 node->fullpath); 800 801 if (func == 0) { 802 snprintf(unit_addr, sizeof(unit_addr), "%x", dev); 803 if (streq(unitname, unit_addr)) 804 return; 805 } 806 807 snprintf(unit_addr, sizeof(unit_addr), "%x,%x", dev, func); 808 if (streq(unitname, unit_addr)) 809 return; 810 811 FAIL(c, dti, "Node %s PCI unit address format error, expected \"%s\"", 812 node->fullpath, unit_addr); 813 } 814 WARNING(pci_device_reg, check_pci_device_reg, NULL, ®_format, &pci_bridge); 815 816 static const struct bus_type simple_bus = { 817 .name = "simple-bus", 818 }; 819 820 static bool node_is_compatible(struct node *node, const char *compat) 821 { 822 struct property *prop; 823 const char *str, *end; 824 825 prop = get_property(node, "compatible"); 826 if (!prop) 827 return false; 828 829 for (str = prop->val.val, end = str + prop->val.len; str < end; 830 str += strnlen(str, end - str) + 1) { 831 if (strneq(str, compat, end - str)) 832 return true; 833 } 834 return false; 835 } 836 837 static void check_simple_bus_bridge(struct check *c, struct dt_info *dti, struct node *node) 838 { 839 if (node_is_compatible(node, "simple-bus")) 840 node->bus = &simple_bus; 841 } 842 WARNING(simple_bus_bridge, check_simple_bus_bridge, NULL, &addr_size_cells); 843 844 static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct node *node) 845 { 846 struct property *prop; 847 const char *unitname = get_unitname(node); 848 char unit_addr[17]; 849 unsigned int size; 850 uint64_t reg = 0; 851 cell_t *cells = NULL; 852 853 if (!node->parent || (node->parent->bus != &simple_bus)) 854 return; 855 856 prop = get_property(node, "reg"); 857 if (prop) 858 cells = (cell_t *)prop->val.val; 859 else { 860 prop = get_property(node, "ranges"); 861 if (prop && prop->val.len) 862 /* skip of child address */ 863 cells = ((cell_t *)prop->val.val) + node_addr_cells(node); 864 } 865 866 if (!cells) { 867 if (node->parent->parent && !(node->bus == &simple_bus)) 868 FAIL(c, dti, "Node %s missing or empty reg/ranges property", node->fullpath); 869 return; 870 } 871 872 size = node_addr_cells(node->parent); 873 while (size--) 874 reg = (reg << 32) | fdt32_to_cpu(*(cells++)); 875 876 snprintf(unit_addr, sizeof(unit_addr), "%llx", (unsigned long long)reg); 877 if (!streq(unitname, unit_addr)) 878 FAIL(c, dti, "Node %s simple-bus unit address format error, expected \"%s\"", 879 node->fullpath, unit_addr); 880 } 881 WARNING(simple_bus_reg, check_simple_bus_reg, NULL, ®_format, &simple_bus_bridge); 882 883 static void check_unit_address_format(struct check *c, struct dt_info *dti, 884 struct node *node) 885 { 886 const char *unitname = get_unitname(node); 887 888 if (node->parent && node->parent->bus) 889 return; 890 891 if (!unitname[0]) 892 return; 893 894 if (!strncmp(unitname, "0x", 2)) { 895 FAIL(c, dti, "Node %s unit name should not have leading \"0x\"", 896 node->fullpath); 897 /* skip over 0x for next test */ 898 unitname += 2; 899 } 900 if (unitname[0] == '0' && isxdigit(unitname[1])) 901 FAIL(c, dti, "Node %s unit name should not have leading 0s", 902 node->fullpath); 903 } 904 WARNING(unit_address_format, check_unit_address_format, NULL, 905 &node_name_format, &pci_bridge, &simple_bus_bridge); 906 907 /* 908 * Style checks 909 */ 910 static void check_avoid_default_addr_size(struct check *c, struct dt_info *dti, 911 struct node *node) 912 { 913 struct property *reg, *ranges; 914 915 if (!node->parent) 916 return; /* Ignore root node */ 917 918 reg = get_property(node, "reg"); 919 ranges = get_property(node, "ranges"); 920 921 if (!reg && !ranges) 922 return; 923 924 if (node->parent->addr_cells == -1) 925 FAIL(c, dti, "Relying on default #address-cells value for %s", 926 node->fullpath); 927 928 if (node->parent->size_cells == -1) 929 FAIL(c, dti, "Relying on default #size-cells value for %s", 930 node->fullpath); 931 } 932 WARNING(avoid_default_addr_size, check_avoid_default_addr_size, NULL, 933 &addr_size_cells); 934 935 static void check_obsolete_chosen_interrupt_controller(struct check *c, 936 struct dt_info *dti, 937 struct node *node) 938 { 939 struct node *dt = dti->dt; 940 struct node *chosen; 941 struct property *prop; 942 943 if (node != dt) 944 return; 945 946 947 chosen = get_node_by_path(dt, "/chosen"); 948 if (!chosen) 949 return; 950 951 prop = get_property(chosen, "interrupt-controller"); 952 if (prop) 953 FAIL(c, dti, "/chosen has obsolete \"interrupt-controller\" " 954 "property"); 955 } 956 WARNING(obsolete_chosen_interrupt_controller, 957 check_obsolete_chosen_interrupt_controller, NULL); 958 959 static struct check *check_table[] = { 960 &duplicate_node_names, &duplicate_property_names, 961 &node_name_chars, &node_name_format, &property_name_chars, 962 &name_is_string, &name_properties, 963 964 &duplicate_label, 965 966 &explicit_phandles, 967 &phandle_references, &path_references, 968 969 &address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell, 970 &device_type_is_string, &model_is_string, &status_is_string, 971 972 &property_name_chars_strict, 973 &node_name_chars_strict, 974 975 &addr_size_cells, ®_format, &ranges_format, 976 977 &unit_address_vs_reg, 978 &unit_address_format, 979 980 &pci_bridge, 981 &pci_device_reg, 982 &pci_device_bus_num, 983 984 &simple_bus_bridge, 985 &simple_bus_reg, 986 987 &avoid_default_addr_size, 988 &obsolete_chosen_interrupt_controller, 989 990 &always_fail, 991 }; 992 993 static void enable_warning_error(struct check *c, bool warn, bool error) 994 { 995 int i; 996 997 /* Raising level, also raise it for prereqs */ 998 if ((warn && !c->warn) || (error && !c->error)) 999 for (i = 0; i < c->num_prereqs; i++) 1000 enable_warning_error(c->prereq[i], warn, error); 1001 1002 c->warn = c->warn || warn; 1003 c->error = c->error || error; 1004 } 1005 1006 static void disable_warning_error(struct check *c, bool warn, bool error) 1007 { 1008 int i; 1009 1010 /* Lowering level, also lower it for things this is the prereq 1011 * for */ 1012 if ((warn && c->warn) || (error && c->error)) { 1013 for (i = 0; i < ARRAY_SIZE(check_table); i++) { 1014 struct check *cc = check_table[i]; 1015 int j; 1016 1017 for (j = 0; j < cc->num_prereqs; j++) 1018 if (cc->prereq[j] == c) 1019 disable_warning_error(cc, warn, error); 1020 } 1021 } 1022 1023 c->warn = c->warn && !warn; 1024 c->error = c->error && !error; 1025 } 1026 1027 void parse_checks_option(bool warn, bool error, const char *arg) 1028 { 1029 int i; 1030 const char *name = arg; 1031 bool enable = true; 1032 1033 if ((strncmp(arg, "no-", 3) == 0) 1034 || (strncmp(arg, "no_", 3) == 0)) { 1035 name = arg + 3; 1036 enable = false; 1037 } 1038 1039 for (i = 0; i < ARRAY_SIZE(check_table); i++) { 1040 struct check *c = check_table[i]; 1041 1042 if (streq(c->name, name)) { 1043 if (enable) 1044 enable_warning_error(c, warn, error); 1045 else 1046 disable_warning_error(c, warn, error); 1047 return; 1048 } 1049 } 1050 1051 die("Unrecognized check name \"%s\"\n", name); 1052 } 1053 1054 void process_checks(bool force, struct dt_info *dti) 1055 { 1056 int i; 1057 int error = 0; 1058 1059 for (i = 0; i < ARRAY_SIZE(check_table); i++) { 1060 struct check *c = check_table[i]; 1061 1062 if (c->warn || c->error) 1063 error = error || run_check(c, dti); 1064 } 1065 1066 if (error) { 1067 if (!force) { 1068 fprintf(stderr, "ERROR: Input tree has errors, aborting " 1069 "(use -f to force output)\n"); 1070 exit(2); 1071 } else if (quiet < 3) { 1072 fprintf(stderr, "Warning: Input tree has errors, " 1073 "output forced\n"); 1074 } 1075 } 1076 } 1077