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