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