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

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

#include <arch_helpers.h>
#include <arch/aarch64/arch_features.h>
#include <bl31/bl31.h>
#include <bl31/interrupt_mgmt.h>
#include <common/debug.h>
#include <common/runtime_svc.h>
#include <common/tbbr/tbbr_img_def.h>
#include <lib/el3_runtime/context_mgmt.h>
#include <lib/fconf/fconf.h>
#include <lib/fconf/fconf_dyn_cfg_getter.h>
#include <lib/smccc.h>
#include <lib/spinlock.h>
#include <lib/utils.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <plat/common/common_def.h>
#include <plat/common/platform.h>
#include <platform_def.h>
#include <services/el3_spmd_logical_sp.h>
#include <services/ffa_svc.h>
#include <services/spmc_svc.h>
#include <services/spmd_svc.h>
#include <smccc_helpers.h>
#include "spmd_private.h"

/*******************************************************************************
 * SPM Core context information.
 ******************************************************************************/
static spmd_spm_core_context_t spm_core_context[PLATFORM_CORE_COUNT];

/*******************************************************************************
 * SPM Core attribute information is read from its manifest if the SPMC is not
 * at EL3. Else, it is populated from the SPMC directly.
 ******************************************************************************/
static spmc_manifest_attribute_t spmc_attrs;

/*******************************************************************************
 * SPM Core entry point information. Discovered on the primary core and reused
 * on secondary cores.
 ******************************************************************************/
static entry_point_info_t *spmc_ep_info;

/*******************************************************************************
 * SPM Core context on CPU based on mpidr.
 ******************************************************************************/
spmd_spm_core_context_t *spmd_get_context_by_mpidr(uint64_t mpidr)
{
	int core_idx = plat_core_pos_by_mpidr(mpidr);

	if (core_idx < 0) {
		ERROR("Invalid mpidr: %" PRIx64 ", returned ID: %d\n", mpidr, core_idx);
		panic();
	}

	return &spm_core_context[core_idx];
}

/*******************************************************************************
 * SPM Core context on current CPU get helper.
 ******************************************************************************/
spmd_spm_core_context_t *spmd_get_context(void)
{
	return spmd_get_context_by_mpidr(read_mpidr());
}

/*******************************************************************************
 * SPM Core ID getter.
 ******************************************************************************/
uint16_t spmd_spmc_id_get(void)
{
	return spmc_attrs.spmc_id;
}

/*******************************************************************************
 * Static function declaration.
 ******************************************************************************/
static int32_t spmd_init(void);
static int spmd_spmc_init(void *pm_addr);
static uint64_t spmd_ffa_error_return(void *handle,
				       int error_code);
static uint64_t spmd_smc_forward(uint32_t smc_fid,
				 bool secure_origin,
				 uint64_t x1,
				 uint64_t x2,
				 uint64_t x3,
				 uint64_t x4,
				 void *cookie,
				 void *handle,
				 uint64_t flags);

/******************************************************************************
 * Builds an SPMD to SPMC direct message request.
 *****************************************************************************/
void spmd_build_spmc_message(gp_regs_t *gpregs, uint8_t target_func,
			     unsigned long long message)
{
	write_ctx_reg(gpregs, CTX_GPREG_X0, FFA_MSG_SEND_DIRECT_REQ_SMC32);
	write_ctx_reg(gpregs, CTX_GPREG_X1,
		(SPMD_DIRECT_MSG_ENDPOINT_ID << FFA_DIRECT_MSG_SOURCE_SHIFT) |
		 spmd_spmc_id_get());
	write_ctx_reg(gpregs, CTX_GPREG_X2, BIT(31) | target_func);
	write_ctx_reg(gpregs, CTX_GPREG_X3, message);
}


/*******************************************************************************
 * This function takes an SPMC context pointer and performs a synchronous
 * SPMC entry.
 ******************************************************************************/
uint64_t spmd_spm_core_sync_entry(spmd_spm_core_context_t *spmc_ctx)
{
	uint64_t rc;

	assert(spmc_ctx != NULL);

	cm_set_context(&(spmc_ctx->cpu_ctx), SECURE);

	/* Restore the context assigned above */
#if SPMD_SPM_AT_SEL2
	cm_el2_sysregs_context_restore(SECURE);
#else
	cm_el1_sysregs_context_restore(SECURE);
#endif
	cm_set_next_eret_context(SECURE);

	/* Enter SPMC */
	rc = spmd_spm_core_enter(&spmc_ctx->c_rt_ctx);

	/* Save secure state */
#if SPMD_SPM_AT_SEL2
	cm_el2_sysregs_context_save(SECURE);
#else
	cm_el1_sysregs_context_save(SECURE);
#endif

	return rc;
}

/*******************************************************************************
 * This function returns to the place where spmd_spm_core_sync_entry() was
 * called originally.
 ******************************************************************************/
__dead2 void spmd_spm_core_sync_exit(uint64_t rc)
{
	spmd_spm_core_context_t *ctx = spmd_get_context();

	/* Get current CPU context from SPMC context */
	assert(cm_get_context(SECURE) == &(ctx->cpu_ctx));

	/*
	 * The SPMD must have initiated the original request through a
	 * synchronous entry into SPMC. Jump back to the original C runtime
	 * context with the value of rc in x0;
	 */
	spmd_spm_core_exit(ctx->c_rt_ctx, rc);

	panic();
}

/*******************************************************************************
 * Jump to the SPM Core for the first time.
 ******************************************************************************/
