/*
 * Copyright (c) 2018, Arm Limited. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <arch_helpers.h>
#include <arm_gic.h>
#include <assert.h>
#include <debug.h>
#include <irq.h>
#include <mmio.h>
#include <nvm.h>
#include <plat_topology.h>
#include <platform.h>
#include <platform_def.h>
#include <power_management.h>
#include <psci.h>
#include <sgi.h>
#include <string.h>
#include <sys/types.h>
#include <tftf.h>
#include <tftf_lib.h>
#include <timer.h>

/* version information for TFTF */
extern const char version_string[];

unsigned int lead_cpu_mpid;

/* Defined in hotplug.c */
extern volatile test_function_t test_entrypoint[PLATFORM_CORE_COUNT];

/* Per-CPU results for the current test */
static test_result_t test_results[PLATFORM_CORE_COUNT];

/* Context ID passed to tftf_psci_cpu_on() */
static u_register_t cpu_on_ctx_id_arr[PLATFORM_CORE_COUNT];

static unsigned int test_is_rebooting;

static inline const test_suite_t *current_testsuite(void)
{
	test_ref_t test_to_run;
	tftf_get_test_to_run(&test_to_run);
	return &testsuites[test_to_run.testsuite_idx];
}

static inline const test_case_t *current_testcase(void)
{
	test_ref_t test_to_run;
	tftf_get_test_to_run(&test_to_run);
	return &testsuites[test_to_run.testsuite_idx].
		testcases[test_to_run.testcase_idx];
}

/*
 * Identify the next test in the tests list and update the NVM data to point to
 * that test.
 * If there is no more tests to execute, return NULL.
 * Otherwise, return the test case.
 */
static const test_case_t *advance_to_next_test(void)
{
	test_ref_t test_to_run;
	const test_case_t *testcase;
	unsigned int testcase_idx;
	unsigned int testsuite_idx;

#if DEBUG
	test_progress_t progress;
	tftf_get_test_progress(&progress);
	assert(progress == TEST_COMPLETE);
#endif

	tftf_get_test_to_run(&test_to_run);
	testcase_idx = test_to_run.testcase_idx;
	testsuite_idx = test_to_run.testsuite_idx;

	/* Move to the next test case in the current test suite */
	++testcase_idx;
	testcase = &testsuites[testsuite_idx].testcases[testcase_idx];

	if (testcase->name == NULL) {
		/*
		 * There's no more test cases in the current test suite so move
		 * to the first test case of the next test suite.
		 */
		const test_suite_t *testsuite;
		testcase_idx = 0;
		++testsuite_idx;
		testsuite = &testsuites[testsuite_idx];
		testcase = &testsuite->testcases[0];

		if (testsuite->name == NULL) {
			/*
			 * This was the last test suite so there's no more tests
			 * at all.
			 */
			return NULL;
		}
	}

	VERBOSE("Moving to test (%u,%u)\n", testsuite_idx, testcase_idx);
	test_to_run.testsuite_idx = testsuite_idx;
	test_to_run.testcase_idx = testcase_idx;
	tftf_set_test_to_run(test_to_run);
	tftf_set_test_progress(TEST_READY);

	return testcase;
}

/*
 * This function is executed only by the lead CPU.
 * It prepares the environment for the next test to run.
 */
static void prepare_next_test(void)
{
	unsigned int mpid;
	unsigned int core_pos;
	unsigned int cpu_node;

	/* This function should be called by the lead CPU only */
	assert((read_mpidr_el1() & MPID_MASK) == lead_cpu_mpid);

	/*
	 * Only the lead CPU should be powered on at this stage. All other CPUs
	 * should be powered off or powering off. If some CPUs are not powered
	 * off yet, wait for them to power off.
	 */
	for_each_cpu(cpu_node) {
		mpid = tftf_get_mpidr_from_node(cpu_node);
		if (mpid == lead_cpu_mpid)
			assert(tftf_is_cpu_online(mpid));
		else
			while (tftf_psci_affinity_info(mpid, MPIDR_AFFLVL0)
					  == PSCI_STATE_ON)
				;
	}

	/* No CPU should have entered the test yet */
	assert(tftf_get_ref_cnt() == 0);

	/* Populate the test entrypoint for the lead CPU */
	core_pos = platform_get_core_pos(lead_cpu_mpid);
	test_entrypoint[core_pos] = (test_function_t) current_testcase()->test;

	for (unsigned int i = 0; i < PLATFORM_CORE_COUNT; ++i)
		test_results[i] = TEST_RESULT_NA;

	NOTICE("Starting unittest '%s - %s'\n",
		current_testsuite()->name, current_testcase()->name);

	/* Program the watchdog */
	tftf_platform_watchdog_set();

	/* TODO: Take a 1st timestamp to be able to measure test duration */

	tftf_set_test_progress(TEST_IN_PROGRESS);
}

