/*
 * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <assert.h>
#include <inttypes.h>
#include <stdint.h>

#include "../../services/std_svc/spm/el3_spmc/spmc.h"
#include "../../services/std_svc/spm/el3_spmc/spmc_shared_mem.h"
#include <arch_features.h>
#include <arch_helpers.h>
#include <bl32/tsp/tsp.h>
#include <common/bl_common.h>
#include <common/debug.h>
#include "ffa_helpers.h"
#include <lib/psci/psci.h>
#include <lib/spinlock.h>
#include <lib/xlat_tables/xlat_tables_defs.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <plat/common/platform.h>
#include <platform_tsp.h>
#include <services/ffa_svc.h>
#include "tsp_private.h"

#include <platform_def.h>

static ffa_endpoint_id16_t tsp_id, spmc_id;
uint8_t mem_region_buffer[4096 * 2]  __aligned(PAGE_SIZE);

/* Partition Mailbox. */
static uint8_t send_page[PAGE_SIZE] __aligned(PAGE_SIZE);
static uint8_t recv_page[PAGE_SIZE] __aligned(PAGE_SIZE);

/*
 * Declare a global mailbox for use within the TSP.
 * This will be initialized appropriately when the buffers
 * are mapped with the SPMC.
 */
static struct mailbox mailbox;

/*******************************************************************************
 * This enum is used to handle test cases driven from the FF-A Test Driver.
 ******************************************************************************/
/* Keep in Sync with FF-A Test Driver. */
enum message_t {
	/* Partition Only Messages. */
	FF_A_RELAY_MESSAGE = 0,

	/* Basic Functionality. */
	FF_A_ECHO_MESSAGE,
	FF_A_RELAY_MESSAGE_EL3,

	/* Memory Sharing. */
	FF_A_MEMORY_SHARE,
	FF_A_MEMORY_SHARE_FRAGMENTED,
	FF_A_MEMORY_LEND,
	FF_A_MEMORY_LEND_FRAGMENTED,

	FF_A_MEMORY_SHARE_MULTI_ENDPOINT,
	FF_A_MEMORY_LEND_MULTI_ENDPOINT,

	LAST,
	FF_A_RUN_ALL = 255,
	FF_A_OP_MAX = 256
};

#if SPMC_AT_EL3
extern void tsp_cpu_on_entry(void);
#endif

/*******************************************************************************
 * Test Functions.
 ******************************************************************************/

/*******************************************************************************
 * Enable the TSP to forward the received message to another partition and ask
 * it to echo the value back in order to validate direct messages functionality.
 ******************************************************************************/
static int ffa_test_relay(uint64_t arg0,
			  uint64_t arg1,
			  uint64_t arg2,
			  uint64_t arg3,
			  uint64_t arg4,
			  uint64_t arg5,
			  uint64_t arg6,
			  uint64_t arg7)
{
	smc_args_t ffa_forward_result;
	ffa_endpoint_id16_t receiver = arg5;

	ffa_forward_result = ffa_msg_send_direct_req(tsp_id,
						     receiver,
						     FF_A_ECHO_MESSAGE, arg4,
						     0, 0, 0);
	return ffa_forward_result._regs[3];
}

/*******************************************************************************
 * This function handles memory management tests, currently share and lend.
 * This test supports the use of FRAG_RX to use memory descriptors that do not
 * fit in a single 4KB buffer.
 ******************************************************************************/