static int32_t spmd_init(void)
{
	spmd_spm_core_context_t *ctx = spmd_get_context();
	uint64_t rc;

	VERBOSE("SPM Core init start.\n");

	/* Primary boot core enters the SPMC for initialization. */
	ctx->state = SPMC_STATE_ON_PENDING;

	rc = spmd_spm_core_sync_entry(ctx);
	if (rc != 0ULL) {
		ERROR("SPMC initialisation failed 0x%" PRIx64 "\n", rc);
		return 0;
	}

	ctx->state = SPMC_STATE_ON;

	VERBOSE("SPM Core init end.\n");

	spmd_logical_sp_set_spmc_initialized();
	rc = spmd_logical_sp_init();
	if (rc != 0) {
		WARN("SPMD Logical partitions failed init.\n");
	}

	return 1;
}

/*******************************************************************************
 * spmd_secure_interrupt_handler
 * Enter the SPMC for further handling of the secure interrupt by the SPMC
 * itself or a Secure Partition.
 ******************************************************************************/
static uint64_t spmd_secure_interrupt_handler(uint32_t id,
					      uint32_t flags,
					      void *handle,
					      void *cookie)
{
	spmd_spm_core_context_t *ctx = spmd_get_context();
	gp_regs_t *gpregs = get_gpregs_ctx(&ctx->cpu_ctx);
	unsigned int linear_id = plat_my_core_pos();
	int64_t rc;

	/* Sanity check the security state when the exception was generated */
	assert(get_interrupt_src_ss(flags) == NON_SECURE);

	/* Sanity check the pointer to this cpu's context */
	assert(handle == cm_get_context(NON_SECURE));

	/* Save the non-secure context before entering SPMC */
	cm_el1_sysregs_context_save(NON_SECURE);
#if SPMD_SPM_AT_SEL2
	cm_el2_sysregs_context_save(NON_SECURE);
#endif

	/* Convey the event to the SPMC through the FFA_INTERRUPT interface. */
	write_ctx_reg(gpregs, CTX_GPREG_X0, FFA_INTERRUPT);
	write_ctx_reg(gpregs, CTX_GPREG_X1, 0);
	write_ctx_reg(gpregs, CTX_GPREG_X2, 0);
	write_ctx_reg(gpregs, CTX_GPREG_X3, 0);
	write_ctx_reg(gpregs, CTX_GPREG_X4, 0);
	write_ctx_reg(gpregs, CTX_GPREG_X5, 0);
	write_ctx_reg(gpregs, CTX_GPREG_X6, 0);
	write_ctx_reg(gpregs, CTX_GPREG_X7, 0);

	/* Mark current core as handling a secure interrupt. */
	ctx->secure_interrupt_ongoing = true;

	rc = spmd_spm_core_sync_entry(ctx);
	if (rc != 0ULL) {
		ERROR("%s failed (%" PRId64 ") on CPU%u\n", __func__, rc, linear_id);
	}

	ctx->secure_interrupt_ongoing = false;

	cm_el1_sysregs_context_restore(NON_SECURE);
#if SPMD_SPM_AT_SEL2
	cm_el2_sysregs_context_restore(NON_SECURE);
#endif
	cm_set_next_eret_context(NON_SECURE);

	SMC_RET0(&ctx->cpu_ctx);
}

#if (EL3_EXCEPTION_HANDLING == 0)
/*******************************************************************************
 * spmd_group0_interrupt_handler_nwd
 * Group0 secure interrupt in the normal world are trapped to EL3. Delegate the
 * handling of the interrupt to the platform handler, and return only upon
 * successfully handling the Group0 interrupt.
 ******************************************************************************/
static uint64_t spmd_group0_interrupt_handler_nwd(uint32_t id,
						  uint32_t flags,
						  void *handle,
						  void *cookie)
{
	uint32_t intid;

	/* Sanity check the security state when the exception was generated. */
	assert(get_interrupt_src_ss(flags) == NON_SECURE);

	/* Sanity check the pointer to this cpu's context. */
	assert(handle == cm_get_context(NON_SECURE));

	assert(id == INTR_ID_UNAVAILABLE);

	assert(plat_ic_get_pending_interrupt_type() == INTR_TYPE_EL3);

	intid = plat_ic_acknowledge_interrupt();

	if (plat_spmd_handle_group0_interrupt(intid) < 0) {
		ERROR("Group0 interrupt %u not handled\n", intid);
		panic();
	}

	/* Deactivate the corresponding Group0 interrupt. */
	plat_ic_end_of_interrupt(intid);

	return 0U;
}
#endif

/*******************************************************************************
 * spmd_handle_group0_intr_swd
 * SPMC delegates handling of Group0 secure interrupt to EL3 firmware using
 * FFA_EL3_INTR_HANDLE SMC call. Further, SPMD delegates the handling of the
 * interrupt to the platform handler, and returns only upon successfully
 * handling the Group0 interrupt.
 ******************************************************************************/
static uint64_t spmd_handle_group0_intr_swd(void *handle)
{
	uint32_t intid;

	/* Sanity check the pointer to this cpu's context */
	assert(handle == cm_get_context(SECURE));

	assert(plat_ic_get_pending_interrupt_type() == INTR_TYPE_EL3);

	intid = plat_ic_acknowledge_interrupt();

	/*
	 * TODO: Currently due to a limitation in SPMD implementation, the
	 * platform handler is expected to not delegate handling to NWd while
	 * processing Group0 secure interrupt.
	 */
	if (plat_spmd_handle_group0_interrupt(intid) < 0) {
		/* Group0 interrupt was not handled by the platform. */
		ERROR("Group0 interrupt %u not handled\n", intid);
		panic();
	}

	/* Deactivate the corresponding Group0 interrupt. */
	plat_ic_end_of_interrupt(intid);

	/* Return success. */
	SMC_RET8(handle, FFA_SUCCESS_SMC32, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
		 FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
		 FFA_PARAM_MBZ);
}

