// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2019, Theobroma Systems Design und Consulting GmbH
 */

#include <command.h>
#include <errno.h>
#include <fdt_support.h>
#include <log.h>
#include <malloc.h>
#include <tee/optee.h>

#include <linux/sizes.h>

#include <test/ut.h>
#include <test/optee.h>
#include <test/suites.h>

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

extern u32 __dtb_test_optee_base_begin;
extern u32 __dtb_test_optee_optee_begin;
extern u32 __dtb_test_optee_no_optee_begin;

static void *fdt;
static bool expect_success;

static int optee_fdt_firmware(struct unit_test_state *uts)
{
	const void *prop;
	int offs, len;

	offs = fdt_path_offset(fdt, "/firmware/optee");
	ut_assert(expect_success ? offs >= 0 : offs < 0);

	/* only continue if we have an optee node */
	if (offs < 0)
		return CMD_RET_SUCCESS;

	prop = fdt_getprop(fdt, offs, "compatible", &len);
	ut_assertok(strncmp((const char *)prop, "linaro,optee-tz", len));

	prop = fdt_getprop(fdt, offs, "method", &len);
	ut_assert(strncmp(prop, "hvc", 3) == 0 || strncmp(prop, "smc", 3) == 0);

	return CMD_RET_SUCCESS;
}
OPTEE_TEST(optee_fdt_firmware, 0);

static int optee_fdt_protected_memory(struct unit_test_state *uts)
{
	int offs, subnode;
	bool found;

	offs = fdt_path_offset(fdt, "/firmware/optee");
	ut_assert(expect_success ? offs >= 0 : offs < 0);

	/* only continue if we have an optee node */
	if (offs < 0)
		return CMD_RET_SUCCESS;

	/* optee inserts its memory regions as reserved-memory nodes */
	offs = fdt_subnode_offset(fdt, 0, "reserved-memory");
	ut_assert(offs >= 0);

	subnode = fdt_first_subnode(fdt, offs);
	ut_assert(subnode);

	found = 0;
	while (subnode >= 0) {
		const char *name = fdt_get_name(fdt, subnode, NULL);
		struct fdt_resource res;

		ut_assert(name);

		/* only handle optee reservations */
		if (strncmp(name, "optee", 5))
			continue;

		found = true;

		/* check if this subnode has a reg property */
		ut_assertok(fdt_get_resource(fdt, subnode, "reg", 0, &res));
		subnode = fdt_next_subnode(fdt, subnode);
	}

	ut_assert(found);

	return CMD_RET_SUCCESS;
}
OPTEE_TEST(optee_fdt_protected_memory, 0);

int do_ut_optee(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
	struct unit_test *tests = UNIT_TEST_SUITE_START(optee_test);
	const int n_ents = UNIT_TEST_SUITE_COUNT(optee_test);
	struct unit_test_state *uts;
	void *fdt_optee = &__dtb_test_optee_optee_begin;
	void *fdt_no_optee = &__dtb_test_optee_no_optee_begin;
	void *fdt_base = &__dtb_test_optee_base_begin;
	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_optee));
	ut_assertok(fdt_check_header(fdt_no_optee));

	fdt = malloc(FDT_COPY_SIZE);
	if (!fdt)
		return ret;

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

	/*
	 * (1) Try to copy optee nodes from empty dt.
	 * This should still run successfully.
	 */
	ut_assertok(optee_copy_fdt_nodes(fdt_no_optee, fdt));

	expect_success = false;
	ret = cmd_ut_category("optee", "", tests, n_ents, argc, argv);

	/* (2) Try to copy optee nodes from prefilled dt */
	ut_assertok(optee_copy_fdt_nodes(fdt_optee, fdt));

	expect_success = true;
	ret = cmd_ut_category("optee", "", tests, n_ents, argc, argv);

	/* (3) Try to copy OP-TEE nodes into a already filled DT */
	ut_assertok(fdt_open_into(fdt_optee, fdt, FDT_COPY_SIZE));
	ut_assertok(optee_copy_fdt_nodes(fdt_optee, fdt));

	expect_success = true;
	ret = cmd_ut_category("optee", "", tests, n_ents, argc, argv);

	free(fdt);
	return ret;
}
