diff options
| author | Gerald Van Baren <vanbaren@cideas.com> | 2007-03-31 11:59:59 -0400 | 
|---|---|---|
| committer | Gerald Van Baren <vanbaren@cideas.com> | 2007-03-31 11:59:59 -0400 | 
| commit | 7cd5da0fe877e7171a4cdd44880bce783132871a (patch) | |
| tree | b938b97ce604e9dadca0ac683275cd8ec9b0f3a3 /libfdt/fdt.c | |
| parent | 6db7d0af2336c126e4d4b2f248cc23516bdd46a8 (diff) | |
| download | olio-uboot-2014.01-7cd5da0fe877e7171a4cdd44880bce783132871a.tar.xz olio-uboot-2014.01-7cd5da0fe877e7171a4cdd44880bce783132871a.zip | |
libfdt: Import libfdt source (1 of 2)
This adds the applicable libfdt source files (unmodified) and a README
to explain where the source came from.
Diffstat (limited to 'libfdt/fdt.c')
| -rw-r--r-- | libfdt/fdt.c | 124 | 
1 files changed, 124 insertions, 0 deletions
| diff --git a/libfdt/fdt.c b/libfdt/fdt.c new file mode 100644 index 000000000..772da46a7 --- /dev/null +++ b/libfdt/fdt.c @@ -0,0 +1,124 @@ +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2006 David Gibson, IBM Corporation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + */ +#include "libfdt_env.h" + +#include <fdt.h> +#include <libfdt.h> + +#include "libfdt_internal.h" + +int _fdt_check_header(const void *fdt) +{ +	if (fdt_magic(fdt) == FDT_MAGIC) { +		/* Complete tree */ +		if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION) +			return -FDT_ERR_BADVERSION; +		if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION) +			return -FDT_ERR_BADVERSION; +	} else if (fdt_magic(fdt) == SW_MAGIC) { +		/* Unfinished sequential-write blob */ +		if (fdt_size_dt_struct(fdt) == 0) +			return -FDT_ERR_BADSTATE; +	} else { +		return -FDT_ERR_BADMAGIC; +	} + +	return 0; +} + +void *fdt_offset_ptr(const void *fdt, int offset, int len) +{ +	void *p; + +	if (fdt_version(fdt) >= 0x11) +		if (((offset + len) < offset) +		    || ((offset + len) > fdt_size_dt_struct(fdt))) +			return NULL; + +	p = _fdt_offset_ptr(fdt, offset); + +	if (p + len < p) +		return NULL; +	return p; +} + +uint32_t _fdt_next_tag(const void *fdt, int offset, int *nextoffset) +{ +	const uint32_t *tagp, *lenp; +	uint32_t tag; +	const char *p; + +	if (offset % FDT_TAGSIZE) +		return -1; + +	tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE); +	if (! tagp) +		return FDT_END; /* premature end */ +	tag = fdt32_to_cpu(*tagp); +	offset += FDT_TAGSIZE; + +	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; +		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); +		break; +	} + +	if (nextoffset) +		*nextoffset = ALIGN(offset, FDT_TAGSIZE); + +	return tag; +} + +const char *_fdt_find_string(const char *strtab, int tabsize, const char *s) +{ +	int len = strlen(s) + 1; +	const char *last = strtab + tabsize - len; +	const char *p; + +	for (p = strtab; p <= last; p++) +		if (memeq(p, s, len)) +			return p; +	return NULL; +} + +int fdt_move(const void *fdt, void *buf, int bufsize) +{ +	int err = _fdt_check_header(fdt); + +	if (err) +		return err; + +	if (fdt_totalsize(fdt) > bufsize) +		return -FDT_ERR_NOSPACE; + +	memmove(buf, fdt, fdt_totalsize(fdt)); +	return 0; +} |