2018-02-28 02:40:38 +03:00
# ifndef DTC_H
# define DTC_H
2007-12-18 07:06:42 +03:00
/*
* ( 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>
2017-10-03 19:37:04 +03:00
# include <inttypes.h>
2007-12-18 07:06:42 +03:00
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 */
2017-01-04 19:45:20 +03:00
extern int alignsize ; /* Additional padding to blob accroding to the alignsize */
2010-11-18 02:28:20 +03:00
extern int phandle_format ; /* Use linux,phandle or phandle properties */
2017-01-04 19:45:20 +03:00
extern int generate_symbols ; /* generate symbols for nodes with labels */
extern int generate_fixups ; /* generate fixups */
extern int auto_label_aliases ; /* auto generate labels -> aliases */
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)
2018-02-28 02:40:38 +03:00
# define strstarts(s, prefix) (strncmp((s), (prefix), strlen(prefix)) == 0)
# define strprefixeq(a, n, b) (strlen(b) == (n) && (memcmp(a, b, n) == 0))
2007-12-18 07:06:42 +03:00
# 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 ) ;
2017-03-21 17:01:08 +03:00
struct data data_append_re ( struct data d , uint64_t address , uint64_t size ) ;
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 ;
} ;
2017-03-21 17:01:08 +03:00
struct bus_type {
const char * name ;
} ;
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 ;
2017-03-21 17:01:08 +03:00
const struct bus_type * bus ;
2018-05-08 21:07:49 +03:00
bool omit_if_unused , is_referenced ;
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 ) ;
2018-05-08 21:07:49 +03:00
struct node * omit_node_if_unused ( struct node * node ) ;
struct node * reference_node ( struct node * node ) ;
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 ) ;
2018-02-28 02:40:38 +03:00
struct node * add_orphan_node ( struct node * old_node , struct node * new_node , char * ref ) ;
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 ) ;
2017-01-04 19:45:20 +03:00
void append_to_property ( struct node * node ,
char * name , const void * data , int len ) ;
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 ) ;
2017-10-03 19:37:04 +03:00
cell_t propval_cell_n ( struct property * prop , int n ) ;
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 {
2017-03-21 17:01:08 +03:00
uint64_t address , size ;
2007-12-18 07:06:42 +03:00
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 ) ;
2017-01-04 19:45:20 +03:00
struct dt_info {
unsigned int dtsflags ;
2007-12-18 07:06:42 +03:00
struct reserve_info * reservelist ;
2008-08-07 06:24:17 +04:00
uint32_t boot_cpuid_phys ;
2017-01-04 19:45:20 +03:00
struct node * dt ; /* the device tree */
2017-03-21 17:01:08 +03:00
const char * outname ; /* filename being written to, "-" for stdout */
2007-12-18 07:06:42 +03:00
} ;
2017-01-04 19:45:20 +03:00
/* DTS version flags definitions */
# define DTSF_V1 0x0001 /* /dts-v1/ */
# define DTSF_PLUGIN 0x0002 /* /plugin/ */
struct dt_info * build_dt_info ( unsigned int dtsflags ,
struct reserve_info * reservelist ,
struct node * tree , uint32_t boot_cpuid_phys ) ;
void sort_tree ( struct dt_info * dti ) ;
void generate_label_tree ( struct dt_info * dti , char * name , bool allocph ) ;
void generate_fixups_tree ( struct dt_info * dti , char * name ) ;
void generate_local_fixups_tree ( struct dt_info * dti , char * name ) ;
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 ) ;
2017-01-04 19:45:20 +03:00
void process_checks ( bool force , struct dt_info * dti ) ;
2007-12-18 07:06:42 +03:00
/* Flattened trees */
2017-01-04 19:45:20 +03:00
void dt_to_blob ( FILE * f , struct dt_info * dti , int version ) ;
void dt_to_asm ( FILE * f , struct dt_info * dti , int version ) ;
2007-12-18 07:06:42 +03:00
2017-01-04 19:45:20 +03:00
struct dt_info * dt_from_blob ( const char * fname ) ;
2007-12-18 07:06:42 +03:00
/* Tree source */
2017-01-04 19:45:20 +03:00
void dt_to_source ( FILE * f , struct dt_info * dti ) ;
struct dt_info * dt_from_source ( const char * f ) ;
2007-12-18 07:06:42 +03:00
/* FS trees */
2017-01-04 19:45:20 +03:00
struct dt_info * dt_from_fs ( const char * dirname ) ;
2007-12-18 07:06:42 +03:00
2018-02-28 02:40:38 +03:00
# endif /* DTC_H */