#if ENABLE_RME && SPMD_SPM_AT_SEL2 && !RESET_TO_BL31
static int spmd_dynamic_map_mem(uintptr_t base_addr, size_t size,
				 unsigned int attr, uintptr_t *align_addr,
				 size_t *align_size)
{
	uintptr_t base_addr_align;
	size_t mapped_size_align;
	int rc;

	/* Page aligned address and size if necessary */
	base_addr_align = page_align(base_addr, DOWN);
	mapped_size_align = page_align(size, UP);

	if ((base_addr != base_addr_align) &&
	    (size == mapped_size_align)) {
		mapped_size_align += PAGE_SIZE;
	}

	/*
	 * Map dynamically given region with its aligned base address and
	 * size
	 */
	rc = mmap_add_dynamic_region((unsigned long long)base_addr_align,
				     base_addr_align,
				     mapped_size_align,
				     attr);
	if (rc == 0) {
		*align_addr = base_addr_align;
		*align_size = mapped_size_align;
	}

	return rc;
}

static void spmd_do_sec_cpy(uintptr_t root_base_addr, uintptr_t sec_base_addr,
			    size_t size)
{
	uintptr_t root_base_addr_align, sec_base_addr_align;
	size_t root_mapped_size_align, sec_mapped_size_align;
	int rc;

	assert(root_base_addr != 0UL);
	assert(sec_base_addr != 0UL);
	assert(size != 0UL);

	/* Map the memory with required attributes */
	rc = spmd_dynamic_map_mem(root_base_addr, size, MT_RO_DATA | MT_ROOT,
				  &root_base_addr_align,
				  &root_mapped_size_align);
	if (rc != 0) {
		ERROR("%s %s %lu (%d)\n", "Error while mapping", "root region",
		      root_base_addr, rc);
		panic();
	}

	rc = spmd_dynamic_map_mem(sec_base_addr, size, MT_RW_DATA | MT_SECURE,
				  &sec_base_addr_align, &sec_mapped_size_align);
	if (rc != 0) {
		ERROR("%s %s %lu (%d)\n", "Error while mapping",
		      "secure region", sec_base_addr, rc);
		panic();
	}

	/* Do copy operation */
	(void)memcpy((void *)sec_base_addr, (void *)root_base_addr, size);

	/* Unmap root memory region */
	rc = mmap_remove_dynamic_region(root_base_addr_align,
					root_mapped_size_align);
	if (rc != 0) {
		ERROR("%s %s %lu (%d)\n", "Error while unmapping",
		      "root region", root_base_addr_align, rc);
		panic();
	}

	/* Unmap secure memory region */
	rc = mmap_remove_dynamic_region(sec_base_addr_align,
					sec_mapped_size_align);
	if (rc != 0) {
		ERROR("%s %s %lu (%d)\n", "Error while unmapping",
		      "secure region", sec_base_addr_align, rc);
		panic();
	}
}
#endif /* ENABLE_RME && SPMD_SPM_AT_SEL2 && !RESET_TO_BL31 */

/*******************************************************************************
 * Loads SPMC manifest and inits SPMC.
 ******************************************************************************/
static int spmd_spmc_init(void *pm_addr)
{
	cpu_context_t *cpu_ctx;
	unsigned int core_id;
	uint32_t ep_attr, flags;
	int rc;
	const struct dyn_cfg_dtb_info_t *image_info __unused;

	/* Load the SPM Core manifest */
	rc = plat_spm_core_manifest_load(&spmc_attrs, pm_addr);
	if (rc != 0) {
		WARN("No or invalid SPM Core manifest image provided by BL2\n");
		return rc;
	}

	/*
	 * Ensure that the SPM Core version is compatible with the SPM
	 * Dispatcher version.
	 */
	if ((spmc_attrs.major_version != FFA_VERSION_MAJOR) ||
	    (spmc_attrs.minor_version > FFA_VERSION_MINOR)) {
		WARN("Unsupported FFA version (%u.%u)\n",
		     spmc_attrs.major_version, spmc_attrs.minor_version);
		return -EINVAL;
	}

	VERBOSE("FFA version (%u.%u)\n", spmc_attrs.major_version,
	     spmc_attrs.minor_version);

	VERBOSE("SPM Core run time EL%x.\n",
	     SPMD_SPM_AT_SEL2 ? MODE_EL2 : MODE_EL1);

	/* Validate the SPMC ID, Ensure high bit is set */
	if (((spmc_attrs.spmc_id >> SPMC_SECURE_ID_SHIFT) &
			SPMC_SECURE_ID_MASK) == 0U) {
		WARN("Invalid ID (0x%x) for SPMC.\n", spmc_attrs.spmc_id);
		return -EINVAL;
	}

	/* Validate the SPM Core execution state */
	if ((spmc_attrs.exec_state != MODE_RW_64) &&
	    (spmc_attrs.exec_state != MODE_RW_32)) {
		WARN("Unsupported %s%x.\n", "SPM Core execution state 0x",
		     spmc_attrs.exec_state);
		return -EINVAL;
	}

	VERBOSE("%s%x.\n", "SPM Core execution state 0x",
		spmc_attrs.exec_state);

#if SPMD_SPM_AT_SEL2
	/* Ensure manifest has not requested AArch32 state in S-EL2 */
	if (spmc_attrs.exec_state == MODE_RW_32) {
		WARN("AArch32 state at S-EL2 is not supported.\n");
		return -EINVAL;
	}

	/*
	 * Check if S-EL2 is supported on this system if S-EL2
	 * is required for SPM
	 */
	if (!is_feat_sel2_supported()) {
		WARN("SPM Core run time S-EL2 is not supported.\n");
		return -EINVAL;
	}
#endif /* SPMD_SPM_AT_SEL2 */

	/* Initialise an entrypoint to set up the CPU context */
	ep_attr = SECURE | EP_ST_ENABLE;
	if ((read_sctlr_el3() & SCTLR_EE_BIT) != 0ULL) {
		ep_attr |= EP_EE_BIG;
	}

	SET_PARAM_HEAD(spmc_ep_info, PARAM_EP, VERSION_1, ep_attr);

	/*
	 * Populate SPSR for SPM Core based upon validated parameters from the
	 * manifest.
	 */
	if (spmc_attrs.exec_state == MODE_RW_32) {
		spmc_ep_info->spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM,
						 SPSR_E_LITTLE,
						 DAIF_FIQ_BIT |
						 DAIF_IRQ_BIT |
						 DAIF_ABT_BIT);
	} else {

#if SPMD_SPM_AT_SEL2
		static const uint32_t runtime_el = MODE_EL2;
#else
		static const uint32_t runtime_el = MODE_EL1;
#endif
		spmc_ep_info->spsr = SPSR_64(runtime_el,
					     MODE_SP_ELX,
					     DISABLE_ALL_EXCEPTIONS);
	}

