xref: /openbmc/linux/scripts/dtc/dtc.h (revision 03ab8e6297acd1bc0eedaa050e2a1635c576fd11)
112869ecdSRob Herring /* SPDX-License-Identifier: GPL-2.0-or-later */
29130ba88SRob Herring #ifndef DTC_H
39130ba88SRob Herring #define DTC_H
49fffb55fSDavid Gibson 
59fffb55fSDavid Gibson /*
69fffb55fSDavid Gibson  * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
79fffb55fSDavid Gibson  */
89fffb55fSDavid Gibson 
99fffb55fSDavid Gibson #include <stdio.h>
109fffb55fSDavid Gibson #include <string.h>
119fffb55fSDavid Gibson #include <stdlib.h>
129fffb55fSDavid Gibson #include <stdint.h>
13cd296721SStephen Warren #include <stdbool.h>
149fffb55fSDavid Gibson #include <stdarg.h>
159fffb55fSDavid Gibson #include <assert.h>
169fffb55fSDavid Gibson #include <ctype.h>
179fffb55fSDavid Gibson #include <errno.h>
189fffb55fSDavid Gibson #include <unistd.h>
194201d057SRob Herring #include <inttypes.h>
209fffb55fSDavid Gibson 
219fffb55fSDavid Gibson #include <libfdt_env.h>
229fffb55fSDavid Gibson #include <fdt.h>
239fffb55fSDavid Gibson 
24658f29a5SJohn Bonesio #include "util.h"
25658f29a5SJohn Bonesio 
26658f29a5SJohn Bonesio #ifdef DEBUG
2747605971SRob Herring #define debug(...)	printf(__VA_ARGS__)
28658f29a5SJohn Bonesio #else
2947605971SRob Herring #define debug(...)
30658f29a5SJohn Bonesio #endif
31658f29a5SJohn Bonesio 
329fffb55fSDavid Gibson #define DEFAULT_FDT_VERSION	17
33658f29a5SJohn Bonesio 
349fffb55fSDavid Gibson /*
359fffb55fSDavid Gibson  * Command line options
369fffb55fSDavid Gibson  */
379fffb55fSDavid Gibson extern int quiet;		/* Level of quietness */
38*a77725a9SRob Herring extern unsigned int reservenum;	/* Number of memory reservation slots */
399fffb55fSDavid Gibson extern int minsize;		/* Minimum blob size */
409fffb55fSDavid Gibson extern int padsize;		/* Additional padding to blob */
416f05afcbSRob Herring extern int alignsize;		/* Additional padding to blob accroding to the alignsize */
42658f29a5SJohn Bonesio extern int phandle_format;	/* Use linux,phandle or phandle properties */
436f05afcbSRob Herring extern int generate_symbols;	/* generate symbols for nodes with labels */
446f05afcbSRob Herring extern int generate_fixups;	/* generate fixups */
456f05afcbSRob Herring extern int auto_label_aliases;	/* auto generate labels -> aliases */
46c2e7075cSRob Herring extern int annotate;		/* annotate .dts with input source location */
479fffb55fSDavid Gibson 
48658f29a5SJohn Bonesio #define PHANDLE_LEGACY	0x1
49658f29a5SJohn Bonesio #define PHANDLE_EPAPR	0x2
50658f29a5SJohn Bonesio #define PHANDLE_BOTH	0x3
519fffb55fSDavid Gibson 
529fffb55fSDavid Gibson typedef uint32_t cell_t;
539fffb55fSDavid Gibson 
phandle_is_valid(cell_t phandle)54*a77725a9SRob Herring static inline bool phandle_is_valid(cell_t phandle)
55*a77725a9SRob Herring {
56*a77725a9SRob Herring 	return phandle != 0 && phandle != ~0U;
57*a77725a9SRob Herring }
58*a77725a9SRob Herring 
dtb_ld16(const void * p)593eb619b2SRob Herring static inline uint16_t dtb_ld16(const void *p)
603eb619b2SRob Herring {
613eb619b2SRob Herring 	const uint8_t *bp = (const uint8_t *)p;
623eb619b2SRob Herring 
633eb619b2SRob Herring 	return ((uint16_t)bp[0] << 8)
643eb619b2SRob Herring 		| bp[1];
653eb619b2SRob Herring }
663eb619b2SRob Herring 
dtb_ld32(const void * p)673eb619b2SRob Herring static inline uint32_t dtb_ld32(const void *p)
683eb619b2SRob Herring {
693eb619b2SRob Herring 	const uint8_t *bp = (const uint8_t *)p;
703eb619b2SRob Herring 
713eb619b2SRob Herring 	return ((uint32_t)bp[0] << 24)
723eb619b2SRob Herring 		| ((uint32_t)bp[1] << 16)
733eb619b2SRob Herring 		| ((uint32_t)bp[2] << 8)
743eb619b2SRob Herring 		| bp[3];
753eb619b2SRob Herring }
763eb619b2SRob Herring 
dtb_ld64(const void * p)773eb619b2SRob Herring static inline uint64_t dtb_ld64(const void *p)
783eb619b2SRob Herring {
793eb619b2SRob Herring 	const uint8_t *bp = (const uint8_t *)p;
803eb619b2SRob Herring 
813eb619b2SRob Herring 	return ((uint64_t)bp[0] << 56)
823eb619b2SRob Herring 		| ((uint64_t)bp[1] << 48)
833eb619b2SRob Herring 		| ((uint64_t)bp[2] << 40)
843eb619b2SRob Herring 		| ((uint64_t)bp[3] << 32)
853eb619b2SRob Herring 		| ((uint64_t)bp[4] << 24)
863eb619b2SRob Herring 		| ((uint64_t)bp[5] << 16)
873eb619b2SRob Herring 		| ((uint64_t)bp[6] << 8)
883eb619b2SRob Herring 		| bp[7];
893eb619b2SRob Herring }
909fffb55fSDavid Gibson 
919fffb55fSDavid Gibson #define streq(a, b)	(strcmp((a), (b)) == 0)
929130ba88SRob Herring #define strstarts(s, prefix)	(strncmp((s), (prefix), strlen(prefix)) == 0)
939130ba88SRob Herring #define strprefixeq(a, n, b)	(strlen(b) == (n) && (memcmp(a, b, n) == 0))
strends(const char * str,const char * suffix)94*a77725a9SRob Herring static inline bool strends(const char *str, const char *suffix)
95*a77725a9SRob Herring {
96*a77725a9SRob Herring 	unsigned int len, suffix_len;
97*a77725a9SRob Herring 
98*a77725a9SRob Herring 	len = strlen(str);
99*a77725a9SRob Herring 	suffix_len = strlen(suffix);
100*a77725a9SRob Herring 	if (len < suffix_len)
101*a77725a9SRob Herring 		return false;
102*a77725a9SRob Herring 	return streq(str + len - suffix_len, suffix);
103*a77725a9SRob Herring }
1049fffb55fSDavid Gibson 
1059fffb55fSDavid Gibson #define ALIGN(x, a)	(((x) + (a) - 1) & ~((a) - 1))
1069fffb55fSDavid Gibson 
1079fffb55fSDavid Gibson /* Data blobs */
1089fffb55fSDavid Gibson enum markertype {
109f858927fSRob Herring 	TYPE_NONE,
1109fffb55fSDavid Gibson 	REF_PHANDLE,
1119fffb55fSDavid Gibson 	REF_PATH,
1129fffb55fSDavid Gibson 	LABEL,
113f858927fSRob Herring 	TYPE_UINT8,
114f858927fSRob Herring 	TYPE_UINT16,
115f858927fSRob Herring 	TYPE_UINT32,
116f858927fSRob Herring 	TYPE_UINT64,
117f858927fSRob Herring 	TYPE_STRING,
1189fffb55fSDavid Gibson };
119*a77725a9SRob Herring 
is_type_marker(enum markertype type)120*a77725a9SRob Herring static inline bool is_type_marker(enum markertype type)
121*a77725a9SRob Herring {
122*a77725a9SRob Herring 	return type >= TYPE_UINT8;
123*a77725a9SRob Herring }
124*a77725a9SRob Herring 
125f858927fSRob Herring extern const char *markername(enum markertype markertype);
1269fffb55fSDavid Gibson 
1279fffb55fSDavid Gibson struct  marker {
1289fffb55fSDavid Gibson 	enum markertype type;
12979edff12SRob Herring 	unsigned int offset;
1309fffb55fSDavid Gibson 	char *ref;
1319fffb55fSDavid Gibson 	struct marker *next;
1329fffb55fSDavid Gibson };
1339fffb55fSDavid Gibson 
1349fffb55fSDavid Gibson struct data {
13579edff12SRob Herring 	unsigned int len;
1369fffb55fSDavid Gibson 	char *val;
1379fffb55fSDavid Gibson 	struct marker *markers;
1389fffb55fSDavid Gibson };
1399fffb55fSDavid Gibson 
1409fffb55fSDavid Gibson 
14147605971SRob Herring #define empty_data ((struct data){ 0 /* all .members = 0 or NULL */ })
1429fffb55fSDavid Gibson 
1439fffb55fSDavid Gibson #define for_each_marker(m) \
1449fffb55fSDavid Gibson 	for (; (m); (m) = (m)->next)
1459fffb55fSDavid Gibson #define for_each_marker_of_type(m, t) \
1469fffb55fSDavid Gibson 	for_each_marker(m) \
1479fffb55fSDavid Gibson 		if ((m)->type == (t))
1489fffb55fSDavid Gibson 
next_type_marker(struct marker * m)149*a77725a9SRob Herring static inline struct marker *next_type_marker(struct marker *m)
150*a77725a9SRob Herring {
151*a77725a9SRob Herring 	for_each_marker(m)
152*a77725a9SRob Herring 		if (is_type_marker(m->type))
153*a77725a9SRob Herring 			break;
154*a77725a9SRob Herring 	return m;
155*a77725a9SRob Herring }
156*a77725a9SRob Herring 
type_marker_length(struct marker * m)157*a77725a9SRob Herring static inline size_t type_marker_length(struct marker *m)
158*a77725a9SRob Herring {
159*a77725a9SRob Herring 	struct marker *next = next_type_marker(m->next);
160*a77725a9SRob Herring 
161*a77725a9SRob Herring 	if (next)
162*a77725a9SRob Herring 		return next->offset - m->offset;
163*a77725a9SRob Herring 	return 0;
164*a77725a9SRob Herring }
165f858927fSRob Herring 
1669fffb55fSDavid Gibson void data_free(struct data d);
1679fffb55fSDavid Gibson 
16879edff12SRob Herring struct data data_grow_for(struct data d, unsigned int xlen);
1699fffb55fSDavid Gibson 
1709fffb55fSDavid Gibson struct data data_copy_mem(const char *mem, int len);
1719fffb55fSDavid Gibson struct data data_copy_escape_string(const char *s, int len);
1729fffb55fSDavid Gibson struct data data_copy_file(FILE *f, size_t len);
1739fffb55fSDavid Gibson 
1749fffb55fSDavid Gibson struct data data_append_data(struct data d, const void *p, int len);
1759fffb55fSDavid Gibson struct data data_insert_at_marker(struct data d, struct marker *m,
1769fffb55fSDavid Gibson 				  const void *p, int len);
1779fffb55fSDavid Gibson struct data data_merge(struct data d1, struct data d2);
1789fffb55fSDavid Gibson struct data data_append_cell(struct data d, cell_t word);
179cd296721SStephen Warren struct data data_append_integer(struct data d, uint64_t word, int bits);
18089d12310SRob Herring struct data data_append_re(struct data d, uint64_t address, uint64_t size);
1819fffb55fSDavid Gibson struct data data_append_addr(struct data d, uint64_t addr);
1829fffb55fSDavid Gibson struct data data_append_byte(struct data d, uint8_t byte);
1839fffb55fSDavid Gibson struct data data_append_zeroes(struct data d, int len);
1849fffb55fSDavid Gibson struct data data_append_align(struct data d, int align);
1859fffb55fSDavid Gibson 
1869fffb55fSDavid Gibson struct data data_add_marker(struct data d, enum markertype type, char *ref);
1879fffb55fSDavid Gibson 
18847605971SRob Herring bool data_is_one_string(struct data d);
1899fffb55fSDavid Gibson 
1909fffb55fSDavid Gibson /* DT constraints */
1919fffb55fSDavid Gibson 
1929fffb55fSDavid Gibson #define MAX_PROPNAME_LEN	31
1939fffb55fSDavid Gibson #define MAX_NODENAME_LEN	31
1949fffb55fSDavid Gibson 
1959fffb55fSDavid Gibson /* Live trees */
196658f29a5SJohn Bonesio struct label {
19747605971SRob Herring 	bool deleted;
198658f29a5SJohn Bonesio 	char *label;
199658f29a5SJohn Bonesio 	struct label *next;
200658f29a5SJohn Bonesio };
201658f29a5SJohn Bonesio 
20289d12310SRob Herring struct bus_type {
20389d12310SRob Herring 	const char *name;
20489d12310SRob Herring };
20589d12310SRob Herring 
2069fffb55fSDavid Gibson struct property {
20747605971SRob Herring 	bool deleted;
2089fffb55fSDavid Gibson 	char *name;
2099fffb55fSDavid Gibson 	struct data val;
2109fffb55fSDavid Gibson 
2119fffb55fSDavid Gibson 	struct property *next;
2129fffb55fSDavid Gibson 
213658f29a5SJohn Bonesio 	struct label *labels;
214c2e7075cSRob Herring 	struct srcpos *srcpos;
2159fffb55fSDavid Gibson };
2169fffb55fSDavid Gibson 
2179fffb55fSDavid Gibson struct node {
21847605971SRob Herring 	bool deleted;
2199fffb55fSDavid Gibson 	char *name;
2209fffb55fSDavid Gibson 	struct property *proplist;
2219fffb55fSDavid Gibson 	struct node *children;
2229fffb55fSDavid Gibson 
2239fffb55fSDavid Gibson 	struct node *parent;
2249fffb55fSDavid Gibson 	struct node *next_sibling;
2259fffb55fSDavid Gibson 
2269fffb55fSDavid Gibson 	char *fullpath;
2279fffb55fSDavid Gibson 	int basenamelen;
2289fffb55fSDavid Gibson 
2299fffb55fSDavid Gibson 	cell_t phandle;
2309fffb55fSDavid Gibson 	int addr_cells, size_cells;
2319fffb55fSDavid Gibson 
232658f29a5SJohn Bonesio 	struct label *labels;
23389d12310SRob Herring 	const struct bus_type *bus;
234c2e7075cSRob Herring 	struct srcpos *srcpos;
23550aafd60SRob Herring 
23650aafd60SRob Herring 	bool omit_if_unused, is_referenced;
2379fffb55fSDavid Gibson };
2389fffb55fSDavid Gibson 
239cd296721SStephen Warren #define for_each_label_withdel(l0, l) \
240658f29a5SJohn Bonesio 	for ((l) = (l0); (l); (l) = (l)->next)
241658f29a5SJohn Bonesio 
242205a8eb7SStephen Warren #define for_each_label(l0, l) \
243205a8eb7SStephen Warren 	for_each_label_withdel(l0, l) \
244205a8eb7SStephen Warren 		if (!(l)->deleted)
245cd296721SStephen Warren 
246cd296721SStephen Warren #define for_each_property_withdel(n, p) \
2479fffb55fSDavid Gibson 	for ((p) = (n)->proplist; (p); (p) = (p)->next)
2489fffb55fSDavid Gibson 
249205a8eb7SStephen Warren #define for_each_property(n, p) \
250205a8eb7SStephen Warren 	for_each_property_withdel(n, p) \
251205a8eb7SStephen Warren 		if (!(p)->deleted)
252cd296721SStephen Warren 
253cd296721SStephen Warren #define for_each_child_withdel(n, c) \
2549fffb55fSDavid Gibson 	for ((c) = (n)->children; (c); (c) = (c)->next_sibling)
2559fffb55fSDavid Gibson 
256205a8eb7SStephen Warren #define for_each_child(n, c) \
257205a8eb7SStephen Warren 	for_each_child_withdel(n, c) \
258205a8eb7SStephen Warren 		if (!(c)->deleted)
259205a8eb7SStephen Warren 
260658f29a5SJohn Bonesio void add_label(struct label **labels, char *label);
261cd296721SStephen Warren void delete_labels(struct label **labels);
262658f29a5SJohn Bonesio 
263c2e7075cSRob Herring struct property *build_property(char *name, struct data val,
264c2e7075cSRob Herring 				struct srcpos *srcpos);
265cd296721SStephen Warren struct property *build_property_delete(char *name);
2669fffb55fSDavid Gibson struct property *chain_property(struct property *first, struct property *list);
2679fffb55fSDavid Gibson struct property *reverse_properties(struct property *first);
2689fffb55fSDavid Gibson 
269c2e7075cSRob Herring struct node *build_node(struct property *proplist, struct node *children,
270c2e7075cSRob Herring 			struct srcpos *srcpos);
271c2e7075cSRob Herring struct node *build_node_delete(struct srcpos *srcpos);
272658f29a5SJohn Bonesio struct node *name_node(struct node *node, char *name);
27350aafd60SRob Herring struct node *omit_node_if_unused(struct node *node);
27450aafd60SRob Herring struct node *reference_node(struct node *node);
2759fffb55fSDavid Gibson struct node *chain_node(struct node *first, struct node *list);
276658f29a5SJohn Bonesio struct node *merge_nodes(struct node *old_node, struct node *new_node);
2779130ba88SRob Herring struct node *add_orphan_node(struct node *old_node, struct node *new_node, char *ref);
2789fffb55fSDavid Gibson 
2799fffb55fSDavid Gibson void add_property(struct node *node, struct property *prop);
280cd296721SStephen Warren void delete_property_by_name(struct node *node, char *name);
281cd296721SStephen Warren void delete_property(struct property *prop);
2829fffb55fSDavid Gibson void add_child(struct node *parent, struct node *child);
283cd296721SStephen Warren void delete_node_by_name(struct node *parent, char *name);
284cd296721SStephen Warren void delete_node(struct node *node);
2856f05afcbSRob Herring void append_to_property(struct node *node,
2869bb9c6a1SRob Herring 			char *name, const void *data, int len,
2879bb9c6a1SRob Herring 			enum markertype type);
2889fffb55fSDavid Gibson 
2899fffb55fSDavid Gibson const char *get_unitname(struct node *node);
2909fffb55fSDavid Gibson struct property *get_property(struct node *node, const char *propname);
2919fffb55fSDavid Gibson cell_t propval_cell(struct property *prop);
29279edff12SRob Herring cell_t propval_cell_n(struct property *prop, unsigned int n);
293658f29a5SJohn Bonesio struct property *get_property_by_label(struct node *tree, const char *label,
294658f29a5SJohn Bonesio 				       struct node **node);
295658f29a5SJohn Bonesio struct marker *get_marker_label(struct node *tree, const char *label,
296658f29a5SJohn Bonesio 				struct node **node, struct property **prop);
2979fffb55fSDavid Gibson struct node *get_subnode(struct node *node, const char *nodename);
2989fffb55fSDavid Gibson struct node *get_node_by_path(struct node *tree, const char *path);
2999fffb55fSDavid Gibson struct node *get_node_by_label(struct node *tree, const char *label);
3009fffb55fSDavid Gibson struct node *get_node_by_phandle(struct node *tree, cell_t phandle);
3019fffb55fSDavid Gibson struct node *get_node_by_ref(struct node *tree, const char *ref);
3029fffb55fSDavid Gibson cell_t get_node_phandle(struct node *root, struct node *node);
3039fffb55fSDavid Gibson 
304658f29a5SJohn Bonesio uint32_t guess_boot_cpuid(struct node *tree);
305658f29a5SJohn Bonesio 
3069fffb55fSDavid Gibson /* Boot info (tree plus memreserve information */
3079fffb55fSDavid Gibson 
3089fffb55fSDavid Gibson struct reserve_info {
30989d12310SRob Herring 	uint64_t address, size;
3109fffb55fSDavid Gibson 
3119fffb55fSDavid Gibson 	struct reserve_info *next;
3129fffb55fSDavid Gibson 
313658f29a5SJohn Bonesio 	struct label *labels;
3149fffb55fSDavid Gibson };
3159fffb55fSDavid Gibson 
316658f29a5SJohn Bonesio struct reserve_info *build_reserve_entry(uint64_t start, uint64_t len);
3179fffb55fSDavid Gibson struct reserve_info *chain_reserve_entry(struct reserve_info *first,
3189fffb55fSDavid Gibson 					 struct reserve_info *list);
3199fffb55fSDavid Gibson struct reserve_info *add_reserve_entry(struct reserve_info *list,
3209fffb55fSDavid Gibson 				       struct reserve_info *new);
3219fffb55fSDavid Gibson 
3229fffb55fSDavid Gibson 
3236f05afcbSRob Herring struct dt_info {
3246f05afcbSRob Herring 	unsigned int dtsflags;
3259fffb55fSDavid Gibson 	struct reserve_info *reservelist;
3269fffb55fSDavid Gibson 	uint32_t boot_cpuid_phys;
3276f05afcbSRob Herring 	struct node *dt;		/* the device tree */
32889d12310SRob Herring 	const char *outname;		/* filename being written to, "-" for stdout */
3299fffb55fSDavid Gibson };
3309fffb55fSDavid Gibson 
3316f05afcbSRob Herring /* DTS version flags definitions */
3326f05afcbSRob Herring #define DTSF_V1		0x0001	/* /dts-v1/ */
3336f05afcbSRob Herring #define DTSF_PLUGIN	0x0002	/* /plugin/ */
3346f05afcbSRob Herring 
3356f05afcbSRob Herring struct dt_info *build_dt_info(unsigned int dtsflags,
3366f05afcbSRob Herring 			      struct reserve_info *reservelist,
3379fffb55fSDavid Gibson 			      struct node *tree, uint32_t boot_cpuid_phys);
3386f05afcbSRob Herring void sort_tree(struct dt_info *dti);
3396f05afcbSRob Herring void generate_label_tree(struct dt_info *dti, char *name, bool allocph);
3406f05afcbSRob Herring void generate_fixups_tree(struct dt_info *dti, char *name);
3416f05afcbSRob Herring void generate_local_fixups_tree(struct dt_info *dti, char *name);
3429fffb55fSDavid Gibson 
3439fffb55fSDavid Gibson /* Checks */
3449fffb55fSDavid Gibson 
34547605971SRob Herring void parse_checks_option(bool warn, bool error, const char *arg);
3466f05afcbSRob Herring void process_checks(bool force, struct dt_info *dti);
3479fffb55fSDavid Gibson 
3489fffb55fSDavid Gibson /* Flattened trees */
3499fffb55fSDavid Gibson 
3506f05afcbSRob Herring void dt_to_blob(FILE *f, struct dt_info *dti, int version);
3516f05afcbSRob Herring void dt_to_asm(FILE *f, struct dt_info *dti, int version);
3529fffb55fSDavid Gibson 
3536f05afcbSRob Herring struct dt_info *dt_from_blob(const char *fname);
3549fffb55fSDavid Gibson 
3559fffb55fSDavid Gibson /* Tree source */
3569fffb55fSDavid Gibson 
3576f05afcbSRob Herring void dt_to_source(FILE *f, struct dt_info *dti);
3586f05afcbSRob Herring struct dt_info *dt_from_source(const char *f);
3599fffb55fSDavid Gibson 
360f858927fSRob Herring /* YAML source */
361f858927fSRob Herring 
362f858927fSRob Herring void dt_to_yaml(FILE *f, struct dt_info *dti);
363f858927fSRob Herring 
3649fffb55fSDavid Gibson /* FS trees */
3659fffb55fSDavid Gibson 
3666f05afcbSRob Herring struct dt_info *dt_from_fs(const char *dirname);
3679fffb55fSDavid Gibson 
3689130ba88SRob Herring #endif /* DTC_H */
369