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> 34d18719a4STom Rini 35d18719a4STom Rini #include <libfdt_env.h> 36d18719a4STom Rini #include <fdt.h> 37d18719a4STom Rini 38d18719a4STom Rini #include "util.h" 39d18719a4STom Rini 40d18719a4STom Rini #ifdef DEBUG 41d18719a4STom Rini #define debug(...) printf(__VA_ARGS__) 42d18719a4STom Rini #else 43d18719a4STom Rini #define debug(...) 44d18719a4STom Rini #endif 45d18719a4STom Rini 46d18719a4STom Rini #define DEFAULT_FDT_VERSION 17 47d18719a4STom Rini 48d18719a4STom Rini /* 49d18719a4STom Rini * Command line options 50d18719a4STom Rini */ 51d18719a4STom Rini extern int quiet; /* Level of quietness */ 52d18719a4STom Rini extern int reservenum; /* Number of memory reservation slots */ 53d18719a4STom Rini extern int minsize; /* Minimum blob size */ 54d18719a4STom Rini extern int padsize; /* Additional padding to blob */ 55d18719a4STom Rini extern int alignsize; /* Additional padding to blob accroding to the alignsize */ 56d18719a4STom Rini extern int phandle_format; /* Use linux,phandle or phandle properties */ 57d18719a4STom Rini extern int generate_symbols; /* generate symbols for nodes with labels */ 58d18719a4STom Rini extern int generate_fixups; /* generate fixups */ 59d18719a4STom Rini extern int auto_label_aliases; /* auto generate labels -> aliases */ 60d18719a4STom Rini 61d18719a4STom Rini #define PHANDLE_LEGACY 0x1 62d18719a4STom Rini #define PHANDLE_EPAPR 0x2 63d18719a4STom Rini #define PHANDLE_BOTH 0x3 64d18719a4STom Rini 65d18719a4STom Rini typedef uint32_t cell_t; 66d18719a4STom Rini 67d18719a4STom Rini 68d18719a4STom Rini #define streq(a, b) (strcmp((a), (b)) == 0) 69d18719a4STom Rini #define strneq(a, b, n) (strncmp((a), (b), (n)) == 0) 70d18719a4STom Rini 71d18719a4STom Rini #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) 72d18719a4STom Rini 73d18719a4STom Rini /* Data blobs */ 74d18719a4STom Rini enum markertype { 75d18719a4STom Rini REF_PHANDLE, 76d18719a4STom Rini REF_PATH, 77d18719a4STom Rini LABEL, 78d18719a4STom Rini }; 79d18719a4STom Rini 80d18719a4STom Rini struct marker { 81d18719a4STom Rini enum markertype type; 82d18719a4STom Rini int offset; 83d18719a4STom Rini char *ref; 84d18719a4STom Rini struct marker *next; 85d18719a4STom Rini }; 86d18719a4STom Rini 87d18719a4STom Rini struct data { 88d18719a4STom Rini int len; 89d18719a4STom Rini char *val; 90d18719a4STom Rini struct marker *markers; 91d18719a4STom Rini }; 92d18719a4STom Rini 93d18719a4STom Rini 94d18719a4STom Rini #define empty_data ((struct data){ 0 /* all .members = 0 or NULL */ }) 95d18719a4STom Rini 96d18719a4STom Rini #define for_each_marker(m) \ 97d18719a4STom Rini for (; (m); (m) = (m)->next) 98d18719a4STom Rini #define for_each_marker_of_type(m, t) \ 99d18719a4STom Rini for_each_marker(m) \ 100d18719a4STom Rini if ((m)->type == (t)) 101d18719a4STom Rini 102d18719a4STom Rini void data_free(struct data d); 103d18719a4STom Rini 104d18719a4STom Rini struct data data_grow_for(struct data d, int xlen); 105d18719a4STom Rini 106d18719a4STom Rini struct data data_copy_mem(const char *mem, int len); 107d18719a4STom Rini struct data data_copy_escape_string(const char *s, int len); 108d18719a4STom Rini struct data data_copy_file(FILE *f, size_t len); 109d18719a4STom Rini 110d18719a4STom Rini struct data data_append_data(struct data d, const void *p, int len); 111d18719a4STom Rini struct data data_insert_at_marker(struct data d, struct marker *m, 112d18719a4STom Rini const void *p, int len); 113d18719a4STom Rini struct data data_merge(struct data d1, struct data d2); 114d18719a4STom Rini struct data data_append_cell(struct data d, cell_t word); 115d18719a4STom Rini struct data data_append_integer(struct data d, uint64_t word, int bits); 116*e23ffda2STom Rini struct data data_append_re(struct data d, uint64_t address, uint64_t size); 117d18719a4STom Rini struct data data_append_addr(struct data d, uint64_t addr); 118d18719a4STom Rini struct data data_append_byte(struct data d, uint8_t byte); 119d18719a4STom Rini struct data data_append_zeroes(struct data d, int len); 120d18719a4STom Rini struct data data_append_align(struct data d, int align); 121d18719a4STom Rini 122d18719a4STom Rini struct data data_add_marker(struct data d, enum markertype type, char *ref); 123d18719a4STom Rini 124d18719a4STom Rini bool data_is_one_string(struct data d); 125d18719a4STom Rini 126d18719a4STom Rini /* DT constraints */ 127d18719a4STom Rini 128d18719a4STom Rini #define MAX_PROPNAME_LEN 31 129d18719a4STom Rini #define MAX_NODENAME_LEN 31 130d18719a4STom Rini 131d18719a4STom Rini /* Live trees */ 132d18719a4STom Rini struct label { 133d18719a4STom Rini bool deleted; 134d18719a4STom Rini char *label; 135d18719a4STom Rini struct label *next; 136d18719a4STom Rini }; 137d18719a4STom Rini 138d18719a4STom Rini struct property { 139d18719a4STom Rini bool deleted; 140d18719a4STom Rini char *name; 141d18719a4STom Rini struct data val; 142d18719a4STom Rini 143d18719a4STom Rini struct property *next; 144d18719a4STom Rini 145d18719a4STom Rini struct label *labels; 146d18719a4STom Rini }; 147d18719a4STom Rini 148d18719a4STom Rini struct node { 149d18719a4STom Rini bool deleted; 150d18719a4STom Rini char *name; 151d18719a4STom Rini struct property *proplist; 152d18719a4STom Rini struct node *children; 153d18719a4STom Rini 154d18719a4STom Rini struct node *parent; 155d18719a4STom Rini struct node *next_sibling; 156d18719a4STom Rini 157d18719a4STom Rini char *fullpath; 158d18719a4STom Rini int basenamelen; 159d18719a4STom Rini 160d18719a4STom Rini cell_t phandle; 161d18719a4STom Rini int addr_cells, size_cells; 162d18719a4STom Rini 163d18719a4STom Rini struct label *labels; 164d18719a4STom Rini }; 165d18719a4STom Rini 166d18719a4STom Rini #define for_each_label_withdel(l0, l) \ 167d18719a4STom Rini for ((l) = (l0); (l); (l) = (l)->next) 168d18719a4STom Rini 169d18719a4STom Rini #define for_each_label(l0, l) \ 170d18719a4STom Rini for_each_label_withdel(l0, l) \ 171d18719a4STom Rini if (!(l)->deleted) 172d18719a4STom Rini 173d18719a4STom Rini #define for_each_property_withdel(n, p) \ 174d18719a4STom Rini for ((p) = (n)->proplist; (p); (p) = (p)->next) 175d18719a4STom Rini 176d18719a4STom Rini #define for_each_property(n, p) \ 177d18719a4STom Rini for_each_property_withdel(n, p) \ 178d18719a4STom Rini if (!(p)->deleted) 179d18719a4STom Rini 180d18719a4STom Rini #define for_each_child_withdel(n, c) \ 181d18719a4STom Rini for ((c) = (n)->children; (c); (c) = (c)->next_sibling) 182d18719a4STom Rini 183d18719a4STom Rini #define for_each_child(n, c) \ 184d18719a4STom Rini for_each_child_withdel(n, c) \ 185d18719a4STom Rini if (!(c)->deleted) 186d18719a4STom Rini 187d18719a4STom Rini void add_label(struct label **labels, char *label); 188d18719a4STom Rini void delete_labels(struct label **labels); 189d18719a4STom Rini 190d18719a4STom Rini struct property *build_property(char *name, struct data val); 191d18719a4STom Rini struct property *build_property_delete(char *name); 192d18719a4STom Rini struct property *chain_property(struct property *first, struct property *list); 193d18719a4STom Rini struct property *reverse_properties(struct property *first); 194d18719a4STom Rini 195d18719a4STom Rini struct node *build_node(struct property *proplist, struct node *children); 196d18719a4STom Rini struct node *build_node_delete(void); 197d18719a4STom Rini struct node *name_node(struct node *node, char *name); 198d18719a4STom Rini struct node *chain_node(struct node *first, struct node *list); 199d18719a4STom Rini struct node *merge_nodes(struct node *old_node, struct node *new_node); 200d18719a4STom Rini 201d18719a4STom Rini void add_property(struct node *node, struct property *prop); 202d18719a4STom Rini void delete_property_by_name(struct node *node, char *name); 203d18719a4STom Rini void delete_property(struct property *prop); 204d18719a4STom Rini void add_child(struct node *parent, struct node *child); 205d18719a4STom Rini void delete_node_by_name(struct node *parent, char *name); 206d18719a4STom Rini void delete_node(struct node *node); 207d18719a4STom Rini void append_to_property(struct node *node, 208d18719a4STom Rini char *name, const void *data, int len); 209d18719a4STom Rini 210d18719a4STom Rini const char *get_unitname(struct node *node); 211d18719a4STom Rini struct property *get_property(struct node *node, const char *propname); 212d18719a4STom Rini cell_t propval_cell(struct property *prop); 213d18719a4STom Rini struct property *get_property_by_label(struct node *tree, const char *label, 214d18719a4STom Rini struct node **node); 215d18719a4STom Rini struct marker *get_marker_label(struct node *tree, const char *label, 216d18719a4STom Rini struct node **node, struct property **prop); 217d18719a4STom Rini struct node *get_subnode(struct node *node, const char *nodename); 218d18719a4STom Rini struct node *get_node_by_path(struct node *tree, const char *path); 219d18719a4STom Rini struct node *get_node_by_label(struct node *tree, const char *label); 220d18719a4STom Rini struct node *get_node_by_phandle(struct node *tree, cell_t phandle); 221d18719a4STom Rini struct node *get_node_by_ref(struct node *tree, const char *ref); 222d18719a4STom Rini cell_t get_node_phandle(struct node *root, struct node *node); 223d18719a4STom Rini 224d18719a4STom Rini uint32_t guess_boot_cpuid(struct node *tree); 225d18719a4STom Rini 226d18719a4STom Rini /* Boot info (tree plus memreserve information */ 227d18719a4STom Rini 228d18719a4STom Rini struct reserve_info { 229*e23ffda2STom Rini uint64_t address, size; 230d18719a4STom Rini 231d18719a4STom Rini struct reserve_info *next; 232d18719a4STom Rini 233d18719a4STom Rini struct label *labels; 234d18719a4STom Rini }; 235d18719a4STom Rini 236d18719a4STom Rini struct reserve_info *build_reserve_entry(uint64_t start, uint64_t len); 237d18719a4STom Rini struct reserve_info *chain_reserve_entry(struct reserve_info *first, 238d18719a4STom Rini struct reserve_info *list); 239d18719a4STom Rini struct reserve_info *add_reserve_entry(struct reserve_info *list, 240d18719a4STom Rini struct reserve_info *new); 241d18719a4STom Rini 242d18719a4STom Rini 243d18719a4STom Rini struct dt_info { 244d18719a4STom Rini unsigned int dtsflags; 245d18719a4STom Rini struct reserve_info *reservelist; 246d18719a4STom Rini uint32_t boot_cpuid_phys; 247d18719a4STom Rini struct node *dt; /* the device tree */ 248d18719a4STom Rini const char *outname; /* filename being written to, "-" for stdout */ 249d18719a4STom Rini }; 250d18719a4STom Rini 251d18719a4STom Rini /* DTS version flags definitions */ 252d18719a4STom Rini #define DTSF_V1 0x0001 /* /dts-v1/ */ 253d18719a4STom Rini #define DTSF_PLUGIN 0x0002 /* /plugin/ */ 254d18719a4STom Rini 255d18719a4STom Rini struct dt_info *build_dt_info(unsigned int dtsflags, 256d18719a4STom Rini struct reserve_info *reservelist, 257d18719a4STom Rini struct node *tree, uint32_t boot_cpuid_phys); 258d18719a4STom Rini void sort_tree(struct dt_info *dti); 259d18719a4STom Rini void generate_label_tree(struct dt_info *dti, char *name, bool allocph); 260d18719a4STom Rini void generate_fixups_tree(struct dt_info *dti, char *name); 261d18719a4STom Rini void generate_local_fixups_tree(struct dt_info *dti, char *name); 262d18719a4STom Rini 263d18719a4STom Rini /* Checks */ 264d18719a4STom Rini 265d18719a4STom Rini void parse_checks_option(bool warn, bool error, const char *arg); 266d18719a4STom Rini void process_checks(bool force, struct dt_info *dti); 267d18719a4STom Rini 268d18719a4STom Rini /* Flattened trees */ 269d18719a4STom Rini 270d18719a4STom Rini void dt_to_blob(FILE *f, struct dt_info *dti, int version); 271d18719a4STom Rini void dt_to_asm(FILE *f, struct dt_info *dti, int version); 272d18719a4STom Rini 273d18719a4STom Rini struct dt_info *dt_from_blob(const char *fname); 274d18719a4STom Rini 275d18719a4STom Rini /* Tree source */ 276d18719a4STom Rini 277d18719a4STom Rini void dt_to_source(FILE *f, struct dt_info *dti); 278d18719a4STom Rini struct dt_info *dt_from_source(const char *f); 279d18719a4STom Rini 280d18719a4STom Rini /* FS trees */ 281d18719a4STom Rini 282d18719a4STom Rini struct dt_info *dt_from_fs(const char *dirname); 283d18719a4STom Rini 284d18719a4STom Rini #endif /* _DTC_H */ 285