#if ENABLE_RME && SPMD_SPM_AT_SEL2 && !RESET_TO_BL31
	image_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TOS_FW_CONFIG_ID);
	assert(image_info != NULL);

	if ((image_info->config_addr == 0UL) ||
	    (image_info->secondary_config_addr == 0UL) ||
	    (image_info->config_max_size == 0UL)) {
		return -EINVAL;
	}

	/* Copy manifest from root->secure region */
	spmd_do_sec_cpy(image_info->config_addr,
			image_info->secondary_config_addr,
			image_info->config_max_size);

	/* Update ep info of BL32 */
	assert(spmc_ep_info != NULL);
	spmc_ep_info->args.arg0 = image_info->secondary_config_addr;
#endif /* ENABLE_RME && SPMD_SPM_AT_SEL2 && !RESET_TO_BL31 */

	/* Set an initial SPMC context state for all cores. */
	for (core_id = 0U; core_id < PLATFORM_CORE_COUNT; core_id++) {
		spm_core_context[core_id].state = SPMC_STATE_OFF;

		/* Setup an initial cpu context for the SPMC. */
		cpu_ctx = &spm_core_context[core_id].cpu_ctx;
		cm_setup_context(cpu_ctx, spmc_ep_info);

		/*
		 * Pass the core linear ID to the SPMC through x4.
		 * (TF-A implementation defined behavior helping
		 * a legacy TOS migration to adopt FF-A).
		 */
		write_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X4, core_id);
	}

	/* Register power management hooks with PSCI */
	psci_register_spd_pm_hook(&spmd_pm);

	/* Register init function for deferred init. */
	bl31_register_bl32_init(&spmd_init);

	INFO("SPM Core setup done.\n");

	/*
	 * Register an interrupt handler routing secure interrupts to SPMD
	 * while the NWd is running.
	 */
	flags = 0;
	set_interrupt_rm_flag(flags, NON_SECURE);
	rc = register_interrupt_type_handler(INTR_TYPE_S_EL1,
					     spmd_secure_interrupt_handler,
					     flags);
	if (rc != 0) {
		panic();
	}

	/*
	 * Permit configurations where the SPM resides at S-EL1/2 and upon a
	 * Group0 interrupt triggering while the normal world runs, the
	 * interrupt is routed either through the EHF or directly to the SPMD:
	 *
	 * EL3_EXCEPTION_HANDLING=0: the Group0 interrupt is routed to the SPMD
	 *                   for handling by spmd_group0_interrupt_handler_nwd.
	 *
	 * EL3_EXCEPTION_HANDLING=1: the Group0 interrupt is routed to the EHF.
	 *
	 */
#if (EL3_EXCEPTION_HANDLING == 0)
	/*
	 * Register an interrupt handler routing Group0 interrupts to SPMD
	 * while the NWd is running.
	 */
	rc = register_interrupt_type_handler(INTR_TYPE_EL3,
					     spmd_group0_interrupt_handler_nwd,
					     flags);
	if (rc != 0) {
		panic();
	}
#endif

	return 0;
}

/*******************************************************************************
 * Initialize context of SPM Core.
 ******************************************************************************/
int spmd_setup(void)
{
	int rc;
	void *spmc_manifest;

	/*
	 * If the SPMC is at EL3, then just initialise it directly. The
	 * shenanigans of when it is at a lower EL are not needed.
	 */
	if (is_spmc_at_el3()) {
		/* Allow the SPMC to populate its attributes directly. */
		spmc_populate_attrs(&spmc_attrs);

		rc = spmc_setup();
		if (rc != 0) {
			WARN("SPMC initialisation failed 0x%x.\n", rc);
		}
		return 0;
	}

	spmc_ep_info = bl31_plat_get_next_image_ep_info(SECURE);
	if (spmc_ep_info == NULL) {
		WARN("No SPM Core image provided by BL2 boot loader.\n");
		return 0;
	}

	/* Under no circumstances will this parameter be 0 */
	assert(spmc_ep_info->pc != 0ULL);

	/*
	 * Check if BL32 ep_info has a reference to 'tos_fw_config'. This will
	 * be used as a manifest for the SPM Core at the next lower EL/mode.
	 */
	spmc_manifest = (void *)spmc_ep_info->args.arg0;
	if (spmc_manifest == NULL) {
		WARN("Invalid or absent SPM Core manifest.\n");
		return 0;
	}

	/* Load manifest, init SPMC */
	rc = spmd_spmc_init(spmc_manifest);
	if (rc != 0) {
		WARN("Booting device without SPM initialization.\n");
	}

	return 0;
}

/*******************************************************************************
 * Forward FF-A SMCs to the other security state.
 ******************************************************************************/
