2007-12-18 07:06:42 +03:00
# ifndef _DTC_H
# define _DTC_H
/*
* ( C ) Copyright David Gibson < dwg @ au1 . ibm . com > , IBM Corporation . 2005.
*
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation ; either version 2 of the
* License , or ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307
* USA
*/
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# include <stdint.h>
2012-09-29 01:25:59 +04:00
# include <stdbool.h>
2007-12-18 07:06:42 +03:00
# include <stdarg.h>
# include <assert.h>
# include <ctype.h>
# include <errno.h>
# include <unistd.h>
2008-08-07 06:24:17 +04:00
# include <libfdt_env.h>
2007-12-18 07:06:42 +03:00
# include <fdt.h>
2010-11-18 02:28:20 +03:00
# include "util.h"
# ifdef DEBUG
2015-04-30 00:00:05 +03:00
# define debug(...) printf(__VA_ARGS__)
2010-11-18 02:28:20 +03:00
# else
2015-04-30 00:00:05 +03:00
# define debug(...)
2010-11-18 02:28:20 +03:00
# endif
2007-12-18 07:06:42 +03:00
# define DEFAULT_FDT_VERSION 17
2010-11-18 02:28:20 +03:00
2007-12-18 07:06:42 +03:00
/*
* Command line options
*/
extern int quiet ; /* Level of quietness */
extern int reservenum ; /* Number of memory reservation slots */
extern int minsize ; /* Minimum blob size */
extern int padsize ; /* Additional padding to blob */
2010-11-18 02:28:20 +03:00
extern int phandle_format ; /* Use linux,phandle or phandle properties */
2007-12-18 07:06:42 +03:00
2010-11-18 02:28:20 +03:00
# define PHANDLE_LEGACY 0x1
# define PHANDLE_EPAPR 0x2
# define PHANDLE_BOTH 0x3
2007-12-18 07:06:42 +03:00
2008-08-07 06:24:17 +04:00
typedef uint32_t cell_t ;
2007-12-18 07:06:42 +03:00
# define streq(a, b) (strcmp((a), (b)) == 0)
# define strneq(a, b, n) (strncmp((a), (b), (n)) == 0)
# define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
/* Data blobs */
enum markertype {
REF_PHANDLE ,
REF_PATH ,
LABEL ,
} ;
struct marker {
enum markertype type ;
int offset ;
char * ref ;
struct marker * next ;
} ;
struct data {
int len ;
char * val ;
struct marker * markers ;
} ;
2015-04-30 00:00:05 +03:00
# define empty_data ((struct data){ 0 /* all .members = 0 or NULL */ })
2007-12-18 07:06:42 +03:00
# define for_each_marker(m) \
for ( ; ( m ) ; ( m ) = ( m ) - > next )
# define for_each_marker_of_type(m, t) \
for_each_marker ( m ) \
if ( ( m ) - > type = = ( t ) )
void data_free ( struct data d ) ;
struct data data_grow_for ( struct data d , int xlen ) ;
struct data data_copy_mem ( const char * mem , int len ) ;
struct data data_copy_escape_string ( const char * s , int len ) ;
struct data data_copy_file ( FILE * f , size_t len ) ;
struct data data_append_data ( struct data d , const void * p , int len ) ;
struct data data_insert_at_marker ( struct data d , struct marker * m ,
const void * p , int len ) ;
struct data data_merge ( struct data d1 , struct data d2 ) ;
struct data data_append_cell ( struct data d , cell_t word ) ;
2012-09-29 01:25:59 +04:00
struct data data_append_integer ( struct data d , uint64_t word , int bits ) ;
2007-12-18 07:06:42 +03:00
struct data data_append_re ( struct data d , const struct fdt_reserve_entry * re ) ;
2008-08-07 06:24:17 +04:00
struct data data_append_addr ( struct data d , uint64_t addr ) ;
2007-12-18 07:06:42 +03:00
struct data data_append_byte ( struct data d , uint8_t byte ) ;
struct data data_append_zeroes ( struct data d , int len ) ;
struct data data_append_align ( struct data d , int align ) ;
struct data data_add_marker ( struct data d , enum markertype type , char * ref ) ;
2015-04-30 00:00:05 +03:00
bool data_is_one_string ( struct data d ) ;
2007-12-18 07:06:42 +03:00
/* DT constraints */
# define MAX_PROPNAME_LEN 31
# define MAX_NODENAME_LEN 31
/* Live trees */
2010-11-18 02:28:20 +03:00
struct label {
2015-04-30 00:00:05 +03:00
bool deleted ;
2010-11-18 02:28:20 +03:00
char * label ;
struct label * next ;
} ;
2007-12-18 07:06:42 +03:00
struct property {
2015-04-30 00:00:05 +03:00
bool deleted ;
2007-12-18 07:06:42 +03:00
char * name ;
struct data val ;
struct property * next ;
2010-11-18 02:28:20 +03:00
struct label * labels ;
2007-12-18 07:06:42 +03:00
} ;
struct node {
2015-04-30 00:00:05 +03:00
bool deleted ;
2007-12-18 07:06:42 +03:00
char * name ;
struct property * proplist ;
struct node * children ;
struct node * parent ;
struct node * next_sibling ;
char * fullpath ;
int basenamelen ;
cell_t phandle ;
int addr_cells , size_cells ;
2010-11-18 02:28:20 +03:00
struct label * labels ;
2007-12-18 07:06:42 +03:00
} ;
2012-09-29 01:25:59 +04:00
# define for_each_label_withdel(l0, l) \
2010-11-18 02:28:20 +03:00
for ( ( l ) = ( l0 ) ; ( l ) ; ( l ) = ( l ) - > next )
2012-10-09 02:15:26 +04:00
# define for_each_label(l0, l) \
for_each_label_withdel ( l0 , l ) \
if ( ! ( l ) - > deleted )
2012-09-29 01:25:59 +04:00
# define for_each_property_withdel(n, p) \
2007-12-18 07:06:42 +03:00
for ( ( p ) = ( n ) - > proplist ; ( p ) ; ( p ) = ( p ) - > next )
2012-10-09 02:15:26 +04:00
# define for_each_property(n, p) \
for_each_property_withdel ( n , p ) \
if ( ! ( p ) - > deleted )
2012-09-29 01:25:59 +04:00
# define for_each_child_withdel(n, c) \
2007-12-18 07:06:42 +03:00
for ( ( c ) = ( n ) - > children ; ( c ) ; ( c ) = ( c ) - > next_sibling )
2012-10-09 02:15:26 +04:00
# define for_each_child(n, c) \
for_each_child_withdel ( n , c ) \
if ( ! ( c ) - > deleted )
2010-11-18 02:28:20 +03:00
void add_label ( struct label * * labels , char * label ) ;
2012-09-29 01:25:59 +04:00
void delete_labels ( struct label * * labels ) ;
2010-11-18 02:28:20 +03:00
struct property * build_property ( char * name , struct data val ) ;
2012-09-29 01:25:59 +04:00
struct property * build_property_delete ( char * name ) ;
2007-12-18 07:06:42 +03:00
struct property * chain_property ( struct property * first , struct property * list ) ;
struct property * reverse_properties ( struct property * first ) ;
struct node * build_node ( struct property * proplist , struct node * children ) ;
2012-09-29 01:25:59 +04:00
struct node * build_node_delete ( void ) ;
2010-11-18 02:28:20 +03:00
struct node * name_node ( struct node * node , char * name ) ;
2007-12-18 07:06:42 +03:00
struct node * chain_node ( struct node * first , struct node * list ) ;
2010-11-18 02:28:20 +03:00
struct node * merge_nodes ( struct node * old_node , struct node * new_node ) ;
2007-12-18 07:06:42 +03:00
void add_property ( struct node * node , struct property * prop ) ;
2012-09-29 01:25:59 +04:00
void delete_property_by_name ( struct node * node , char * name ) ;
void delete_property ( struct property * prop ) ;
2007-12-18 07:06:42 +03:00
void add_child ( struct node * parent , struct node * child ) ;
2012-09-29 01:25:59 +04:00
void delete_node_by_name ( struct node * parent , char * name ) ;
void delete_node ( struct node * node ) ;
2007-12-18 07:06:42 +03:00
const char * get_unitname ( struct node * node ) ;
struct property * get_property ( struct node * node , const char * propname ) ;
cell_t propval_cell ( struct property * prop ) ;
2010-11-18 02:28:20 +03:00
struct property * get_property_by_label ( struct node * tree , const char * label ,
struct node * * node ) ;
struct marker * get_marker_label ( struct node * tree , const char * label ,
struct node * * node , struct property * * prop ) ;
2007-12-18 07:06:42 +03:00
struct node * get_subnode ( struct node * node , const char * nodename ) ;
struct node * get_node_by_path ( struct node * tree , const char * path ) ;
struct node * get_node_by_label ( struct node * tree , const char * label ) ;
struct node * get_node_by_phandle ( struct node * tree , cell_t phandle ) ;
struct node * get_node_by_ref ( struct node * tree , const char * ref ) ;
cell_t get_node_phandle ( struct node * root , struct node * node ) ;
2010-11-18 02:28:20 +03:00
uint32_t guess_boot_cpuid ( struct node * tree ) ;
2007-12-18 07:06:42 +03:00
/* Boot info (tree plus memreserve information */
struct reserve_info {
struct fdt_reserve_entry re ;
struct reserve_info * next ;
2010-11-18 02:28:20 +03:00
struct label * labels ;
2007-12-18 07:06:42 +03:00
} ;
2010-11-18 02:28:20 +03:00
struct reserve_info * build_reserve_entry ( uint64_t start , uint64_t len ) ;
2007-12-18 07:06:42 +03:00
struct reserve_info * chain_reserve_entry ( struct reserve_info * first ,
struct reserve_info * list ) ;
struct reserve_info * add_reserve_entry ( struct reserve_info * list ,
struct reserve_info * new ) ;
struct boot_info {
struct reserve_info * reservelist ;
struct node * dt ; /* the device tree */
2008-08-07 06:24:17 +04:00
uint32_t boot_cpuid_phys ;
2007-12-18 07:06:42 +03:00
} ;
struct boot_info * build_boot_info ( struct reserve_info * reservelist ,
2008-08-07 06:24:17 +04:00
struct node * tree , uint32_t boot_cpuid_phys ) ;
2010-11-18 02:28:20 +03:00
void sort_tree ( struct boot_info * bi ) ;
2007-12-18 07:06:42 +03:00
/* Checks */
2015-04-30 00:00:05 +03:00
void parse_checks_option ( bool warn , bool error , const char * arg ) ;
void process_checks ( bool force , struct boot_info * bi ) ;
2007-12-18 07:06:42 +03:00
/* Flattened trees */
2008-08-07 06:24:17 +04:00
void dt_to_blob ( FILE * f , struct boot_info * bi , int version ) ;
void dt_to_asm ( FILE * f , struct boot_info * bi , int version ) ;
2007-12-18 07:06:42 +03:00
2008-08-07 06:24:17 +04:00
struct boot_info * dt_from_blob ( const char * fname ) ;
2007-12-18 07:06:42 +03:00
/* Tree source */
void dt_to_source ( FILE * f , struct boot_info * bi ) ;
struct boot_info * dt_from_source ( const char * f ) ;
/* FS trees */
struct boot_info * dt_from_fs ( const char * dirname ) ;
# endif /* _DTC_H */