/*
 * Go through individual CPUs' test results and determine the overall
 * test result from that.
 */
static test_result_t get_overall_test_result(void)
{
	test_result_t result = TEST_RESULT_NA;
	unsigned int cpu_mpid;
	unsigned int cpu_node;
	unsigned int core_pos;

	for_each_cpu(cpu_node) {
		cpu_mpid = tftf_get_mpidr_from_node(cpu_node);
		core_pos = platform_get_core_pos(cpu_mpid);

		switch (test_results[core_pos]) {
		case TEST_RESULT_NA:
			VERBOSE("CPU%u not involved in the test\n", core_pos);
			/* Ignoring */
			break;

		case TEST_RESULT_SKIPPED:
			/*
			 * If at least one CPU skipped the test, consider the
			 * whole test as skipped as well.
			 */
			NOTICE("CPU%u skipped the test\n", core_pos);
			return TEST_RESULT_SKIPPED;

		case TEST_RESULT_SUCCESS:
			result = TEST_RESULT_SUCCESS;
			break;

		case TEST_RESULT_FAIL:
			ERROR("CPU%u failed the test\n", core_pos);
			return TEST_RESULT_FAIL;

		case TEST_RESULT_CRASHED:
			/*
			 * Means the CPU never returned from the test whereas it
			 * was supposed to. Either there is a bug in the test's
			 * implementation or some sort of unexpected crash
			 * happened.
			 * If at least one CPU crashed, consider the whole test
			 * as crashed as well.
			 */
			ERROR("CPU%u never returned from the test!\n", core_pos);
			return TEST_RESULT_CRASHED;

		default:
			ERROR("Unknown test result value: %u\n",
				test_results[core_pos]);
			panic();
		}
	}

	/*
	 * At least one CPU (i.e. the lead CPU) should have participated in the
	 * test.
	 */
	assert(result != TEST_RESULT_NA);
	return result;
}

/*
 * This function is executed by the last CPU to exit the test only.
 * It does the necessary bookkeeping and reports the overall test result.
 * If it was the last test, it will also generate the final test report.
 * Otherwise, it will reset the platform, provided that the platform
 * supports reset from non-trusted world. This ensures that the next test
 * runs in a clean environment
 *
 * Return 1 if this was the last test, 0 otherwise.
 */
static unsigned int close_test(void)
{
	const test_case_t *next_test;

#if DEBUG
	/*
	 * Check that the test didn't pretend resetting the platform, when in
	 * fact it returned into the framework.
	 *
	 * If that happens, the test implementation should be fixed.
	 * However, it is not a fatal error so just flag the problem in debug
	 * builds.
	 */
	test_progress_t progress;
	tftf_get_test_progress(&progress);
	assert(progress != TEST_REBOOTING);
#endif /* DEBUG */

	tftf_set_test_progress(TEST_COMPLETE);
	test_is_rebooting = 0;

	/* TODO: Take a 2nd timestamp and compute test duration */

	/* Reset watchdog */
	tftf_platform_watchdog_reset();

	/* Ensure no CPU is still executing the test */
	assert(tftf_get_ref_cnt() == 0);

	/* Save test result in NVM */
	test_result_t overall_test_result = get_overall_test_result();
	tftf_testcase_set_result(current_testcase(),
				overall_test_result,
				0);

	NOTICE("Unittest '%s - %s' complete. Result: %s\n",
	       current_testsuite()->name, current_testcase()->name,
	       test_result_to_string(overall_test_result));

	/* The test is finished, let's move to the next one (if any) */
	next_test = advance_to_next_test();

	/* If this was the last test then report all results */
	if (!next_test) {
		tftf_report_generate();
		tftf_clean_nvm();
		return 1;
	} else {
#if (PLAT_SUPPORTS_NS_RESET && !NEW_TEST_SESSION && USE_NVM)
		/*
		 * Reset the platform so that the next test runs in a clean
		 * environment.
		 */
		INFO("Reset platform before executing next test:%p\n",
				(void *) &(next_test->test));
		tftf_plat_reset();
		bug_unreachable();
#endif
	}

	return 0;
}

