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