1*4882a593Smuzhiyun #ifndef _DTC_H 2*4882a593Smuzhiyun #define _DTC_H 3*4882a593Smuzhiyun 4*4882a593Smuzhiyun /* 5*4882a593Smuzhiyun * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005. 6*4882a593Smuzhiyun * 7*4882a593Smuzhiyun * 8*4882a593Smuzhiyun * This program is free software; you can redistribute it and/or 9*4882a593Smuzhiyun * modify it under the terms of the GNU General Public License as 10*4882a593Smuzhiyun * published by the Free Software Foundation; either version 2 of the 11*4882a593Smuzhiyun * License, or (at your option) any later version. 12*4882a593Smuzhiyun * 13*4882a593Smuzhiyun * This program is distributed in the hope that it will be useful, 14*4882a593Smuzhiyun * but WITHOUT ANY WARRANTY; without even the implied warranty of 15*4882a593Smuzhiyun * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16*4882a593Smuzhiyun * General Public License for more details. 17*4882a593Smuzhiyun * 18*4882a593Smuzhiyun * You should have received a copy of the GNU General Public License 19*4882a593Smuzhiyun * along with this program; if not, write to the Free Software 20*4882a593Smuzhiyun * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 21*4882a593Smuzhiyun * USA 22*4882a593Smuzhiyun */ 23*4882a593Smuzhiyun 24*4882a593Smuzhiyun #include <stdio.h> 25*4882a593Smuzhiyun #include <string.h> 26*4882a593Smuzhiyun #include <stdlib.h> 27*4882a593Smuzhiyun #include <stdint.h> 28*4882a593Smuzhiyun #include <stdbool.h> 29*4882a593Smuzhiyun #include <stdarg.h> 30*4882a593Smuzhiyun #include <assert.h> 31*4882a593Smuzhiyun #include <ctype.h> 32*4882a593Smuzhiyun #include <errno.h> 33*4882a593Smuzhiyun #include <unistd.h> 34*4882a593Smuzhiyun #include <inttypes.h> 35*4882a593Smuzhiyun 36*4882a593Smuzhiyun #include <libfdt_env.h> 37*4882a593Smuzhiyun #include <fdt.h> 38*4882a593Smuzhiyun 39*4882a593Smuzhiyun #include "util.h" 40*4882a593Smuzhiyun 41*4882a593Smuzhiyun #ifdef DEBUG 42*4882a593Smuzhiyun #define debug(...) printf(__VA_ARGS__) 43*4882a593Smuzhiyun #else 44*4882a593Smuzhiyun #define debug(...) 45*4882a593Smuzhiyun #endif 46*4882a593Smuzhiyun 47*4882a593Smuzhiyun #define DEFAULT_FDT_VERSION 17 48*4882a593Smuzhiyun 49*4882a593Smuzhiyun /* 50*4882a593Smuzhiyun * Command line options 51*4882a593Smuzhiyun */ 52*4882a593Smuzhiyun extern int quiet; /* Level of quietness */ 53*4882a593Smuzhiyun extern int reservenum; /* Number of memory reservation slots */ 54*4882a593Smuzhiyun extern int minsize; /* Minimum blob size */ 55*4882a593Smuzhiyun extern int padsize; /* Additional padding to blob */ 56*4882a593Smuzhiyun extern int alignsize; /* Additional padding to blob accroding to the alignsize */ 57*4882a593Smuzhiyun extern int phandle_format; /* Use linux,phandle or phandle properties */ 58*4882a593Smuzhiyun extern int generate_symbols; /* generate symbols for nodes with labels */ 59*4882a593Smuzhiyun extern int generate_fixups; /* generate fixups */ 60*4882a593Smuzhiyun extern int auto_label_aliases; /* auto generate labels -> aliases */ 61*4882a593Smuzhiyun 62*4882a593Smuzhiyun #define PHANDLE_LEGACY 0x1 63*4882a593Smuzhiyun #define PHANDLE_EPAPR 0x2 64*4882a593Smuzhiyun #define PHANDLE_BOTH 0x3 65*4882a593Smuzhiyun 66*4882a593Smuzhiyun typedef uint32_t cell_t; 67*4882a593Smuzhiyun 68*4882a593Smuzhiyun 69*4882a593Smuzhiyun #define streq(a, b) (strcmp((a), (b)) == 0) 70*4882a593Smuzhiyun #define strneq(a, b, n) (strncmp((a), (b), (n)) == 0) 71*4882a593Smuzhiyun 72*4882a593Smuzhiyun #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) 73*4882a593Smuzhiyun 74*4882a593Smuzhiyun /* Data blobs */ 75*4882a593Smuzhiyun enum markertype { 76*4882a593Smuzhiyun REF_PHANDLE, 77*4882a593Smuzhiyun REF_PATH, 78*4882a593Smuzhiyun LABEL, 79*4882a593Smuzhiyun }; 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun struct marker { 82*4882a593Smuzhiyun enum markertype type; 83*4882a593Smuzhiyun int offset; 84*4882a593Smuzhiyun char *ref; 85*4882a593Smuzhiyun struct marker *next; 86*4882a593Smuzhiyun }; 87*4882a593Smuzhiyun 88*4882a593Smuzhiyun struct data { 89*4882a593Smuzhiyun int len; 90*4882a593Smuzhiyun char *val; 91*4882a593Smuzhiyun struct marker *markers; 92*4882a593Smuzhiyun }; 93*4882a593Smuzhiyun 94*4882a593Smuzhiyun 95*4882a593Smuzhiyun #define empty_data ((struct data){ 0 /* all .members = 0 or NULL */ }) 96*4882a593Smuzhiyun 97*4882a593Smuzhiyun #define for_each_marker(m) \ 98*4882a593Smuzhiyun for (; (m); (m) = (m)->next) 99*4882a593Smuzhiyun #define for_each_marker_of_type(m, t) \ 100*4882a593Smuzhiyun for_each_marker(m) \ 101*4882a593Smuzhiyun if ((m)->type == (t)) 102*4882a593Smuzhiyun 103*4882a593Smuzhiyun void data_free(struct data d); 104*4882a593Smuzhiyun 105*4882a593Smuzhiyun struct data data_grow_for(struct data d, int xlen); 106*4882a593Smuzhiyun 107*4882a593Smuzhiyun struct data data_copy_mem(const char *mem, int len); 108*4882a593Smuzhiyun struct data data_copy_escape_string(const char *s, int len); 109*4882a593Smuzhiyun struct data data_copy_file(FILE *f, size_t len); 110*4882a593Smuzhiyun 111*4882a593Smuzhiyun struct data data_append_data(struct data d, const void *p, int len); 112*4882a593Smuzhiyun struct data data_insert_at_marker(struct data d, struct marker *m, 113*4882a593Smuzhiyun const void *p, int len); 114*4882a593Smuzhiyun struct data data_merge(struct data d1, struct data d2); 115*4882a593Smuzhiyun struct data data_append_cell(struct data d, cell_t word); 116*4882a593Smuzhiyun struct data data_append_integer(struct data d, uint64_t word, int bits); 117*4882a593Smuzhiyun struct data data_append_re(struct data d, uint64_t address, uint64_t size); 118*4882a593Smuzhiyun struct data data_append_addr(struct data d, uint64_t addr); 119*4882a593Smuzhiyun struct data data_append_byte(struct data d, uint8_t byte); 120*4882a593Smuzhiyun struct data data_append_zeroes(struct data d, int len); 121*4882a593Smuzhiyun struct data data_append_align(struct data d, int align); 122*4882a593Smuzhiyun 123*4882a593Smuzhiyun struct data data_add_marker(struct data d, enum markertype type, char *ref); 124*4882a593Smuzhiyun 125*4882a593Smuzhiyun bool data_is_one_string(struct data d); 126*4882a593Smuzhiyun 127*4882a593Smuzhiyun /* DT constraints */ 128*4882a593Smuzhiyun 129*4882a593Smuzhiyun #define MAX_PROPNAME_LEN 31 130*4882a593Smuzhiyun #define MAX_NODENAME_LEN 31 131*4882a593Smuzhiyun 132*4882a593Smuzhiyun /* Live trees */ 133*4882a593Smuzhiyun struct label { 134*4882a593Smuzhiyun bool deleted; 135*4882a593Smuzhiyun char *label; 136*4882a593Smuzhiyun struct label *next; 137*4882a593Smuzhiyun }; 138*4882a593Smuzhiyun 139*4882a593Smuzhiyun struct bus_type { 140*4882a593Smuzhiyun const char *name; 141*4882a593Smuzhiyun }; 142*4882a593Smuzhiyun 143*4882a593Smuzhiyun struct property { 144*4882a593Smuzhiyun bool deleted; 145*4882a593Smuzhiyun char *name; 146*4882a593Smuzhiyun struct data val; 147*4882a593Smuzhiyun 148*4882a593Smuzhiyun struct property *next; 149*4882a593Smuzhiyun 150*4882a593Smuzhiyun struct label *labels; 151*4882a593Smuzhiyun }; 152*4882a593Smuzhiyun 153*4882a593Smuzhiyun struct node { 154*4882a593Smuzhiyun bool deleted; 155*4882a593Smuzhiyun char *name; 156*4882a593Smuzhiyun struct property *proplist; 157*4882a593Smuzhiyun struct node *children; 158*4882a593Smuzhiyun 159*4882a593Smuzhiyun struct node *parent; 160*4882a593Smuzhiyun struct node *next_sibling; 161*4882a593Smuzhiyun 162*4882a593Smuzhiyun char *fullpath; 163*4882a593Smuzhiyun int basenamelen; 164*4882a593Smuzhiyun 165*4882a593Smuzhiyun cell_t phandle; 166*4882a593Smuzhiyun int addr_cells, size_cells; 167*4882a593Smuzhiyun 168*4882a593Smuzhiyun struct label *labels; 169*4882a593Smuzhiyun const struct bus_type *bus; 170*4882a593Smuzhiyun }; 171*4882a593Smuzhiyun 172*4882a593Smuzhiyun #define for_each_label_withdel(l0, l) \ 173*4882a593Smuzhiyun for ((l) = (l0); (l); (l) = (l)->next) 174*4882a593Smuzhiyun 175*4882a593Smuzhiyun #define for_each_label(l0, l) \ 176*4882a593Smuzhiyun for_each_label_withdel(l0, l) \ 177*4882a593Smuzhiyun if (!(l)->deleted) 178*4882a593Smuzhiyun 179*4882a593Smuzhiyun #define for_each_property_withdel(n, p) \ 180*4882a593Smuzhiyun for ((p) = (n)->proplist; (p); (p) = (p)->next) 181*4882a593Smuzhiyun 182*4882a593Smuzhiyun #define for_each_property(n, p) \ 183*4882a593Smuzhiyun for_each_property_withdel(n, p) \ 184*4882a593Smuzhiyun if (!(p)->deleted) 185*4882a593Smuzhiyun 186*4882a593Smuzhiyun #define for_each_child_withdel(n, c) \ 187*4882a593Smuzhiyun for ((c) = (n)->children; (c); (c) = (c)->next_sibling) 188*4882a593Smuzhiyun 189*4882a593Smuzhiyun #define for_each_child(n, c) \ 190*4882a593Smuzhiyun for_each_child_withdel(n, c) \ 191*4882a593Smuzhiyun if (!(c)->deleted) 192*4882a593Smuzhiyun 193*4882a593Smuzhiyun void add_label(struct label **labels, char *label); 194*4882a593Smuzhiyun void delete_labels(struct label **labels); 195*4882a593Smuzhiyun 196*4882a593Smuzhiyun struct property *build_property(char *name, struct data val); 197*4882a593Smuzhiyun struct property *build_property_delete(char *name); 198*4882a593Smuzhiyun struct property *chain_property(struct property *first, struct property *list); 199*4882a593Smuzhiyun struct property *reverse_properties(struct property *first); 200*4882a593Smuzhiyun 201*4882a593Smuzhiyun struct node *build_node(struct property *proplist, struct node *children); 202*4882a593Smuzhiyun struct node *build_node_delete(void); 203*4882a593Smuzhiyun struct node *name_node(struct node *node, char *name); 204*4882a593Smuzhiyun struct node *chain_node(struct node *first, struct node *list); 205*4882a593Smuzhiyun struct node *merge_nodes(struct node *old_node, struct node *new_node); 206*4882a593Smuzhiyun void add_orphan_node(struct node *old_node, struct node *new_node, char *ref); 207*4882a593Smuzhiyun 208*4882a593Smuzhiyun void add_property(struct node *node, struct property *prop); 209*4882a593Smuzhiyun void delete_property_by_name(struct node *node, char *name); 210*4882a593Smuzhiyun void delete_property(struct property *prop); 211*4882a593Smuzhiyun void add_child(struct node *parent, struct node *child); 212*4882a593Smuzhiyun void delete_node_by_name(struct node *parent, char *name); 213*4882a593Smuzhiyun void delete_node(struct node *node); 214*4882a593Smuzhiyun void append_to_property(struct node *node, 215*4882a593Smuzhiyun char *name, const void *data, int len); 216*4882a593Smuzhiyun 217*4882a593Smuzhiyun const char *get_unitname(struct node *node); 218*4882a593Smuzhiyun struct property *get_property(struct node *node, const char *propname); 219*4882a593Smuzhiyun cell_t propval_cell(struct property *prop); 220*4882a593Smuzhiyun cell_t propval_cell_n(struct property *prop, int n); 221*4882a593Smuzhiyun struct property *get_property_by_label(struct node *tree, const char *label, 222*4882a593Smuzhiyun struct node **node); 223*4882a593Smuzhiyun struct marker *get_marker_label(struct node *tree, const char *label, 224*4882a593Smuzhiyun struct node **node, struct property **prop); 225*4882a593Smuzhiyun struct node *get_subnode(struct node *node, const char *nodename); 226*4882a593Smuzhiyun struct node *get_node_by_path(struct node *tree, const char *path); 227*4882a593Smuzhiyun struct node *get_node_by_label(struct node *tree, const char *label); 228*4882a593Smuzhiyun struct node *get_node_by_phandle(struct node *tree, cell_t phandle); 229*4882a593Smuzhiyun struct node *get_node_by_ref(struct node *tree, const char *ref); 230*4882a593Smuzhiyun cell_t get_node_phandle(struct node *root, struct node *node); 231*4882a593Smuzhiyun 232*4882a593Smuzhiyun uint32_t guess_boot_cpuid(struct node *tree); 233*4882a593Smuzhiyun 234*4882a593Smuzhiyun /* Boot info (tree plus memreserve information */ 235*4882a593Smuzhiyun 236*4882a593Smuzhiyun struct reserve_info { 237*4882a593Smuzhiyun uint64_t address, size; 238*4882a593Smuzhiyun 239*4882a593Smuzhiyun struct reserve_info *next; 240*4882a593Smuzhiyun 241*4882a593Smuzhiyun struct label *labels; 242*4882a593Smuzhiyun }; 243*4882a593Smuzhiyun 244*4882a593Smuzhiyun struct reserve_info *build_reserve_entry(uint64_t start, uint64_t len); 245*4882a593Smuzhiyun struct reserve_info *chain_reserve_entry(struct reserve_info *first, 246*4882a593Smuzhiyun struct reserve_info *list); 247*4882a593Smuzhiyun struct reserve_info *add_reserve_entry(struct reserve_info *list, 248*4882a593Smuzhiyun struct reserve_info *new); 249*4882a593Smuzhiyun 250*4882a593Smuzhiyun 251*4882a593Smuzhiyun struct dt_info { 252*4882a593Smuzhiyun unsigned int dtsflags; 253*4882a593Smuzhiyun struct reserve_info *reservelist; 254*4882a593Smuzhiyun uint32_t boot_cpuid_phys; 255*4882a593Smuzhiyun struct node *dt; /* the device tree */ 256*4882a593Smuzhiyun const char *outname; /* filename being written to, "-" for stdout */ 257*4882a593Smuzhiyun }; 258*4882a593Smuzhiyun 259*4882a593Smuzhiyun /* DTS version flags definitions */ 260*4882a593Smuzhiyun #define DTSF_V1 0x0001 /* /dts-v1/ */ 261*4882a593Smuzhiyun #define DTSF_PLUGIN 0x0002 /* /plugin/ */ 262*4882a593Smuzhiyun 263*4882a593Smuzhiyun struct dt_info *build_dt_info(unsigned int dtsflags, 264*4882a593Smuzhiyun struct reserve_info *reservelist, 265*4882a593Smuzhiyun struct node *tree, uint32_t boot_cpuid_phys); 266*4882a593Smuzhiyun void sort_tree(struct dt_info *dti); 267*4882a593Smuzhiyun void generate_label_tree(struct dt_info *dti, char *name, bool allocph); 268*4882a593Smuzhiyun void generate_fixups_tree(struct dt_info *dti, char *name); 269*4882a593Smuzhiyun void generate_local_fixups_tree(struct dt_info *dti, char *name); 270*4882a593Smuzhiyun 271*4882a593Smuzhiyun /* Checks */ 272*4882a593Smuzhiyun 273*4882a593Smuzhiyun void parse_checks_option(bool warn, bool error, const char *arg); 274*4882a593Smuzhiyun void process_checks(bool force, struct dt_info *dti); 275*4882a593Smuzhiyun 276*4882a593Smuzhiyun /* Flattened trees */ 277*4882a593Smuzhiyun 278*4882a593Smuzhiyun void dt_to_blob(FILE *f, struct dt_info *dti, int version); 279*4882a593Smuzhiyun void dt_to_asm(FILE *f, struct dt_info *dti, int version); 280*4882a593Smuzhiyun 281*4882a593Smuzhiyun struct dt_info *dt_from_blob(const char *fname); 282*4882a593Smuzhiyun 283*4882a593Smuzhiyun /* Tree source */ 284*4882a593Smuzhiyun 285*4882a593Smuzhiyun void dt_to_source(FILE *f, struct dt_info *dti); 286*4882a593Smuzhiyun struct dt_info *dt_from_source(const char *f); 287*4882a593Smuzhiyun 288*4882a593Smuzhiyun /* FS trees */ 289*4882a593Smuzhiyun 290*4882a593Smuzhiyun struct dt_info *dt_from_fs(const char *dirname); 291*4882a593Smuzhiyun 292*4882a593Smuzhiyun #endif /* _DTC_H */ 293