/* Copyright 2013-2014 IBM Corp.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <skiboot.h>
#include <stdarg.h>
#include <libfdt.h>
#include <device.h>
#include <cpu.h>
#include <opal.h>
#include <interrupts.h>
#include <fsp.h>
#include <cec.h>
#include <vpd.h>
#include <ccan/str/str.h>

static int fdt_error;

#undef DEBUG_FDT
#ifdef DEBUG_FDT
#define FDT_DBG(fmt, a...)	prlog(PR_DEBUG, "FDT: " fmt, ##a)
#else
#define FDT_DBG(fmt, a...)
#endif

static void __save_err(int err, const char *str)
{
	FDT_DBG("rc: %d from \"%s\"\n", err, str);
	if (err && !fdt_error) {
		prerror("FDT: Error %d from \"%s\"\n", err, str);
		fdt_error = err;
	}
}

#define save_err(...) __save_err(__VA_ARGS__, #__VA_ARGS__)

static void dt_property_cell(void *fdt, const char *name, u32 cell)
{
	save_err(fdt_property_cell(fdt, name, cell));
}

static void dt_begin_node(void *fdt, const struct dt_node *dn)
{
	save_err(fdt_begin_node(fdt, dn->name));

	dt_property_cell(fdt, "phandle", dn->phandle);
}

static void dt_property(void *fdt, const struct dt_property *p)
{
	save_err(fdt_property(fdt, p->name, p->prop, p->len));
}

static void dt_end_node(void *fdt)
{
	save_err(fdt_end_node(fdt));
}

#ifdef DEBUG_FDT
static void dump_fdt(void *fdt)
{
	int i, off, depth, err;

	prlog(PR_INFO, "Device tree %u@%p\n", fdt_totalsize(fdt), fdt);
	err = fdt_check_header(fdt);
	if (err) {
		prerror("fdt_check_header: %s\n", fdt_strerror(err));
		return;
	}
	prlog(PR_INFO, "fdt_check_header passed\n");

	prlog(PR_INFO, "fdt_num_mem_rsv = %u\n", fdt_num_mem_rsv(fdt));
	for (i = 0; i < fdt_num_mem_rsv(fdt); i++) {
		u64 addr, size;

		err = fdt_get_mem_rsv(fdt, i, &addr, &size);
		if (err) {
			prlog(PR_INFO, " ERR %s\n", fdt_strerror(err));
			return;
		}
		prlog(PR_INFO, "  mem_rsv[%i] = %lu@%#lx\n",
		      i, (long)addr, (long)size);
	}

	for (off = fdt_next_node(fdt, 0, &depth);
	     off > 0;
	     off = fdt_next_node(fdt, off, &depth)) {
		int len;
		const char *name;

		name = fdt_get_name(fdt, off, &len);
		if (!name) {
			prerror("fdt: offset %i no name!\n", off);
			return;
		}
		prlog(PR_INFO, "name: %s [%u]\n", name, off);
	}
}
#else
static inline void dump_fdt(void *fdt __unused) { }
#endif

static void flatten_dt_properties(void *fdt, const struct dt_node *dn)
{
	const struct dt_property *p;

	list_for_each(&dn->properties, p, list) {
		if (strstarts(p->name, DT_PRIVATE))
			continue;

		FDT_DBG("  prop: %s size: %ld\n", p->name, p->len);
		dt_property(fdt, p);
	}
}

static void flatten_dt_node(void *fdt, const struct dt_node *root,
			    bool exclusive)
{
	const struct dt_node *i;

	if (!exclusive) {
		FDT_DBG("node: %s\n", root->name);
		dt_begin_node(fdt, root);
		flatten_dt_properties(fdt, root);
	}

	list_for_each(&root->children, i, list)
		flatten_dt_node(fdt, i, false);

	if (!exclusive)
		dt_end_node(fdt);
}

static void create_dtb_reservemap(void *fdt, const struct dt_node *root)
{
	uint64_t base, size;
	const uint64_t *ranges;
	const struct dt_property *prop;
	int i;

	/* Duplicate the reserved-ranges property into the fdt reservemap */
	prop = dt_find_property(root, "reserved-ranges");
	if (prop) {
		ranges = (const void *)prop->prop;

		for (i = 0; i < prop->len / (sizeof(uint64_t) * 2); i++) {
			base = *(ranges++);
			size = *(ranges++);
			save_err(fdt_add_reservemap_entry(fdt, base, size));
		}
	}

	save_err(fdt_finish_reservemap(fdt));
}

static int __create_dtb(void *fdt, size_t len,
			const struct dt_node *root,
			bool exclusive)
{
	fdt_create(fdt, len);
	if (root == dt_root && !exclusive)
		create_dtb_reservemap(fdt, root);
	else
		fdt_finish_reservemap(fdt);

	flatten_dt_node(fdt, root, exclusive);

	save_err(fdt_finish(fdt));
	if (fdt_error) {
		prerror("dtb: error %s\n", fdt_strerror(fdt_error));
		return fdt_error;
	}

	dump_fdt(fdt);
	return 0;
}

void *create_dtb(const struct dt_node *root, bool exclusive)
{
	void *fdt = NULL;
	size_t len = DEVICE_TREE_MAX_SIZE;
	uint32_t old_last_phandle = get_last_phandle();
	int ret;

	do {
		set_last_phandle(old_last_phandle);
		fdt_error = 0;
		fdt = malloc(len);
		if (!fdt) {
			prerror("dtb: could not malloc %lu\n", (long)len);
			return NULL;
		}

		ret = __create_dtb(fdt, len, root, exclusive);
		if (ret) {
			free(fdt);
			fdt = NULL;
		}

		len *= 2;
	} while (ret == -FDT_ERR_NOSPACE);

	return fdt;
}

static int64_t opal_get_device_tree(uint32_t phandle,
				    uint64_t buf, uint64_t len)
{
	struct dt_node *root;
	void *fdt = (void *)buf;
	uint32_t old_last_phandle;
	int64_t totalsize;
	int ret;

	if (!opal_addr_valid(fdt))
		return OPAL_PARAMETER;

	root = dt_find_by_phandle(dt_root, phandle);
	if (!root)
		return OPAL_PARAMETER;

	if (!fdt) {
		fdt = create_dtb(root, true);
		if (!fdt)
			return OPAL_INTERNAL_ERROR;
		totalsize = fdt_totalsize(fdt);
		free(fdt);
		return totalsize;
	}

	if (!len)
		return OPAL_PARAMETER;

	fdt_error = 0;
	old_last_phandle = get_last_phandle();
	ret = __create_dtb(fdt, len, root, true);
	if (ret) {
		set_last_phandle(old_last_phandle);
		if (ret == -FDT_ERR_NOSPACE)
			return OPAL_NO_MEM;

		return OPAL_EMPTY;
	}

	return OPAL_SUCCESS;
}
opal_call(OPAL_GET_DEVICE_TREE, opal_get_device_tree, 3);