uint64_t spmd_smc_switch_state(uint32_t smc_fid,
			       bool secure_origin,
			       uint64_t x1,
			       uint64_t x2,
			       uint64_t x3,
			       uint64_t x4,
			       void *handle)
{
	unsigned int secure_state_in = (secure_origin) ? SECURE : NON_SECURE;
	unsigned int secure_state_out = (!secure_origin) ? SECURE : NON_SECURE;

	/* Save incoming security state */
#if SPMD_SPM_AT_SEL2
	if (secure_state_in == NON_SECURE) {
		cm_el1_sysregs_context_save(secure_state_in);
	}
	cm_el2_sysregs_context_save(secure_state_in);
#else
	cm_el1_sysregs_context_save(secure_state_in);
#endif

	/* Restore outgoing security state */
#if SPMD_SPM_AT_SEL2
	if (secure_state_out == NON_SECURE) {
		cm_el1_sysregs_context_restore(secure_state_out);
	}
	cm_el2_sysregs_context_restore(secure_state_out);
#else
	cm_el1_sysregs_context_restore(secure_state_out);
#endif
	cm_set_next_eret_context(secure_state_out);

#if SPMD_SPM_AT_SEL2
	/*
	 * If SPMC is at SEL2, save additional registers x8-x17, which may
	 * be used in FF-A calls such as FFA_PARTITION_INFO_GET_REGS.
	 * Note that technically, all SPMCs can support this, but this code is
	 * under ifdef to minimize breakage in case other SPMCs do not save
	 * and restore x8-x17.
	 * We also need to pass through these registers since not all FF-A ABIs
	 * modify x8-x17, in which case, SMCCC requires that these registers be
	 * preserved, so the SPMD passes through these registers and expects the
	 * SPMC to save and restore (potentially also modify) them.
	 */
	SMC_RET18(cm_get_context(secure_state_out), smc_fid, x1, x2, x3, x4,
			SMC_GET_GP(handle, CTX_GPREG_X5),
			SMC_GET_GP(handle, CTX_GPREG_X6),
			SMC_GET_GP(handle, CTX_GPREG_X7),
			SMC_GET_GP(handle, CTX_GPREG_X8),
			SMC_GET_GP(handle, CTX_GPREG_X9),
			SMC_GET_GP(handle, CTX_GPREG_X10),
			SMC_GET_GP(handle, CTX_GPREG_X11),
			SMC_GET_GP(handle, CTX_GPREG_X12),
			SMC_GET_GP(handle, CTX_GPREG_X13),
			SMC_GET_GP(handle, CTX_GPREG_X14),
			SMC_GET_GP(handle, CTX_GPREG_X15),
			SMC_GET_GP(handle, CTX_GPREG_X16),
			SMC_GET_GP(handle, CTX_GPREG_X17)
			);

#else
	SMC_RET8(cm_get_context(secure_state_out), smc_fid, x1, x2, x3, x4,
			SMC_GET_GP(handle, CTX_GPREG_X5),
			SMC_GET_GP(handle, CTX_GPREG_X6),
			SMC_GET_GP(handle, CTX_GPREG_X7));
#endif
}

/*******************************************************************************
 * Forward SMCs to the other security state.
 ******************************************************************************/
static uint64_t spmd_smc_forward(uint32_t smc_fid,
				 bool secure_origin,
				 uint64_t x1,
				 uint64_t x2,
				 uint64_t x3,
				 uint64_t x4,
				 void *cookie,
				 void *handle,
				 uint64_t flags)
{
	if (is_spmc_at_el3() && !secure_origin) {
		return spmc_smc_handler(smc_fid, secure_origin, x1, x2, x3, x4,
					cookie, handle, flags);
	}
	return spmd_smc_switch_state(smc_fid, secure_origin, x1, x2, x3, x4,
				     handle);

}

/*******************************************************************************
 * Return FFA_ERROR with specified error code
 ******************************************************************************/
static uint64_t spmd_ffa_error_return(void *handle, int error_code)
{
	SMC_RET8(handle, (uint32_t) FFA_ERROR,
		 FFA_TARGET_INFO_MBZ, (uint32_t)error_code,
		 FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
		 FFA_PARAM_MBZ, FFA_PARAM_MBZ);
}

/*******************************************************************************
 * spmd_check_address_in_binary_image
 ******************************************************************************/
bool spmd_check_address_in_binary_image(uint64_t address)
{
	assert(!check_uptr_overflow(spmc_attrs.load_address, spmc_attrs.binary_size));

	return ((address >= spmc_attrs.load_address) &&
		(address < (spmc_attrs.load_address + spmc_attrs.binary_size)));
}

/******************************************************************************
 * spmd_is_spmc_message
 *****************************************************************************/
static bool spmd_is_spmc_message(unsigned int ep)
{
	if (is_spmc_at_el3()) {
		return false;
	}

	return ((ffa_endpoint_destination(ep) == SPMD_DIRECT_MSG_ENDPOINT_ID)
		&& (ffa_endpoint_source(ep) == spmc_attrs.spmc_id));
}

/******************************************************************************
 * spmd_handle_spmc_message
 *****************************************************************************/
static int spmd_handle_spmc_message(unsigned long long msg,
		unsigned long long parm1, unsigned long long parm2,
		unsigned long long parm3, unsigned long long parm4)
{
	VERBOSE("%s %llx %llx %llx %llx %llx\n", __func__,
		msg, parm1, parm2, parm3, parm4);

	return -EINVAL;
}

/*******************************************************************************
 * This function forwards FF-A SMCs to either the main SPMD handler or the
 * SPMC at EL3, depending on the origin security state, if enabled.
 ******************************************************************************/
uint64_t spmd_ffa_smc_handler(uint32_t smc_fid,
			      uint64_t x1,
			      uint64_t x2,
			      uint64_t x3,
			      uint64_t x4,
			      void *cookie,
			      void *handle,
			      uint64_t flags)
{
	if (is_spmc_at_el3()) {
		/*
		 * If we have an SPMC at EL3 allow handling of the SMC first.
		 * The SPMC will call back through to SPMD handler if required.
		 */
		if (is_caller_secure(flags)) {
			return spmc_smc_handler(smc_fid,
						is_caller_secure(flags),
						x1, x2, x3, x4, cookie,
						handle, flags);
		}
	}
	return spmd_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
				handle, flags);
}