/*
 * Hand over to lead CPU, i.e.:
 *  1) Power on lead CPU
 *  2) Power down calling CPU
 */
static void __dead2 hand_over_to_lead_cpu(void)
{
	int ret;
	unsigned int mpid = read_mpidr_el1() & MPID_MASK;
	unsigned int core_pos = platform_get_core_pos(mpid);

	VERBOSE("CPU%u: Hand over to lead CPU%u\n", core_pos,
		platform_get_core_pos(lead_cpu_mpid));

	/*
	 * Power on lead CPU.
	 * The entry point address passed as the 2nd argument of tftf_cpu_on()
	 * doesn't matter because it will be overwritten by prepare_next_test().
	 * Pass a NULL pointer to easily catch the problem in case something
	 * goes wrong.
	 */
	ret = tftf_cpu_on(lead_cpu_mpid, 0, 0);
	if (ret != PSCI_E_SUCCESS) {
		ERROR("CPU%u: Failed to power on lead CPU%u (%d)\n",
			core_pos, platform_get_core_pos(lead_cpu_mpid), ret);
		panic();
	}

	/* Wait for lead CPU to be actually powered on */
	while (!tftf_is_cpu_online(lead_cpu_mpid))
		;

	/*
	 * Lead CPU has successfully booted, let's now power down the calling
	 * core.
	 */
	tftf_cpu_off();
	panic();
}

void __dead2 run_tests(void)
{
	unsigned int mpid = read_mpidr_el1() & MPID_MASK;
	unsigned int core_pos = platform_get_core_pos(mpid);
	unsigned int test_session_finished;
	unsigned int cpus_cnt;

	while (1) {
		if (mpid == lead_cpu_mpid && (tftf_get_ref_cnt() == 0))
			prepare_next_test();

		/*
		 * Increment the reference count to indicate that the CPU is
		 * participating in the test.
		 */
		tftf_inc_ref_cnt();

		/*
		 * Mark the CPU's test result as "crashed". This is meant to be
		 * overwritten by the actual test result when the CPU returns
		 * from the test function into the framework. In case the CPU
		 * crashes in the test (and thus, never returns from it), this
		 * variable will hold the right value.
		 */
		test_results[core_pos] = TEST_RESULT_CRASHED;

		/*
		 * Jump to the test entrypoint for this core.
		 * - For the lead CPU, it has been populated by
		 *   prepare_next_test()
		 * - For other CPUs, it has been populated by tftf_cpu_on() or
		 *   tftf_try_cpu_on()
		 */
		while (test_entrypoint[core_pos] == 0)
			;

		test_results[core_pos] = test_entrypoint[core_pos]();
		test_entrypoint[core_pos] = 0;

		/*
		 * Decrement the reference count to indicate that the CPU is not
		 * participating in the test any longer.
		 */
		cpus_cnt = tftf_dec_ref_cnt();

		/*
		 * Last CPU to exit the test gets to do the necessary
		 * bookkeeping and to report the overall test result.
		 * Other CPUs shut down.
		 */
		if (cpus_cnt == 0) {
			test_session_finished = close_test();
			if (test_session_finished)
				break;

			if (mpid != lead_cpu_mpid) {
				hand_over_to_lead_cpu();
				bug_unreachable();
			}
		} else {
			tftf_cpu_off();
			panic();
		}
	}

	tftf_exit();

	/* Should never reach this point */
	bug_unreachable();
}

u_register_t tftf_get_cpu_on_ctx_id(unsigned int core_pos)
{
	assert(core_pos < PLATFORM_CORE_COUNT);

	return cpu_on_ctx_id_arr[core_pos];
}

void tftf_set_cpu_on_ctx_id(unsigned int core_pos, u_register_t context_id)
{
	assert(core_pos < PLATFORM_CORE_COUNT);

	cpu_on_ctx_id_arr[core_pos] = context_id;
}

unsigned int tftf_is_rebooted(void)
{
	return test_is_rebooting;
}

/*
 * Return 0 if the test session can be resumed
 *        -1 otherwise.
 */
