// SPDX-License-Identifier: LGPL-2.1-or-later
/*
 * libfdt - Flat Device Tree manipulation
 *	Testcase for DT overlays()
 * Copyright (C) 2016 Free Electrons
 * Copyright (C) 2016 NextThing Co.
 */

#include <stdio.h>

#include <libfdt.h>

#include "tests.h"

#define CHECK(code) \
	{ \
		int err = (code); \
		if (err) \
			FAIL(#code ": %s", fdt_strerror(err)); \
	}

/* 4k ought to be enough for anybody */
#define FDT_COPY_SIZE	(4 * 1024)

static int fdt_getprop_u32_by_poffset(void *fdt, const char *path,
				      const char *name, int poffset,
				      unsigned long *out)
{
	const fdt32_t *val;
	int node_off;
	int len;

	node_off = fdt_path_offset(fdt, path);
	if (node_off < 0)
		return node_off;

	val = fdt_getprop(fdt, node_off, name, &len);
	if (val && len < 0)
		FAIL("fdt_getprop() returns negative length");
	if (!val && len < 0)
		return len;
	if (!val || ((unsigned)len < (sizeof(uint32_t) * (poffset + 1))))
		return -FDT_ERR_NOTFOUND;

	*out = fdt32_to_cpu(*(val + poffset));

	return 0;
}

static int check_getprop_string_by_name(void *fdt, const char *path,
					const char *name, const char *val)
{
	int node_off;

	node_off = fdt_path_offset(fdt, path);
	if (node_off < 0)
		return node_off;

	check_getprop_string(fdt, node_off, name, val);

	return 0;
}

static int check_getprop_u32_by_name(void *fdt, const char *path,
				     const char *name, uint32_t val)
{
	int node_off;

	node_off = fdt_path_offset(fdt, path);
	CHECK(node_off < 0);

	check_getprop_cell(fdt, node_off, name, val);

	return 0;
}

static int check_getprop_null_by_name(void *fdt, const char *path,
				      const char *name)
{
	int node_off;

	node_off = fdt_path_offset(fdt, path);
	CHECK(node_off < 0);

	check_property(fdt, node_off, name, 0, NULL);

	return 0;
}

static int fdt_overlay_change_int_property(void *fdt)
{
	return check_getprop_u32_by_name(fdt, "/test-node", "test-int-property",
					 43);
}

static int fdt_overlay_change_str_property(void *fdt)
{
	return check_getprop_string_by_name(fdt, "/test-node",
					    "test-str-property", "foobar");
}

static int fdt_overlay_add_str_property(void *fdt)
{
	return check_getprop_string_by_name(fdt, "/test-node",
					    "test-str-property-2", "foobar2");
}

static int fdt_overlay_add_node(void *fdt)
{
	return check_getprop_null_by_name(fdt, "/test-node/new-node",
					  "new-property");
}

static int fdt_overlay_add_subnode_property(void *fdt)
{
	check_getprop_null_by_name(fdt, "/test-node/sub-test-node",
				   "sub-test-property");
	check_getprop_null_by_name(fdt, "/test-node/sub-test-node",
				   "new-sub-test-property");

	return 0;
}

static int fdt_overlay_local_phandle(void *fdt)
{
	uint32_t local_phandle;
	unsigned long val = 0;
	int off;

	off = fdt_path_offset(fdt, "/test-node/new-local-node");
	CHECK(off < 0);

	local_phandle = fdt_get_phandle(fdt, off);
	CHECK(!local_phandle);

	CHECK(fdt_getprop_u32_by_poffset(fdt, "/test-node",
					 "test-several-phandle",
					 0, &val));
	CHECK(val != local_phandle);

	CHECK(fdt_getprop_u32_by_poffset(fdt, "/test-node",
					 "test-several-phandle",
					 1, &val));
	CHECK(val != local_phandle);

	return 0;
}

static int fdt_overlay_local_phandles(void *fdt)
{
	uint32_t local_phandle, test_phandle;
	unsigned long val = 0;
	int off;

	off = fdt_path_offset(fdt, "/test-node/new-local-node");
	CHECK(off < 0);

	local_phandle = fdt_get_phandle(fdt, off);
	CHECK(!local_phandle);

	off = fdt_path_offset(fdt, "/test-node");
	CHECK(off < 0);

	test_phandle = fdt_get_phandle(fdt, off);
	CHECK(!test_phandle);

	CHECK(fdt_getprop_u32_by_poffset(fdt, "/test-node",
					 "test-phandle", 0, &val));
	CHECK(test_phandle != val);

	CHECK(fdt_getprop_u32_by_poffset(fdt, "/test-node",
					 "test-phandle", 1, &val));
	CHECK(local_phandle != val);

	return 0;
}

static void *open_dt(char *path)
{
	void *dt, *copy;

	dt = load_blob(path);
	copy = xmalloc(FDT_COPY_SIZE);

	/*
	 * Resize our DTs to 4k so that we have room to operate on
	 */
	CHECK(fdt_open_into(dt, copy, FDT_COPY_SIZE));

	return copy;
}

int main(int argc, char *argv[])
{
	void *fdt_base, *fdt_overlay;

	test_init(argc, argv);
	if (argc != 3)
		CONFIG("Usage: %s <base dtb> <overlay dtb>", argv[0]);

	fdt_base = open_dt(argv[1]);
	fdt_overlay = open_dt(argv[2]);

	/* Apply the overlay */
	CHECK(fdt_overlay_apply(fdt_base, fdt_overlay));

	fdt_overlay_change_int_property(fdt_base);
	fdt_overlay_change_str_property(fdt_base);
	fdt_overlay_add_str_property(fdt_base);
	fdt_overlay_add_node(fdt_base);
	fdt_overlay_add_subnode_property(fdt_base);

	/*
	 * If the base tree has a __symbols__ node, do the tests that
	 * are only successful with a proper phandle support, and thus
	 * dtc -@
	 */
	if (fdt_path_offset(fdt_base, "/__symbols__") >= 0) {
		fdt_overlay_local_phandle(fdt_base);
		fdt_overlay_local_phandles(fdt_base);
	}

	PASS();
}
