/*
 * 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 struct fdt_header *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 (sw_size_dt_struct(fdt) == 0)
			return FDT_ERR_BADSTATE;
	} else {
		return FDT_ERR_BADMAGIC;
	}

	return 0;
}

void *fdt_offset_ptr(const struct fdt_header *fdt, int offset, int len)
{
	void *p;

	p = (void *)fdt + fdt_off_dt_struct(fdt) + offset;

	if (p + len < p)
		return NULL;
	return p;
}

uint32_t _fdt_next_tag(const struct fdt_header *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 + FDT_TAGSIZE, 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;
}

struct fdt_header *fdt_move(const struct fdt_header *fdt, void *buf, int bufsize)
{
	int err = _fdt_check_header(fdt);

	if (err)
		return PTR_ERROR(err);

	if (fdt_totalsize(fdt) > bufsize)
		return PTR_ERROR(FDT_ERR_NOSPACE);

	memmove(buf, fdt, fdt_totalsize(fdt));
	return (struct fdt_header *)buf;
}