static int resume_test_session(void)
{
	test_ref_t test_to_run;
	test_progress_t test_progress;
	const test_case_t *next_test;

	/* Get back on our feet. Where did we stop? */
	tftf_get_test_to_run(&test_to_run);
	tftf_get_test_progress(&test_progress);
	assert(TEST_PROGRESS_IS_VALID(test_progress));

	switch (test_progress) {
	case TEST_READY:
		/*
		 * The TFTF has reset in the framework code, before the test
		 * actually started.
		 * Nothing to update, just start the test from scratch.
		 */
		break;

	case TEST_IN_PROGRESS:
		/*
		 * The test crashed, i.e. it couldn't complete.
		 * Update the test result in NVM then move to the next test.
		 */
		INFO("Test has crashed, moving to the next one\n");
		tftf_testcase_set_result(current_testcase(),
					TEST_RESULT_CRASHED,
					0);
		next_test = advance_to_next_test();
		if (!next_test) {
			INFO("No more tests\n");
			return -1;
		}
		break;

	case TEST_COMPLETE:
		/*
		 * The TFTF has reset in the framework code, after the test had
		 * completed but before we finished the framework maintenance
		 * required to move to the next test.
		 *
		 * In this case, we don't know the exact state of the data:
		 * maybe we had the time to update the test result,
		 * maybe we had the time to move to the next test.
		 * We can't be sure so let's stay on the safe side and just
		 * restart the test session from the beginning...
		 */
		NOTICE("The test framework has been interrupted in the middle "
			"of critical maintenance operations.\n");
		NOTICE("Can't recover execution.\n");
		return -1;

	case TEST_REBOOTING:
		/*
		 * Nothing to update about the test session, as we want to
		 * re-enter the same test. Just remember that the test is
		 * rebooting in case it queries this information.
		 */
		test_is_rebooting = 1;
		break;

	default:
		bug_unreachable();
	}

	return 0;
}

/*
 * C entry point in the TFTF.
 * This function is executed by the primary CPU only.
 */
void __dead2 tftf_cold_boot_main(void)
{
	STATUS status;
	int rc;

	NOTICE("%s\n", TFTF_WELCOME_STR);
	NOTICE("%s\n", build_message);
	NOTICE("%s\n\n", version_string);

#ifndef AARCH32
	NOTICE("Running at NS-EL%u\n", IS_IN_EL(1) ? 1 : 2);
#else
	NOTICE("Running in AArch32 HYP mode\n");
#endif

	tftf_arch_setup();
	tftf_platform_setup();
	tftf_init_topology();

	tftf_irq_setup();

	rc = tftf_initialise_timer();
	if (rc != 0) {
		ERROR("Failed to initialize the timer subsystem (%d).\n", rc);
		tftf_exit();
	}

	/* Enable the SGI used by the timer management framework */
	tftf_irq_enable(IRQ_WAKE_SGI, GIC_HIGHEST_NS_PRIORITY);
	enable_irq();

	if (new_test_session()) {
		NOTICE("Starting a new test session\n");
		status = tftf_init_nvm();
		if (status != STATUS_SUCCESS) {
			/*
			 * TFTF will have an undetermined behavior if its data
			 * structures have not been initialised. There's no
			 * point in continuing execution.
			 */
			ERROR("FATAL: Failed to initialise internal data structures in NVM.\n");
			tftf_clean_nvm();
			tftf_exit();
		}
	} else {
		NOTICE("Resuming interrupted test session\n");
		rc = resume_test_session();
		if (rc < 0) {
			tftf_report_generate();
			tftf_clean_nvm();
			tftf_exit();
		}
	}

	/* Initialise the CPUs status map */
	tftf_init_cpus_status_map();

	/*
	 * Detect power state format and get power state information for
	 * a platform.
	 */
	tftf_init_pstate_framework();

	/* The lead CPU is always the primary core. */
	lead_cpu_mpid = read_mpidr_el1() & MPID_MASK;

	/*
	 * Hand over to lead CPU if required.
	 * If the primary CPU is not the lead CPU for the first test then:
	 *  1) Power on the lead CPU
	 *  2) Power down the primary CPU
	 */
	if ((read_mpidr_el1() & MPID_MASK) != lead_cpu_mpid) {
		hand_over_to_lead_cpu();
		bug_unreachable();
	}

	/* Enter the test session */
	run_tests();

	/* Should never reach this point */
	bug_unreachable();
}

void __dead2 tftf_exit(void)
{
	NOTICE("Exiting tests.\n");

	/* Let the platform code clean up if required */
	tftf_platform_end();

	while (1)
		wfi();
}
