diff options
Diffstat (limited to 'scripts/dtc/libfdt')
| -rw-r--r-- | scripts/dtc/libfdt/Makefile.libfdt | 6 | ||||
| -rw-r--r-- | scripts/dtc/libfdt/fdt.c | 61 | ||||
| -rw-r--r-- | scripts/dtc/libfdt/fdt_empty_tree.c | 83 | ||||
| -rw-r--r-- | scripts/dtc/libfdt/fdt_ro.c | 275 | ||||
| -rw-r--r-- | scripts/dtc/libfdt/fdt_rw.c | 29 | ||||
| -rw-r--r-- | scripts/dtc/libfdt/fdt_sw.c | 11 | ||||
| -rw-r--r-- | scripts/dtc/libfdt/fdt_wip.c | 41 | ||||
| -rw-r--r-- | scripts/dtc/libfdt/libfdt.h | 438 | ||||
| -rw-r--r-- | scripts/dtc/libfdt/libfdt_env.h | 16 | ||||
| -rw-r--r-- | scripts/dtc/libfdt/libfdt_internal.h | 2 | 
10 files changed, 791 insertions, 171 deletions
diff --git a/scripts/dtc/libfdt/Makefile.libfdt b/scripts/dtc/libfdt/Makefile.libfdt index 6c42acfa21e..91126c000a1 100644 --- a/scripts/dtc/libfdt/Makefile.libfdt +++ b/scripts/dtc/libfdt/Makefile.libfdt @@ -3,6 +3,8 @@  # This is not a complete Makefile of itself.  Instead, it is designed to  # be easily embeddable into other systems of Makefiles.  # -LIBFDT_INCLUDES = fdt.h libfdt.h -LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c +LIBFDT_soname = libfdt.$(SHAREDLIB_EXT).1 +LIBFDT_INCLUDES = fdt.h libfdt.h libfdt_env.h +LIBFDT_VERSION = version.lds +LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c fdt_empty_tree.c  LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o) diff --git a/scripts/dtc/libfdt/fdt.c b/scripts/dtc/libfdt/fdt.c index 2acaec5923a..e56833ae9b6 100644 --- a/scripts/dtc/libfdt/fdt.c +++ b/scripts/dtc/libfdt/fdt.c @@ -74,7 +74,7 @@ int fdt_check_header(const void *fdt)  	return 0;  } -const void *fdt_offset_ptr(const void *fdt, int offset, int len) +const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)  {  	const char *p; @@ -90,42 +90,53 @@ const void *fdt_offset_ptr(const void *fdt, int offset, int len)  	return p;  } -uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset) +uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)  {  	const uint32_t *tagp, *lenp;  	uint32_t tag; +	int offset = startoffset;  	const char *p; -	if (offset % FDT_TAGSIZE) -		return -1; - +	*nextoffset = -FDT_ERR_TRUNCATED;  	tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE); -	if (! tagp) +	if (!tagp)  		return FDT_END; /* premature end */  	tag = fdt32_to_cpu(*tagp);  	offset += FDT_TAGSIZE; +	*nextoffset = -FDT_ERR_BADSTRUCTURE;  	switch (tag) {  	case FDT_BEGIN_NODE:  		/* skip name */  		do {  			p = fdt_offset_ptr(fdt, offset++, 1);  		} while (p && (*p != '\0')); -		if (! p) -			return FDT_END; +		if (!p) +			return FDT_END; /* premature end */  		break; +  	case FDT_PROP:  		lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp)); -		if (! lenp) -			return FDT_END; -		/* skip name offset, length and value */ -		offset += 2*FDT_TAGSIZE + fdt32_to_cpu(*lenp); +		if (!lenp) +			return FDT_END; /* premature end */ +		/* skip-name offset, length and value */ +		offset += sizeof(struct fdt_property) - FDT_TAGSIZE +			+ fdt32_to_cpu(*lenp); +		break; + +	case FDT_END: +	case FDT_END_NODE: +	case FDT_NOP:  		break; + +	default: +		return FDT_END;  	} -	if (nextoffset) -		*nextoffset = FDT_TAGALIGN(offset); +	if (!fdt_offset_ptr(fdt, startoffset, offset - startoffset)) +		return FDT_END; /* premature end */ +	*nextoffset = FDT_TAGALIGN(offset);  	return tag;  } @@ -138,6 +149,15 @@ int _fdt_check_node_offset(const void *fdt, int offset)  	return offset;  } +int _fdt_check_prop_offset(const void *fdt, int offset) +{ +	if ((offset < 0) || (offset % FDT_TAGSIZE) +	    || (fdt_next_tag(fdt, offset, &offset) != FDT_PROP)) +		return -FDT_ERR_BADOFFSET; + +	return offset; +} +  int fdt_next_node(const void *fdt, int offset, int *depth)  {  	int nextoffset = 0; @@ -162,15 +182,16 @@ int fdt_next_node(const void *fdt, int offset, int *depth)  			break;  		case FDT_END_NODE: -			if (depth) -				(*depth)--; +			if (depth && ((--(*depth)) < 0)) +				return nextoffset;  			break;  		case FDT_END: -			return -FDT_ERR_NOTFOUND; - -		default: -			return -FDT_ERR_BADSTRUCTURE; +			if ((nextoffset >= 0) +			    || ((nextoffset == -FDT_ERR_TRUNCATED) && !depth)) +				return -FDT_ERR_NOTFOUND; +			else +				return nextoffset;  		}  	} while (tag != FDT_BEGIN_NODE); diff --git a/scripts/dtc/libfdt/fdt_empty_tree.c b/scripts/dtc/libfdt/fdt_empty_tree.c new file mode 100644 index 00000000000..f2ae9b77c28 --- /dev/null +++ b/scripts/dtc/libfdt/fdt_empty_tree.c @@ -0,0 +1,83 @@ +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2012 David Gibson, IBM Corporation. + * + * libfdt is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * + *  a) This library is free software; you can redistribute it and/or + *     modify it under the terms of the GNU General Public License as + *     published by the Free Software Foundation; either version 2 of the + *     License, or (at your option) any later version. + * + *     This library is distributed in the hope that it will be useful, + *     but WITHOUT ANY WARRANTY; without even the implied warranty of + *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *     GNU General Public License for more details. + * + *     You should have received a copy of the GNU General Public + *     License along with this library; if not, write to the Free + *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + *     MA 02110-1301 USA + * + * Alternatively, + * + *  b) Redistribution and use in source and binary forms, with or + *     without modification, are permitted provided that the following + *     conditions are met: + * + *     1. Redistributions of source code must retain the above + *        copyright notice, this list of conditions and the following + *        disclaimer. + *     2. Redistributions in binary form must reproduce the above + *        copyright notice, this list of conditions and the following + *        disclaimer in the documentation and/or other materials + *        provided with the distribution. + * + *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "libfdt_env.h" + +#include <fdt.h> +#include <libfdt.h> + +#include "libfdt_internal.h" + +int fdt_create_empty_tree(void *buf, int bufsize) +{ +	int err; + +	err = fdt_create(buf, bufsize); +	if (err) +		return err; + +	err = fdt_finish_reservemap(buf); +	if (err) +		return err; + +	err = fdt_begin_node(buf, ""); +	if (err) +		return err; + +	err =  fdt_end_node(buf); +	if (err) +		return err; + +	err = fdt_finish(buf); +	if (err) +		return err; + +	return fdt_open_into(buf, buf, bufsize); +} diff --git a/scripts/dtc/libfdt/fdt_ro.c b/scripts/dtc/libfdt/fdt_ro.c index 22e692919ff..02b6d687537 100644 --- a/scripts/dtc/libfdt/fdt_ro.c +++ b/scripts/dtc/libfdt/fdt_ro.c @@ -80,6 +80,14 @@ const char *fdt_string(const void *fdt, int stroffset)  	return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset;  } +static int _fdt_string_eq(const void *fdt, int stroffset, +			  const char *s, int len) +{ +	const char *p = fdt_string(fdt, stroffset); + +	return (strlen(p) == len) && (memcmp(p, s, len) == 0); +} +  int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)  {  	FDT_CHECK_HEADER(fdt); @@ -97,6 +105,30 @@ int fdt_num_mem_rsv(const void *fdt)  	return i;  } +static int _nextprop(const void *fdt, int offset) +{ +	uint32_t tag; +	int nextoffset; + +	do { +		tag = fdt_next_tag(fdt, offset, &nextoffset); + +		switch (tag) { +		case FDT_END: +			if (nextoffset >= 0) +				return -FDT_ERR_BADSTRUCTURE; +			else +				return nextoffset; + +		case FDT_PROP: +			return offset; +		} +		offset = nextoffset; +	} while (tag == FDT_NOP); + +	return -FDT_ERR_NOTFOUND; +} +  int fdt_subnode_offset_namelen(const void *fdt, int offset,  			       const char *name, int namelen)  { @@ -104,20 +136,16 @@ int fdt_subnode_offset_namelen(const void *fdt, int offset,  	FDT_CHECK_HEADER(fdt); -	for (depth = 0, offset = fdt_next_node(fdt, offset, &depth); -	     (offset >= 0) && (depth > 0); -	     offset = fdt_next_node(fdt, offset, &depth)) { -		if (depth < 0) -			return -FDT_ERR_NOTFOUND; -		else if ((depth == 1) -			 && _fdt_nodename_eq(fdt, offset, name, namelen)) +	for (depth = 0; +	     (offset >= 0) && (depth >= 0); +	     offset = fdt_next_node(fdt, offset, &depth)) +		if ((depth == 1) +		    && _fdt_nodename_eq(fdt, offset, name, namelen))  			return offset; -	} -	if (offset < 0) -		return offset; /* error */ -	else +	if (depth < 0)  		return -FDT_ERR_NOTFOUND; +	return offset; /* error */  }  int fdt_subnode_offset(const void *fdt, int parentoffset, @@ -134,8 +162,20 @@ int fdt_path_offset(const void *fdt, const char *path)  	FDT_CHECK_HEADER(fdt); -	if (*path != '/') -		return -FDT_ERR_BADPATH; +	/* see if we have an alias */ +	if (*path != '/') { +		const char *q = strchr(path, '/'); + +		if (!q) +			q = end; + +		p = fdt_get_alias_namelen(fdt, p, q - p); +		if (!p) +			return -FDT_ERR_BADPATH; +		offset = fdt_path_offset(fdt, p); + +		p = q; +	}  	while (*p) {  		const char *q; @@ -178,93 +218,142 @@ const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)  	return NULL;  } -const struct fdt_property *fdt_get_property(const void *fdt, -					    int nodeoffset, -					    const char *name, int *lenp) +int fdt_first_property_offset(const void *fdt, int nodeoffset) +{ +	int offset; + +	if ((offset = _fdt_check_node_offset(fdt, nodeoffset)) < 0) +		return offset; + +	return _nextprop(fdt, offset); +} + +int fdt_next_property_offset(const void *fdt, int offset) +{ +	if ((offset = _fdt_check_prop_offset(fdt, offset)) < 0) +		return offset; + +	return _nextprop(fdt, offset); +} + +const struct fdt_property *fdt_get_property_by_offset(const void *fdt, +						      int offset, +						      int *lenp)  { -	uint32_t tag; -	const struct fdt_property *prop; -	int namestroff; -	int offset, nextoffset;  	int err; +	const struct fdt_property *prop; -	if (((err = fdt_check_header(fdt)) != 0) -	    || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0)) -			goto fail; +	if ((err = _fdt_check_prop_offset(fdt, offset)) < 0) { +		if (lenp) +			*lenp = err; +		return NULL; +	} -	nextoffset = err; -	do { -		offset = nextoffset; +	prop = _fdt_offset_ptr(fdt, offset); -		tag = fdt_next_tag(fdt, offset, &nextoffset); -		switch (tag) { -		case FDT_END: -			err = -FDT_ERR_TRUNCATED; -			goto fail; +	if (lenp) +		*lenp = fdt32_to_cpu(prop->len); -		case FDT_BEGIN_NODE: -		case FDT_END_NODE: -		case FDT_NOP: -			break; +	return prop; +} -		case FDT_PROP: -			err = -FDT_ERR_BADSTRUCTURE; -			prop = fdt_offset_ptr(fdt, offset, sizeof(*prop)); -			if (! prop) -				goto fail; -			namestroff = fdt32_to_cpu(prop->nameoff); -			if (strcmp(fdt_string(fdt, namestroff), name) == 0) { -				/* Found it! */ -				int len = fdt32_to_cpu(prop->len); -				prop = fdt_offset_ptr(fdt, offset, -						      sizeof(*prop)+len); -				if (! prop) -					goto fail; - -				if (lenp) -					*lenp = len; - -				return prop; -			} -			break; +const struct fdt_property *fdt_get_property_namelen(const void *fdt, +						    int offset, +						    const char *name, +						    int namelen, int *lenp) +{ +	for (offset = fdt_first_property_offset(fdt, offset); +	     (offset >= 0); +	     (offset = fdt_next_property_offset(fdt, offset))) { +		const struct fdt_property *prop; -		default: -			err = -FDT_ERR_BADSTRUCTURE; -			goto fail; +		if (!(prop = fdt_get_property_by_offset(fdt, offset, lenp))) { +			offset = -FDT_ERR_INTERNAL; +			break;  		} -	} while ((tag != FDT_BEGIN_NODE) && (tag != FDT_END_NODE)); +		if (_fdt_string_eq(fdt, fdt32_to_cpu(prop->nameoff), +				   name, namelen)) +			return prop; +	} -	err = -FDT_ERR_NOTFOUND; - fail:  	if (lenp) -		*lenp = err; +		*lenp = offset;  	return NULL;  } -const void *fdt_getprop(const void *fdt, int nodeoffset, -		  const char *name, int *lenp) +const struct fdt_property *fdt_get_property(const void *fdt, +					    int nodeoffset, +					    const char *name, int *lenp) +{ +	return fdt_get_property_namelen(fdt, nodeoffset, name, +					strlen(name), lenp); +} + +const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, +				const char *name, int namelen, int *lenp)  {  	const struct fdt_property *prop; -	prop = fdt_get_property(fdt, nodeoffset, name, lenp); +	prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp);  	if (! prop)  		return NULL;  	return prop->data;  } +const void *fdt_getprop_by_offset(const void *fdt, int offset, +				  const char **namep, int *lenp) +{ +	const struct fdt_property *prop; + +	prop = fdt_get_property_by_offset(fdt, offset, lenp); +	if (!prop) +		return NULL; +	if (namep) +		*namep = fdt_string(fdt, fdt32_to_cpu(prop->nameoff)); +	return prop->data; +} + +const void *fdt_getprop(const void *fdt, int nodeoffset, +			const char *name, int *lenp) +{ +	return fdt_getprop_namelen(fdt, nodeoffset, name, strlen(name), lenp); +} +  uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)  {  	const uint32_t *php;  	int len; -	php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len); -	if (!php || (len != sizeof(*php))) -		return 0; +	/* FIXME: This is a bit sub-optimal, since we potentially scan +	 * over all the properties twice. */ +	php = fdt_getprop(fdt, nodeoffset, "phandle", &len); +	if (!php || (len != sizeof(*php))) { +		php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len); +		if (!php || (len != sizeof(*php))) +			return 0; +	}  	return fdt32_to_cpu(*php);  } +const char *fdt_get_alias_namelen(const void *fdt, +				  const char *name, int namelen) +{ +	int aliasoffset; + +	aliasoffset = fdt_path_offset(fdt, "/aliases"); +	if (aliasoffset < 0) +		return NULL; + +	return fdt_getprop_namelen(fdt, aliasoffset, name, namelen, NULL); +} + +const char *fdt_get_alias(const void *fdt, const char *name) +{ +	return fdt_get_alias_namelen(fdt, name, strlen(name)); +} +  int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)  {  	int pdepth = 0, p = 0; @@ -279,9 +368,6 @@ int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)  	for (offset = 0, depth = 0;  	     (offset >= 0) && (offset <= nodeoffset);  	     offset = fdt_next_node(fdt, offset, &depth)) { -		if (pdepth < depth) -			continue; /* overflowed buffer */ -  		while (pdepth > depth) {  			do {  				p--; @@ -289,14 +375,16 @@ int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)  			pdepth--;  		} -		name = fdt_get_name(fdt, offset, &namelen); -		if (!name) -			return namelen; -		if ((p + namelen + 1) <= buflen) { -			memcpy(buf + p, name, namelen); -			p += namelen; -			buf[p++] = '/'; -			pdepth++; +		if (pdepth >= depth) { +			name = fdt_get_name(fdt, offset, &namelen); +			if (!name) +				return namelen; +			if ((p + namelen + 1) <= buflen) { +				memcpy(buf + p, name, namelen); +				p += namelen; +				buf[p++] = '/'; +				pdepth++; +			}  		}  		if (offset == nodeoffset) { @@ -306,7 +394,7 @@ int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)  			if (p > 1) /* special case so that root path is "/", not "" */  				p--;  			buf[p] = '\0'; -			return p; +			return 0;  		}  	} @@ -404,14 +492,31 @@ int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,  int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)  { +	int offset; +  	if ((phandle == 0) || (phandle == -1))  		return -FDT_ERR_BADPHANDLE; -	phandle = cpu_to_fdt32(phandle); -	return fdt_node_offset_by_prop_value(fdt, -1, "linux,phandle", -					     &phandle, sizeof(phandle)); + +	FDT_CHECK_HEADER(fdt); + +	/* FIXME: The algorithm here is pretty horrible: we +	 * potentially scan each property of a node in +	 * fdt_get_phandle(), then if that didn't find what +	 * we want, we scan over them again making our way to the next +	 * node.  Still it's the easiest to implement approach; +	 * performance can come later. */ +	for (offset = fdt_next_node(fdt, -1, NULL); +	     offset >= 0; +	     offset = fdt_next_node(fdt, offset, NULL)) { +		if (fdt_get_phandle(fdt, offset) == phandle) +			return offset; +	} + +	return offset; /* error from fdt_next_node() */  } -static int _stringlist_contains(const char *strlist, int listlen, const char *str) +static int _fdt_stringlist_contains(const char *strlist, int listlen, +				    const char *str)  {  	int len = strlen(str);  	const char *p; @@ -437,7 +542,7 @@ int fdt_node_check_compatible(const void *fdt, int nodeoffset,  	prop = fdt_getprop(fdt, nodeoffset, "compatible", &len);  	if (!prop)  		return len; -	if (_stringlist_contains(prop, len, compatible)) +	if (_fdt_stringlist_contains(prop, len, compatible))  		return 0;  	else  		return 1; diff --git a/scripts/dtc/libfdt/fdt_rw.c b/scripts/dtc/libfdt/fdt_rw.c index 8e7ec4cb7bc..24437dfc32b 100644 --- a/scripts/dtc/libfdt/fdt_rw.c +++ b/scripts/dtc/libfdt/fdt_rw.c @@ -289,6 +289,33 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,  	return 0;  } +int fdt_appendprop(void *fdt, int nodeoffset, const char *name, +		   const void *val, int len) +{ +	struct fdt_property *prop; +	int err, oldlen, newlen; + +	FDT_RW_CHECK_HEADER(fdt); + +	prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen); +	if (prop) { +		newlen = len + oldlen; +		err = _fdt_splice_struct(fdt, prop->data, +					 FDT_TAGALIGN(oldlen), +					 FDT_TAGALIGN(newlen)); +		if (err) +			return err; +		prop->len = cpu_to_fdt32(newlen); +		memcpy(prop->data + oldlen, val, len); +	} else { +		err = _fdt_add_property(fdt, nodeoffset, name, len, &prop); +		if (err) +			return err; +		memcpy(prop->data, val, len); +	} +	return 0; +} +  int fdt_delprop(void *fdt, int nodeoffset, const char *name)  {  	struct fdt_property *prop; @@ -406,6 +433,8 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)  		struct_size = 0;  		while (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END)  			; +		if (struct_size < 0) +			return struct_size;  	}  	if (!_fdt_blocks_misordered(fdt, mem_rsv_size, struct_size)) { diff --git a/scripts/dtc/libfdt/fdt_sw.c b/scripts/dtc/libfdt/fdt_sw.c index 698329e0cca..55ebebf1eb2 100644 --- a/scripts/dtc/libfdt/fdt_sw.c +++ b/scripts/dtc/libfdt/fdt_sw.c @@ -70,7 +70,7 @@ static int _fdt_sw_check_header(void *fdt)  			return err; \  	} -static void *_fdt_grab_space(void *fdt, int len) +static void *_fdt_grab_space(void *fdt, size_t len)  {  	int offset = fdt_size_dt_struct(fdt);  	int spaceleft; @@ -82,7 +82,7 @@ static void *_fdt_grab_space(void *fdt, int len)  		return NULL;  	fdt_set_size_dt_struct(fdt, offset + len); -	return fdt_offset_ptr_w(fdt, offset, len); +	return _fdt_offset_ptr_w(fdt, offset);  }  int fdt_create(void *buf, int bufsize) @@ -237,18 +237,17 @@ int fdt_finish(void *fdt)  	while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) {  		if (tag == FDT_PROP) {  			struct fdt_property *prop = -				fdt_offset_ptr_w(fdt, offset, sizeof(*prop)); +				_fdt_offset_ptr_w(fdt, offset);  			int nameoff; -			if (! prop) -				return -FDT_ERR_BADSTRUCTURE; -  			nameoff = fdt32_to_cpu(prop->nameoff);  			nameoff += fdt_size_dt_strings(fdt);  			prop->nameoff = cpu_to_fdt32(nameoff);  		}  		offset = nextoffset;  	} +	if (nextoffset < 0) +		return nextoffset;  	/* Finally, adjust the header */  	fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt)); diff --git a/scripts/dtc/libfdt/fdt_wip.c b/scripts/dtc/libfdt/fdt_wip.c index a4652c6e787..6025fa1fe8f 100644 --- a/scripts/dtc/libfdt/fdt_wip.c +++ b/scripts/dtc/libfdt/fdt_wip.c @@ -94,41 +94,14 @@ int fdt_nop_property(void *fdt, int nodeoffset, const char *name)  	return 0;  } -int _fdt_node_end_offset(void *fdt, int nodeoffset) +int _fdt_node_end_offset(void *fdt, int offset)  { -	int level = 0; -	uint32_t tag; -	int offset, nextoffset; - -	tag = fdt_next_tag(fdt, nodeoffset, &nextoffset); -	if (tag != FDT_BEGIN_NODE) -		return -FDT_ERR_BADOFFSET; -	do { -		offset = nextoffset; -		tag = fdt_next_tag(fdt, offset, &nextoffset); - -		switch (tag) { -		case FDT_END: -			return offset; - -		case FDT_BEGIN_NODE: -			level++; -			break; - -		case FDT_END_NODE: -			level--; -			break; - -		case FDT_PROP: -		case FDT_NOP: -			break; - -		default: -			return -FDT_ERR_BADSTRUCTURE; -		} -	} while (level >= 0); - -	return nextoffset; +	int depth = 0; + +	while ((offset >= 0) && (depth >= 0)) +		offset = fdt_next_node(fdt, offset, &depth); + +	return offset;  }  int fdt_nop_node(void *fdt, int nodeoffset) diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h index ce80e4fb41b..73f49759a5e 100644 --- a/scripts/dtc/libfdt/libfdt.h +++ b/scripts/dtc/libfdt/libfdt.h @@ -122,7 +122,7 @@  /* Low-level functions (you probably don't need these)                */  /**********************************************************************/ -const void *fdt_offset_ptr(const void *fdt, int offset, int checklen); +const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int checklen);  static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen)  {  	return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen); @@ -156,7 +156,7 @@ int fdt_next_node(const void *fdt, int offset, int *depth);  #define __fdt_set_hdr(name) \  	static inline void fdt_set_##name(void *fdt, uint32_t val) \  	{ \ -		struct fdt_header *fdth = fdt; \ +		struct fdt_header *fdth = (struct fdt_header*)fdt; \  		fdth->name = cpu_to_fdt32(val); \  	}  __fdt_set_hdr(magic); @@ -343,6 +343,91 @@ int fdt_path_offset(const void *fdt, const char *path);  const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp);  /** + * fdt_first_property_offset - find the offset of a node's first property + * @fdt: pointer to the device tree blob + * @nodeoffset: structure block offset of a node + * + * fdt_first_property_offset() finds the first property of the node at + * the given structure block offset. + * + * returns: + *	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_BADVERSION, + *	-FDT_ERR_BADSTATE, + *	-FDT_ERR_BADSTRUCTURE, + *	-FDT_ERR_TRUNCATED, standard meanings. + */ +int fdt_first_property_offset(const void *fdt, int nodeoffset); + +/** + * fdt_next_property_offset - step through a node's properties + * @fdt: pointer to the device tree blob + * @offset: structure block offset of a property + * + * fdt_next_property_offset() finds the property immediately after the + * one at the given structure block offset.  This will be a property + * of the same node as the given property. + * + * returns: + *	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_BADVERSION, + *	-FDT_ERR_BADSTATE, + *	-FDT_ERR_BADSTRUCTURE, + *	-FDT_ERR_TRUNCATED, standard meanings. + */ +int fdt_next_property_offset(const void *fdt, int offset); + +/** + * fdt_get_property_by_offset - retrieve the property at a given offset + * @fdt: pointer to the device tree blob + * @offset: offset of the property to retrieve + * @lenp: pointer to an integer variable (will be overwritten) or NULL + * + * fdt_get_property_by_offset() retrieves a pointer to the + * fdt_property structure within the device tree blob at the given + * offset.  If lenp is non-NULL, the length of the property value is + * also returned, in the integer pointed to by lenp. + * + * returns: + *	pointer to the structure representing the property + *		if lenp is non-NULL, *lenp contains the length of the property + *		value (>=0) + *	NULL, on error + *		if lenp is non-NULL, *lenp contains an error code (<0): + *		-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag + *		-FDT_ERR_BADMAGIC, + *		-FDT_ERR_BADVERSION, + *		-FDT_ERR_BADSTATE, + *		-FDT_ERR_BADSTRUCTURE, + *		-FDT_ERR_TRUNCATED, standard meanings + */ +const struct fdt_property *fdt_get_property_by_offset(const void *fdt, +						      int offset, +						      int *lenp); + +/** + * fdt_get_property_namelen - find a property based on substring + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to find + * @name: name of the property to find + * @namelen: number of characters of name to consider + * @lenp: pointer to an integer variable (will be overwritten) or NULL + * + * Identical to fdt_get_property_namelen(), but only examine the first + * namelen characters of name for matching the property name. + */ +const struct fdt_property *fdt_get_property_namelen(const void *fdt, +						    int nodeoffset, +						    const char *name, +						    int namelen, int *lenp); + +/**   * fdt_get_property - find a given property in a given node   * @fdt: pointer to the device tree blob   * @nodeoffset: offset of the node whose property to find @@ -380,6 +465,54 @@ static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,  }  /** + * fdt_getprop_by_offset - retrieve the value of a property at a given offset + * @fdt: pointer to the device tree blob + * @ffset: offset of the property to read + * @namep: pointer to a string variable (will be overwritten) or NULL + * @lenp: pointer to an integer variable (will be overwritten) or NULL + * + * fdt_getprop_by_offset() retrieves a pointer to the value of the + * property at structure block offset 'offset' (this will be a pointer + * 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 + * by namep (this will be a pointer to within the device tree's string + * block, not a new copy of the name). + * + * returns: + *	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 + *		name. + *	NULL, on error + *		if lenp is non-NULL, *lenp contains an error code (<0): + *		-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag + *		-FDT_ERR_BADMAGIC, + *		-FDT_ERR_BADVERSION, + *		-FDT_ERR_BADSTATE, + *		-FDT_ERR_BADSTRUCTURE, + *		-FDT_ERR_TRUNCATED, standard meanings + */ +const void *fdt_getprop_by_offset(const void *fdt, int offset, +				  const char **namep, int *lenp); + +/** + * fdt_getprop_namelen - get property value based on substring + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to find + * @name: name of the property to find + * @namelen: number of characters of name to consider + * @lenp: pointer to an integer variable (will be overwritten) or NULL + * + * Identical to fdt_getprop(), but only examine the first namelen + * characters of name for matching the property name. + */ +const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, +				const char *name, int namelen, int *lenp); + +/**   * fdt_getprop - retrieve the value of a given property   * @fdt: pointer to the device tree blob   * @nodeoffset: offset of the node whose property to find @@ -429,6 +562,32 @@ static inline void *fdt_getprop_w(void *fdt, int nodeoffset,  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 + * @namelen: number of characters of name to consider + * + * Identical to fdt_get_alias(), but only examine the first namelen + * characters of name for matching the alias name. + */ +const char *fdt_get_alias_namelen(const void *fdt, +				  const char *name, int namelen); + +/** + * fdt_get_alias - retreive the path referenced by a given alias + * @fdt: pointer to the device tree blob + * @name: name of the alias th 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. + * + * returns: + *	a pointer to the expansion of the alias named 'name', of it exists + *	NULL, if the given alias or the /aliases node does not exist + */ +const char *fdt_get_alias(const void *fdt, const char *name); + +/**   * fdt_get_path - determine the full path of a node   * @fdt: pointer to the device tree blob   * @nodeoffset: offset of the node whose path to find @@ -693,17 +852,17 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,  			const void *val, int len);  /** - * fdt_setprop_inplace_cell - change the value of a single-cell property + * fdt_setprop_inplace_u32 - change the value of a 32-bit integer property   * @fdt: pointer to the device tree blob   * @nodeoffset: offset of the node whose property to change   * @name: name of the property to change - * @val: cell (32-bit integer) value to replace the property with + * @val: 32-bit integer value to replace the property with   * - * fdt_setprop_inplace_cell() replaces the value of a given property - * with the 32-bit integer cell value in val, converting val to - * big-endian if necessary.  This function cannot change the size of a - * property, and so will only work if the property already exists and - * has length 4. + * fdt_setprop_inplace_u32() replaces the value of a given property + * with the 32-bit integer value in val, converting val to big-endian + * if necessary.  This function cannot change the size of a property, + * and so will only work if the property already exists and has length + * 4.   *   * This function will alter only the bytes in the blob which contain   * the given property value, and will not alter or move any other part @@ -712,7 +871,7 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,   * returns:   *	0, on success   *	-FDT_ERR_NOSPACE, if the property's length is not equal to 4 -  *	-FDT_ERR_NOTFOUND, node does not have the named property + *	-FDT_ERR_NOTFOUND, node does not have the named property   *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag   *	-FDT_ERR_BADMAGIC,   *	-FDT_ERR_BADVERSION, @@ -720,14 +879,60 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,   *	-FDT_ERR_BADSTRUCTURE,   *	-FDT_ERR_TRUNCATED, standard meanings   */ -static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset, -					   const char *name, uint32_t val) +static inline int fdt_setprop_inplace_u32(void *fdt, int nodeoffset, +					  const char *name, uint32_t val)  {  	val = cpu_to_fdt32(val);  	return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val));  }  /** + * fdt_setprop_inplace_u64 - change the value of a 64-bit integer property + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to change + * @name: name of the property to change + * @val: 64-bit integer value to replace the property with + * + * fdt_setprop_inplace_u64() replaces the value of a given property + * with the 64-bit integer value in val, converting val to big-endian + * if necessary.  This function cannot change the size of a property, + * and so will only work if the property already exists and has length + * 8. + * + * This function will alter only the bytes in the blob which contain + * the given property value, and will not alter or move any other part + * of the tree. + * + * returns: + *	0, on success + *	-FDT_ERR_NOSPACE, if the property's length is not equal to 8 + *	-FDT_ERR_NOTFOUND, node does not have the named property + *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + *	-FDT_ERR_BADMAGIC, + *	-FDT_ERR_BADVERSION, + *	-FDT_ERR_BADSTATE, + *	-FDT_ERR_BADSTRUCTURE, + *	-FDT_ERR_TRUNCATED, standard meanings + */ +static inline int fdt_setprop_inplace_u64(void *fdt, int nodeoffset, +					  const char *name, uint64_t val) +{ +	val = cpu_to_fdt64(val); +	return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val)); +} + +/** + * fdt_setprop_inplace_cell - change the value of a single-cell property + * + * This is an alternative name for fdt_setprop_inplace_u32() + */ +static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset, +					   const char *name, uint32_t val) +{ +	return fdt_setprop_inplace_u32(fdt, nodeoffset, name, val); +} + +/**   * fdt_nop_property - replace a property with nop tags   * @fdt: pointer to the device tree blob   * @nodeoffset: offset of the node whose property to nop @@ -786,11 +991,20 @@ int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size);  int fdt_finish_reservemap(void *fdt);  int fdt_begin_node(void *fdt, const char *name);  int fdt_property(void *fdt, const char *name, const void *val, int len); -static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val) +static inline int fdt_property_u32(void *fdt, const char *name, uint32_t val)  {  	val = cpu_to_fdt32(val);  	return fdt_property(fdt, name, &val, sizeof(val));  } +static inline int fdt_property_u64(void *fdt, const char *name, uint64_t val) +{ +	val = cpu_to_fdt64(val); +	return fdt_property(fdt, name, &val, sizeof(val)); +} +static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val) +{ +	return fdt_property_u32(fdt, name, val); +}  #define fdt_property_string(fdt, name, str) \  	fdt_property(fdt, name, str, strlen(str)+1)  int fdt_end_node(void *fdt); @@ -800,6 +1014,7 @@ int fdt_finish(void *fdt);  /* Read-write functions                                               */  /**********************************************************************/ +int fdt_create_empty_tree(void *buf, int bufsize);  int fdt_open_into(const void *fdt, void *buf, int bufsize);  int fdt_pack(void *fdt); @@ -909,14 +1124,14 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,  		const void *val, int len);  /** - * fdt_setprop_cell - set a property to a single cell value + * fdt_setprop_u32 - set a property to a 32-bit integer   * @fdt: pointer to the device tree blob   * @nodeoffset: offset of the node whose property to change   * @name: name of the property to change   * @val: 32-bit integer value for the property (native endian)   * - * fdt_setprop_cell() sets the value of the named property in the - * given node to the given cell value (converting to big-endian if + * fdt_setprop_u32() sets the value of the named property in the given + * node to the given 32-bit integer value (converting to big-endian if   * necessary), or creates a new property with that value if it does   * not already exist.   * @@ -936,14 +1151,60 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,   *	-FDT_ERR_BADLAYOUT,   *	-FDT_ERR_TRUNCATED, standard meanings   */ -static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name, -				   uint32_t val) +static inline int fdt_setprop_u32(void *fdt, int nodeoffset, const char *name, +				  uint32_t val)  {  	val = cpu_to_fdt32(val);  	return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val));  }  /** + * fdt_setprop_u64 - set a property to a 64-bit integer + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to change + * @name: name of the property to change + * @val: 64-bit integer value for the property (native endian) + * + * fdt_setprop_u64() sets the value of the named property in the given + * node to the given 64-bit integer value (converting to big-endian if + * necessary), 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 + */ +static inline int fdt_setprop_u64(void *fdt, int nodeoffset, const char *name, +				  uint64_t val) +{ +	val = cpu_to_fdt64(val); +	return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val)); +} + +/** + * fdt_setprop_cell - set a property to a single cell value + * + * This is an alternative name for fdt_setprop_u32() + */ +static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name, +				   uint32_t val) +{ +	return fdt_setprop_u32(fdt, nodeoffset, name, val); +} + +/**   * fdt_setprop_string - set a property to a string value   * @fdt: pointer to the device tree blob   * @nodeoffset: offset of the node whose property to change @@ -975,6 +1236,147 @@ static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,  	fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)  /** + * fdt_appendprop - append to or create a property + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to change + * @name: name of the property to append to + * @val: pointer to data to append to the property value + * @len: length of the data to append to the property value + * + * fdt_appendprop() appends the value to the named property in the + * given node, creating the property if it does not already exist. + * + * This function may insert data into 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_appendprop(void *fdt, int nodeoffset, const char *name, +		   const void *val, int len); + +/** + * fdt_appendprop_u32 - append a 32-bit integer value to 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 + * @val: 32-bit integer value to append to the property (native endian) + * + * fdt_appendprop_u32() appends the given 32-bit integer value + * (converting to big-endian if necessary) to the value of the named + * property in the given node, or creates a new property with that + * value if it does not already exist. + * + * This function may insert data into 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 + */ +static inline int fdt_appendprop_u32(void *fdt, int nodeoffset, +				     const char *name, uint32_t val) +{ +	val = cpu_to_fdt32(val); +	return fdt_appendprop(fdt, nodeoffset, name, &val, sizeof(val)); +} + +/** + * fdt_appendprop_u64 - append a 64-bit integer value to 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 + * @val: 64-bit integer value to append to the property (native endian) + * + * fdt_appendprop_u64() appends the given 64-bit integer value + * (converting to big-endian if necessary) to the value of the named + * property in the given node, or creates a new property with that + * value if it does not already exist. + * + * This function may insert data into 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 + */ +static inline int fdt_appendprop_u64(void *fdt, int nodeoffset, +				     const char *name, uint64_t val) +{ +	val = cpu_to_fdt64(val); +	return fdt_appendprop(fdt, nodeoffset, name, &val, sizeof(val)); +} + +/** + * fdt_appendprop_cell - append a single cell value to a property + * + * This is an alternative name for fdt_appendprop_u32() + */ +static inline int fdt_appendprop_cell(void *fdt, int nodeoffset, +				      const char *name, uint32_t val) +{ +	return fdt_appendprop_u32(fdt, nodeoffset, name, val); +} + +/** + * fdt_appendprop_string - append a string to 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 + * @str: string value to append to the property + * + * fdt_appendprop_string() appends the given string to the value of + * the named property in the given node, or creates a new property + * with that value if it does not already exist. + * + * This function may insert data into 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_appendprop_string(fdt, nodeoffset, name, str) \ +	fdt_appendprop((fdt), (nodeoffset), (name), (str), strlen(str)+1) + +/**   * fdt_delprop - delete a property   * @fdt: pointer to the device tree blob   * @nodeoffset: offset of the node whose property to nop diff --git a/scripts/dtc/libfdt/libfdt_env.h b/scripts/dtc/libfdt/libfdt_env.h index 449bf602daf..213d7fb81c4 100644 --- a/scripts/dtc/libfdt/libfdt_env.h +++ b/scripts/dtc/libfdt/libfdt_env.h @@ -5,19 +5,25 @@  #include <stdint.h>  #include <string.h> -#define _B(n)	((unsigned long long)((uint8_t *)&x)[n]) +#define EXTRACT_BYTE(n)	((unsigned long long)((uint8_t *)&x)[n]) +static inline uint16_t fdt16_to_cpu(uint16_t x) +{ +	return (EXTRACT_BYTE(0) << 8) | EXTRACT_BYTE(1); +} +#define cpu_to_fdt16(x) fdt16_to_cpu(x) +  static inline uint32_t fdt32_to_cpu(uint32_t x)  { -	return (_B(0) << 24) | (_B(1) << 16) | (_B(2) << 8) | _B(3); +	return (EXTRACT_BYTE(0) << 24) | (EXTRACT_BYTE(1) << 16) | (EXTRACT_BYTE(2) << 8) | EXTRACT_BYTE(3);  }  #define cpu_to_fdt32(x) fdt32_to_cpu(x)  static inline uint64_t fdt64_to_cpu(uint64_t x)  { -	return (_B(0) << 56) | (_B(1) << 48) | (_B(2) << 40) | (_B(3) << 32) -		| (_B(4) << 24) | (_B(5) << 16) | (_B(6) << 8) | _B(7); +	return (EXTRACT_BYTE(0) << 56) | (EXTRACT_BYTE(1) << 48) | (EXTRACT_BYTE(2) << 40) | (EXTRACT_BYTE(3) << 32) +		| (EXTRACT_BYTE(4) << 24) | (EXTRACT_BYTE(5) << 16) | (EXTRACT_BYTE(6) << 8) | EXTRACT_BYTE(7);  }  #define cpu_to_fdt64(x) fdt64_to_cpu(x) -#undef _B +#undef EXTRACT_BYTE  #endif /* _LIBFDT_ENV_H */ diff --git a/scripts/dtc/libfdt/libfdt_internal.h b/scripts/dtc/libfdt/libfdt_internal.h index 46eb93e4af5..381133ba81d 100644 --- a/scripts/dtc/libfdt/libfdt_internal.h +++ b/scripts/dtc/libfdt/libfdt_internal.h @@ -62,8 +62,8 @@  			return err; \  	} -uint32_t _fdt_next_tag(const void *fdt, int startoffset, int *nextoffset);  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);  int _fdt_node_end_offset(void *fdt, int nodeoffset);  | 