static int test_memory_send(ffa_endpoint_id16_t sender, uint64_t handle,
			    ffa_mtd_flag32_t flags, bool multi_endpoint)
{
	struct ffa_mtd *m;
	struct ffa_emad_v1_0 *receivers;
	struct ffa_comp_mrd *composite;
	int ret, status = 0;
	unsigned int mem_attrs;
	char *ptr;
	ffa_endpoint_id16_t source = sender;
	uint32_t total_length, recv_length = 0;

	/*
	 * In the case that we're testing multiple endpoints choose a partition
	 * ID that resides in the normal world so the SPMC won't detect it as
	 * invalid.
	 * TODO: Should get endpoint receiver id and flag as input from NWd.
	 */
	uint32_t receiver_count = multi_endpoint ? 2 : 1;
	ffa_endpoint_id16_t test_receivers[2] = { tsp_id, 0x10 };

	/* Ensure that the sender ID resides in the normal world. */
	if (ffa_is_secure_world_id(sender)) {
		ERROR("Invalid sender ID 0x%x.\n", sender);
		return FFA_ERROR_DENIED;
	}

	if (!memory_retrieve(&mailbox, &m, handle, source, test_receivers,
			     receiver_count, flags, &recv_length,
			     &total_length)) {
		return FFA_ERROR_INVALID_PARAMETER;
	}

	receivers = (struct ffa_emad_v1_0 *)
		    ((uint8_t *) m + m->emad_offset);
	while (total_length != recv_length) {
		smc_args_t ffa_return;
		uint32_t frag_length;

		ffa_return = ffa_mem_frag_rx(handle, recv_length);

		if (ffa_return._regs[0] == FFA_ERROR) {
			WARN("TSP: failed to resume mem with handle %lx\n",
			     handle);
			return ffa_return._regs[2];
		}
		frag_length = ffa_return._regs[3];

		/* Validate frag_length is less than total_length and mailbox size. */
		if (frag_length > total_length ||
				frag_length > (mailbox.rxtx_page_count * PAGE_SIZE)) {
			ERROR("Invalid parameters!\n");
			return FFA_ERROR_INVALID_PARAMETER;
		}

		/* Validate frag_length is less than remaining mem_region_buffer size. */
		if (frag_length + recv_length >= REGION_BUF_SIZE) {
			ERROR("Out of memory!\n");
			return FFA_ERROR_INVALID_PARAMETER;
		}

		memcpy(&mem_region_buffer[recv_length], mailbox.rx_buffer,
		       frag_length);

		if (ffa_rx_release()) {
			ERROR("Failed to release buffer!\n");
			return FFA_ERROR_DENIED;
		}

		recv_length += frag_length;

		assert(recv_length <= total_length);
	}

	composite = ffa_memory_region_get_composite(m, 0);
	if (composite == NULL) {
		WARN("Failed to get composite descriptor!\n");
		return FFA_ERROR_INVALID_PARAMETER;
	}

	VERBOSE("Address: %p; page_count: %x %lx\n",
		(void *)composite->address_range_array[0].address,
		composite->address_range_array[0].page_count, PAGE_SIZE);

	/* This test is only concerned with RW permissions. */
	if (ffa_get_data_access_attr(
	    receivers[0].mapd.memory_access_permissions) != FFA_MEM_PERM_RW) {
		ERROR("Data permission in retrieve response %x does not match share/lend %x!\n",
		      ffa_get_data_access_attr(receivers[0].mapd.memory_access_permissions),
		      FFA_MEM_PERM_RW);
		return FFA_ERROR_INVALID_PARAMETER;
	}

	mem_attrs = MT_RW_DATA | MT_EXECUTE_NEVER;

	/* Only expecting to be sent memory from NWd so map accordingly. */
	mem_attrs |= MT_NS;

	for (int32_t i = 0; i < (int32_t)composite->address_range_count; i++) {
		size_t size = composite->address_range_array[i].page_count * PAGE_SIZE;

		ptr = (char *) composite->address_range_array[i].address;
		ret = mmap_add_dynamic_region(
				(uint64_t)ptr,
				(uint64_t)ptr,
				size, mem_attrs);

		if (ret != 0) {
			ERROR("Failed [%d] mmap_add_dynamic_region %u (%lx) (%lx) (%x)!\n",
				i, ret,
				(uint64_t)composite->address_range_array[i].address,
				size, mem_attrs);

			/* Remove mappings previously created in this transaction. */
			for (i--; i >= 0; i--) {
				ret = mmap_remove_dynamic_region(
					(uint64_t)composite->address_range_array[i].address,
					composite->address_range_array[i].page_count * PAGE_SIZE);

				if (ret != 0) {
					ERROR("Failed [%d] mmap_remove_dynamic_region!\n", i);
					panic();
				}
			}

			return FFA_ERROR_NO_MEMORY;
		}

		/* Increment memory region for validation purposes. */
		++(*ptr);

		/*
		 * Read initial magic number from memory region for
		 * validation purposes.
		 */
		if (!i) {
			status = *ptr;
		}
	}

	for (uint32_t i = 0U; i < composite->address_range_count; i++) {
		ret = mmap_remove_dynamic_region(
			(uint64_t)composite->address_range_array[i].address,
			composite->address_range_array[i].page_count * PAGE_SIZE);

		if (ret != 0) {
			ERROR("Failed [%d] mmap_remove_dynamic_region!\n", i);
			return FFA_ERROR_NO_MEMORY;
		}
	}

	if (!memory_relinquish((struct ffa_mem_relinquish_descriptor *)mailbox.tx_buffer,
				m->handle, tsp_id)) {
		ERROR("Failed to relinquish memory region!\n");
		return FFA_ERROR_INVALID_PARAMETER;
	}
	return status;
}

