diff options
Diffstat (limited to 'scripts/dtc')
| -rw-r--r-- | scripts/dtc/checks.c | 23 | ||||
| -rw-r--r-- | scripts/dtc/data.c | 47 | ||||
| -rwxr-xr-x | scripts/dtc/dt_to_config | 8 | ||||
| -rw-r--r-- | scripts/dtc/dtc-lexer.l | 15 | ||||
| -rw-r--r-- | scripts/dtc/dtc.c | 6 | ||||
| -rw-r--r-- | scripts/dtc/dtc.h | 5 | ||||
| -rw-r--r-- | scripts/dtc/fdtoverlay.c | 8 | ||||
| -rw-r--r-- | scripts/dtc/flattree.c | 2 | ||||
| -rw-r--r-- | scripts/dtc/libfdt/fdt.c | 8 | ||||
| -rw-r--r-- | scripts/dtc/libfdt/fdt.h | 4 | ||||
| -rw-r--r-- | scripts/dtc/libfdt/fdt_overlay.c | 8 | ||||
| -rw-r--r-- | scripts/dtc/libfdt/fdt_rw.c | 41 | ||||
| -rw-r--r-- | scripts/dtc/libfdt/libfdt.h | 179 | ||||
| -rw-r--r-- | scripts/dtc/libfdt/libfdt_internal.h | 14 | ||||
| -rw-r--r-- | scripts/dtc/livetree.c | 25 | ||||
| -rw-r--r-- | scripts/dtc/srcpos.c | 17 | ||||
| -rw-r--r-- | scripts/dtc/srcpos.h | 1 | ||||
| -rw-r--r-- | scripts/dtc/treesource.c | 52 | ||||
| -rw-r--r-- | scripts/dtc/util.c | 16 | ||||
| -rw-r--r-- | scripts/dtc/util.h | 5 | ||||
| -rw-r--r-- | scripts/dtc/version_gen.h | 2 | 
21 files changed, 375 insertions, 111 deletions
| diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c index 6e06aeab5503..7e3fed5005b3 100644 --- a/scripts/dtc/checks.c +++ b/scripts/dtc/checks.c @@ -1024,7 +1024,7 @@ static void check_i2c_bus_bridge(struct check *c, struct dt_info *dti, struct no  	} else if (strprefixeq(node->name, node->basenamelen, "i2c")) {  		struct node *child;  		for_each_child(node, child) { -			if (strprefixeq(child->name, node->basenamelen, "i2c-bus")) +			if (strprefixeq(child->name, child->basenamelen, "i2c-bus"))  				return;  		}  		node->bus = &i2c_bus; @@ -1217,9 +1217,7 @@ WARNING(avoid_default_addr_size, check_avoid_default_addr_size, NULL,  static void check_avoid_unnecessary_addr_size(struct check *c, struct dt_info *dti,  					      struct node *node)  { -	struct property *prop;  	struct node *child; -	bool has_reg = false;  	if (!node->parent || node->addr_cells < 0 || node->size_cells < 0)  		return; @@ -1228,13 +1226,18 @@ static void check_avoid_unnecessary_addr_size(struct check *c, struct dt_info *d  		return;  	for_each_child(node, child) { -		prop = get_property(child, "reg"); -		if (prop) -			has_reg = true; +		/* +		 * Even if the child devices' address space is not mapped into +		 * the parent bus (no 'ranges' property on node), children can +		 * still have registers on a local bus, or map local addresses +		 * to another subordinate address space. The properties on the +		 * child nodes then make #address-cells/#size-cells necessary: +		 */ +		if (get_property(child, "reg") || get_property(child, "ranges")) +			return;  	} -	if (!has_reg) -		FAIL(c, dti, node, "unnecessary #address-cells/#size-cells without \"ranges\", \"dma-ranges\" or child \"reg\" property"); +	FAIL(c, dti, node, "unnecessary #address-cells/#size-cells without \"ranges\", \"dma-ranges\" or child \"reg\" or \"ranges\" property");  }  WARNING(avoid_unnecessary_addr_size, check_avoid_unnecessary_addr_size, NULL, &avoid_default_addr_size); @@ -1673,6 +1676,10 @@ static void check_interrupt_map(struct check *c,  		cellprop = get_property(provider_node, "#address-cells");  		if (cellprop)  			parent_cellsize += propval_cell(cellprop); +		else +			FAIL_PROP(c, dti, node, irq_map_prop, +				"Missing property '#address-cells' in node %s, using 0 as fallback", +				provider_node->fullpath);  		cell += 1 + parent_cellsize;  		if (cell > map_cells) diff --git a/scripts/dtc/data.c b/scripts/dtc/data.c index 14734233ad8b..5b25aa060416 100644 --- a/scripts/dtc/data.c +++ b/scripts/dtc/data.c @@ -228,11 +228,7 @@ struct data data_add_marker(struct data d, enum markertype type, char *ref)  {  	struct marker *m; -	m = xmalloc(sizeof(*m)); -	m->offset = d.len; -	m->type = type; -	m->ref = ref; -	m->next = NULL; +	m = alloc_marker(d.len, type, ref);  	return data_append_markers(d, m);  } @@ -254,3 +250,44 @@ bool data_is_one_string(struct data d)  	return true;  } + +struct data data_insert_data(struct data d, struct marker *m, struct data old) +{ +	unsigned int offset = m->offset; +	struct marker *next = m->next; +	struct marker *marker; +	struct data new_data; +	char *ref; + +	new_data = data_insert_at_marker(d, m, old.val, old.len); + +	/* Copy all markers from old value */ +	marker = old.markers; +	for_each_marker(marker) { +		ref = NULL; + +		if (marker->ref) +			ref = xstrdup(marker->ref); + +		m->next = alloc_marker(marker->offset + offset, marker->type, +				       ref); +		m = m->next; +	} +	m->next = next; + +	return new_data; +} + +struct marker *alloc_marker(unsigned int offset, enum markertype type, +			    char *ref) +{ +	struct marker *m; + +	m = xmalloc(sizeof(*m)); +	m->offset = offset; +	m->type = type; +	m->ref = ref; +	m->next = NULL; + +	return m; +} diff --git a/scripts/dtc/dt_to_config b/scripts/dtc/dt_to_config index 299d1c2b20d7..70d6d5f06bdc 100755 --- a/scripts/dtc/dt_to_config +++ b/scripts/dtc/dt_to_config @@ -51,10 +51,10 @@ $num_pr_flags = $pr_flag_pos_config_test_fail + 1;      "compatible is white listed",      "matching driver and/or kernel config is hard coded",      "kernel config hard coded in Makefile", -    "one or more kernel config file options is not set", -    "one or more kernel config file options is set to 'm'", -    "one or more kernel config file options is set to 'y'", -    "one of more kernel config file options fails to have correct value" +    "one or more kernel config file options are not set", +    "one or more kernel config file options are set to 'm'", +    "one or more kernel config file options are set to 'y'", +    "one or more kernel config file options fail to have correct value"  ); diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l index de60a70b6bdb..15d585c80798 100644 --- a/scripts/dtc/dtc-lexer.l +++ b/scripts/dtc/dtc-lexer.l @@ -151,6 +151,21 @@ static void PRINTF(1, 2) lexical_error(const char *fmt, ...);  			return DT_LABEL;  		} +<V1>{LABEL} 	{ +			/* Missed includes or macro definitions while +			 * preprocessing can lead to unexpected identifiers in +			 * the input. Report a slightly more informative error +			 * in this case */ + +			lexical_error("Unexpected '%s'", yytext); + +			/* Treat it as a literal which often generates further +			 * useful error messages */ + +			yylval.integer = 0; +			return DT_LITERAL; +		} +  <V1>([0-9]+|0[xX][0-9a-fA-F]+)(U|L|UL|LL|ULL)? {  			char *e;  			DPRINT("Integer Literal: '%s'\n", yytext); diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c index 0655c2e2c362..b3445b7d6473 100644 --- a/scripts/dtc/dtc.c +++ b/scripts/dtc/dtc.c @@ -15,7 +15,7 @@ int quiet;		/* Level of quietness */  unsigned int reservenum;/* Number of memory reservation slots */  int minsize;		/* Minimum blob size */  int padsize;		/* Additional padding to blob */ -int alignsize;		/* Additional padding to blob accroding to the alignsize */ +int alignsize;		/* Additional padding to blob according to the alignsize */  int phandle_format = PHANDLE_EPAPR;	/* Use linux,phandle or phandle properties */  int generate_symbols;	/* enable symbols & fixup support */  int generate_fixups;		/* suppress generation of fixups on symbol support */ @@ -289,7 +289,9 @@ int main(int argc, char *argv[])  		if (!depfile)  			die("Couldn't open dependency file %s: %s\n", depname,  			    strerror(errno)); -		fprintf(depfile, "%s:", outname); + +		fprint_path_escaped(depfile, outname); +		fputc(':', depfile);  	}  	if (inform == NULL) diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h index 4c4aaca1fc41..3a220b9afc99 100644 --- a/scripts/dtc/dtc.h +++ b/scripts/dtc/dtc.h @@ -38,7 +38,7 @@ extern int quiet;		/* Level of quietness */  extern unsigned int reservenum;	/* Number of memory reservation slots */  extern int minsize;		/* Minimum blob size */  extern int padsize;		/* Additional padding to blob */ -extern int alignsize;		/* Additional padding to blob accroding to the alignsize */ +extern int alignsize;		/* Additional padding to blob according to the alignsize */  extern int phandle_format;	/* Use linux,phandle or phandle properties */  extern int generate_symbols;	/* generate symbols for nodes with labels */  extern int generate_fixups;	/* generate fixups */ @@ -182,7 +182,10 @@ struct data data_append_addr(struct data d, uint64_t addr);  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_insert_data(struct data d, struct marker *m, struct data old); +struct marker *alloc_marker(unsigned int offset, enum markertype type, +			    char *ref);  struct data data_add_marker(struct data d, enum markertype type, char *ref);  bool data_is_one_string(struct data d); diff --git a/scripts/dtc/fdtoverlay.c b/scripts/dtc/fdtoverlay.c index 699b4f616502..ee1eb8f3ad28 100644 --- a/scripts/dtc/fdtoverlay.c +++ b/scripts/dtc/fdtoverlay.c @@ -46,6 +46,7 @@ static void *apply_one(char *base, const char *overlay, size_t *buf_len,  	char *tmp = NULL;  	char *tmpo;  	int ret; +	bool has_symbols;  	/*  	 * We take copies first, because a failed apply can trash @@ -62,6 +63,8 @@ static void *apply_one(char *base, const char *overlay, size_t *buf_len,  				fdt_strerror(ret));  			goto fail;  		} +		ret = fdt_path_offset(tmp, "/__symbols__"); +		has_symbols = ret >= 0;  		memcpy(tmpo, overlay, fdt_totalsize(overlay)); @@ -74,6 +77,11 @@ static void *apply_one(char *base, const char *overlay, size_t *buf_len,  	if (ret) {  		fprintf(stderr, "\nFailed to apply '%s': %s\n",  			name, fdt_strerror(ret)); +		if (!has_symbols) { +			fprintf(stderr, +				"base blob does not have a '/__symbols__' node, " +				"make sure you have compiled the base blob with '-@' option\n"); +		}  		goto fail;  	} diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c index 1bcd8089c5b9..30e6de2044b2 100644 --- a/scripts/dtc/flattree.c +++ b/scripts/dtc/flattree.c @@ -503,7 +503,7 @@ void dt_to_asm(FILE *f, struct dt_info *dti, int version)  	 * Reserve map entries.  	 * Align the reserve map to a doubleword boundary.  	 * Each entry is an (address, size) pair of u64 values. -	 * Always supply a zero-sized temination entry. +	 * Always supply a zero-sized termination entry.  	 */  	asm_emit_align(f, 8);  	emit_label(f, symprefix, "reserve_map"); diff --git a/scripts/dtc/libfdt/fdt.c b/scripts/dtc/libfdt/fdt.c index 20c6415b9ced..95f644c31f94 100644 --- a/scripts/dtc/libfdt/fdt.c +++ b/scripts/dtc/libfdt/fdt.c @@ -312,14 +312,14 @@ int fdt_next_subnode(const void *fdt, int offset)  	return offset;  } -const char *fdt_find_string_(const char *strtab, int tabsize, const char *s) +const char *fdt_find_string_len_(const char *strtab, int tabsize, const char *s, +				 int slen)  { -	int len = strlen(s) + 1; -	const char *last = strtab + tabsize - len; +	const char *last = strtab + tabsize - (slen + 1);  	const char *p;  	for (p = strtab; p <= last; p++) -		if (memcmp(p, s, len) == 0) +		if (memcmp(p, s, slen) == 0 && p[slen] == '\0')  			return p;  	return NULL;  } diff --git a/scripts/dtc/libfdt/fdt.h b/scripts/dtc/libfdt/fdt.h index 0c91aa7f67b5..a07abfcc7108 100644 --- a/scripts/dtc/libfdt/fdt.h +++ b/scripts/dtc/libfdt/fdt.h @@ -7,7 +7,7 @@   * Copyright 2012 Kim Phillips, Freescale Semiconductor.   */ -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__  struct fdt_header {  	fdt32_t magic;			 /* magic word FDT_MAGIC */ @@ -45,7 +45,7 @@ struct fdt_property {  	char data[];  }; -#endif /* !__ASSEMBLY */ +#endif /* !__ASSEMBLER__ */  #define FDT_MAGIC	0xd00dfeed	/* 4: version, 4: total size */  #define FDT_TAGSIZE	sizeof(fdt32_t) diff --git a/scripts/dtc/libfdt/fdt_overlay.c b/scripts/dtc/libfdt/fdt_overlay.c index 28b667ffc490..e6b9eb643958 100644 --- a/scripts/dtc/libfdt/fdt_overlay.c +++ b/scripts/dtc/libfdt/fdt_overlay.c @@ -307,7 +307,6 @@ static int overlay_update_local_references(void *fdto, uint32_t delta)  /**   * overlay_fixup_one_phandle - Set an overlay phandle to the base one - * @fdt: Base Device Tree blob   * @fdto: Device tree overlay blob   * @symbols_off: Node offset of the symbols node in the base device tree   * @path: Path to a node holding a phandle in the overlay @@ -328,8 +327,7 @@ static int overlay_update_local_references(void *fdto, uint32_t delta)   *      0 on success   *      Negative error code on failure   */ -static int overlay_fixup_one_phandle(void *fdt, void *fdto, -				     int symbols_off, +static int overlay_fixup_one_phandle(void *fdto, int symbols_off,  				     const char *path, uint32_t path_len,  				     const char *name, uint32_t name_len,  				     int poffset, uint32_t phandle) @@ -351,7 +349,7 @@ static int overlay_fixup_one_phandle(void *fdt, void *fdto,  						   name, name_len, poffset,  						   &phandle_prop,  						   sizeof(phandle_prop)); -}; +}  /**   * overlay_fixup_phandle - Set an overlay phandle to the base one @@ -443,7 +441,7 @@ static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off,  		if ((*endptr != '\0') || (endptr <= (sep + 1)))  			return -FDT_ERR_BADOVERLAY; -		ret = overlay_fixup_one_phandle(fdt, fdto, symbols_off, +		ret = overlay_fixup_one_phandle(fdto, symbols_off,  						path, path_len, name, name_len,  						poffset, phandle);  		if (ret) diff --git a/scripts/dtc/libfdt/fdt_rw.c b/scripts/dtc/libfdt/fdt_rw.c index 3621d3651d3f..7475cafce071 100644 --- a/scripts/dtc/libfdt/fdt_rw.c +++ b/scripts/dtc/libfdt/fdt_rw.c @@ -124,31 +124,33 @@ static int fdt_splice_string_(void *fdt, int newlen)   *	allocated. Ignored if can_assume(NO_ROLLBACK)   * @return offset of string in the string table (whether found or added)   */ -static int fdt_find_add_string_(void *fdt, const char *s, int *allocated) +static int fdt_find_add_string_(void *fdt, const char *s, int slen, +				int *allocated)  {  	char *strtab = (char *)fdt + fdt_off_dt_strings(fdt);  	const char *p;  	char *new; -	int len = strlen(s) + 1;  	int err;  	if (!can_assume(NO_ROLLBACK))  		*allocated = 0; -	p = fdt_find_string_(strtab, fdt_size_dt_strings(fdt), s); +	p = fdt_find_string_len_(strtab, fdt_size_dt_strings(fdt), s, slen);  	if (p)  		/* found it */  		return (p - strtab);  	new = strtab + fdt_size_dt_strings(fdt); -	err = fdt_splice_string_(fdt, len); +	err = fdt_splice_string_(fdt, slen + 1);  	if (err)  		return err;  	if (!can_assume(NO_ROLLBACK))  		*allocated = 1; -	memcpy(new, s, len); +	memcpy(new, s, slen); +	new[slen] = '\0'; +  	return (new - strtab);  } @@ -181,13 +183,15 @@ int fdt_del_mem_rsv(void *fdt, int n)  	return fdt_splice_mem_rsv_(fdt, re, 1, 0);  } -static int fdt_resize_property_(void *fdt, int nodeoffset, const char *name, +static int fdt_resize_property_(void *fdt, int nodeoffset, +				const char *name, int namelen,  				int len, struct fdt_property **prop)  {  	int oldlen;  	int err; -	*prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen); +	*prop = fdt_get_property_namelen_w(fdt, nodeoffset, name, namelen, +					   &oldlen);  	if (!*prop)  		return oldlen; @@ -200,7 +204,7 @@ static int fdt_resize_property_(void *fdt, int nodeoffset, const char *name,  }  static int fdt_add_property_(void *fdt, int nodeoffset, const char *name, -			     int len, struct fdt_property **prop) +			     int namelen, int len, struct fdt_property **prop)  {  	int proplen;  	int nextoffset; @@ -211,7 +215,7 @@ static int fdt_add_property_(void *fdt, int nodeoffset, const char *name,  	if ((nextoffset = fdt_check_node_offset_(fdt, nodeoffset)) < 0)  		return nextoffset; -	namestroff = fdt_find_add_string_(fdt, name, &allocated); +	namestroff = fdt_find_add_string_(fdt, name, namelen, &allocated);  	if (namestroff < 0)  		return namestroff; @@ -255,17 +259,18 @@ int fdt_set_name(void *fdt, int nodeoffset, const char *name)  	return 0;  } -int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name, -			    int len, void **prop_data) +int fdt_setprop_placeholder_namelen(void *fdt, int nodeoffset, const char *name, +				    int namelen, int len, void **prop_data)  {  	struct fdt_property *prop;  	int err;  	FDT_RW_PROBE(fdt); -	err = fdt_resize_property_(fdt, nodeoffset, name, len, &prop); +	err = fdt_resize_property_(fdt, nodeoffset, name, namelen, len, &prop);  	if (err == -FDT_ERR_NOTFOUND) -		err = fdt_add_property_(fdt, nodeoffset, name, len, &prop); +		err = fdt_add_property_(fdt, nodeoffset, name, namelen, len, +					&prop);  	if (err)  		return err; @@ -273,13 +278,14 @@ int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,  	return 0;  } -int fdt_setprop(void *fdt, int nodeoffset, const char *name, -		const void *val, int len) +int fdt_setprop_namelen(void *fdt, int nodeoffset, const char *name, +			int namelen, const void *val, int len)  {  	void *prop_data;  	int err; -	err = fdt_setprop_placeholder(fdt, nodeoffset, name, len, &prop_data); +	err = fdt_setprop_placeholder_namelen(fdt, nodeoffset, name, namelen, +					      len, &prop_data);  	if (err)  		return err; @@ -307,7 +313,8 @@ int fdt_appendprop(void *fdt, int nodeoffset, const char *name,  		prop->len = cpu_to_fdt32(newlen);  		memcpy(prop->data + oldlen, val, len);  	} else { -		err = fdt_add_property_(fdt, nodeoffset, name, len, &prop); +		err = fdt_add_property_(fdt, nodeoffset, name, strlen(name), +					len, &prop);  		if (err)  			return err;  		memcpy(prop->data, val, len); diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h index 2d409d8e829b..914bf90785ab 100644 --- a/scripts/dtc/libfdt/libfdt.h +++ b/scripts/dtc/libfdt/libfdt.h @@ -14,7 +14,7 @@ extern "C" {  #endif  #define FDT_FIRST_SUPPORTED_VERSION	0x02 -#define FDT_LAST_COMPATIBLE_VERSION 0x10 +#define FDT_LAST_COMPATIBLE_VERSION	0x10  #define FDT_LAST_SUPPORTED_VERSION	0x11  /* Error codes: informative error codes */ @@ -263,16 +263,16 @@ int fdt_next_subnode(const void *fdt, int offset);  		struct fdt_header *fdth = (struct fdt_header *)fdt; \  		fdth->name = cpu_to_fdt32(val); \  	} -fdt_set_hdr_(magic); -fdt_set_hdr_(totalsize); -fdt_set_hdr_(off_dt_struct); -fdt_set_hdr_(off_dt_strings); -fdt_set_hdr_(off_mem_rsvmap); -fdt_set_hdr_(version); -fdt_set_hdr_(last_comp_version); -fdt_set_hdr_(boot_cpuid_phys); -fdt_set_hdr_(size_dt_strings); -fdt_set_hdr_(size_dt_struct); +fdt_set_hdr_(magic) +fdt_set_hdr_(totalsize) +fdt_set_hdr_(off_dt_struct) +fdt_set_hdr_(off_dt_strings) +fdt_set_hdr_(off_mem_rsvmap) +fdt_set_hdr_(version) +fdt_set_hdr_(last_comp_version) +fdt_set_hdr_(boot_cpuid_phys) +fdt_set_hdr_(size_dt_strings) +fdt_set_hdr_(size_dt_struct)  #undef fdt_set_hdr_  /** @@ -285,7 +285,7 @@ size_t fdt_header_size(const void *fdt);  /**   * fdt_header_size_ - internal function to get header size from a version number - * @version: devicetree version number + * @version: device tree version number   *   * Return: size of DTB header in bytes   */ @@ -554,7 +554,7 @@ int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen);   *	-FDT_ERR_BADPATH, given path does not begin with '/' and the first   *		component is not a valid alias   *	-FDT_ERR_NOTFOUND, if the requested node does not exist - *      -FDT_ERR_BADMAGIC, + *	-FDT_ERR_BADMAGIC,   *	-FDT_ERR_BADVERSION,   *	-FDT_ERR_BADSTATE,   *	-FDT_ERR_BADSTRUCTURE, @@ -599,7 +599,7 @@ const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp);   *	structure block offset of the property (>=0), on success   *	-FDT_ERR_NOTFOUND, if the requested node has no properties   *	-FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_BEGIN_NODE tag - *      -FDT_ERR_BADMAGIC, + *	-FDT_ERR_BADMAGIC,   *	-FDT_ERR_BADVERSION,   *	-FDT_ERR_BADSTATE,   *	-FDT_ERR_BADSTRUCTURE, @@ -620,7 +620,7 @@ int fdt_first_property_offset(const void *fdt, int nodeoffset);   *	structure block offset of the next property (>=0), on success   *	-FDT_ERR_NOTFOUND, if the given property is the last in its node   *	-FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_PROP tag - *      -FDT_ERR_BADMAGIC, + *	-FDT_ERR_BADMAGIC,   *	-FDT_ERR_BADVERSION,   *	-FDT_ERR_BADSTATE,   *	-FDT_ERR_BADSTRUCTURE, @@ -712,6 +712,13 @@ const struct fdt_property *fdt_get_property_namelen(const void *fdt,  						    int nodeoffset,  						    const char *name,  						    int namelen, int *lenp); +static inline struct fdt_property * +fdt_get_property_namelen_w(void *fdt, int nodeoffset, const char *name, +			   int namelen, int *lenp) +{ +	return (struct fdt_property *)(uintptr_t)fdt_get_property_namelen( +		fdt, nodeoffset, name, namelen, lenp); +}  #endif  /** @@ -764,7 +771,7 @@ static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,   * to within the device blob itself, not a copy of the value).  If   * lenp is non-NULL, the length of the property value is also   * returned, in the integer pointed to by lenp.  If namep is non-NULL, - * the property's namne will also be returned in the char * pointed to + * the property's name will also be returned in the char * pointed to   * by namep (this will be a pointer to within the device tree's string   * block, not a new copy of the name).   * @@ -772,7 +779,7 @@ static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,   *	pointer to the property's value   *		if lenp is non-NULL, *lenp contains the length of the property   *		value (>=0) - *		if namep is non-NULL *namep contiains a pointer to the property + *		if namep is non-NULL *namep contains a pointer to the property   *		name.   *	NULL, on error   *		if lenp is non-NULL, *lenp contains an error code (<0): @@ -866,7 +873,7 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset);  /**   * fdt_get_alias_namelen - get alias based on substring   * @fdt: pointer to the device tree blob - * @name: name of the alias th look up + * @name: name of the alias to look up   * @namelen: number of characters of name to consider   *   * Identical to fdt_get_alias(), but only examine the first @namelen @@ -883,7 +890,7 @@ const char *fdt_get_alias_namelen(const void *fdt,  /**   * fdt_get_alias - retrieve the path referenced by a given alias   * @fdt: pointer to the device tree blob - * @name: name of the alias th look up + * @name: name of the alias to look up   *   * fdt_get_alias() retrieves the value of a given alias.  That is, the   * value of the property named @name in the node /aliases. @@ -1259,8 +1266,8 @@ const char *fdt_stringlist_get(const void *fdt, int nodeoffset,   *   * returns:   *	0 <= n < FDT_MAX_NCELLS, on success - *      2, if the node has no #address-cells property - *      -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid + *	2, if the node has no #address-cells property + *	-FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid   *		#address-cells property   *	-FDT_ERR_BADMAGIC,   *	-FDT_ERR_BADVERSION, @@ -1280,8 +1287,8 @@ int fdt_address_cells(const void *fdt, int nodeoffset);   *   * returns:   *	0 <= n < FDT_MAX_NCELLS, on success - *      1, if the node has no #size-cells property - *      -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid + *	1, if the node has no #size-cells property + *	-FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid   *		#size-cells property   *	-FDT_ERR_BADMAGIC,   *	-FDT_ERR_BADVERSION, @@ -1562,7 +1569,7 @@ static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)   * @fdt: pointer to the device tree blob   * @name: name of property to add   * @len: length of property value in bytes - * @valp: returns a pointer to where where the value should be placed + * @valp: returns a pointer to where the value should be placed   *   * returns:   *	0, on success @@ -1660,6 +1667,38 @@ int fdt_del_mem_rsv(void *fdt, int n);  int fdt_set_name(void *fdt, int nodeoffset, const char *name);  /** + * fdt_setprop_namelen - create or change a property + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to change + * @name: name of the property to change + * @namelen: length of the name + * @val: pointer to data to set the property value to + * @len: length of the property value + * + * fdt_setprop_namelen() sets the value of the named property in the given + * node to the given value and length, creating the property if it + * does not already exist. + * + * This function may insert or delete data from the blob, and will + * therefore change the offsets of some existing nodes. + * + * returns: + *	0, on success + *	-FDT_ERR_NOSPACE, there is insufficient free space in the blob to + *		contain the new property value + *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + *	-FDT_ERR_BADLAYOUT, + *	-FDT_ERR_BADMAGIC, + *	-FDT_ERR_BADVERSION, + *	-FDT_ERR_BADSTATE, + *	-FDT_ERR_BADSTRUCTURE, + *	-FDT_ERR_BADLAYOUT, + *	-FDT_ERR_TRUNCATED, standard meanings + */ +int fdt_setprop_namelen(void *fdt, int nodeoffset, const char *name, +			int namelen, const void *val, int len); + +/**   * fdt_setprop - create or change a property   * @fdt: pointer to the device tree blob   * @nodeoffset: offset of the node whose property to change @@ -1687,8 +1726,44 @@ int fdt_set_name(void *fdt, int nodeoffset, const char *name);   *	-FDT_ERR_BADLAYOUT,   *	-FDT_ERR_TRUNCATED, standard meanings   */ -int fdt_setprop(void *fdt, int nodeoffset, const char *name, -		const void *val, int len); +static inline int fdt_setprop(void *fdt, int nodeoffset, const char *name, +			      const void *val, int len) +{ +	return fdt_setprop_namelen(fdt, nodeoffset, name, strlen(name), val, +				   len); +} + +/** + * fdt_setprop_placeholder_namelen - allocate space for a property + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to change + * @name: name of the property to change + * @namelen: length of the name + * @len: length of the property value + * @prop_data: return pointer to property data + * + * fdt_setprop_placeholder_namelen() allocates the named property in the given node. + * If the property exists it is resized. In either case a pointer to the + * property data is returned. + * + * This function may insert or delete data from the blob, and will + * therefore change the offsets of some existing nodes. + * + * returns: + *	0, on success + *	-FDT_ERR_NOSPACE, there is insufficient free space in the blob to + *		contain the new property value + *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + *	-FDT_ERR_BADLAYOUT, + *	-FDT_ERR_BADMAGIC, + *	-FDT_ERR_BADVERSION, + *	-FDT_ERR_BADSTATE, + *	-FDT_ERR_BADSTRUCTURE, + *	-FDT_ERR_BADLAYOUT, + *	-FDT_ERR_TRUNCATED, standard meanings + */ +int fdt_setprop_placeholder_namelen(void *fdt, int nodeoffset, const char *name, +				    int namelen, int len, void **prop_data);  /**   * fdt_setprop_placeholder - allocate space for a property @@ -1698,7 +1773,7 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,   * @len: length of the property value   * @prop_data: return pointer to property data   * - * fdt_setprop_placeholer() allocates the named property in the given node. + * fdt_setprop_placeholder() allocates the named property in the given node.   * If the property exists it is resized. In either case a pointer to the   * property data is returned.   * @@ -1718,8 +1793,13 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,   *	-FDT_ERR_BADLAYOUT,   *	-FDT_ERR_TRUNCATED, standard meanings   */ -int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name, -			    int len, void **prop_data); +static inline int fdt_setprop_placeholder(void *fdt, int nodeoffset, +					  const char *name, int len, +					  void **prop_data) +{ +	return fdt_setprop_placeholder_namelen(fdt, nodeoffset, name, +					       strlen(name), len, prop_data); +}  /**   * fdt_setprop_u32 - set a property to a 32-bit integer @@ -1839,6 +1919,38 @@ static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,  #define fdt_setprop_string(fdt, nodeoffset, name, str) \  	fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1) +/** + * fdt_setprop_namelen_string - set a property to a string value + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to change + * @name: name of the property to change + * @namelen: number of characters of name to consider + * @str: string value for the property + * + * fdt_setprop_namelen_string() sets the value of the named property in the + * given node to the given string value (using the length of the + * string to determine the new length of the property), or creates a + * new property with that value if it does not already exist. + * + * This function may insert or delete data from the blob, and will + * therefore change the offsets of some existing nodes. + * + * returns: + *	0, on success + *	-FDT_ERR_NOSPACE, there is insufficient free space in the blob to + *		contain the new property value + *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + *	-FDT_ERR_BADLAYOUT, + *	-FDT_ERR_BADMAGIC, + *	-FDT_ERR_BADVERSION, + *	-FDT_ERR_BADSTATE, + *	-FDT_ERR_BADSTRUCTURE, + *	-FDT_ERR_BADLAYOUT, + *	-FDT_ERR_TRUNCATED, standard meanings + */ +#define fdt_setprop_namelen_string(fdt, nodeoffset, name, namelen, str)    \ +	fdt_setprop_namelen((fdt), (nodeoffset), (name), (namelen), (str), \ +			    strlen(str) + 1)  /**   * fdt_setprop_empty - set a property to an empty value @@ -2059,7 +2171,7 @@ int fdt_appendprop_addrrange(void *fdt, int parent, int nodeoffset,   * @nodeoffset: offset of the node whose property to nop   * @name: name of the property to nop   * - * fdt_del_property() will delete the given property. + * fdt_delprop() will delete the given property.   *   * This function will delete data from the blob, and will therefore   * change the offsets of some existing nodes. @@ -2111,8 +2223,7 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset,   * change the offsets of some existing nodes.   *   * returns: - *	structure block offset of the created nodeequested subnode (>=0), on - *		success + *	structure block offset of the created subnode (>=0), on success   *	-FDT_ERR_NOTFOUND, if the requested subnode does not exist   *	-FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE   *		tag @@ -2122,7 +2233,7 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset,   *		blob to contain the new node   *	-FDT_ERR_NOSPACE   *	-FDT_ERR_BADLAYOUT - *      -FDT_ERR_BADMAGIC, + *	-FDT_ERR_BADMAGIC,   *	-FDT_ERR_BADVERSION,   *	-FDT_ERR_BADSTATE,   *	-FDT_ERR_BADSTRUCTURE, @@ -2167,7 +2278,7 @@ int fdt_del_node(void *fdt, int nodeoffset);   * returns:   *	0, on success   *	-FDT_ERR_NOSPACE, there's not enough space in the base device tree - *	-FDT_ERR_NOTFOUND, the overlay points to some inexistant nodes or + *	-FDT_ERR_NOTFOUND, the overlay points to some nonexistent nodes or   *		properties in the base DT   *	-FDT_ERR_BADPHANDLE,   *	-FDT_ERR_BADOVERLAY, diff --git a/scripts/dtc/libfdt/libfdt_internal.h b/scripts/dtc/libfdt/libfdt_internal.h index 16bda1906a7b..b60b5456f596 100644 --- a/scripts/dtc/libfdt/libfdt_internal.h +++ b/scripts/dtc/libfdt/libfdt_internal.h @@ -20,7 +20,15 @@ int32_t fdt_ro_probe_(const void *fdt);  int fdt_check_node_offset_(const void *fdt, int offset);  int fdt_check_prop_offset_(const void *fdt, int offset); -const char *fdt_find_string_(const char *strtab, int tabsize, const char *s); + +const char *fdt_find_string_len_(const char *strtab, int tabsize, const char *s, +				 int s_len); +static inline const char *fdt_find_string_(const char *strtab, int tabsize, +					   const char *s) +{ +	return fdt_find_string_len_(strtab, tabsize, s, strlen(s)); +} +  int fdt_node_end_offset_(void *fdt, int nodeoffset);  static inline const void *fdt_offset_ptr_(const void *fdt, int offset) @@ -47,8 +55,8 @@ static inline struct fdt_reserve_entry *fdt_mem_rsv_w_(void *fdt, int n)  }  /* - * Internal helpers to access tructural elements of the device tree - * blob (rather than for exaple reading integers from within property + * Internal helpers to access structural elements of the device tree + * blob (rather than for example reading integers from within property   * values).  We assume that we are either given a naturally aligned   * address for the platform or if we are not, we are on a platform   * where unaligned memory reads will be handled in a graceful manner. diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c index 49f723002f85..d51d05830b18 100644 --- a/scripts/dtc/livetree.c +++ b/scripts/dtc/livetree.c @@ -174,7 +174,7 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)  				old_prop->val = new_prop->val;  				old_prop->deleted = 0; -				free(old_prop->srcpos); +				srcpos_free(old_prop->srcpos);  				old_prop->srcpos = new_prop->srcpos;  				free(new_prop);  				new_prop = NULL; @@ -504,7 +504,7 @@ struct node *get_subnode(struct node *node, const char *nodename)  	struct node *child;  	for_each_child(node, child) -		if (streq(child->name, nodename)) +		if (streq(child->name, nodename) && !child->deleted)  			return child;  	return NULL; @@ -1014,9 +1014,7 @@ static void add_local_fixup_entry(struct dt_info *dti,  	/* walk the path components creating nodes if they don't exist */  	for (wn = lfn, i = 1; i < depth; i++, wn = nwn) {  		/* if no node exists, create it */ -		nwn = get_subnode(wn, compp[i]); -		if (!nwn) -			nwn = build_and_name_child_node(wn, compp[i]); +		nwn = build_root_node(wn, compp[i]);  	}  	free(compp); @@ -1058,16 +1056,29 @@ void generate_label_tree(struct dt_info *dti, const char *name, bool allocph)  void generate_fixups_tree(struct dt_info *dti, const char *name)  { +	struct node *n = get_subnode(dti->dt, name); + +	/* Start with an empty __fixups__ node to not get duplicates */ +	if (n) +		n->deleted = true; +  	if (!any_fixup_tree(dti, dti->dt))  		return; -	generate_fixups_tree_internal(dti, build_root_node(dti->dt, name), +	generate_fixups_tree_internal(dti, +				      build_and_name_child_node(dti->dt, name),  				      dti->dt);  }  void generate_local_fixups_tree(struct dt_info *dti, const char *name)  { +	struct node *n = get_subnode(dti->dt, name); + +	/* Start with an empty __local_fixups__ node to not get duplicates */ +	if (n) +		n->deleted = true;  	if (!any_local_fixup_tree(dti, dti->dt))  		return; -	generate_local_fixups_tree_internal(dti, build_root_node(dti->dt, name), +	generate_local_fixups_tree_internal(dti, +					    build_and_name_child_node(dti->dt, name),  					    dti->dt);  } diff --git a/scripts/dtc/srcpos.c b/scripts/dtc/srcpos.c index 8e4d18a90b47..5bb57bf6856c 100644 --- a/scripts/dtc/srcpos.c +++ b/scripts/dtc/srcpos.c @@ -160,8 +160,10 @@ FILE *srcfile_relative_open(const char *fname, char **fullnamep)  			    strerror(errno));  	} -	if (depfile) -		fprintf(depfile, " %s", fullname); +	if (depfile) { +		fputc(' ', depfile); +		fprint_path_escaped(depfile, fullname); +	}  	if (fullnamep)  		*fullnamep = fullname; @@ -285,6 +287,17 @@ struct srcpos *srcpos_extend(struct srcpos *pos, struct srcpos *newtail)  	return pos;  } +void srcpos_free(struct srcpos *pos) +{ +	struct srcpos *p_next; + +	while (pos) { +		p_next = pos->next; +		free(pos); +		pos = p_next; +	} +} +  char *  srcpos_string(struct srcpos *pos)  { diff --git a/scripts/dtc/srcpos.h b/scripts/dtc/srcpos.h index 4318d7ad34d9..4d60b50e3119 100644 --- a/scripts/dtc/srcpos.h +++ b/scripts/dtc/srcpos.h @@ -88,6 +88,7 @@ extern void srcpos_update(struct srcpos *pos, const char *text, int len);  extern struct srcpos *srcpos_copy(struct srcpos *pos);  extern struct srcpos *srcpos_extend(struct srcpos *new_srcpos,  				    struct srcpos *old_srcpos); +extern void srcpos_free(struct srcpos *pos);  extern char *srcpos_string(struct srcpos *pos);  extern char *srcpos_string_first(struct srcpos *pos, int level);  extern char *srcpos_string_last(struct srcpos *pos, int level); diff --git a/scripts/dtc/treesource.c b/scripts/dtc/treesource.c index ae15839ba6a5..d25f01fc6937 100644 --- a/scripts/dtc/treesource.c +++ b/scripts/dtc/treesource.c @@ -139,26 +139,48 @@ static const char *delim_end[] = {  	[TYPE_STRING] = "",  }; +/* + * The invariants in the marker list are: + *  - offsets are non-strictly monotonically increasing + *  - for a single offset there is at most one type marker + *  - for a single offset that has both a type marker and non-type markers, the + *    type marker appears before the others. + */ +static struct marker **add_marker(struct marker **mi, +				  enum markertype type, unsigned int offset, char *ref) +{ +	struct marker *nm; + +	while (*mi && (*mi)->offset < offset) +		mi = &(*mi)->next; + +	if (*mi && (*mi)->offset == offset && is_type_marker((*mi)->type)) { +		if (is_type_marker(type)) +			return mi; +		mi = &(*mi)->next; +	} + +	if (*mi && (*mi)->offset == offset && type == (*mi)->type) +		return mi; + +	nm = xmalloc(sizeof(*nm)); +	nm->type = type; +	nm->offset = offset; +	nm->ref = ref; +	nm->next = *mi; +	*mi = nm; + +	return &nm->next; +} +  static void add_string_markers(struct property *prop)  {  	int l, len = prop->val.len;  	const char *p = prop->val.val; +	struct marker **mi = &prop->val.markers; -	for (l = strlen(p) + 1; l < len; l += strlen(p + l) + 1) { -		struct marker *m, **nextp; - -		m = xmalloc(sizeof(*m)); -		m->offset = l; -		m->type = TYPE_STRING; -		m->ref = NULL; -		m->next = NULL; - -		/* Find the end of the markerlist */ -		nextp = &prop->val.markers; -		while (*nextp) -			nextp = &((*nextp)->next); -		*nextp = m; -	} +	for (l = strlen(p) + 1; l < len; l += strlen(p + l) + 1) +		mi = add_marker(mi, TYPE_STRING, l, NULL);  }  static enum markertype guess_value_type(struct property *prop) diff --git a/scripts/dtc/util.c b/scripts/dtc/util.c index 507f0120cd13..412592320265 100644 --- a/scripts/dtc/util.c +++ b/scripts/dtc/util.c @@ -23,6 +23,22 @@  #include "util.h"  #include "version_gen.h" +void fprint_path_escaped(FILE *fp, const char *path) +{ +	const char *p = path; + +	while (*p) { +		if (*p == ' ') { +			fputc('\\', fp); +			fputc(' ', fp); +		} else { +			fputc(*p, fp); +		} + +		p++; +	} +} +  char *xstrdup(const char *s)  {  	int len = strlen(s) + 1; diff --git a/scripts/dtc/util.h b/scripts/dtc/util.h index b448cd79efd3..800f2e2c55b1 100644 --- a/scripts/dtc/util.h +++ b/scripts/dtc/util.h @@ -42,6 +42,11 @@ static inline void NORETURN PRINTF(1, 2) die(const char *str, ...)  	exit(1);  } +/** + * Writes path to fp, escaping spaces with a backslash. + */ +void fprint_path_escaped(FILE *fp, const char *path); +  static inline void *xmalloc(size_t len)  {  	void *new = malloc(len); diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h index bf81ce593685..226c48bf75dc 100644 --- a/scripts/dtc/version_gen.h +++ b/scripts/dtc/version_gen.h @@ -1 +1 @@ -#define DTC_VERSION "DTC 1.7.0-gbcd02b52" +#define DTC_VERSION "DTC 1.7.2-g52f07dcc" | 
