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