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