]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.bin/dtc/fdt.hh
Merge libc++ trunk r338150 (just before the 7.0.0 branch point), and
[FreeBSD/FreeBSD.git] / usr.bin / dtc / fdt.hh
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_