/*
 * 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;
extern u32 __dtb_test_fdt_overlay_stacked_begin;

static int ut_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 ut_fdt_getprop_u32(void *fdt, const char *path, const char *name,
			   u32 *out)
{
	return ut_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;
	int len;

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

	*out = fdt_stringlist_get(fdt, node_off, name, 0, &len);

	return len < 0 ? len : 0;
}

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

	ut_assertok(ut_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(ut_fdt_getprop_u32_by_index(fdt, "/", "test-several-phandle",
					     0, &val));
	ut_asserteq(local_phandle, val);

	ut_assertok(ut_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(ut_fdt_getprop_u32_by_index(fdt, "/", "test-phandle", 0,
					     &val));
	ut_asserteq(test_phandle, val);

	ut_assertok(ut_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);

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

	ut_assertok(ut_fdt_getprop_u32(fdt, "/new-local-node",
				       "stacked-test-int-property", &val));
	ut_asserteq(43, val);

	return CMD_RET_SUCCESS;
}
OVERLAY_TEST(fdt_overlay_stacked, 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_overlay_stacked = &__dtb_test_fdt_overlay_stacked_begin;
	void *fdt_base_copy, *fdt_overlay_copy, *fdt_overlay_stacked_copy;
	int ret = -ENOMEM;

	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)
		goto err1;
	uts->priv = fdt_base_copy;

	fdt_overlay_copy = malloc(FDT_COPY_SIZE);
	if (!fdt_overlay_copy)
		goto err2;

	fdt_overlay_stacked_copy = malloc(FDT_COPY_SIZE);
	if (!fdt_overlay_stacked_copy)
		goto err3;

	/*
	 * 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));

	/*
	 * Resize the stacked 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_stacked, fdt_overlay_stacked_copy,
				  FDT_COPY_SIZE));

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

	/* Apply the stacked overlay */
	ut_assertok(fdt_overlay_apply(fdt_base_copy, fdt_overlay_stacked_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);
	if (!uts->fail_count)
		ret = 0;
	else
		ret = CMD_RET_FAILURE;

	free(fdt_overlay_stacked_copy);
err3:
	free(fdt_overlay_copy);
err2:
	free(fdt_base_copy);
err1:
	free(uts);

	return ret;
}