static smc_args_t *send_ffa_pm_success(void)
{
	return set_smc_args(FFA_MSG_SEND_DIRECT_RESP_SMC32,
			    ((tsp_id & FFA_DIRECT_MSG_ENDPOINT_ID_MASK)
			    << FFA_DIRECT_MSG_SOURCE_SHIFT) | spmc_id,
			    FFA_FWK_MSG_BIT |
			    (FFA_PM_MSG_PM_RESP & FFA_FWK_MSG_MASK),
			    0, 0, 0, 0, 0);
}

/*******************************************************************************
 * This function performs any remaining book keeping in the test secure payload
 * before this cpu is turned off in response to a psci cpu_off request.
 ******************************************************************************/
smc_args_t *tsp_cpu_off_main(uint64_t arg0,
			     uint64_t arg1,
			     uint64_t arg2,
			     uint64_t arg3,
			     uint64_t arg4,
			     uint64_t arg5,
			     uint64_t arg6,
			     uint64_t arg7)
{
	uint32_t linear_id = plat_my_core_pos();

	/*
	 * This cpu is being turned off, so disable the timer to prevent the
	 * secure timer interrupt from interfering with power down. A pending
	 * interrupt will be lost but we do not care as we are turning off.
	 */
	tsp_generic_timer_stop();

	/* Update this cpu's statistics. */
	tsp_stats[linear_id].smc_count++;
	tsp_stats[linear_id].eret_count++;
	tsp_stats[linear_id].cpu_off_count++;

	VERBOSE("TSP: cpu 0x%lx off request\n", read_mpidr());
	VERBOSE("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu off requests\n",
		read_mpidr(),
		tsp_stats[linear_id].smc_count,
		tsp_stats[linear_id].eret_count,
		tsp_stats[linear_id].cpu_off_count);

	return send_ffa_pm_success();
}

/*******************************************************************************
 * This function performs any book keeping in the test secure payload before
 * this cpu's architectural state is saved in response to an earlier psci
 * cpu_suspend request.
 ******************************************************************************/
smc_args_t *tsp_cpu_suspend_main(uint64_t arg0,
				 uint64_t arg1,
				 uint64_t arg2,
				 uint64_t arg3,
				 uint64_t arg4,
				 uint64_t arg5,
				 uint64_t arg6,
				 uint64_t arg7)
{
	uint32_t linear_id = plat_my_core_pos();

	/*
	 * Save the time context and disable it to prevent the secure timer
	 * interrupt from interfering with wakeup from the suspend state.
	 */
	tsp_generic_timer_save();
	tsp_generic_timer_stop();

	/* Update this cpu's statistics. */
	tsp_stats[linear_id].smc_count++;
	tsp_stats[linear_id].eret_count++;
	tsp_stats[linear_id].cpu_suspend_count++;

	VERBOSE("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu suspend requests\n",
		read_mpidr(),
		tsp_stats[linear_id].smc_count,
		tsp_stats[linear_id].eret_count,
		tsp_stats[linear_id].cpu_suspend_count);

	return send_ffa_pm_success();
}

