1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2013 David Chisnall 5 * All rights reserved. 6 * 7 * This software was developed by SRI International and the University of 8 * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) 9 * ("CTSRD"), as part of the DARPA CRASH research programme. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 #ifndef _FDT_HH_ 34 #define _FDT_HH_ 35 #include <algorithm> 36 #include <unordered_map> 37 #include <unordered_set> 38 #include <memory> 39 #include <string> 40 #include <functional> 41 42 #include "util.hh" 43 #include "input_buffer.hh" 44 45 namespace dtc 46 { 47 48 namespace dtb 49 { 50 struct output_writer; 51 class string_table; 52 } 53 54 namespace fdt 55 { 56 class property; 57 class node; 58 class device_tree; 59 /** 60 * Type for device tree write functions. 61 */ 62 typedef void (device_tree::* tree_write_fn_ptr)(int); 63 /** 64 * Type for device tree read functions. 65 */ 66 typedef void (device_tree::* tree_read_fn_ptr)(const std::string &, FILE *); 67 /** 68 * Type for (owned) pointers to properties. 69 */ 70 typedef std::shared_ptr<property> property_ptr; 71 /** 72 * Owning pointer to a node. 73 */ 74 typedef std::shared_ptr<node> node_ptr; 75 /** 76 * Map from macros to property pointers. 77 */ 78 typedef std::unordered_map<std::string, property_ptr> define_map; 79 /** 80 * Set of strings used for label names. 81 */ 82 typedef std::unordered_set<std::string> string_set; 83 /** 84 * Properties may contain a number of different value, each with a different 85 * label. This class encapsulates a single value. 86 */ 87 struct property_value 88 { 89 /** 90 * The label for this data. This is usually empty. 91 */ 92 std::string label; 93 /** 94 * If this value is a string, or something resolved from a string (a 95 * reference) then this contains the source string. 96 */ 97 std::string string_data; 98 /** 99 * The data that should be written to the final output. 100 */ 101 byte_buffer byte_data; 102 /** 103 * Enumeration describing the possible types of a value. Note that 104 * property-coded arrays will appear simply as binary (or possibly 105 * string, if they happen to be nul-terminated and printable), and must 106 * be checked separately. 107 */ 108 enum value_type 109 { 110 /** 111 * This is a list of strings. When read from source, string 112 * lists become one property value for each string, however 113 * when read from binary we have a single property value 114 * incorporating the entire text, with nul bytes separating the 115 * strings. 116 */ 117 STRING_LIST, 118 /** 119 * This property contains a single string. 120 */ 121 STRING, 122 /** 123 * This is a binary value. Check the size of byte_data to 124 * determine how many bytes this contains. 125 */ 126 BINARY, 127 /** This contains a short-form address that should be replaced 128 * by a fully-qualified version. This will only appear when 129 * the input is a device tree source. When parsed from a 130 * device tree blob, the cross reference will have already been 131 * resolved and the property value will be a string containing 132 * the full path of the target node. */ 133 CROSS_REFERENCE, 134 /** 135 * This is a phandle reference. When parsed from source, the 136 * string_data will contain the node label for the target and, 137 * after cross references have been resolved, the binary data 138 * will contain a 32-bit integer that should match the phandle 139 * property of the target node. 140 */ 141 PHANDLE, 142 /** 143 * An empty property value. This will never appear on a real 144 * property value, it is used by checkers to indicate that no 145 * property values should exist for a property. 146 */ 147 EMPTY, 148 /** 149 * The type of this property has not yet been determined. 150 */ 151 UNKNOWN 152 }; 153 /** 154 * The type of this property. 155 */ 156 value_type type; 157 /** 158 * Returns true if this value is a cross reference, false otherwise. 159 */ is_cross_referencedtc::fdt::property_value160 inline bool is_cross_reference() 161 { 162 return is_type(CROSS_REFERENCE); 163 } 164 /** 165 * Returns true if this value is a phandle reference, false otherwise. 166 */ is_phandledtc::fdt::property_value167 inline bool is_phandle() 168 { 169 return is_type(PHANDLE); 170 } 171 /** 172 * Returns true if this value is a string, false otherwise. 173 */ is_stringdtc::fdt::property_value174 inline bool is_string() 175 { 176 return is_type(STRING); 177 } 178 /** 179 * Returns true if this value is a string list (a nul-separated 180 * sequence of strings), false otherwise. 181 */ is_string_listdtc::fdt::property_value182 inline bool is_string_list() 183 { 184 return is_type(STRING_LIST); 185 } 186 /** 187 * Returns true if this value is binary, false otherwise. 188 */ is_binarydtc::fdt::property_value189 inline bool is_binary() 190 { 191 return is_type(BINARY); 192 } 193 /** 194 * Returns this property value as a 32-bit integer. Returns 0 if this 195 * property value is not 32 bits long. The bytes in the property value 196 * are assumed to be in big-endian format, but the return value is in 197 * the host native endian. 198 */ 199 uint32_t get_as_uint32(); 200 /** 201 * Default constructor, specifying the label of the value. 202 */ property_valuedtc::fdt::property_value203 property_value(std::string l=std::string()) : label(l), type(UNKNOWN) {} 204 /** 205 * Writes the data for this value into an output buffer. 206 */ 207 void push_to_buffer(byte_buffer &buffer); 208 209 /** 210 * Writes the property value to the standard output. This uses the 211 * following heuristics for deciding how to print the output: 212 * 213 * - If the value is nul-terminated and only contains printable 214 * characters, it is written as a string. 215 * - If it is a multiple of 4 bytes long, then it is printed as cells. 216 * - Otherwise, it is printed as a byte buffer. 217 */ 218 void write_dts(FILE *file); 219 /** 220 * Tries to merge adjacent property values, returns true if it succeeds and 221 * false otherwise. 222 */ 223 bool try_to_merge(property_value &other); 224 /** 225 * Returns the size (in bytes) of this property value. 226 */ 227 size_t size(); 228 private: 229 /** 230 * Returns whether the value is of the specified type. If the type of 231 * the value has not yet been determined, then this calculates it. 232 */ is_typedtc::fdt::property_value233 inline bool is_type(value_type v) 234 { 235 if (type == UNKNOWN) 236 { 237 resolve_type(); 238 } 239 return type == v; 240 } 241 /** 242 * Determines the type of the value based on its contents. 243 */ 244 void resolve_type(); 245 /** 246 * Writes the property value to the specified file as a quoted string. 247 * This is used when generating DTS. 248 */ 249 void write_as_string(FILE *file); 250 /** 251 * Writes the property value to the specified file as a sequence of 252 * 32-bit big-endian cells. This is used when generating DTS. 253 */ 254 void write_as_cells(FILE *file); 255 /** 256 * Writes the property value to the specified file as a sequence of 257 * bytes. This is used when generating DTS. 258 */ 259 void write_as_bytes(FILE *file); 260 }; 261 262 /** 263 * A value encapsulating a single property. This contains a key, optionally a 264 * label, and optionally one or more values. 265 */ 266 class property 267 { 268 /** 269 * The name of this property. 270 */ 271 std::string key; 272 /** 273 * Zero or more labels. 274 */ 275 string_set labels; 276 /** 277 * The values in this property. 278 */ 279 std::vector<property_value> values; 280 /** 281 * Value indicating that this is a valid property. If a parse error 282 * occurs, then this value is false. 283 */ 284 bool valid; 285 /** 286 * Parses a string property value, i.e. a value enclosed in double quotes. 287 */ 288 void parse_string(text_input_buffer &input); 289 /** 290 * Parses one or more 32-bit values enclosed in angle brackets. 291 */ 292 void parse_cells(text_input_buffer &input, int cell_size); 293 /** 294 * Parses an array of bytes, contained within square brackets. 295 */ 296 void parse_bytes(text_input_buffer &input); 297 /** 298 * Parses a reference. This is a node label preceded by an ampersand 299 * symbol, which should expand to the full path to that node. 300 * 301 * Note: The specification says that the target of such a reference is 302 * a node name, however dtc assumes that it is a label, and so we 303 * follow their interpretation for compatibility. 304 */ 305 void parse_reference(text_input_buffer &input); 306 /** 307 * Parse a predefined macro definition for a property. 308 */ 309 void parse_define(text_input_buffer &input, define_map *defines); 310 /** 311 * Constructs a new property from two input buffers, pointing to the 312 * struct and strings tables in the device tree blob, respectively. 313 * The structs input buffer is assumed to have just consumed the 314 * FDT_PROP token. 315 */ 316 property(input_buffer &structs, input_buffer &strings); 317 /** 318 * Parses a new property from the input buffer. 319 */ 320 property(text_input_buffer &input, 321 std::string &&k, 322 string_set &&l, 323 bool terminated, 324 define_map *defines); 325 public: 326 /** 327 * Creates an empty property. 328 */ property(std::string && k,string_set && l=string_set ())329 property(std::string &&k, string_set &&l=string_set()) 330 : key(k), labels(l), valid(true) {} 331 /** 332 * Copy constructor. 333 */ property(property & p)334 property(property &p) : key(p.key), labels(p.labels), values(p.values), 335 valid(p.valid) {} 336 /** 337 * Factory method for constructing a new property. Attempts to parse a 338 * property from the input, and returns it on success. On any parse 339 * error, this will return 0. 340 */ 341 static property_ptr parse_dtb(input_buffer &structs, 342 input_buffer &strings); 343 /** 344 * Factory method for constructing a new property. Attempts to parse a 345 * property from the input, and returns it on success. On any parse 346 * error, this will return 0. 347 */ 348 static property_ptr parse(text_input_buffer &input, 349 std::string &&key, 350 string_set &&labels=string_set(), 351 bool semicolonTerminated=true, 352 define_map *defines=0); 353 /** 354 * Iterator type used for accessing the values of a property. 355 */ 356 typedef std::vector<property_value>::iterator value_iterator; 357 /** 358 * Returns an iterator referring to the first value in this property. 359 */ begin()360 inline value_iterator begin() 361 { 362 return values.begin(); 363 } 364 /** 365 * Returns an iterator referring to the last value in this property. 366 */ end()367 inline value_iterator end() 368 { 369 return values.end(); 370 } 371 /** 372 * Adds a new value to an existing property. 373 */ add_value(property_value v)374 inline void add_value(property_value v) 375 { 376 values.push_back(v); 377 } 378 /** 379 * Returns the key for this property. 380 */ get_key()381 inline const std::string &get_key() 382 { 383 return key; 384 } 385 /** 386 * Writes the property to the specified writer. The property name is a 387 * reference into the strings table. 388 */ 389 void write(dtb::output_writer &writer, dtb::string_table &strings); 390 /** 391 * Writes in DTS format to the specified file, at the given indent 392 * level. This will begin the line with the number of tabs specified 393 * as the indent level and then write the property in the most 394 * applicable way that it can determine. 395 */ 396 void write_dts(FILE *file, int indent); 397 /** 398 * Returns the byte offset of the specified property value. 399 */ 400 size_t offset_of_value(property_value &val); 401 }; 402 403 /** 404 * Class encapsulating a device tree node. Nodes may contain properties and 405 * other nodes. 406 */ 407 class node 408 { 409 public: 410 /** 411 * The labels for this node, if any. Node labels are used as the 412 * targets for cross references. 413 */ 414 std::unordered_set<std::string> labels; 415 /** 416 * The name of the node. 417 */ 418 std::string name; 419 /** 420 * The name of the node is a path reference. 421 */ 422 bool name_is_path_reference = false; 423 /** 424 * The unit address of the node, which is optionally written after the 425 * name followed by an at symbol. 426 */ 427 std::string unit_address; 428 /** 429 * A flag indicating that this node has been marked /omit-if-no-ref/ and 430 * will be omitted if it is not referenced, either directly or indirectly, 431 * by a node that is not similarly denoted. 432 */ 433 bool omit_if_no_ref = false; 434 /** 435 * A flag indicating that this node has been referenced, either directly 436 * or indirectly, by a node that is not marked /omit-if-no-ref/. 437 */ 438 bool used = false; 439 /** 440 * The type for the property vector. 441 */ 442 typedef std::vector<property_ptr> property_vector; 443 /** 444 * Iterator type for child nodes. 445 */ 446 typedef std::vector<node_ptr>::iterator child_iterator; 447 /** 448 * Recursion behavior to be observed for visiting 449 */ 450 enum visit_behavior 451 { 452 /** 453 * Recurse as normal through the rest of the tree. 454 */ 455 VISIT_RECURSE, 456 /** 457 * Continue recursing through the device tree, but do not 458 * recurse through this branch of the tree any further. 459 */ 460 VISIT_CONTINUE, 461 /** 462 * Immediately halt the visit. No further nodes will be visited. 463 */ 464 VISIT_BREAK 465 }; 466 private: 467 /** 468 * Adaptor to use children in range-based for loops. 469 */ 470 struct child_range 471 { child_rangedtc::fdt::node::child_range472 child_range(node &nd) : n(nd) {} begindtc::fdt::node::child_range473 child_iterator begin() { return n.child_begin(); } enddtc::fdt::node::child_range474 child_iterator end() { return n.child_end(); } 475 private: 476 node &n; 477 }; 478 /** 479 * Adaptor to use properties in range-based for loops. 480 */ 481 struct property_range 482 { property_rangedtc::fdt::node::property_range483 property_range(node &nd) : n(nd) {} begindtc::fdt::node::property_range484 property_vector::iterator begin() { return n.property_begin(); } enddtc::fdt::node::property_range485 property_vector::iterator end() { return n.property_end(); } 486 private: 487 node &n; 488 }; 489 /** 490 * The properties contained within this node. 491 */ 492 property_vector props; 493 /** 494 * The children of this node. 495 */ 496 std::vector<node_ptr> children; 497 /** 498 * Children that should be deleted from this node when merging. 499 */ 500 std::unordered_set<std::string> deleted_children; 501 /** 502 * Properties that should be deleted from this node when merging. 503 */ 504 std::unordered_set<std::string> deleted_props; 505 /** 506 * A flag indicating whether this node is valid. This is set to false 507 * if an error occurs during parsing. 508 */ 509 bool valid; 510 /** 511 * Parses a name inside a node, writing the string passed as the last 512 * argument as an error if it fails. 513 */ 514 std::string parse_name(text_input_buffer &input, 515 bool &is_property, 516 const char *error); 517 /** 518 * Constructs a new node from two input buffers, pointing to the struct 519 * and strings tables in the device tree blob, respectively. 520 */ 521 node(input_buffer &structs, input_buffer &strings); 522 /** 523 * Parses a new node from the specified input buffer. This is called 524 * when the input cursor is on the open brace for the start of the 525 * node. The name, and optionally label and unit address, should have 526 * already been parsed. 527 */ 528 node(text_input_buffer &input, 529 device_tree &tree, 530 std::string &&n, 531 std::unordered_set<std::string> &&l, 532 std::string &&a, 533 define_map*); 534 /** 535 * Creates a special node with the specified name and properties. 536 */ 537 node(const std::string &n, const std::vector<property_ptr> &p); 538 /** 539 * Comparison function for properties, used when sorting the properties 540 * vector. Orders the properties based on their names. 541 */ 542 static inline bool cmp_properties(property_ptr &p1, property_ptr &p2); 543 /* 544 { 545 return p1->get_key() < p2->get_key(); 546 } 547 */ 548 /** 549 * Comparison function for nodes, used when sorting the children 550 * vector. Orders the nodes based on their names or, if the names are 551 * the same, by the unit addresses. 552 */ 553 static inline bool cmp_children(node_ptr &c1, node_ptr &c2); 554 public: 555 /** 556 * Sorts the node's properties and children into alphabetical order and 557 * recursively sorts the children. 558 */ 559 void sort(); 560 /** 561 * Returns an iterator for the first child of this node. 562 */ child_begin()563 inline child_iterator child_begin() 564 { 565 return children.begin(); 566 } 567 /** 568 * Returns an iterator after the last child of this node. 569 */ child_end()570 inline child_iterator child_end() 571 { 572 return children.end(); 573 } 574 /** 575 * Returns a range suitable for use in a range-based for loop describing 576 * the children of this node. 577 */ child_nodes()578 inline child_range child_nodes() 579 { 580 return child_range(*this); 581 } 582 /** 583 * Accessor for the deleted children. 584 */ deleted_child_nodes()585 inline const std::unordered_set<std::string> &deleted_child_nodes() 586 { 587 return deleted_children; 588 } 589 /** 590 * Accessor for the deleted properties 591 */ deleted_properties()592 inline const std::unordered_set<std::string> &deleted_properties() 593 { 594 return deleted_props; 595 } 596 /** 597 * Returns a range suitable for use in a range-based for loop describing 598 * the properties of this node. 599 */ properties()600 inline property_range properties() 601 { 602 return property_range(*this); 603 } 604 /** 605 * Returns an iterator after the last property of this node. 606 */ property_begin()607 inline property_vector::iterator property_begin() 608 { 609 return props.begin(); 610 } 611 /** 612 * Returns an iterator for the first property of this node. 613 */ property_end()614 inline property_vector::iterator property_end() 615 { 616 return props.end(); 617 } 618 /** 619 * Factory method for constructing a new node. Attempts to parse a 620 * node in DTS format from the input, and returns it on success. On 621 * any parse error, this will return 0. This should be called with the 622 * cursor on the open brace of the property, after the name and so on 623 * have been parsed. 624 */ 625 static node_ptr parse(text_input_buffer &input, 626 device_tree &tree, 627 std::string &&name, 628 std::unordered_set<std::string> &&label=std::unordered_set<std::string>(), 629 std::string &&address=std::string(), 630 define_map *defines=0); 631 /** 632 * Factory method for constructing a new node. Attempts to parse a 633 * node in DTB format from the input, and returns it on success. On 634 * any parse error, this will return 0. This should be called with the 635 * cursor on the open brace of the property, after the name and so on 636 * have been parsed. 637 */ 638 static node_ptr parse_dtb(input_buffer &structs, input_buffer &strings); 639 /** 640 * Construct a new special node from a name and set of properties. 641 */ 642 static node_ptr create_special_node(const std::string &name, 643 const std::vector<property_ptr> &props); 644 /** 645 * Returns a property corresponding to the specified key, or 0 if this 646 * node does not contain a property of that name. 647 */ 648 property_ptr get_property(const std::string &key); 649 /** 650 * Adds a new property to this node. 651 */ add_property(property_ptr & p)652 inline void add_property(property_ptr &p) 653 { 654 props.push_back(p); 655 } 656 /** 657 * Adds a new child to this node. 658 */ add_child(node_ptr && n)659 inline void add_child(node_ptr &&n) 660 { 661 children.push_back(std::move(n)); 662 } 663 /** 664 * Deletes any children from this node. 665 */ delete_children_if(std::function<bool (node_ptr &)> predicate)666 inline void delete_children_if(std::function<bool(node_ptr &)> predicate) 667 { 668 children.erase(std::remove_if(children.begin(), children.end(), predicate), children.end()); 669 } 670 /** 671 * Merges a node into this one. Any properties present in both are 672 * overridden, any properties present in only one are preserved. 673 */ 674 void merge_node(node_ptr &other); 675 /** 676 * Write this node to the specified output. Although nodes do not 677 * refer to a string table directly, their properties do. The string 678 * table passed as the second argument is used for the names of 679 * properties within this node and its children. 680 */ 681 void write(dtb::output_writer &writer, dtb::string_table &strings); 682 /** 683 * Writes the current node as DTS to the specified file. The second 684 * parameter is the indent level. This function will start every line 685 * with this number of tabs. 686 */ 687 void write_dts(FILE *file, int indent); 688 /** 689 * Recursively visit this node and then its children based on the 690 * callable's return value. The callable may return VISIT_BREAK 691 * immediately halt all recursion and end the visit, VISIT_CONTINUE to 692 * not recurse into the current node's children, or VISIT_RECURSE to recurse 693 * through children as expected. parent will be passed to the callable. 694 */ 695 visit_behavior visit(std::function<visit_behavior(node&, node*)>, node *parent); 696 }; 697 698 /** 699 * Class encapsulating the entire parsed FDT. This is the top-level class, 700 * which parses the entire DTS representation and write out the finished 701 * version. 702 */ 703 class device_tree 704 { 705 public: 706 /** 707 * Type used for node paths. A node path is sequence of names and unit 708 * addresses. 709 */ 710 class node_path : public std::vector<std::pair<std::string,std::string>> 711 { 712 public: 713 /** 714 * Converts this to a string representation. 715 */ 716 std::string to_string() const; 717 }; 718 /** 719 * Name that we should use for phandle nodes. 720 */ 721 enum phandle_format 722 { 723 /** linux,phandle */ 724 LINUX, 725 /** phandle */ 726 EPAPR, 727 /** Create both nodes. */ 728 BOTH 729 }; 730 private: 731 /** 732 * The format that we should use for writing phandles. 733 */ 734 phandle_format phandle_node_name = EPAPR; 735 /** 736 * Flag indicating that this tree is valid. This will be set to false 737 * on parse errors. 738 */ 739 bool valid = true; 740 /** 741 * Flag indicating that this tree requires garbage collection. This will be 742 * set to true if a node marked /omit-if-no-ref/ is encountered. 743 */ 744 bool garbage_collect = false; 745 /** 746 * Type used for memory reservations. A reservation is two 64-bit 747 * values indicating a base address and length in memory that the 748 * kernel should not use. The high 32 bits are ignored on 32-bit 749 * platforms. 750 */ 751 typedef std::pair<uint64_t, uint64_t> reservation; 752 /** 753 * The memory reserves table. 754 */ 755 std::vector<reservation> reservations; 756 /** 757 * Root node. All other nodes are children of this node. 758 */ 759 node_ptr root; 760 /** 761 * Mapping from names to nodes. Only unambiguous names are recorded, 762 * duplicate names are stored as (node*)-1. 763 */ 764 std::unordered_map<std::string, node_ptr> node_names; 765 /** 766 * Mapping from names to the nodes that contain them. 767 */ 768 std::unordered_map<std::string, node_ptr> node_name_parents; 769 /** 770 * A map from labels to node paths. When resolving cross references, 771 * we look up referenced nodes in this and replace the cross reference 772 * with the full path to its target. 773 */ 774 std::unordered_map<std::string, node_path> node_paths; 775 /** 776 * All of the elements in `node_paths` in the order that they were 777 * created. This is used for emitting the `__symbols__` section, where 778 * we want to guarantee stable ordering. 779 */ 780 std::vector<std::pair<std::string, node_path>> ordered_node_paths; 781 /** 782 * A collection of property values that are references to other nodes. 783 * These should be expanded to the full path of their targets. 784 */ 785 std::vector<property_value*> cross_references; 786 /** 787 * Labels collected from top-level /delete-node/ directives. 788 */ 789 std::vector<std::string> deletions; 790 /** 791 * The location of something requiring a fixup entry. 792 */ 793 struct fixup 794 { 795 /** 796 * The path to the node. 797 */ 798 node_path path; 799 /** 800 * The property containing the reference. 801 */ 802 property_ptr prop; 803 /** 804 * The property value that contains the reference. 805 */ 806 property_value &val; 807 }; 808 /** 809 * A collection of property values that refer to phandles. These will 810 * be replaced by the value of the phandle property in their 811 * destination. 812 */ 813 std::vector<fixup> fixups; 814 /** 815 * The locations of all of the values that are supposed to become phandle 816 * references, but refer to things outside of this file. 817 */ 818 std::vector<std::reference_wrapper<fixup>> unresolved_fixups; 819 /** 820 * The names of nodes that target phandles. 821 */ 822 std::unordered_set<std::string> phandle_targets; 823 /** 824 * A collection of input buffers that we are using. These input 825 * buffers are the ones that own their memory, and so we must preserve 826 * them for the lifetime of the device tree. 827 */ 828 std::vector<std::unique_ptr<input_buffer>> buffers; 829 /** 830 * A map of used phandle values to nodes. All phandles must be unique, 831 * so we keep a set of ones that the user explicitly provides in the 832 * input to ensure that we don't reuse them. 833 * 834 * This is a map, rather than a set, because we also want to be able to 835 * find phandles that were provided by the user explicitly when we are 836 * doing checking. 837 */ 838 std::unordered_map<uint32_t, node_ptr> used_phandles; 839 /** 840 * Paths to search for include files. This contains a set of 841 * nul-terminated strings, which are not owned by this class and so 842 * must be freed separately. 843 */ 844 std::vector<std::string> include_paths; 845 /** 846 * Dictionary of predefined macros provided on the command line. 847 */ 848 define_map defines; 849 /** 850 * The default boot CPU, specified in the device tree header. 851 */ 852 uint32_t boot_cpu = 0; 853 /** 854 * The number of empty reserve map entries to generate in the blob. 855 */ 856 uint32_t spare_reserve_map_entries = 0; 857 /** 858 * The minimum size in bytes of the blob. 859 */ 860 uint32_t minimum_blob_size = 0; 861 /** 862 * The number of bytes of padding to add to the end of the blob. 863 */ 864 uint32_t blob_padding = 0; 865 /** 866 * Is this tree a plugin? 867 */ 868 bool is_plugin = false; 869 /** 870 * Visit all of the nodes recursively, and if they have labels then add 871 * them to the node_paths and node_names vectors so that they can be 872 * used in resolving cross references. Also collects phandle 873 * properties that have been explicitly added. 874 */ 875 void collect_names_recursive(node_ptr parent, node_ptr n, node_path &path); 876 /** 877 * Assign a phandle property to a single node. The next parameter 878 * holds the phandle to be assigned, and will be incremented upon 879 * assignment. 880 */ 881 property_ptr assign_phandle(node_ptr n, uint32_t &next); 882 /** 883 * Assign phandle properties to all nodes that have been referenced and 884 * require one. This method will recursively visit the tree starting at 885 * the node that it is passed. 886 */ 887 void assign_phandles(node_ptr n, uint32_t &next); 888 /** 889 * Calls the recursive version of this method on every root node. 890 */ 891 void collect_names(); 892 /** 893 * Resolves all cross references. Any properties that refer to another 894 * node must have their values replaced by either the node path or 895 * phandle value. The phandle parameter holds the next phandle to be 896 * assigned, should the need arise. It will be incremented upon each 897 * assignment of a phandle. Garbage collection of unreferenced nodes 898 * marked for "delete if unreferenced" will also occur here. 899 */ 900 void resolve_cross_references(uint32_t &phandle); 901 /** 902 * Garbage collects nodes that have been marked /omit-if-no-ref/ and do not 903 * have any references to them from nodes that are similarly marked. This 904 * is a fairly expensive operation. The return value indicates whether the 905 * tree has been dirtied as a result of this operation, so that the caller 906 * may take appropriate measures to bring the device tree into a consistent 907 * state as needed. 908 */ 909 bool garbage_collect_marked_nodes(); 910 /** 911 * Parses a dts file in the given buffer and adds the roots to the parsed 912 * set. The `read_header` argument indicates whether the header has 913 * already been read. Some dts files place the header in an include, 914 * rather than in the top-level file. 915 */ 916 void parse_file(text_input_buffer &input, 917 std::vector<node_ptr> &roots, 918 bool &read_header); 919 /** 920 * Template function that writes a dtb blob using the specified writer. 921 * The writer defines the output format (assembly, blob). 922 */ 923 template<class writer> 924 void write(int fd); 925 public: 926 /** 927 * Should we write the __symbols__ node (to allow overlays to be linked 928 * against this blob)? 929 */ 930 bool write_symbols = false; 931 /** 932 * Returns the node referenced by the property. If this is a tree that 933 * is in source form, then we have a string that we can use to index 934 * the cross_references array and so we can just look that up. 935 */ 936 node_ptr referenced_node(property_value &v); 937 /** 938 * Writes this FDT as a DTB to the specified output. 939 */ 940 void write_binary(int fd); 941 /** 942 * Writes this FDT as an assembly representation of the DTB to the 943 * specified output. The result can then be assembled and linked into 944 * a program. 945 */ 946 void write_asm(int fd); 947 /** 948 * Writes the tree in DTS (source) format. 949 */ 950 void write_dts(int fd); 951 /** 952 * Default constructor. Creates a valid, but empty FDT. 953 */ device_tree()954 device_tree() {} 955 /** 956 * Constructs a device tree from the specified file name, referring to 957 * a file that contains a device tree blob. 958 */ 959 void parse_dtb(const std::string &fn, FILE *depfile); 960 /** 961 * Construct a fragment wrapper around node. This will assume that node's 962 * name may be used as the target of the fragment, and the contents are to 963 * be wrapped in an __overlay__ node. The fragment wrapper will be assigned 964 * fragnumas its fragment number, and fragment number will be incremented. 965 */ 966 node_ptr create_fragment_wrapper(node_ptr &node, int &fragnum); 967 /** 968 * Generate a root node from the node passed in. This is sensitive to 969 * whether we're in a plugin context or not, so that if we're in a plugin we 970 * can circumvent any errors that might normally arise from a non-/ root. 971 * fragnum will be assigned to any fragment wrapper generated as a result 972 * of the call, and fragnum will be incremented. 973 */ 974 node_ptr generate_root(node_ptr &node, int &fragnum); 975 /** 976 * Reassign any fragment numbers from this new node, based on the given 977 * delta. 978 */ 979 void reassign_fragment_numbers(node_ptr &node, int &delta); 980 /* 981 * Constructs a device tree from the specified file name, referring to 982 * a file that contains device tree source. 983 */ 984 void parse_dts(const std::string &fn, FILE *depfile); 985 /** 986 * Returns whether this tree is valid. 987 */ is_valid()988 inline bool is_valid() 989 { 990 return valid; 991 } 992 /** 993 * Mark this tree as needing garbage collection, because an /omit-if-no-ref/ 994 * node has been encountered. 995 */ set_needs_garbage_collection()996 void set_needs_garbage_collection() 997 { 998 garbage_collect = true; 999 } 1000 /** 1001 * Sets the format for writing phandle properties. 1002 */ set_phandle_format(phandle_format f)1003 inline void set_phandle_format(phandle_format f) 1004 { 1005 phandle_node_name = f; 1006 } 1007 /** 1008 * Returns a pointer to the root node of this tree. No ownership 1009 * transfer. 1010 */ get_root() const1011 inline const node_ptr &get_root() const 1012 { 1013 return root; 1014 } 1015 /** 1016 * Sets the physical boot CPU. 1017 */ set_boot_cpu(uint32_t cpu)1018 void set_boot_cpu(uint32_t cpu) 1019 { 1020 boot_cpu = cpu; 1021 } 1022 /** 1023 * Sorts the tree. Useful for debugging device trees. 1024 */ sort()1025 void sort() 1026 { 1027 if (root) 1028 { 1029 root->sort(); 1030 } 1031 } 1032 /** 1033 * Adds a path to search for include files. The argument must be a 1034 * nul-terminated string representing the path. The device tree keeps 1035 * a pointer to this string, but does not own it: the caller is 1036 * responsible for freeing it if required. 1037 */ add_include_path(const char * path)1038 void add_include_path(const char *path) 1039 { 1040 std::string p(path); 1041 include_paths.push_back(std::move(p)); 1042 } 1043 /** 1044 * Sets the number of empty reserve map entries to add. 1045 */ set_empty_reserve_map_entries(uint32_t e)1046 void set_empty_reserve_map_entries(uint32_t e) 1047 { 1048 spare_reserve_map_entries = e; 1049 } 1050 /** 1051 * Sets the minimum size, in bytes, of the blob. 1052 */ set_blob_minimum_size(uint32_t s)1053 void set_blob_minimum_size(uint32_t s) 1054 { 1055 minimum_blob_size = s; 1056 } 1057 /** 1058 * Sets the amount of padding to add to the blob. 1059 */ set_blob_padding(uint32_t p)1060 void set_blob_padding(uint32_t p) 1061 { 1062 blob_padding = p; 1063 } 1064 /** 1065 * Parses a predefined macro value. 1066 */ 1067 bool parse_define(const char *def); 1068 }; 1069 1070 } // namespace fdt 1071 1072 } // namespace dtc 1073 1074 #endif // !_FDT_HH_ 1075