/*
 * Copyright (c) 2013-2024, 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/build_message.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", build_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));
}
