diff options
Diffstat (limited to 'libfdt/fdt_wip.c')
| -rw-r--r-- | libfdt/fdt_wip.c | 137 | 
1 files changed, 137 insertions, 0 deletions
diff --git a/libfdt/fdt_wip.c b/libfdt/fdt_wip.c new file mode 100644 index 000000000..2d2ed37c4 --- /dev/null +++ b/libfdt/fdt_wip.c @@ -0,0 +1,137 @@ +/* + * 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_setprop_inplace(void *fdt, int nodeoffset, const char *name, +			const void *val, int len) +{ +	void *propval; +	int proplen; + +	propval = fdt_getprop(fdt, nodeoffset, name, &proplen); +	if (! propval) +		return proplen; + +	if (proplen != len) +		return -FDT_ERR_NOSPACE; + +	memcpy(propval, val, len); +	return 0; +} + +static void nop_region(void *start, int len) +{ +	uint32_t *p; + +	for (p = start; (void *)p < (start + len); p++) +		*p = cpu_to_fdt32(FDT_NOP); +} + +int fdt_nop_property(void *fdt, int nodeoffset, const char *name) +{ +	struct fdt_property *prop; +	int len; + +	prop = fdt_get_property(fdt, nodeoffset, name, &len); +	if (! prop) +		return len; + +	nop_region(prop, len + sizeof(*prop)); + +	return 0; +} + +int _fdt_node_end_offset(void *fdt, int nodeoffset) +{ +	int level = 0; +	uint32_t tag; +	int offset, nextoffset; + +	tag = fdt_next_tag(fdt, nodeoffset, &nextoffset, NULL); +	if (tag != FDT_BEGIN_NODE) +		return -FDT_ERR_BADOFFSET; +	do { +		offset = nextoffset; +		tag = fdt_next_tag(fdt, offset, &nextoffset, NULL); + +		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 fdt_nop_node(void *fdt, int nodeoffset) +{ +	int endoffset; + +	endoffset = _fdt_node_end_offset(fdt, nodeoffset); +	if (endoffset < 0) +		return endoffset; + +	nop_region(fdt_offset_ptr(fdt, nodeoffset, 0), endoffset - nodeoffset); +	return 0; +} + +/* + * Replace a reserve map entry in the nth slot. + */ +int fdt_replace_reservemap_entry(void *fdt, int n, uint64_t addr, uint64_t size) +{ +	struct fdt_reserve_entry *re; +	int  used; +	int  total; +	int  err; + +	err = fdt_num_reservemap(fdt, &used, &total); +	if (err != 0) +		return err; + +	if (n >= total) +		return -FDT_ERR_NOSPACE; +	re = (struct fdt_reserve_entry *) +		(fdt + fdt_off_mem_rsvmap(fdt) + +		 (n * sizeof(struct fdt_reserve_entry))); +	re->address = cpu_to_fdt64(addr); +	re->size    = cpu_to_fdt64(size); + +	return 0; +}  |