1245803Stheraven/*-
2245803Stheraven * Copyright (c) 2013 David Chisnall
3245803Stheraven * All rights reserved.
4245803Stheraven *
5245803Stheraven * This software was developed by SRI International and the University of
6245803Stheraven * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
7245803Stheraven * ("CTSRD"), as part of the DARPA CRASH research programme.
8245803Stheraven *
9245803Stheraven * Redistribution and use in source and binary forms, with or without
10245803Stheraven * modification, are permitted provided that the following conditions
11245803Stheraven * are met:
12245803Stheraven * 1. Redistributions of source code must retain the above copyright
13245803Stheraven *    notice, this list of conditions and the following disclaimer.
14245803Stheraven * 2. Redistributions in binary form must reproduce the above copyright
15245803Stheraven *    notice, this list of conditions and the following disclaimer in the
16245803Stheraven *    documentation and/or other materials provided with the distribution.
17245803Stheraven *
18245803Stheraven * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19245803Stheraven * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20245803Stheraven * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21245803Stheraven * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22245803Stheraven * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23245803Stheraven * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24245803Stheraven * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25245803Stheraven * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26245803Stheraven * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27245803Stheraven * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28245803Stheraven * SUCH DAMAGE.
29245803Stheraven *
30245803Stheraven * $FreeBSD$
31245803Stheraven */
32245803Stheraven
33245803Stheraven#ifndef _FDT_HH_
34245803Stheraven#define _FDT_HH_
35245803Stheraven#include <map>
36245803Stheraven
37245803Stheraven#include "util.hh"
38245803Stheraven#include "string.hh"
39245803Stheraven
40245803Stheravennamespace dtc
41245803Stheraven{
42245803Stheraven
43245803Stheravennamespace dtb
44245803Stheraven{
45245803Stheravenstruct output_writer;
46245803Stheravenclass string_table;
47245803Stheraven}
48245803Stheraven
49245803Stheravennamespace fdt
50245803Stheraven{
51254522Stheravenclass property;
52254522Stheraventypedef std::map<string, property*> define_map;
53245803Stheraven/**
54245803Stheraven * Properties may contain a number of different value, each with a different
55245803Stheraven * label.  This class encapsulates a single value.
56245803Stheraven */
57245803Stheravenstruct property_value
58245803Stheraven{
59245803Stheraven	/**
60245803Stheraven	 * The label for this data.  This is usually empty.
61245803Stheraven	 */
62245803Stheraven	string label;
63245803Stheraven	/**
64245803Stheraven	 * If this value is a string, or something resolved from a string (a
65245803Stheraven	 * reference) then this contains the source string.
66245803Stheraven	 */
67245803Stheraven	string string_data;
68245803Stheraven	/**
69245803Stheraven	 * The data that should be written to the final output.
70245803Stheraven	 */
71245803Stheraven	byte_buffer byte_data;
72245803Stheraven	/**
73245803Stheraven	 * Enumeration describing the possible types of a value.  Note that
74245803Stheraven	 * property-coded arrays will appear simply as binary (or possibly
75245803Stheraven	 * string, if they happen to be nul-terminated and printable), and must
76245803Stheraven	 * be checked separately.
77245803Stheraven	 */
78245803Stheraven	enum value_type
79245803Stheraven	{
80245803Stheraven		/**
81245803Stheraven		 * This is a list of strings.  When read from source, string
82245803Stheraven		 * lists become one property value for each string, however
83245803Stheraven		 * when read from binary we have a single property value
84245803Stheraven		 * incorporating the entire text, with nul bytes separating the
85245803Stheraven		 * strings.
86245803Stheraven		 */
87245803Stheraven		STRING_LIST,
88245803Stheraven		/**
89245803Stheraven		 * This property contains a single string.
90245803Stheraven		 */
91245803Stheraven		STRING,
92245803Stheraven		/**
93245803Stheraven		 * This is a binary value.  Check the size of byte_data to
94245803Stheraven		 * determine how many bytes this contains.
95245803Stheraven		 */
96245803Stheraven		BINARY,
97245803Stheraven		/** This contains a short-form address that should be replaced
98245803Stheraven		 * by a fully-qualified version.  This will only appear when
99245803Stheraven		 * the input is a device tree source.  When parsed from a
100245803Stheraven		 * device tree blob, the cross reference will have already been
101245803Stheraven		 * resolved and the property value will be a string containing
102245803Stheraven		 * the full path of the target node.  */
103245803Stheraven		CROSS_REFERENCE,
104245803Stheraven		/**
105245803Stheraven		 * This is a phandle reference.  When parsed from source, the
106245803Stheraven		 * string_data will contain the node label for the target and,
107245803Stheraven		 * after cross references have been resolved, the binary data
108245803Stheraven		 * will contain a 32-bit integer that should match the phandle
109245803Stheraven		 * property of the target node.
110245803Stheraven		 */
111245803Stheraven		PHANDLE,
112245803Stheraven		/**
113245803Stheraven		 * An empty property value.  This will never appear on a real
114245803Stheraven		 * property value, it is used by checkers to indicate that no
115245803Stheraven		 * property values should exist for a property.
116245803Stheraven		 */
117245803Stheraven		EMPTY,
118245803Stheraven		/**
119245803Stheraven		 * The type of this property has not yet been determined.
120245803Stheraven		 */
121245803Stheraven		UNKNOWN
122245803Stheraven	};
123245803Stheraven	/**
124245803Stheraven	 * The type of this property.
125245803Stheraven	 */
126245803Stheraven	value_type type;
127245803Stheraven	/**
128245803Stheraven	 * Returns true if this value is a cross reference, false otherwise.
129245803Stheraven	 */
130245803Stheraven	inline bool is_cross_reference()
131245803Stheraven	{
132245803Stheraven		return is_type(CROSS_REFERENCE);
133245803Stheraven	}
134245803Stheraven	/**
135245803Stheraven	 * Returns true if this value is a phandle reference, false otherwise.
136245803Stheraven	 */
137245803Stheraven	inline bool is_phandle()
138245803Stheraven	{
139245803Stheraven		return is_type(PHANDLE);
140245803Stheraven	}
141245803Stheraven	/**
142245803Stheraven	 * Returns true if this value is a string, false otherwise.
143245803Stheraven	 */
144245803Stheraven	inline bool is_string()
145245803Stheraven	{
146245803Stheraven		return is_type(STRING);
147245803Stheraven	}
148245803Stheraven	/**
149245803Stheraven	 * Returns true if this value is a string list (a nul-separated
150245803Stheraven	 * sequence of strings), false otherwise.
151245803Stheraven	 */
152245803Stheraven	inline bool is_string_list()
153245803Stheraven	{
154245803Stheraven		return is_type(STRING_LIST);
155245803Stheraven	}
156245803Stheraven	/**
157245803Stheraven	 * Returns true if this value is binary, false otherwise.
158245803Stheraven	 */
159245803Stheraven	inline bool is_binary()
160245803Stheraven	{
161245803Stheraven		return is_type(BINARY);
162245803Stheraven	}
163245803Stheraven	/**
164245803Stheraven	 * Returns this property value as a 32-bit integer.  Returns 0 if this
165245803Stheraven	 * property value is not 32 bits long.  The bytes in the property value
166245803Stheraven	 * are assumed to be in big-endian format, but the return value is in
167245803Stheraven	 * the host native endian.
168245803Stheraven	 */
169245803Stheraven	uint32_t get_as_uint32();
170245803Stheraven	/**
171245803Stheraven	 * Default constructor, specifying the label of the value.
172245803Stheraven	 */
173245803Stheraven	property_value(string l=string()) : label(l), type(UNKNOWN) {}
174245803Stheraven	/**
175245803Stheraven	 * Writes the data for this value into an output buffer.
176245803Stheraven	 */
177245803Stheraven	void push_to_buffer(byte_buffer &buffer);
178245803Stheraven
179245803Stheraven	/**
180245803Stheraven	 * Writes the property value to the standard output.  This uses the
181245803Stheraven	 * following heuristics for deciding how to print the output:
182245803Stheraven	 *
183245803Stheraven	 * - If the value is nul-terminated and only contains printable
184245803Stheraven	 *   characters, it is written as a string.
185245803Stheraven	 * - If it is a multiple of 4 bytes long, then it is printed as cells.
186245803Stheraven	 * - Otherwise, it is printed as a byte buffer.
187245803Stheraven	 */
188245803Stheraven	void write_dts(FILE *file);
189245803Stheraven	private:
190245803Stheraven	/**
191245803Stheraven	 * Returns whether the value is of the specified type.  If the type of
192245803Stheraven	 * the value has not yet been determined, then this calculates it.
193245803Stheraven	 */
194245803Stheraven	inline bool is_type(value_type v)
195245803Stheraven	{
196245803Stheraven		if (type == UNKNOWN)
197245803Stheraven		{
198245803Stheraven			resolve_type();
199245803Stheraven		}
200245803Stheraven		return type == v;
201245803Stheraven	}
202245803Stheraven	/**
203245803Stheraven	 * Determines the type of the value based on its contents.
204245803Stheraven	 */
205245803Stheraven	void resolve_type();
206245803Stheraven	/**
207245803Stheraven	 * Writes the property value to the specified file as a quoted string.
208245803Stheraven	 * This is used when generating DTS.
209245803Stheraven	 */
210245803Stheraven	void write_as_string(FILE *file);
211245803Stheraven	/**
212245803Stheraven	 * Writes the property value to the specified file as a sequence of
213245803Stheraven	 * 32-bit big-endian cells.  This is used when generating DTS.
214245803Stheraven	 */
215245803Stheraven	void write_as_cells(FILE *file);
216245803Stheraven	/**
217245803Stheraven	 * Writes the property value to the specified file as a sequence of
218245803Stheraven	 * bytes.  This is used when generating DTS.
219245803Stheraven	 */
220245803Stheraven	void write_as_bytes(FILE *file);
221245803Stheraven};
222245803Stheraven
223245803Stheraven/**
224245803Stheraven * A value encapsulating a single property.  This contains a key, optionally a
225245803Stheraven * label, and optionally one or more values.
226245803Stheraven */
227245803Stheravenclass property
228245803Stheraven{
229245803Stheraven	/**
230245803Stheraven	 * The name of this property.
231245803Stheraven	 */
232245803Stheraven	string key;
233245803Stheraven	/**
234245803Stheraven	 * An optional label.
235245803Stheraven	 */
236245803Stheraven	string label;
237245803Stheraven	/**
238245803Stheraven	 * The values in this property.
239245803Stheraven	 */
240245803Stheraven	std::vector<property_value> values;
241245803Stheraven	/**
242245803Stheraven	 * Value indicating that this is a valid property.  If a parse error
243245803Stheraven	 * occurs, then this value is false.
244245803Stheraven	 */
245245803Stheraven	bool valid;
246245803Stheraven	/**
247245803Stheraven	 * Parses a string property value, i.e. a value enclosed in double quotes.
248245803Stheraven	 */
249245803Stheraven	void parse_string(input_buffer &input);
250245803Stheraven	/**
251245803Stheraven	 * Parses one or more 32-bit values enclosed in angle brackets.
252245803Stheraven	 */
253245803Stheraven	void parse_cells(input_buffer &input);
254245803Stheraven	/**
255245803Stheraven	 * Parses an array of bytes, contained within square brackets.
256245803Stheraven	 */
257245803Stheraven	void parse_bytes(input_buffer &input);
258245803Stheraven	/**
259245803Stheraven	 * Parses a reference.  This is a node label preceded by an ampersand
260245803Stheraven	 * symbol, which should expand to the full path to that node.
261245803Stheraven	 *
262245803Stheraven	 * Note: The specification says that the target of such a reference is
263245803Stheraven	 * a node name, however dtc assumes that it is a label, and so we
264245803Stheraven	 * follow their interpretation for compatibility.
265245803Stheraven	 */
266245803Stheraven	void parse_reference(input_buffer &input);
267245803Stheraven	/**
268254522Stheraven	 * Parse a predefined macro definition for a property.
269254522Stheraven	 */
270254522Stheraven	void parse_define(input_buffer &input, define_map *defines);
271254522Stheraven	/**
272245803Stheraven	 * Constructs a new property from two input buffers, pointing to the
273245803Stheraven	 * struct and strings tables in the device tree blob, respectively.
274245803Stheraven	 * The structs input buffer is assumed to have just consumed the
275245803Stheraven	 * FDT_PROP token.
276245803Stheraven	 */
277245803Stheraven	property(input_buffer &structs, input_buffer &strings);
278245803Stheraven	/**
279245803Stheraven	 * Parses a new property from the input buffer.
280245803Stheraven	 */
281254522Stheraven	property(input_buffer &input,
282254522Stheraven	         string k,
283254522Stheraven	         string l,
284254522Stheraven	         bool terminated,
285254522Stheraven	         define_map *defines);
286245803Stheraven	public:
287245803Stheraven	/**
288245803Stheraven	 * Creates an empty property.
289245803Stheraven	 */
290245803Stheraven	property(string k, string l=string()) : key(k), label(l), valid(true)
291245803Stheraven	{}
292245803Stheraven	/**
293245803Stheraven	 * Copy constructor.
294245803Stheraven	 */
295245803Stheraven	property(property &p) : key(p.key), label(p.label), values(p.values),
296245803Stheraven		valid(p.valid) {}
297245803Stheraven	/**
298245803Stheraven	 * Factory method for constructing a new property.  Attempts to parse a
299245803Stheraven	 * property from the input, and returns it on success.  On any parse
300245803Stheraven	 * error, this will return 0.
301245803Stheraven	 */
302245803Stheraven	static property* parse_dtb(input_buffer &structs,
303245803Stheraven	                           input_buffer &strings);
304245803Stheraven	/**
305245803Stheraven	 * Factory method for constructing a new property.  Attempts to parse a
306245803Stheraven	 * property from the input, and returns it on success.  On any parse
307245803Stheraven	 * error, this will return 0.
308245803Stheraven	 */
309245803Stheraven	static property* parse(input_buffer &input,
310245803Stheraven	                       string key,
311254522Stheraven	                       string label=string(),
312254522Stheraven	                       bool semicolonTerminated=true,
313254522Stheraven	                       define_map *defines=0);
314245803Stheraven	/**
315245803Stheraven	 * Iterator type used for accessing the values of a property.
316245803Stheraven	 */
317245803Stheraven	typedef std::vector<property_value>::iterator value_iterator;
318245803Stheraven	/**
319245803Stheraven	 * Returns an iterator referring to the first value in this property.
320245803Stheraven	 */
321245803Stheraven	inline value_iterator begin()
322245803Stheraven	{
323245803Stheraven		return values.begin();
324245803Stheraven	}
325245803Stheraven	/**
326245803Stheraven	 * Returns an iterator referring to the last value in this property.
327245803Stheraven	 */
328245803Stheraven	inline value_iterator end()
329245803Stheraven	{
330245803Stheraven		return values.end();
331245803Stheraven	}
332245803Stheraven	/**
333245803Stheraven	 * Adds a new value to an existing property.
334245803Stheraven	 */
335245803Stheraven	inline void add_value(property_value v)
336245803Stheraven	{
337245803Stheraven		values.push_back(v);
338245803Stheraven	}
339245803Stheraven	/**
340245803Stheraven	 * Returns the key for this property.
341245803Stheraven	 */
342245803Stheraven	inline string get_key()
343245803Stheraven	{
344245803Stheraven		return key;
345245803Stheraven	}
346245803Stheraven	/**
347245803Stheraven	 * Writes the property to the specified writer.  The property name is a
348245803Stheraven	 * reference into the strings table.
349245803Stheraven	 */
350245803Stheraven	void write(dtb::output_writer &writer, dtb::string_table &strings);
351245803Stheraven	/**
352245803Stheraven	 * Writes in DTS format to the specified file, at the given indent
353245803Stheraven	 * level.  This will begin the line with the number of tabs specified
354245803Stheraven	 * as the indent level and then write the property in the most
355245803Stheraven	 * applicable way that it can determine.
356245803Stheraven	 */
357245803Stheraven	void write_dts(FILE *file, int indent);
358245803Stheraven};
359245803Stheraven
360245803Stheraven/**
361245803Stheraven * Class encapsulating a device tree node.  Nodes may contain properties and
362245803Stheraven * other nodes.
363245803Stheraven */
364245803Stheravenclass node
365245803Stheraven{
366245803Stheraven	public:
367245803Stheraven	/**
368245803Stheraven	 * The label for this node, if any.  Node labels are used as the
369245803Stheraven	 * targets for cross references.
370245803Stheraven	 */
371245803Stheraven	string label;
372245803Stheraven	/**
373245803Stheraven	 * The name of the node.
374245803Stheraven	 */
375245803Stheraven	string name;
376245803Stheraven	/**
377245803Stheraven	 * The unit address of the node, which is optionally written after the
378245803Stheraven	 * name followed by an at symbol.
379245803Stheraven	 */
380245803Stheraven	string unit_address;
381245803Stheraven	private:
382245803Stheraven	/**
383245803Stheraven	 * The properties contained within this node.
384245803Stheraven	 */
385245803Stheraven	std::vector<property*> properties;
386245803Stheraven	/**
387245803Stheraven	 * The children of this node.
388245803Stheraven	 */
389245803Stheraven	std::vector<node*> children;
390245803Stheraven	/**
391245803Stheraven	 * A flag indicating whether this node is valid.  This is set to false
392245803Stheraven	 * if an error occurs during parsing.
393245803Stheraven	 */
394245803Stheraven	bool valid;
395245803Stheraven	/**
396245803Stheraven	 * Parses a name inside a node, writing the string passed as the last
397245803Stheraven	 * argument as an error if it fails.
398245803Stheraven	 */
399245803Stheraven	string parse_name(input_buffer &input,
400245803Stheraven	                  bool &is_property,
401245803Stheraven	                  const char *error);
402245803Stheraven	/**
403245803Stheraven	 * Constructs a new node from two input buffers, pointing to the struct
404245803Stheraven	 * and strings tables in the device tree blob, respectively.
405245803Stheraven	 */
406245803Stheraven	node(input_buffer &structs, input_buffer &strings);
407245803Stheraven	/**
408245803Stheraven	 * Parses a new node from the specified input buffer.  This is called
409245803Stheraven	 * when the input cursor is on the open brace for the start of the
410245803Stheraven	 * node.  The name, and optionally label and unit address, should have
411245803Stheraven	 * already been parsed.
412245803Stheraven	 */
413254522Stheraven	node(input_buffer &input, string n, string l, string a, define_map*);
414245803Stheraven	/**
415245803Stheraven	 * Comparison function for properties, used when sorting the properties
416245803Stheraven	 * vector.  Orders the properties based on their names.
417245803Stheraven	 */
418245803Stheraven	static inline bool cmp_properties(property *p1, property *p2);
419245803Stheraven		/*
420245803Stheraven	{
421245803Stheraven		return p1->get_key() < p2->get_key();
422245803Stheraven	}
423245803Stheraven	*/
424245803Stheraven	/**
425245803Stheraven	 * Comparison function for nodes, used when sorting the children
426245803Stheraven	 * vector.  Orders the nodes based on their names or, if the names are
427245803Stheraven	 * the same, by the unit addresses.
428245803Stheraven	 */
429245803Stheraven	static inline bool cmp_children(node *c1, node *c2);
430245803Stheraven		/*
431245803Stheraven	{
432245803Stheraven		if (c1->name == c2->name)
433245803Stheraven		{
434245803Stheraven			return c1->unit_address < c2->unit_address;
435245803Stheraven		}
436245803Stheraven		return c1->name < c2->name;
437245803Stheraven	}
438245803Stheraven	*/
439245803Stheraven	public:
440245803Stheraven	/**
441245803Stheraven	 * Sorts the node's properties and children into alphabetical order and
442245803Stheraven	 * recursively sorts the children.
443245803Stheraven	 */
444245803Stheraven	void sort();
445245803Stheraven	/**
446245803Stheraven	 * Iterator type for child nodes.
447245803Stheraven	 */
448245803Stheraven	typedef std::vector<node*>::iterator child_iterator;
449245803Stheraven	/**
450245803Stheraven	 * Returns an iterator for the first child of this node.
451245803Stheraven	 */
452245803Stheraven	inline child_iterator child_begin()
453245803Stheraven	{
454245803Stheraven		return children.begin();
455245803Stheraven	}
456245803Stheraven	/**
457245803Stheraven	 * Returns an iterator after the last child of this node.
458245803Stheraven	 */
459245803Stheraven	inline child_iterator child_end()
460245803Stheraven	{
461245803Stheraven		return children.end();
462245803Stheraven	}
463245803Stheraven	/**
464245803Stheraven	 * Iterator type for properties of a node.
465245803Stheraven	 */
466245803Stheraven	typedef std::vector<property*>::iterator property_iterator;
467245803Stheraven	/**
468245803Stheraven	 * Returns an iterator after the last property of this node.
469245803Stheraven	 */
470245803Stheraven	inline property_iterator property_begin()
471245803Stheraven	{
472245803Stheraven		return properties.begin();
473245803Stheraven	}
474245803Stheraven	/**
475245803Stheraven	 * Returns an iterator for the first property of this node.
476245803Stheraven	 */
477245803Stheraven	inline property_iterator property_end()
478245803Stheraven	{
479245803Stheraven		return properties.end();
480245803Stheraven	}
481245803Stheraven	/**
482245803Stheraven	 * Factory method for constructing a new node.  Attempts to parse a
483245803Stheraven	 * node in DTS format from the input, and returns it on success.  On
484245803Stheraven	 * any parse error, this will return 0.  This should be called with the
485245803Stheraven	 * cursor on the open brace of the property, after the name and so on
486245803Stheraven	 * have been parsed.
487245803Stheraven	 */
488245803Stheraven	static node* parse(input_buffer &input,
489245803Stheraven	                   string name,
490245803Stheraven	                   string label=string(),
491254522Stheraven	                   string address=string(),
492254522Stheraven	                   define_map *defines=0);
493245803Stheraven	/**
494245803Stheraven	 * Factory method for constructing a new node.  Attempts to parse a
495245803Stheraven	 * node in DTB format from the input, and returns it on success.  On
496245803Stheraven	 * any parse error, this will return 0.  This should be called with the
497245803Stheraven	 * cursor on the open brace of the property, after the name and so on
498245803Stheraven	 * have been parsed.
499245803Stheraven	 */
500245803Stheraven	static node* parse_dtb(input_buffer &structs, input_buffer &strings);
501245803Stheraven	/**
502245803Stheraven	 * Destroys the node, recursively deleting all of its properties and
503245803Stheraven	 * children.
504245803Stheraven	 */
505245803Stheraven	~node();
506245803Stheraven	/**
507245803Stheraven	 * Returns a property corresponding to the specified key, or 0 if this
508245803Stheraven	 * node does not contain a property of that name.
509245803Stheraven	 */
510245803Stheraven	property *get_property(string key);
511245803Stheraven	/**
512245803Stheraven	 * Adds a new property to this node.
513245803Stheraven	 */
514245803Stheraven	inline void add_property(property *p)
515245803Stheraven	{
516245803Stheraven		properties.push_back(p);
517245803Stheraven	}
518245803Stheraven	/**
519245803Stheraven	 * Merges a node into this one.  Any properties present in both are
520245803Stheraven	 * overridden, any properties present in only one are preserved.
521245803Stheraven	 */
522245803Stheraven	void merge_node(node *other);
523245803Stheraven	/**
524245803Stheraven	 * Write this node to the specified output.  Although nodes do not
525245803Stheraven	 * refer to a string table directly, their properties do.  The string
526245803Stheraven	 * table passed as the second argument is used for the names of
527245803Stheraven	 * properties within this node and its children.
528245803Stheraven	 */
529245803Stheraven	void write(dtb::output_writer &writer, dtb::string_table &strings);
530245803Stheraven	/**
531245803Stheraven	 * Writes the current node as DTS to the specified file.  The second
532245803Stheraven	 * parameter is the indent level.  This function will start every line
533245803Stheraven	 * with this number of tabs.
534245803Stheraven	 */
535245803Stheraven	void write_dts(FILE *file, int indent);
536245803Stheraven};
537245803Stheraven
538245803Stheraven/**
539245803Stheraven * Class encapsulating the entire parsed FDT.  This is the top-level class,
540245803Stheraven * which parses the entire DTS representation and write out the finished
541245803Stheraven * version.
542245803Stheraven */
543245803Stheravenclass device_tree
544245803Stheraven{
545245803Stheraven	public:
546245803Stheraven	/**
547245803Stheraven	 * Type used for node paths.  A node path is sequence of names and unit
548245803Stheraven	 * addresses.
549245803Stheraven	 */
550245803Stheraven	typedef std::vector<std::pair<string,string> > node_path;
551245803Stheraven	/**
552245803Stheraven	 * Name that we should use for phandle nodes.
553245803Stheraven	 */
554245803Stheraven	enum phandle_format
555245803Stheraven	{
556245803Stheraven		/** linux,phandle */
557245803Stheraven		LINUX,
558245803Stheraven		/** phandle */
559245803Stheraven		EPAPR,
560245803Stheraven		/** Create both nodes. */
561245803Stheraven		BOTH
562245803Stheraven	};
563245803Stheraven	private:
564245803Stheraven	/**
565245803Stheraven	 * The format that we should use for writing phandles.
566245803Stheraven	 */
567245803Stheraven	phandle_format phandle_node_name;
568245803Stheraven	/**
569245803Stheraven	 * Flag indicating that this tree is valid.  This will be set to false
570245803Stheraven	 * on parse errors.
571245803Stheraven	 */
572245803Stheraven	bool valid;
573245803Stheraven	/**
574245803Stheraven	 * Type used for memory reservations.  A reservation is two 64-bit
575245803Stheraven	 * values indicating a base address and length in memory that the
576245803Stheraven	 * kernel should not use.  The high 32 bits are ignored on 32-bit
577245803Stheraven	 * platforms.
578245803Stheraven	 */
579245803Stheraven	typedef std::pair<uint64_t, uint64_t> reservation;
580245803Stheraven	/**
581245803Stheraven	 * The memory reserves table.
582245803Stheraven	 */
583245803Stheraven	std::vector<reservation> reservations;
584245803Stheraven	/**
585245803Stheraven	 * Root node.  All other nodes are children of this node.
586245803Stheraven	 */
587245803Stheraven	node *root;
588245803Stheraven	/**
589245803Stheraven	 * Mapping from names to nodes.  Only unambiguous names are recorded,
590245803Stheraven	 * duplicate names are stored as (node*)-1.
591245803Stheraven	 */
592245803Stheraven	std::map<string, node*> node_names;
593245803Stheraven	/**
594245803Stheraven	 * A map from labels to node paths.  When resolving cross references,
595245803Stheraven	 * we look up referenced nodes in this and replace the cross reference
596245803Stheraven	 * with the full path to its target.
597245803Stheraven	 */
598245803Stheraven	std::map<string, node_path> node_paths;
599245803Stheraven	/**
600245803Stheraven	 * A collection of property values that are references to other nodes.
601245803Stheraven	 * These should be expanded to the full path of their targets.
602245803Stheraven	 */
603245803Stheraven	std::vector<property_value*> cross_references;
604245803Stheraven	/**
605245803Stheraven	 * A collection of property values that refer to phandles.  These will
606245803Stheraven	 * be replaced by the value of the phandle property in their
607245803Stheraven	 * destination.
608245803Stheraven	 */
609245803Stheraven	std::vector<property_value*> phandles;
610245803Stheraven	/**
611245803Stheraven	 * A collection of input buffers that we are using.  These input
612245803Stheraven	 * buffers are the ones that own their memory, and so we must preserve
613245803Stheraven	 * them for the lifetime of the device tree.
614245803Stheraven	 */
615245803Stheraven	std::vector<input_buffer*> buffers;
616245803Stheraven	/**
617245803Stheraven	 * A map of used phandle values to nodes.  All phandles must be unique,
618245803Stheraven	 * so we keep a set of ones that the user explicitly provides in the
619245803Stheraven	 * input to ensure that we don't reuse them.
620245803Stheraven	 *
621245803Stheraven	 * This is a map, rather than a set, because we also want to be able to
622245803Stheraven	 * find phandles that were provided by the user explicitly when we are
623245803Stheraven	 * doing checking.
624245803Stheraven	 */
625245803Stheraven	std::map<uint32_t, node*> used_phandles;
626245803Stheraven	/**
627245803Stheraven	 * Paths to search for include files.  This contains a set of
628245803Stheraven	 * nul-terminated strings, which are not owned by this class and so
629245803Stheraven	 * must be freed separately.
630245803Stheraven	 */
631245803Stheraven	std::vector<const char*> include_paths;
632245803Stheraven	/**
633254522Stheraven	 * Dictionary of predefined macros provided on the command line.
634254522Stheraven	 */
635254522Stheraven	define_map               defines;
636254522Stheraven	/**
637245803Stheraven	 * The default boot CPU, specified in the device tree header.
638245803Stheraven	 */
639245803Stheraven	uint32_t boot_cpu;
640245803Stheraven	/**
641245803Stheraven	 * The number of empty reserve map entries to generate in the blob.
642245803Stheraven	 */
643245803Stheraven	uint32_t spare_reserve_map_entries;
644245803Stheraven	/**
645245803Stheraven	 * The minimum size in bytes of the blob.
646245803Stheraven	 */
647245803Stheraven	uint32_t minimum_blob_size;
648245803Stheraven	/**
649245803Stheraven	 * The number of bytes of padding to add to the end of the blob.
650245803Stheraven	 */
651245803Stheraven	uint32_t blob_padding;
652245803Stheraven	/**
653245803Stheraven	 * Visit all of the nodes recursively, and if they have labels then add
654245803Stheraven	 * them to the node_paths and node_names vectors so that they can be
655245803Stheraven	 * used in resolving cross references.  Also collects phandle
656245803Stheraven	 * properties that have been explicitly added.
657245803Stheraven	 */
658245803Stheraven	void collect_names_recursive(node* n, node_path &path);
659245803Stheraven	/**
660245803Stheraven	 * Calls the recursive version of this method on every root node.
661245803Stheraven	 */
662245803Stheraven	void collect_names();
663245803Stheraven	/**
664245803Stheraven	 * Resolves all cross references.  Any properties that refer to another
665245803Stheraven	 * node must have their values replaced by either the node path or
666245803Stheraven	 * phandle value.
667245803Stheraven	 */
668245803Stheraven	void resolve_cross_references();
669245803Stheraven	/**
670245803Stheraven	 * Parses root nodes from the top level of a dts file.
671245803Stheraven	 */
672245803Stheraven	void parse_roots(input_buffer &input, std::vector<node*> &roots);
673245803Stheraven	/**
674245803Stheraven	 * Allocates a new mmap()'d input buffer for use in parsing.  This
675245803Stheraven	 * object then keeps a reference to it, ensuring that it is not
676245803Stheraven	 * deallocated until the device tree is destroyed.
677245803Stheraven	 */
678245803Stheraven	input_buffer *buffer_for_file(const char *path);
679245803Stheraven	/**
680245803Stheraven	 * Template function that writes a dtb blob using the specified writer.
681245803Stheraven	 * The writer defines the output format (assembly, blob).
682245803Stheraven	 */
683245803Stheraven	template<class writer>
684245803Stheraven	void write(int fd);
685245803Stheraven	public:
686245803Stheraven	/**
687245803Stheraven	 * Returns the node referenced by the property.  If this is a tree that
688245803Stheraven	 * is in source form, then we have a string that we can use to index
689245803Stheraven	 * the cross_references array and so we can just look that up.
690245803Stheraven	 */
691245803Stheraven	node *referenced_node(property_value &v);
692245803Stheraven	/**
693245803Stheraven	 * Writes this FDT as a DTB to the specified output.
694245803Stheraven	 */
695245803Stheraven	void write_binary(int fd);
696245803Stheraven	/**
697245803Stheraven	 * Writes this FDT as an assembly representation of the DTB to the
698245803Stheraven	 * specified output.  The result can then be assembled and linked into
699245803Stheraven	 * a program.
700245803Stheraven	 */
701245803Stheraven	void write_asm(int fd);
702245803Stheraven	/**
703245803Stheraven	 * Writes the tree in DTS (source) format.
704245803Stheraven	 */
705245803Stheraven	void write_dts(int fd);
706245803Stheraven	/**
707245803Stheraven	 * Default constructor.  Creates a valid, but empty FDT.
708245803Stheraven	 */
709245803Stheraven	device_tree() : phandle_node_name(EPAPR), valid(true), root(0),
710245803Stheraven		boot_cpu(0), spare_reserve_map_entries(0),
711245803Stheraven		minimum_blob_size(0), blob_padding(0) {}
712245803Stheraven	/**
713245803Stheraven	 * Constructs a device tree from the specified file name, referring to
714245803Stheraven	 * a file that contains a device tree blob.
715245803Stheraven	 */
716245803Stheraven	void parse_dtb(const char *fn, FILE *depfile);
717245803Stheraven	/**
718245803Stheraven	 * Constructs a device tree from the specified file name, referring to
719245803Stheraven	 * a file that contains device tree source.
720245803Stheraven	 */
721245803Stheraven	void parse_dts(const char *fn, FILE *depfile);
722245803Stheraven	/**
723245803Stheraven	 * Destroy the tree and any input buffers that it holds.
724245803Stheraven	 */
725245803Stheraven	~device_tree();
726245803Stheraven	/**
727245803Stheraven	 * Returns whether this tree is valid.
728245803Stheraven	 */
729245803Stheraven	inline bool is_valid()
730245803Stheraven	{
731245803Stheraven		return valid;
732245803Stheraven	}
733245803Stheraven	/**
734245803Stheraven	 * Sets the format for writing phandle properties.
735245803Stheraven	 */
736245803Stheraven	inline void set_phandle_format(phandle_format f)
737245803Stheraven	{
738245803Stheraven		phandle_node_name = f;
739245803Stheraven	}
740245803Stheraven	/**
741245803Stheraven	 * Returns a pointer to the root node of this tree.  No ownership
742245803Stheraven	 * transfer.
743245803Stheraven	 */
744245803Stheraven	inline node *get_root() const
745245803Stheraven	{
746245803Stheraven		return root;
747245803Stheraven	}
748245803Stheraven	/**
749245803Stheraven	 * Sets the physical boot CPU.
750245803Stheraven	 */
751245803Stheraven	void set_boot_cpu(uint32_t cpu)
752245803Stheraven	{
753245803Stheraven		boot_cpu = cpu;
754245803Stheraven	}
755245803Stheraven	/**
756245803Stheraven	 * Sorts the tree.  Useful for debugging device trees.
757245803Stheraven	 */
758245803Stheraven	void sort()
759245803Stheraven	{
760245803Stheraven		root->sort();
761245803Stheraven	}
762245803Stheraven	/**
763245803Stheraven	 * Adds a path to search for include files.  The argument must be a
764245803Stheraven	 * nul-terminated string representing the path.  The device tree keeps
765245803Stheraven	 * a pointer to this string, but does not own it: the caller is
766245803Stheraven	 * responsible for freeing it if required.
767245803Stheraven	 */
768245803Stheraven	void add_include_path(const char *path)
769245803Stheraven	{
770245803Stheraven		include_paths.push_back(path);
771245803Stheraven	}
772245803Stheraven	/**
773245803Stheraven	 * Sets the number of empty reserve map entries to add.
774245803Stheraven	 */
775245803Stheraven	void set_empty_reserve_map_entries(uint32_t e)
776245803Stheraven	{
777245803Stheraven		spare_reserve_map_entries = e;
778245803Stheraven	}
779245803Stheraven	/**
780245803Stheraven	 * Sets the minimum size, in bytes, of the blob.
781245803Stheraven	 */
782245803Stheraven	void set_blob_minimum_size(uint32_t s)
783245803Stheraven	{
784245803Stheraven		minimum_blob_size = s;
785245803Stheraven	}
786245803Stheraven	/**
787245803Stheraven	 * Sets the amount of padding to add to the blob.
788245803Stheraven	 */
789245803Stheraven	void set_blob_padding(uint32_t p)
790245803Stheraven	{
791245803Stheraven		blob_padding = p;
792245803Stheraven	}
793254522Stheraven	/**
794254522Stheraven	 * Parses a predefined macro value.
795254522Stheraven	 */
796254522Stheraven	bool parse_define(const char *def);
797245803Stheraven};
798245803Stheraven
799245803Stheraven} // namespace fdt
800245803Stheraven
801245803Stheraven} // namespace dtc
802245803Stheraven
803245803Stheraven#endif // !_FDT_HH_
804