/*******************************************************************************
 * This function performs any bookkeeping in the test secure payload after this
 * cpu's architectural state has been restored after wakeup from an earlier psci
 * cpu_suspend request.
 ******************************************************************************/
smc_args_t *tsp_cpu_resume_main(uint64_t max_off_pwrlvl,
				uint64_t arg1,
				uint64_t arg2,
				uint64_t arg3,
				uint64_t arg4,
				uint64_t arg5,
				uint64_t arg6,
				uint64_t arg7)
{
	uint32_t linear_id = plat_my_core_pos();

	/* Restore the generic timer context. */
	tsp_generic_timer_restore();

	/* Update this cpu's statistics. */
	tsp_stats[linear_id].smc_count++;
	tsp_stats[linear_id].eret_count++;
	tsp_stats[linear_id].cpu_resume_count++;

	VERBOSE("TSP: cpu 0x%lx resumed. maximum off power level %" PRId64 "\n",
	     read_mpidr(), max_off_pwrlvl);
	VERBOSE("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu resume requests\n",
		read_mpidr(),
		tsp_stats[linear_id].smc_count,
		tsp_stats[linear_id].eret_count,
		tsp_stats[linear_id].cpu_resume_count);

	return send_ffa_pm_success();
}

/*******************************************************************************
 * This function handles framework messages. Currently only PM.
 ******************************************************************************/
static smc_args_t *handle_framework_message(uint64_t arg0,
					    uint64_t arg1,
					    uint64_t arg2,
					    uint64_t arg3,
					    uint64_t arg4,
					    uint64_t arg5,
					    uint64_t arg6,
					    uint64_t arg7)
{
	/* Check if it is a power management message from the SPMC. */
	if (ffa_endpoint_source(arg1) != spmc_id) {
		goto err;
	}

	/* Check if it is a PM request message. */
	if ((arg2 & FFA_FWK_MSG_MASK) == FFA_FWK_MSG_PSCI) {
		/* Check if it is a PSCI CPU_OFF request. */
		if (arg3 == PSCI_CPU_OFF) {
			return tsp_cpu_off_main(arg0, arg1, arg2, arg3,
						arg4, arg5, arg6, arg7);
		} else if (arg3 == PSCI_CPU_SUSPEND_AARCH64) {
			return tsp_cpu_suspend_main(arg0, arg1, arg2, arg3,
						arg4, arg5, arg6, arg7);
		}
	} else if ((arg2 & FFA_FWK_MSG_MASK) == FFA_PM_MSG_WB_REQ) {
		/* Check it is a PSCI Warm Boot request. */
		if (arg3 == FFA_WB_TYPE_NOTS2RAM) {
			return tsp_cpu_resume_main(arg0, arg1, arg2, arg3,
						arg4, arg5, arg6, arg7);
		}
	}

err:
	ERROR("%s: Unknown framework message!\n", __func__);
	panic();
}

/*******************************************************************************
 * Handles partition messages. Exercised from the FF-A Test Driver.
 ******************************************************************************/
static smc_args_t *handle_partition_message(uint64_t arg0,
					    uint64_t arg1,
					    uint64_t arg2,
					    uint64_t arg3,
					    uint64_t arg4,
					    uint64_t arg5,
					    uint64_t arg6,
					    uint64_t arg7)
{
	uint16_t sender = ffa_endpoint_source(arg1);
	uint16_t receiver = ffa_endpoint_destination(arg1);
	int status = -1;
	const bool multi_endpoint = true;

	switch (arg3) {
	case FF_A_MEMORY_SHARE:
		INFO("TSP Tests: Memory Share Request--\n");
		status = test_memory_send(sender, arg4, FFA_FLAG_SHARE_MEMORY, !multi_endpoint);
		break;

	case FF_A_MEMORY_LEND:
		INFO("TSP Tests: Memory Lend Request--\n");
		status = test_memory_send(sender, arg4, FFA_FLAG_LEND_MEMORY, !multi_endpoint);
		break;

	case FF_A_MEMORY_SHARE_MULTI_ENDPOINT:
		INFO("TSP Tests: Multi Endpoint Memory Share Request--\n");
		status = test_memory_send(sender, arg4, FFA_FLAG_SHARE_MEMORY, multi_endpoint);
		break;

	case FF_A_MEMORY_LEND_MULTI_ENDPOINT:
		INFO("TSP Tests: Multi Endpoint Memory Lend Request--\n");
		status = test_memory_send(sender, arg4, FFA_FLAG_LEND_MEMORY, multi_endpoint);
		break;
	case FF_A_RELAY_MESSAGE:
		INFO("TSP Tests: Relaying message--\n");
		status = ffa_test_relay(arg0, arg1, arg2, arg3, arg4,
					arg5, arg6, arg7);
		break;

	case FF_A_ECHO_MESSAGE:
		INFO("TSP Tests: echo message--\n");
		status = arg4;
		break;

	default:
		INFO("TSP Tests: Unknown request ID %d--\n", (int) arg3);
	}

	/* Swap the sender and receiver in the response. */
	return ffa_msg_send_direct_resp(receiver, sender, status, 0, 0, 0, 0);
}