/*******************************************************************************
 * This function handles all SMCs in the range reserved for FFA. Each call is
 * either forwarded to the other security state or handled by the SPM dispatcher
 ******************************************************************************/
uint64_t spmd_smc_handler(uint32_t smc_fid,
			  uint64_t x1,
			  uint64_t x2,
			  uint64_t x3,
			  uint64_t x4,
			  void *cookie,
			  void *handle,
			  uint64_t flags)
{
	unsigned int linear_id = plat_my_core_pos();
	spmd_spm_core_context_t *ctx = spmd_get_context();
	bool secure_origin;
	int32_t ret;
	uint32_t input_version;

	/* Determine which security state this SMC originated from */
	secure_origin = is_caller_secure(flags);

	VERBOSE("SPM(%u): 0x%x 0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64
		" 0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64 "\n",
		    linear_id, smc_fid, x1, x2, x3, x4,
		    SMC_GET_GP(handle, CTX_GPREG_X5),
		    SMC_GET_GP(handle, CTX_GPREG_X6),
		    SMC_GET_GP(handle, CTX_GPREG_X7));

	switch (smc_fid) {
	case FFA_ERROR:
		/*
		 * Check if this is the first invocation of this interface on
		 * this CPU. If so, then indicate that the SPM Core initialised
		 * unsuccessfully.
		 */
		if (secure_origin && (ctx->state == SPMC_STATE_ON_PENDING)) {
			spmd_spm_core_sync_exit(x2);
		}

		/*
		 * If there was an SPMD logical partition direct request on-going,
		 * return back to the SPMD logical partition so the error can be
		 * consumed.
		 */
		if (is_spmd_logical_sp_dir_req_in_progress(ctx)) {
			assert(secure_origin);
			spmd_spm_core_sync_exit(0ULL);
		}

		return spmd_smc_forward(smc_fid, secure_origin,
					x1, x2, x3, x4, cookie,
					handle, flags);
		break; /* not reached */

	case FFA_VERSION:
		input_version = (uint32_t)(0xFFFFFFFF & x1);
		/*
		 * If caller is secure and SPMC was initialized,
		 * return FFA_VERSION of SPMD.
		 * If caller is non secure and SPMC was initialized,
		 * forward to the EL3 SPMC if enabled, otherwise return
		 * the SPMC version if implemented at a lower EL.
		 * Sanity check to "input_version".
		 * If the EL3 SPMC is enabled, ignore the SPMC state as
		 * this is not used.
		 */
		if ((input_version & FFA_VERSION_BIT31_MASK) ||
		    (!is_spmc_at_el3() && (ctx->state == SPMC_STATE_RESET))) {
			ret = FFA_ERROR_NOT_SUPPORTED;
		} else if (!secure_origin) {
			if (is_spmc_at_el3()) {
				/*
				 * Forward the call directly to the EL3 SPMC, if
				 * enabled, as we don't need to wrap the call in
				 * a direct request.
				 */
				return spmd_smc_forward(smc_fid, secure_origin,
							x1, x2, x3, x4, cookie,
							handle, flags);
			}

			gp_regs_t *gpregs = get_gpregs_ctx(&ctx->cpu_ctx);
			uint64_t rc;

			if (spmc_attrs.major_version == 1 &&
			    spmc_attrs.minor_version == 0) {
				ret = MAKE_FFA_VERSION(spmc_attrs.major_version,
						       spmc_attrs.minor_version);
				SMC_RET8(handle, (uint32_t)ret,
					 FFA_TARGET_INFO_MBZ,
					 FFA_TARGET_INFO_MBZ,
					 FFA_PARAM_MBZ, FFA_PARAM_MBZ,
					 FFA_PARAM_MBZ, FFA_PARAM_MBZ,
					 FFA_PARAM_MBZ);
				break;
			}
			/* Save non-secure system registers context */
			cm_el1_sysregs_context_save(NON_SECURE);
#if SPMD_SPM_AT_SEL2
			cm_el2_sysregs_context_save(NON_SECURE);
#endif

			/*
			 * The incoming request has FFA_VERSION as X0 smc_fid
			 * and requested version in x1. Prepare a direct request
			 * from SPMD to SPMC with FFA_VERSION framework function
			 * identifier in X2 and requested version in X3.
			 */
			spmd_build_spmc_message(gpregs,
						SPMD_FWK_MSG_FFA_VERSION_REQ,
						input_version);

			rc = spmd_spm_core_sync_entry(ctx);

			if ((rc != 0ULL) ||
			    (SMC_GET_GP(gpregs, CTX_GPREG_X0) !=
				FFA_MSG_SEND_DIRECT_RESP_SMC32) ||
			    (SMC_GET_GP(gpregs, CTX_GPREG_X2) !=
				(FFA_FWK_MSG_BIT |
				 SPMD_FWK_MSG_FFA_VERSION_RESP))) {
				ERROR("Failed to forward FFA_VERSION\n");
				ret = FFA_ERROR_NOT_SUPPORTED;
			} else {
				ret = SMC_GET_GP(gpregs, CTX_GPREG_X3);
			}

			/*
			 * Return here after SPMC has handled FFA_VERSION.
			 * The returned SPMC version is held in X3.
			 * Forward this version in X0 to the non-secure caller.
			 */
			return spmd_smc_forward(ret, true, FFA_PARAM_MBZ,
						FFA_PARAM_MBZ, FFA_PARAM_MBZ,
						FFA_PARAM_MBZ, cookie, gpregs,
						flags);
		} else {
			ret = MAKE_FFA_VERSION(FFA_VERSION_MAJOR,
					       FFA_VERSION_MINOR);
		}

		SMC_RET8(handle, (uint32_t)ret, FFA_TARGET_INFO_MBZ,
			 FFA_TARGET_INFO_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
			 FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ);
		break; /* not reached */

	case FFA_FEATURES:
		/*
		 * This is an optional interface. Do the minimal checks and
		 * forward to SPM Core which will handle it if implemented.
		 */

		/* Forward SMC from Normal world to the SPM Core */
		if (!secure_origin) {
			return spmd_smc_forward(smc_fid, secure_origin,
						x1, x2, x3, x4, cookie,
						handle, flags);
		}

		/*
		 * Return success if call was from secure world i.e. all
		 * FFA functions are supported. This is essentially a
		 * nop.
		 */
		SMC_RET8(handle, FFA_SUCCESS_SMC32, x1, x2, x3, x4,
			 SMC_GET_GP(handle, CTX_GPREG_X5),
			 SMC_GET_GP(handle, CTX_GPREG_X6),
			 SMC_GET_GP(handle, CTX_GPREG_X7));

		break; /* not reached */

	case FFA_ID_GET:
		/*
		 * Returns the ID of the calling FFA component.
		 */
		if (!secure_origin) {
			SMC_RET8(handle, FFA_SUCCESS_SMC32,
				 FFA_TARGET_INFO_MBZ, FFA_NS_ENDPOINT_ID,
				 FFA_PARAM_MBZ, FFA_PARAM_MBZ,
				 FFA_PARAM_MBZ, FFA_PARAM_MBZ,
				 FFA_PARAM_MBZ);
		}

		SMC_RET8(handle, FFA_SUCCESS_SMC32,
			 FFA_TARGET_INFO_MBZ, spmc_attrs.spmc_id,
			 FFA_PARAM_MBZ, FFA_PARAM_MBZ,
			 FFA_PARAM_MBZ, FFA_PARAM_MBZ,
			 FFA_PARAM_MBZ);

		break; /* not reached */

	case FFA_SECONDARY_EP_REGISTER_SMC64:
		if (secure_origin) {
			ret = spmd_pm_secondary_ep_register(x1);

			if (ret < 0) {
				SMC_RET8(handle, FFA_ERROR_SMC64,
					FFA_TARGET_INFO_MBZ, ret,
					FFA_PARAM_MBZ, FFA_PARAM_MBZ,
					FFA_PARAM_MBZ, FFA_PARAM_MBZ,
					FFA_PARAM_MBZ);
			} else {
				SMC_RET8(handle, FFA_SUCCESS_SMC64,
					FFA_TARGET_INFO_MBZ, FFA_PARAM_MBZ,
					FFA_PARAM_MBZ, FFA_PARAM_MBZ,
					FFA_PARAM_MBZ, FFA_PARAM_MBZ,
					FFA_PARAM_MBZ);
			}
		}

		return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
		break; /* Not reached */

	case FFA_SPM_ID_GET:
		if (MAKE_FFA_VERSION(1, 1) > FFA_VERSION_COMPILED) {
			return spmd_ffa_error_return(handle,
						     FFA_ERROR_NOT_SUPPORTED);
		}
		/*
		 * Returns the ID of the SPMC or SPMD depending on the FF-A
		 * instance where this function is invoked
		 */
		if (!secure_origin) {
			SMC_RET8(handle, FFA_SUCCESS_SMC32,
				 FFA_TARGET_INFO_MBZ, spmc_attrs.spmc_id,
				 FFA_PARAM_MBZ, FFA_PARAM_MBZ,
				 FFA_PARAM_MBZ, FFA_PARAM_MBZ,
				 FFA_PARAM_MBZ);
		}
		SMC_RET8(handle, FFA_SUCCESS_SMC32,
			 FFA_TARGET_INFO_MBZ, SPMD_DIRECT_MSG_ENDPOINT_ID,
			 FFA_PARAM_MBZ, FFA_PARAM_MBZ,
			 FFA_PARAM_MBZ, FFA_PARAM_MBZ,
			 FFA_PARAM_MBZ);

		break; /* not reached */

	case FFA_MSG_SEND_DIRECT_REQ_SMC32:
	case FFA_MSG_SEND_DIRECT_REQ_SMC64:
		/*
		 * Regardless of secure_origin, SPMD logical partitions cannot
		 * handle direct messages. They can only initiate direct
		 * messages and consume direct responses or errors.
		 */
		if (is_spmd_lp_id(ffa_endpoint_source(x1)) ||
				  is_spmd_lp_id(ffa_endpoint_destination(x1))) {
			return spmd_ffa_error_return(handle,
						     FFA_ERROR_INVALID_PARAMETER
						     );
		}

		/*
		 * When there is an ongoing SPMD logical partition direct
		 * request, there cannot be another direct request. Return
		 * error in this case. Panic'ing is an option but that does
		 * not provide the opportunity for caller to abort based on
		 * error codes.
		 */
		if (is_spmd_logical_sp_dir_req_in_progress(ctx)) {
			assert(secure_origin);
			return spmd_ffa_error_return(handle,
						     FFA_ERROR_DENIED);
		}

		if (!secure_origin) {
			/* Validate source endpoint is non-secure for non-secure caller. */
			if (ffa_is_secure_world_id(ffa_endpoint_source(x1))) {
				return spmd_ffa_error_return(handle,
						FFA_ERROR_INVALID_PARAMETER);
			}
		}
		if (secure_origin && spmd_is_spmc_message(x1)) {
			ret = spmd_handle_spmc_message(x3, x4,
				SMC_GET_GP(handle, CTX_GPREG_X5),
				SMC_GET_GP(handle, CTX_GPREG_X6),
				SMC_GET_GP(handle, CTX_GPREG_X7));

			SMC_RET8(handle, FFA_SUCCESS_SMC32,
				FFA_TARGET_INFO_MBZ, ret,
				FFA_PARAM_MBZ, FFA_PARAM_MBZ,
				FFA_PARAM_MBZ, FFA_PARAM_MBZ,
				FFA_PARAM_MBZ);
		} else {
			/* Forward direct message to the other world */
			return spmd_smc_forward(smc_fid, secure_origin,
						x1, x2, x3, x4, cookie,
						handle, flags);
		}
		break; /* Not reached */

	case FFA_MSG_SEND_DIRECT_RESP_SMC32:
	case FFA_MSG_SEND_DIRECT_RESP_SMC64:
		if (secure_origin && (spmd_is_spmc_message(x1) ||
		    is_spmd_logical_sp_dir_req_in_progress(ctx))) {
			spmd_spm_core_sync_exit(0ULL);
		} else {
			/* Forward direct message to the other world */
			return spmd_smc_forward(smc_fid, secure_origin,
						x1, x2, x3, x4, cookie,
						handle, flags);
		}
		break; /* Not reached */

	case FFA_RX_RELEASE:
	case FFA_RXTX_MAP_SMC32:
	case FFA_RXTX_MAP_SMC64:
	case FFA_RXTX_UNMAP:
	case FFA_PARTITION_INFO_GET:
#if MAKE_FFA_VERSION(1, 1) <= FFA_VERSION_COMPILED
	case FFA_NOTIFICATION_BITMAP_CREATE:
	case FFA_NOTIFICATION_BITMAP_DESTROY:
	case FFA_NOTIFICATION_BIND:
	case FFA_NOTIFICATION_UNBIND:
	case FFA_NOTIFICATION_SET:
	case FFA_NOTIFICATION_GET:
	case FFA_NOTIFICATION_INFO_GET:
	case FFA_NOTIFICATION_INFO_GET_SMC64:
	case FFA_MSG_SEND2:
	case FFA_RX_ACQUIRE:
#endif
	case FFA_MSG_RUN:
		/*
		 * Above calls should be invoked only by the Normal world and
		 * must not be forwarded from Secure world to Normal world.
		 */
		if (secure_origin) {
			return spmd_ffa_error_return(handle,
						     FFA_ERROR_NOT_SUPPORTED);
		}

		/* Forward the call to the other world */
		/* fallthrough */
	case FFA_MSG_SEND:
	case FFA_MEM_DONATE_SMC32:
	case FFA_MEM_DONATE_SMC64:
	case FFA_MEM_LEND_SMC32:
	case FFA_MEM_LEND_SMC64:
	case FFA_MEM_SHARE_SMC32:
	case FFA_MEM_SHARE_SMC64:
	case FFA_MEM_RETRIEVE_REQ_SMC32:
	case FFA_MEM_RETRIEVE_REQ_SMC64:
	case FFA_MEM_RETRIEVE_RESP:
	case FFA_MEM_RELINQUISH:
	case FFA_MEM_RECLAIM:
	case FFA_MEM_FRAG_TX:
	case FFA_MEM_FRAG_RX:
	case FFA_SUCCESS_SMC32:
	case FFA_SUCCESS_SMC64:
		/*
		 * If there is an ongoing direct request from an SPMD logical
		 * partition, return an error.
		 */
		if (is_spmd_logical_sp_dir_req_in_progress(ctx)) {
			assert(secure_origin);
			return spmd_ffa_error_return(handle,
					FFA_ERROR_DENIED);
		}

		return spmd_smc_forward(smc_fid, secure_origin,
					x1, x2, x3, x4, cookie,
					handle, flags);
		break; /* not reached */

	case FFA_MSG_WAIT:
		/*
		 * Check if this is the first invocation of this interface on
		 * this CPU from the Secure world. If so, then indicate that the
		 * SPM Core initialised successfully.
		 */
		if (secure_origin && (ctx->state == SPMC_STATE_ON_PENDING)) {
			spmd_spm_core_sync_exit(0ULL);
		}

		/* Forward the call to the other world */
		/* fallthrough */
	case FFA_INTERRUPT:
	case FFA_MSG_YIELD:
		/* This interface must be invoked only by the Secure world */
		if (!secure_origin) {
			return spmd_ffa_error_return(handle,
						      FFA_ERROR_NOT_SUPPORTED);
		}

		if (is_spmd_logical_sp_dir_req_in_progress(ctx)) {
			assert(secure_origin);
			return spmd_ffa_error_return(handle,
					FFA_ERROR_DENIED);
		}

		return spmd_smc_forward(smc_fid, secure_origin,
					x1, x2, x3, x4, cookie,
					handle, flags);
		break; /* not reached */

	case FFA_NORMAL_WORLD_RESUME:
		if (secure_origin && ctx->secure_interrupt_ongoing) {
			spmd_spm_core_sync_exit(0ULL);
		} else {
			return spmd_ffa_error_return(handle, FFA_ERROR_DENIED);
		}
		break; /* Not reached */
#if MAKE_FFA_VERSION(1, 1) <= FFA_VERSION_COMPILED
	case FFA_PARTITION_INFO_GET_REGS_SMC64:
		if (secure_origin) {
			/* TODO: Future patches to enable support for this */
			return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
		}

		/* Call only supported with SMCCC 1.2+ */
		if (MAKE_SMCCC_VERSION(SMCCC_MAJOR_VERSION, SMCCC_MINOR_VERSION) < 0x10002) {
			return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
		}

		return spmd_smc_forward(smc_fid, secure_origin,
					x1, x2, x3, x4, cookie,
					handle, flags);
		break; /* Not reached */
#endif
	case FFA_EL3_INTR_HANDLE:
		if (secure_origin) {
			return spmd_handle_group0_intr_swd(handle);
		} else {
			return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
		}
	default:
		WARN("SPM: Unsupported call 0x%08x\n", smc_fid);
		return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
	}
}
