fdt.hh revision 332562
1219820Sjeff/*-
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 332562 2018-04-16 13:50:01Z 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;
59/**
60 * Type for (owned) pointers to properties.
61 */
62typedef std::shared_ptr<property> property_ptr;
63/**
64 * Owning pointer to a node.
65 */
66typedef std::unique_ptr<node> node_ptr;
67/**
68 * Map from macros to property pointers.
69 */
70typedef std::unordered_map<std::string, property_ptr> define_map;
71/**
72 * Set of strings used for label names.
73 */
74typedef 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 */
79struct 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 */
258class 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 */
399class 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 */
675class device_tree
676{
677	public:
678	/**
679	 * Type used for node paths.  A node path is sequence of names and unit
680	 * addresses.
681	 */
682	class node_path : public std::vector<std::pair<std::string,std::string>>
683	{
684		public:
685		/**
686		 * Converts this to a string representation.
687		 */
688		std::string to_string() const;
689	};
690	/**
691	 * Name that we should use for phandle nodes.
692	 */
693	enum phandle_format
694	{
695		/** linux,phandle */
696		LINUX,
697		/** phandle */
698		EPAPR,
699		/** Create both nodes. */
700		BOTH
701	};
702	private:
703	/**
704	 * The format that we should use for writing phandles.
705	 */
706	phandle_format phandle_node_name = EPAPR;
707	/**
708	 * Flag indicating that this tree is valid.  This will be set to false
709	 * on parse errors.
710	 */
711	bool valid = true;
712	/**
713	 * Type used for memory reservations.  A reservation is two 64-bit
714	 * values indicating a base address and length in memory that the
715	 * kernel should not use.  The high 32 bits are ignored on 32-bit
716	 * platforms.
717	 */
718	typedef std::pair<uint64_t, uint64_t> reservation;
719	/**
720	 * The memory reserves table.
721	 */
722	std::vector<reservation> reservations;
723	/**
724	 * Root node.  All other nodes are children of this node.
725	 */
726	node_ptr root;
727	/**
728	 * Mapping from names to nodes.  Only unambiguous names are recorded,
729	 * duplicate names are stored as (node*)-1.
730	 */
731	std::unordered_map<std::string, node*> node_names;
732	/**
733	 * A map from labels to node paths.  When resolving cross references,
734	 * we look up referenced nodes in this and replace the cross reference
735	 * with the full path to its target.
736	 */
737	std::unordered_map<std::string, node_path> node_paths;
738	/**
739	 * A collection of property values that are references to other nodes.
740	 * These should be expanded to the full path of their targets.
741	 */
742	std::vector<property_value*> cross_references;
743	/**
744	 * The location of something requiring a fixup entry.
745	 */
746	struct fixup
747	{
748		/**
749		 * The path to the node.
750		 */
751		node_path path;
752		/**
753		 * The property containing the reference.
754		 */
755		property_ptr prop;
756		/**
757		 * The property value that contains the reference.
758		 */
759		property_value &val;
760	};
761	/**
762	 * A collection of property values that refer to phandles.  These will
763	 * be replaced by the value of the phandle property in their
764	 * destination.
765	 */
766	std::vector<fixup> fixups;
767	/**
768	 * The locations of all of the values that are supposed to become phandle
769	 * references, but refer to things outside of this file.
770	 */
771	std::vector<std::reference_wrapper<fixup>> unresolved_fixups;
772	/**
773	 * The names of nodes that target phandles.
774	 */
775	std::unordered_set<std::string> phandle_targets;
776	/**
777	 * A collection of input buffers that we are using.  These input
778	 * buffers are the ones that own their memory, and so we must preserve
779	 * them for the lifetime of the device tree.
780	 */
781	std::vector<std::unique_ptr<input_buffer>> buffers;
782	/**
783	 * A map of used phandle values to nodes.  All phandles must be unique,
784	 * so we keep a set of ones that the user explicitly provides in the
785	 * input to ensure that we don't reuse them.
786	 *
787	 * This is a map, rather than a set, because we also want to be able to
788	 * find phandles that were provided by the user explicitly when we are
789	 * doing checking.
790	 */
791	std::unordered_map<uint32_t, node*> used_phandles;
792	/**
793	 * Paths to search for include files.  This contains a set of
794	 * nul-terminated strings, which are not owned by this class and so
795	 * must be freed separately.
796	 */
797	std::vector<std::string> include_paths;
798	/**
799	 * Dictionary of predefined macros provided on the command line.
800	 */
801	define_map               defines;
802	/**
803	 * The default boot CPU, specified in the device tree header.
804	 */
805	uint32_t boot_cpu = 0;
806	/**
807	 * The number of empty reserve map entries to generate in the blob.
808	 */
809	uint32_t spare_reserve_map_entries = 0;
810	/**
811	 * The minimum size in bytes of the blob.
812	 */
813	uint32_t minimum_blob_size = 0;
814	/**
815	 * The number of bytes of padding to add to the end of the blob.
816	 */
817	uint32_t blob_padding = 0;
818	/**
819	 * Is this tree a plugin?
820	 */
821	bool is_plugin = false;
822	/**
823	 * Visit all of the nodes recursively, and if they have labels then add
824	 * them to the node_paths and node_names vectors so that they can be
825	 * used in resolving cross references.  Also collects phandle
826	 * properties that have been explicitly added.
827	 */
828	void collect_names_recursive(node_ptr &n, node_path &path);
829	/**
830	 * Assign a phandle property to a single node.  The next parameter
831	 * holds the phandle to be assigned, and will be incremented upon
832	 * assignment.
833	 */
834	property_ptr assign_phandle(node *n, uint32_t &next);
835	/**
836	 * Assign phandle properties to all nodes that have been referenced and
837	 * require one.  This method will recursively visit the tree starting at
838	 * the node that it is passed.
839	 */
840	void assign_phandles(node_ptr &n, uint32_t &next);
841	/**
842	 * Calls the recursive version of this method on every root node.
843	 */
844	void collect_names();
845	/**
846	 * Resolves all cross references.  Any properties that refer to another
847	 * node must have their values replaced by either the node path or
848	 * phandle value.  The phandle parameter holds the next phandle to be
849	 * assigned, should the need arise.  It will be incremented upon each
850	 * assignment of a phandle.
851	 */
852	void resolve_cross_references(uint32_t &phandle);
853	/**
854	 * Parses a dts file in the given buffer and adds the roots to the parsed
855	 * set.  The `read_header` argument indicates whether the header has
856	 * already been read.  Some dts files place the header in an include,
857	 * rather than in the top-level file.
858	 */
859	void parse_file(text_input_buffer &input,
860	                std::vector<node_ptr> &roots,
861	                bool &read_header);
862	/**
863	 * Template function that writes a dtb blob using the specified writer.
864	 * The writer defines the output format (assembly, blob).
865	 */
866	template<class writer>
867	void write(int fd);
868	public:
869	/**
870	 * Should we write the __symbols__ node (to allow overlays to be linked
871	 * against this blob)?
872	 */
873	bool write_symbols = false;
874	/**
875	 * Returns the node referenced by the property.  If this is a tree that
876	 * is in source form, then we have a string that we can use to index
877	 * the cross_references array and so we can just look that up.
878	 */
879	node *referenced_node(property_value &v);
880	/**
881	 * Writes this FDT as a DTB to the specified output.
882	 */
883	void write_binary(int fd);
884	/**
885	 * Writes this FDT as an assembly representation of the DTB to the
886	 * specified output.  The result can then be assembled and linked into
887	 * a program.
888	 */
889	void write_asm(int fd);
890	/**
891	 * Writes the tree in DTS (source) format.
892	 */
893	void write_dts(int fd);
894	/**
895	 * Default constructor.  Creates a valid, but empty FDT.
896	 */
897	device_tree() {}
898	/**
899	 * Constructs a device tree from the specified file name, referring to
900	 * a file that contains a device tree blob.
901	 */
902	void parse_dtb(const std::string &fn, FILE *depfile);
903	/**
904	 * Construct a fragment wrapper around node.  This will assume that node's
905	 * name may be used as the target of the fragment, and the contents are to
906	 * be wrapped in an __overlay__ node.  The fragment wrapper will be assigned
907	 * fragnumas its fragment number, and fragment number will be incremented.
908	 */
909	node_ptr create_fragment_wrapper(node_ptr &node, int &fragnum);
910	/**
911	 * Generate a root node from the node passed in.  This is sensitive to
912	 * whether we're in a plugin context or not, so that if we're in a plugin we
913	 * can circumvent any errors that might normally arise from a non-/ root.
914	 * fragnum will be assigned to any fragment wrapper generated as a result
915	 * of the call, and fragnum will be incremented.
916	 */
917	node_ptr generate_root(node_ptr &node, int &fragnum);
918	/**
919	 * Reassign any fragment numbers from this new node, based on the given
920	 * delta.
921	 */
922	void reassign_fragment_numbers(node_ptr &node, int &delta);
923	/*
924	 * Constructs a device tree from the specified file name, referring to
925	 * a file that contains device tree source.
926	 */
927	void parse_dts(const std::string &fn, FILE *depfile);
928	/**
929	 * Returns whether this tree is valid.
930	 */
931	inline bool is_valid()
932	{
933		return valid;
934	}
935	/**
936	 * Sets the format for writing phandle properties.
937	 */
938	inline void set_phandle_format(phandle_format f)
939	{
940		phandle_node_name = f;
941	}
942	/**
943	 * Returns a pointer to the root node of this tree.  No ownership
944	 * transfer.
945	 */
946	inline const node_ptr &get_root() const
947	{
948		return root;
949	}
950	/**
951	 * Sets the physical boot CPU.
952	 */
953	void set_boot_cpu(uint32_t cpu)
954	{
955		boot_cpu = cpu;
956	}
957	/**
958	 * Sorts the tree.  Useful for debugging device trees.
959	 */
960	void sort()
961	{
962		if (root)
963		{
964			root->sort();
965		}
966	}
967	/**
968	 * Adds a path to search for include files.  The argument must be a
969	 * nul-terminated string representing the path.  The device tree keeps
970	 * a pointer to this string, but does not own it: the caller is
971	 * responsible for freeing it if required.
972	 */
973	void add_include_path(const char *path)
974	{
975		std::string p(path);
976		include_paths.push_back(std::move(p));
977	}
978	/**
979	 * Sets the number of empty reserve map entries to add.
980	 */
981	void set_empty_reserve_map_entries(uint32_t e)
982	{
983		spare_reserve_map_entries = e;
984	}
985	/**
986	 * Sets the minimum size, in bytes, of the blob.
987	 */
988	void set_blob_minimum_size(uint32_t s)
989	{
990		minimum_blob_size = s;
991	}
992	/**
993	 * Sets the amount of padding to add to the blob.
994	 */
995	void set_blob_padding(uint32_t p)
996	{
997		blob_padding = p;
998	}
999	/**
1000	 * Parses a predefined macro value.
1001	 */
1002	bool parse_define(const char *def);
1003};
1004
1005} // namespace fdt
1006
1007} // namespace dtc
1008
1009#endif // !_FDT_HH_
1010