/*
 * Copyright (c) 2016 NextThing Co
 * Copyright (c) 2016 Free Electrons
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <command.h>
#include <errno.h>
#include <malloc.h>

#include <linux/sizes.h>

#include <test/ut.h>
#include <test/overlay.h>

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

extern u32 __dtb_test_fdt_base_begin;
extern u32 __dtb_test_fdt_overlay_begin;

static int fdt_getprop_u32_by_index(void *fdt, const char *path,
				    const char *name, int index,
				    u32 *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 < (sizeof(uint32_t) * (index + 1))))
		return -FDT_ERR_NOTFOUND;

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

	return 0;
}

static int fdt_getprop_u32(void *fdt, const char *path, const char *name,
			   u32 *out)
{
	return fdt_getprop_u32_by_index(fdt, path, name, 0, out);
}

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

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

	return fdt_get_string(fdt, node_off, name, out);
}

static int fdt_overlay_change_int_property(struct unit_test_state *uts)
{
	void *fdt = uts->priv;
	u32 val = 0;

	ut_assertok(fdt_getprop_u32(fdt, "/test-node", "test-int-property",
				    &val));
	ut_asserteq(43, val);

	return CMD_RET_SUCCESS;
}
OVERLAY_TEST(fdt_overlay_change_int_property, 0);

static int fdt_overlay_change_str_property(struct unit_test_state *uts)
{
	void *fdt = uts->priv;
	const char *val = NULL;

	ut_assertok(fdt_getprop_str(fdt, "/test-node", "test-str-property",
				    &val));
	ut_asserteq_str("foobar", val);

	return CMD_RET_SUCCESS;
}
OVERLAY_TEST(fdt_overlay_change_str_property, 0);

static int fdt_overlay_add_str_property(struct unit_test_state *uts)
{
	void *fdt = uts->priv;
	const char *val = NULL;

	ut_assertok(fdt_getprop_str(fdt, "/test-node", "test-str-property-2",
				    &val));
	ut_asserteq_str("foobar2", val);

	return CMD_RET_SUCCESS;
}
OVERLAY_TEST(fdt_overlay_add_str_property, 0);

static int fdt_overlay_add_node_by_phandle(struct unit_test_state *uts)
{
	void *fdt = uts->priv;
	int off;

	off = fdt_path_offset(fdt, "/test-node/new-node");
	ut_assert(off >= 0);

	ut_assertnonnull(fdt_getprop(fdt, off, "new-property", NULL));

	return CMD_RET_SUCCESS;
}
OVERLAY_TEST(fdt_overlay_add_node_by_phandle, 0);

static int fdt_overlay_add_node_by_path(struct unit_test_state *uts)
{
	void *fdt = uts->priv;
	int off;

	off = fdt_path_offset(fdt, "/new-node");
	ut_assert(off >= 0);

	ut_assertnonnull(fdt_getprop(fdt, off, "new-property", NULL));

	return CMD_RET_SUCCESS;
}
OVERLAY_TEST(fdt_overlay_add_node_by_path, 0);

static int fdt_overlay_add_subnode_property(struct unit_test_state *uts)
{
	void *fdt = uts->priv;
	int off;

	off = fdt_path_offset(fdt, "/test-node/sub-test-node");
	ut_assert(off >= 0);

	ut_assertnonnull(fdt_getprop(fdt, off, "sub-test-property", NULL));
	ut_assertnonnull(fdt_getprop(fdt, off, "new-sub-test-property", NULL));

	return CMD_RET_SUCCESS;
}
OVERLAY_TEST(fdt_overlay_add_subnode_property, 0);

static int fdt_overlay_local_phandle(struct unit_test_state *uts)
{
	uint32_t local_phandle;
	void *fdt = uts->priv;
	u32 val = 0;
	int off;

	off = fdt_path_offset(fdt, "/new-local-node");
	ut_assert(off >= 0);

	local_phandle = fdt_get_phandle(fdt, off);
	ut_assert(local_phandle);

	ut_assertok(fdt_getprop_u32_by_index(fdt, "/", "test-several-phandle",
					     0, &val));
	ut_asserteq(local_phandle, val);

	ut_assertok(fdt_getprop_u32_by_index(fdt, "/", "test-several-phandle",
					     1, &val));
	ut_asserteq(local_phandle, val);

	return CMD_RET_SUCCESS;
}
OVERLAY_TEST(fdt_overlay_local_phandle, 0);

static int fdt_overlay_local_phandles(struct unit_test_state *uts)
{
	uint32_t local_phandle, test_phandle;
	void *fdt = uts->priv;
	u32 val = 0;
	int off;

	off = fdt_path_offset(fdt, "/new-local-node");
	ut_assert(off >= 0);

	local_phandle = fdt_get_phandle(fdt, off);
	ut_assert(local_phandle);

	off = fdt_path_offset(fdt, "/test-node");
	ut_assert(off >= 0);

	test_phandle = fdt_get_phandle(fdt, off);
	ut_assert(test_phandle);

	ut_assertok(fdt_getprop_u32_by_index(fdt, "/", "test-phandle", 0,
					     &val));
	ut_asserteq(test_phandle, val);

	ut_assertok(fdt_getprop_u32_by_index(fdt, "/", "test-phandle", 1,
					     &val));
	ut_asserteq(local_phandle, val);

	return CMD_RET_SUCCESS;
}
OVERLAY_TEST(fdt_overlay_local_phandles, 0);

int do_ut_overlay(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	struct unit_test *tests = ll_entry_start(struct unit_test,
						 overlay_test);
	const int n_ents = ll_entry_count(struct unit_test, overlay_test);
	struct unit_test_state *uts;
	struct unit_test *test;
	void *fdt_base = &__dtb_test_fdt_base_begin;
	void *fdt_overlay = &__dtb_test_fdt_overlay_begin;
	void *fdt_base_copy, *fdt_overlay_copy;

	uts = calloc(1, sizeof(*uts));
	if (!uts)
		return -ENOMEM;

	ut_assertok(fdt_check_header(fdt_base));
	ut_assertok(fdt_check_header(fdt_overlay));

	fdt_base_copy = malloc(FDT_COPY_SIZE);
	if (!fdt_base_copy)
		return -ENOMEM;
	uts->priv = fdt_base_copy;

	fdt_overlay_copy = malloc(FDT_COPY_SIZE);
	if (!fdt_overlay_copy)
		return -ENOMEM;

	/*
	 * Resize the FDT to 4k so that we have room to operate on
	 *
	 * (and relocate it since the memory might be mapped
	 * read-only)
	 */
	ut_assertok(fdt_open_into(fdt_base, fdt_base_copy, FDT_COPY_SIZE));

	/*
	 * Resize the overlay to 4k so that we have room to operate on
	 *
	 * (and relocate it since the memory might be mapped
	 * read-only)
	 */
	ut_assertok(fdt_open_into(fdt_overlay, fdt_overlay_copy,
				  FDT_COPY_SIZE));

	/* Apply the overlay */
	ut_assertok(fdt_overlay_apply(fdt_base_copy, fdt_overlay_copy));

	if (argc == 1)
		printf("Running %d environment tests\n", n_ents);

	for (test = tests; test < tests + n_ents; test++) {
		if (argc > 1 && strcmp(argv[1], test->name))
			continue;
		printf("Test: %s\n", test->name);

		uts->start = mallinfo();

		test->func(uts);
	}

	printf("Failures: %d\n", uts->fail_count);

	free(fdt_overlay_copy);
	free(fdt_base_copy);
	free(uts);

	return uts->fail_count ? CMD_RET_FAILURE : 0;
}
