fdt.hh revision 330449
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2013 David Chisnall
5 * All rights reserved.
6 *
7 * This software was developed by SRI International and the University of
8 * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
9 * ("CTSRD"), as part of the DARPA CRASH research programme.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in the
18 *    documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * $FreeBSD: stable/11/usr.bin/dtc/fdt.hh 330449 2018-03-05 07:26:05Z eadler $
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 unit address of the node, which is optionally written after the
413	 * name followed by an at symbol.
414	 */
415	std::string unit_address;
416	/**
417	 * The type for the property vector.
418	 */
419	typedef std::vector<property_ptr> property_vector;
420	/**
421	 * Iterator type for child nodes.
422	 */
423	typedef std::vector<node_ptr>::iterator child_iterator;
424	private:
425	/**
426	 * Adaptor to use children in range-based for loops.
427	 */
428	struct child_range
429	{
430		child_range(node &nd) : n(nd) {}
431		child_iterator begin() { return n.child_begin(); }
432		child_iterator end() { return n.child_end(); }
433		private:
434		node &n;
435	};
436	/**
437	 * Adaptor to use properties in range-based for loops.
438	 */
439	struct property_range
440	{
441		property_range(node &nd) : n(nd) {}
442		property_vector::iterator begin() { return n.property_begin(); }
443		property_vector::iterator end() { return n.property_end(); }
444		private:
445		node &n;
446	};
447	/**
448	 * The properties contained within this node.
449	 */
450	property_vector props;
451	/**
452	 * The children of this node.
453	 */
454	std::vector<node_ptr> children;
455	/**
456	 * Children that should be deleted from this node when merging.
457	 */
458	std::unordered_set<std::string> deleted_children;
459	/**
460	 * Properties that should be deleted from this node when merging.
461	 */
462	std::unordered_set<std::string> deleted_props;
463	/**
464	 * A flag indicating whether this node is valid.  This is set to false
465	 * if an error occurs during parsing.
466	 */
467	bool valid;
468	/**
469	 * Parses a name inside a node, writing the string passed as the last
470	 * argument as an error if it fails.
471	 */
472	std::string parse_name(text_input_buffer &input,
473	                       bool &is_property,
474	                       const char *error);
475	/**
476	 * Constructs a new node from two input buffers, pointing to the struct
477	 * and strings tables in the device tree blob, respectively.
478	 */
479	node(input_buffer &structs, input_buffer &strings);
480	/**
481	 * Parses a new node from the specified input buffer.  This is called
482	 * when the input cursor is on the open brace for the start of the
483	 * node.  The name, and optionally label and unit address, should have
484	 * already been parsed.
485	 */
486	node(text_input_buffer &input,
487	     std::string &&n,
488	     std::unordered_set<std::string> &&l,
489	     std::string &&a,
490	     define_map*);
491	/**
492	 * Creates a special node with the specified name and properties.
493	 */
494	node(const std::string &n, const std::vector<property_ptr> &p);
495	/**
496	 * Comparison function for properties, used when sorting the properties
497	 * vector.  Orders the properties based on their names.
498	 */
499	static inline bool cmp_properties(property_ptr &p1, property_ptr &p2);
500		/*
501	{
502		return p1->get_key() < p2->get_key();
503	}
504	*/
505	/**
506	 * Comparison function for nodes, used when sorting the children
507	 * vector.  Orders the nodes based on their names or, if the names are
508	 * the same, by the unit addresses.
509	 */
510	static inline bool cmp_children(node_ptr &c1, node_ptr &c2);
511	public:
512	/**
513	 * Sorts the node's properties and children into alphabetical order and
514	 * recursively sorts the children.
515	 */
516	void sort();
517	/**
518	 * Returns an iterator for the first child of this node.
519	 */
520	inline child_iterator child_begin()
521	{
522		return children.begin();
523	}
524	/**
525	 * Returns an iterator after the last child of this node.
526	 */
527	inline child_iterator child_end()
528	{
529		return children.end();
530	}
531	/**
532	 * Returns a range suitable for use in a range-based for loop describing
533	 * the children of this node.
534	 */
535	inline child_range child_nodes()
536	{
537		return child_range(*this);
538	}
539	/**
540	 * Accessor for the deleted children.
541	 */
542	inline const std::unordered_set<std::string> &deleted_child_nodes()
543	{
544		return deleted_children;
545	}
546	/**
547	 * Accessor for the deleted properties
548	 */
549	inline const std::unordered_set<std::string> &deleted_properties()
550	{
551		return deleted_props;
552	}
553	/**
554	 * Returns a range suitable for use in a range-based for loop describing
555	 * the properties of this node.
556	 */
557	inline property_range properties()
558	{
559		return property_range(*this);
560	}
561	/**
562	 * Returns an iterator after the last property of this node.
563	 */
564	inline property_vector::iterator property_begin()
565	{
566		return props.begin();
567	}
568	/**
569	 * Returns an iterator for the first property of this node.
570	 */
571	inline property_vector::iterator property_end()
572	{
573		return props.end();
574	}
575	/**
576	 * Factory method for constructing a new node.  Attempts to parse a
577	 * node in DTS format from the input, and returns it on success.  On
578	 * any parse error, this will return 0.  This should be called with the
579	 * cursor on the open brace of the property, after the name and so on
580	 * have been parsed.
581	 */
582	static node_ptr parse(text_input_buffer &input,
583	                      std::string &&name,
584	                      std::unordered_set<std::string> &&label=std::unordered_set<std::string>(),
585	                      std::string &&address=std::string(),
586	                      define_map *defines=0);
587	/**
588	 * Factory method for constructing a new node.  Attempts to parse a
589	 * node in DTB format from the input, and returns it on success.  On
590	 * any parse error, this will return 0.  This should be called with the
591	 * cursor on the open brace of the property, after the name and so on
592	 * have been parsed.
593	 */
594	static node_ptr parse_dtb(input_buffer &structs, input_buffer &strings);
595	/**
596	 * Construct a new special node from a name and set of properties.
597	 */
598	static node_ptr create_special_node(const std::string &name,
599			const std::vector<property_ptr> &props);
600	/**
601	 * Returns a property corresponding to the specified key, or 0 if this
602	 * node does not contain a property of that name.
603	 */
604	property_ptr get_property(const std::string &key);
605	/**
606	 * Adds a new property to this node.
607	 */
608	inline void add_property(property_ptr &p)
609	{
610		props.push_back(p);
611	}
612	/**
613	 * Adds a new child to this node.
614	 */
615	inline void add_child(node_ptr &&n)
616	{
617		children.push_back(std::move(n));
618	}
619	/**
620	 * Merges a node into this one.  Any properties present in both are
621	 * overridden, any properties present in only one are preserved.
622	 */
623	void merge_node(node_ptr &other);
624	/**
625	 * Write this node to the specified output.  Although nodes do not
626	 * refer to a string table directly, their properties do.  The string
627	 * table passed as the second argument is used for the names of
628	 * properties within this node and its children.
629	 */
630	void write(dtb::output_writer &writer, dtb::string_table &strings);
631	/**
632	 * Writes the current node as DTS to the specified file.  The second
633	 * parameter is the indent level.  This function will start every line
634	 * with this number of tabs.
635	 */
636	void write_dts(FILE *file, int indent);
637	/**
638	 * Recursively visit this node and then its children.
639	 */
640	void visit(std::function<void(node&)>);
641};
642
643/**
644 * Class encapsulating the entire parsed FDT.  This is the top-level class,
645 * which parses the entire DTS representation and write out the finished
646 * version.
647 */
648class device_tree
649{
650	public:
651	/**
652	 * Type used for node paths.  A node path is sequence of names and unit
653	 * addresses.
654	 */
655	class node_path : public std::vector<std::pair<std::string,std::string>>
656	{
657		public:
658		/**
659		 * Converts this to a string representation.
660		 */
661		std::string to_string() const;
662	};
663	/**
664	 * Name that we should use for phandle nodes.
665	 */
666	enum phandle_format
667	{
668		/** linux,phandle */
669		LINUX,
670		/** phandle */
671		EPAPR,
672		/** Create both nodes. */
673		BOTH
674	};
675	private:
676	/**
677	 * The format that we should use for writing phandles.
678	 */
679	phandle_format phandle_node_name = EPAPR;
680	/**
681	 * Flag indicating that this tree is valid.  This will be set to false
682	 * on parse errors.
683	 */
684	bool valid = true;
685	/**
686	 * Type used for memory reservations.  A reservation is two 64-bit
687	 * values indicating a base address and length in memory that the
688	 * kernel should not use.  The high 32 bits are ignored on 32-bit
689	 * platforms.
690	 */
691	typedef std::pair<uint64_t, uint64_t> reservation;
692	/**
693	 * The memory reserves table.
694	 */
695	std::vector<reservation> reservations;
696	/**
697	 * Root node.  All other nodes are children of this node.
698	 */
699	node_ptr root;
700	/**
701	 * Mapping from names to nodes.  Only unambiguous names are recorded,
702	 * duplicate names are stored as (node*)-1.
703	 */
704	std::unordered_map<std::string, node*> node_names;
705	/**
706	 * A map from labels to node paths.  When resolving cross references,
707	 * we look up referenced nodes in this and replace the cross reference
708	 * with the full path to its target.
709	 */
710	std::unordered_map<std::string, node_path> node_paths;
711	/**
712	 * A collection of property values that are references to other nodes.
713	 * These should be expanded to the full path of their targets.
714	 */
715	std::vector<property_value*> cross_references;
716	/**
717	 * The location of something requiring a fixup entry.
718	 */
719	struct fixup
720	{
721		/**
722		 * The path to the node.
723		 */
724		node_path path;
725		/**
726		 * The property containing the reference.
727		 */
728		property_ptr prop;
729		/**
730		 * The property value that contains the reference.
731		 */
732		property_value &val;
733	};
734	/**
735	 * A collection of property values that refer to phandles.  These will
736	 * be replaced by the value of the phandle property in their
737	 * destination.
738	 */
739	std::vector<fixup> fixups;
740	/**
741	 * The locations of all of the values that are supposed to become phandle
742	 * references, but refer to things outside of this file.
743	 */
744	std::vector<std::reference_wrapper<fixup>> unresolved_fixups;
745	/**
746	 * The names of nodes that target phandles.
747	 */
748	std::unordered_set<std::string> phandle_targets;
749	/**
750	 * A collection of input buffers that we are using.  These input
751	 * buffers are the ones that own their memory, and so we must preserve
752	 * them for the lifetime of the device tree.
753	 */
754	std::vector<std::unique_ptr<input_buffer>> buffers;
755	/**
756	 * A map of used phandle values to nodes.  All phandles must be unique,
757	 * so we keep a set of ones that the user explicitly provides in the
758	 * input to ensure that we don't reuse them.
759	 *
760	 * This is a map, rather than a set, because we also want to be able to
761	 * find phandles that were provided by the user explicitly when we are
762	 * doing checking.
763	 */
764	std::unordered_map<uint32_t, node*> used_phandles;
765	/**
766	 * Paths to search for include files.  This contains a set of
767	 * nul-terminated strings, which are not owned by this class and so
768	 * must be freed separately.
769	 */
770	std::vector<std::string> include_paths;
771	/**
772	 * Dictionary of predefined macros provided on the command line.
773	 */
774	define_map               defines;
775	/**
776	 * The default boot CPU, specified in the device tree header.
777	 */
778	uint32_t boot_cpu = 0;
779	/**
780	 * The number of empty reserve map entries to generate in the blob.
781	 */
782	uint32_t spare_reserve_map_entries = 0;
783	/**
784	 * The minimum size in bytes of the blob.
785	 */
786	uint32_t minimum_blob_size = 0;
787	/**
788	 * The number of bytes of padding to add to the end of the blob.
789	 */
790	uint32_t blob_padding = 0;
791	/**
792	 * Is this tree a plugin?
793	 */
794	bool is_plugin = false;
795	/**
796	 * Visit all of the nodes recursively, and if they have labels then add
797	 * them to the node_paths and node_names vectors so that they can be
798	 * used in resolving cross references.  Also collects phandle
799	 * properties that have been explicitly added.
800	 */
801	void collect_names_recursive(node_ptr &n, node_path &path);
802	/**
803	 * Assign a phandle property to a single node.  The next parameter
804	 * holds the phandle to be assigned, and will be incremented upon
805	 * assignment.
806	 */
807	property_ptr assign_phandle(node *n, uint32_t &next);
808	/**
809	 * Assign phandle properties to all nodes that have been referenced and
810	 * require one.  This method will recursively visit the tree starting at
811	 * the node that it is passed.
812	 */
813	void assign_phandles(node_ptr &n, uint32_t &next);
814	/**
815	 * Calls the recursive version of this method on every root node.
816	 */
817	void collect_names();
818	/**
819	 * Resolves all cross references.  Any properties that refer to another
820	 * node must have their values replaced by either the node path or
821	 * phandle value.  The phandle parameter holds the next phandle to be
822	 * assigned, should the need arise.  It will be incremented upon each
823	 * assignment of a phandle.
824	 */
825	void resolve_cross_references(uint32_t &phandle);
826	/**
827	 * Parses a dts file in the given buffer and adds the roots to the parsed
828	 * set.  The `read_header` argument indicates whether the header has
829	 * already been read.  Some dts files place the header in an include,
830	 * rather than in the top-level file.
831	 */
832	void parse_file(text_input_buffer &input,
833	                std::vector<node_ptr> &roots,
834	                bool &read_header);
835	/**
836	 * Template function that writes a dtb blob using the specified writer.
837	 * The writer defines the output format (assembly, blob).
838	 */
839	template<class writer>
840	void write(int fd);
841	public:
842	/**
843	 * Should we write the __symbols__ node (to allow overlays to be linked
844	 * against this blob)?
845	 */
846	bool write_symbols = false;
847	/**
848	 * Returns the node referenced by the property.  If this is a tree that
849	 * is in source form, then we have a string that we can use to index
850	 * the cross_references array and so we can just look that up.
851	 */
852	node *referenced_node(property_value &v);
853	/**
854	 * Writes this FDT as a DTB to the specified output.
855	 */
856	void write_binary(int fd);
857	/**
858	 * Writes this FDT as an assembly representation of the DTB to the
859	 * specified output.  The result can then be assembled and linked into
860	 * a program.
861	 */
862	void write_asm(int fd);
863	/**
864	 * Writes the tree in DTS (source) format.
865	 */
866	void write_dts(int fd);
867	/**
868	 * Default constructor.  Creates a valid, but empty FDT.
869	 */
870	device_tree() {}
871	/**
872	 * Constructs a device tree from the specified file name, referring to
873	 * a file that contains a device tree blob.
874	 */
875	void parse_dtb(const std::string &fn, FILE *depfile);
876	/**
877	 * Construct a fragment wrapper around node.  This will assume that node's
878	 * name may be used as the target of the fragment, and the contents are to
879	 * be wrapped in an __overlay__ node.  The fragment wrapper will be assigned
880	 * fragnumas its fragment number, and fragment number will be incremented.
881	 */
882	node_ptr create_fragment_wrapper(node_ptr &node, int &fragnum);
883	/**
884	 * Generate a root node from the node passed in.  This is sensitive to
885	 * whether we're in a plugin context or not, so that if we're in a plugin we
886	 * can circumvent any errors that might normally arise from a non-/ root.
887	 * fragnum will be assigned to any fragment wrapper generated as a result
888	 * of the call, and fragnum will be incremented.
889	 */
890	node_ptr generate_root(node_ptr &node, int &fragnum);
891	/**
892	 * Reassign any fragment numbers from this new node, based on the given
893	 * delta.
894	 */
895	void reassign_fragment_numbers(node_ptr &node, int &delta);
896	/*
897	 * Constructs a device tree from the specified file name, referring to
898	 * a file that contains device tree source.
899	 */
900	void parse_dts(const std::string &fn, FILE *depfile);
901	/**
902	 * Returns whether this tree is valid.
903	 */
904	inline bool is_valid()
905	{
906		return valid;
907	}
908	/**
909	 * Sets the format for writing phandle properties.
910	 */
911	inline void set_phandle_format(phandle_format f)
912	{
913		phandle_node_name = f;
914	}
915	/**
916	 * Returns a pointer to the root node of this tree.  No ownership
917	 * transfer.
918	 */
919	inline const node_ptr &get_root() const
920	{
921		return root;
922	}
923	/**
924	 * Sets the physical boot CPU.
925	 */
926	void set_boot_cpu(uint32_t cpu)
927	{
928		boot_cpu = cpu;
929	}
930	/**
931	 * Sorts the tree.  Useful for debugging device trees.
932	 */
933	void sort()
934	{
935		if (root)
936		{
937			root->sort();
938		}
939	}
940	/**
941	 * Adds a path to search for include files.  The argument must be a
942	 * nul-terminated string representing the path.  The device tree keeps
943	 * a pointer to this string, but does not own it: the caller is
944	 * responsible for freeing it if required.
945	 */
946	void add_include_path(const char *path)
947	{
948		std::string p(path);
949		include_paths.push_back(std::move(p));
950	}
951	/**
952	 * Sets the number of empty reserve map entries to add.
953	 */
954	void set_empty_reserve_map_entries(uint32_t e)
955	{
956		spare_reserve_map_entries = e;
957	}
958	/**
959	 * Sets the minimum size, in bytes, of the blob.
960	 */
961	void set_blob_minimum_size(uint32_t s)
962	{
963		minimum_blob_size = s;
964	}
965	/**
966	 * Sets the amount of padding to add to the blob.
967	 */
968	void set_blob_padding(uint32_t p)
969	{
970		blob_padding = p;
971	}
972	/**
973	 * Parses a predefined macro value.
974	 */
975	bool parse_define(const char *def);
976};
977
978} // namespace fdt
979
980} // namespace dtc
981
982#endif // !_FDT_HH_
983