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