/*******************************************************************************
 * This function implements the event loop for handling FF-A ABI invocations.
 ******************************************************************************/
static smc_args_t *tsp_event_loop(uint64_t smc_fid,
				  uint64_t arg1,
				  uint64_t arg2,
				  uint64_t arg3,
				  uint64_t arg4,
				  uint64_t arg5,
				  uint64_t arg6,
				  uint64_t arg7)
{
	/* Panic if the SPMC did not forward an FF-A call. */
	if (!is_ffa_fid(smc_fid)) {
		ERROR("%s: Unknown SMC FID (0x%lx)\n", __func__, smc_fid);
		panic();
	}

	switch (smc_fid) {
	case FFA_INTERRUPT:
		/*
		 * IRQs were enabled upon re-entry into the TSP. The interrupt
		 * must have been handled by now. Return to the SPMC indicating
		 * the same.
		 */
		return set_smc_args(FFA_MSG_WAIT, 0, 0, 0, 0, 0, 0, 0);

	case FFA_MSG_SEND_DIRECT_REQ_SMC64:
	case FFA_MSG_SEND_DIRECT_REQ_SMC32:
		/* Check if a framework message, handle accordingly. */
		if ((arg2 & FFA_FWK_MSG_BIT)) {
			return handle_framework_message(smc_fid, arg1, arg2, arg3,
							arg4, arg5, arg6, arg7);
		}
		return handle_partition_message(smc_fid, arg1, arg2, arg3,
							arg4, arg5, arg6, arg7);
	}

	ERROR("%s: Unsupported FF-A FID (0x%lx)\n", __func__, smc_fid);
	panic();
}

static smc_args_t *tsp_loop(smc_args_t *args)
{
	smc_args_t ret;

	do {
		/* --------------------------------------------
		 * Mask FIQ interrupts to avoid preemption
		 * in case EL3 SPMC delegates an IRQ next or a
		 * managed exit. Lastly, unmask IRQs so that
		 * they can be handled immediately upon re-entry.
		 *  ---------------------------------------------
		 */
		write_daifset(DAIF_FIQ_BIT);
		write_daifclr(DAIF_IRQ_BIT);
		ret = smc_helper(args->_regs[0], args->_regs[1], args->_regs[2],
			       args->_regs[3], args->_regs[4], args->_regs[5],
			       args->_regs[6], args->_regs[7]);
		args = tsp_event_loop(ret._regs[0], ret._regs[1], ret._regs[2],
				ret._regs[3], ret._regs[4], ret._regs[5],
				ret._regs[6], ret._regs[7]);
	} while (1);

	/* Not Reached. */
	return NULL;
}

/*******************************************************************************
 * TSP main entry point where it gets the opportunity to initialize its secure
 * state/applications. Once the state is initialized, it must return to the
 * SPD with a pointer to the 'tsp_vector_table' jump table.
 ******************************************************************************/
