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