uint64_t tsp_main(void)
{
	smc_args_t smc_args = {0};

	NOTICE("TSP: %s\n", version_string);
	NOTICE("TSP: %s\n", build_message);
	INFO("TSP: Total memory base : 0x%lx\n", (unsigned long) BL32_BASE);
	INFO("TSP: Total memory size : 0x%lx bytes\n", BL32_TOTAL_SIZE);
	uint32_t linear_id = plat_my_core_pos();

	/* Initialize the platform. */
	tsp_platform_setup();

	/* Initialize secure/applications state here. */
	tsp_generic_timer_start();

	/* Register secondary entrypoint with the SPMC. */
	smc_args = smc_helper(FFA_SECONDARY_EP_REGISTER_SMC64,
			(uint64_t) tsp_cpu_on_entry,
			0, 0, 0, 0, 0, 0);
	if (smc_args._regs[SMC_ARG0] != FFA_SUCCESS_SMC32) {
		ERROR("TSP could not register secondary ep (0x%lx)\n",
				smc_args._regs[2]);
		panic();
	}
	/* Get TSP's endpoint id. */
	smc_args = smc_helper(FFA_ID_GET, 0, 0, 0, 0, 0, 0, 0);
	if (smc_args._regs[SMC_ARG0] != FFA_SUCCESS_SMC32) {
		ERROR("TSP could not get own ID (0x%lx) on core%d\n",
				smc_args._regs[2], linear_id);
		panic();
	}

	tsp_id = smc_args._regs[2];
	INFO("TSP FF-A endpoint id = 0x%x\n", tsp_id);

	/* Get the SPMC ID. */
	smc_args = smc_helper(FFA_SPM_ID_GET, 0, 0, 0, 0, 0, 0, 0);
	if (smc_args._regs[SMC_ARG0] != FFA_SUCCESS_SMC32) {
		ERROR("TSP could not get SPMC ID (0x%lx) on core%d\n",
				smc_args._regs[2], linear_id);
		panic();
	}

	spmc_id = smc_args._regs[2];

	/* Call RXTX_MAP to map a 4k RX and TX buffer. */
	if (ffa_rxtx_map((uintptr_t) send_page,
			 (uintptr_t) recv_page, 1)) {
		ERROR("TSP could not map it's RX/TX Buffers\n");
		panic();
	}

	mailbox.tx_buffer = send_page;
	mailbox.rx_buffer = recv_page;
	mailbox.rxtx_page_count = 1;

	/* Update this cpu's statistics. */
	tsp_stats[linear_id].smc_count++;
	tsp_stats[linear_id].eret_count++;
	tsp_stats[linear_id].cpu_on_count++;

	VERBOSE("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu on requests\n",
			read_mpidr(),
			tsp_stats[linear_id].smc_count,
			tsp_stats[linear_id].eret_count,
			tsp_stats[linear_id].cpu_on_count);

	/* Tell SPMD that we are done initialising. */
	tsp_loop(set_smc_args(FFA_MSG_WAIT, 0, 0, 0, 0, 0, 0, 0));

	/* Not reached. */
	return 0;
}

/*******************************************************************************
 * This function performs any remaining book keeping in the test secure payload
 * after this cpu's architectural state has been setup in response to an earlier
 * psci cpu_on request.
 ******************************************************************************/
smc_args_t *tsp_cpu_on_main(void)
{
	uint32_t linear_id = plat_my_core_pos();

	/* Initialize secure/applications state here. */
	tsp_generic_timer_start();

	/* Update this cpu's statistics. */
	tsp_stats[linear_id].smc_count++;
	tsp_stats[linear_id].eret_count++;
	tsp_stats[linear_id].cpu_on_count++;
	VERBOSE("TSP: cpu 0x%lx turned on\n", read_mpidr());
	VERBOSE("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu on requests\n",
			read_mpidr(),
			tsp_stats[linear_id].smc_count,
			tsp_stats[linear_id].eret_count,
			tsp_stats[linear_id].cpu_on_count);
	/* ---------------------------------------------
	 * Jump to the main event loop to return to EL3
	 * and be ready for the next request on this cpu.
	 * ---------------------------------------------
	 */
	return tsp_loop(set_smc_args(FFA_MSG_WAIT, 0, 0, 0, 0, 0, 0, 0));
}
