/*
 * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
 * SPDX-License-Identifier: BSD-3-Clause
 */
#ifndef EL3_SPMD_LOGICAL_SP_H
#define EL3_SPMD_LOGICAL_SP_H

#include <common/bl_common.h>
#include <lib/cassert.h>
#include <services/ffa_svc.h>

/*******************************************************************************
 * Structure definition, typedefs & constants for the SPMD Logical Partitions.
 ******************************************************************************/
typedef struct spmd_spm_core_context spmd_spm_core_context_t;

/* Prototype for SPMD logical partition initializing function. */
typedef int32_t (*ffa_spmd_lp_init_t)(void);

/* SPMD Logical Partition Descriptor. */
struct spmd_lp_desc {
	ffa_spmd_lp_init_t init;
	uint16_t sp_id;
	uint32_t properties;
	uint32_t uuid[4];  /* Little Endian. */
	const char *debug_name;
};

struct ffa_value {
	uint64_t func;
	uint64_t arg1;
	uint64_t arg2;
	uint64_t arg3;
	uint64_t arg4;
	uint64_t arg5;
	uint64_t arg6;
	uint64_t arg7;
	uint64_t arg8;
	uint64_t arg9;
	uint64_t arg10;
	uint64_t arg11;
	uint64_t arg12;
	uint64_t arg13;
	uint64_t arg14;
	uint64_t arg15;
	uint64_t arg16;
	uint64_t arg17;
};

/* Convenience macro to declare a SPMD logical partition descriptor. */
#define DECLARE_SPMD_LOGICAL_PARTITION(_name, _init, _sp_id, _uuid, _properties) \
	static const struct spmd_lp_desc __partition_desc_ ## _name	    \
		__section(".spmd_lp_descs") __used = {			    \
			.debug_name = #_name,				    \
			.init = (_init),				    \
			.sp_id = (_sp_id),				    \
			.uuid = _uuid,					    \
			.properties = (_properties),			    \
		}

IMPORT_SYM(uintptr_t, __SPMD_LP_DESCS_START__,	SPMD_LP_DESCS_START);
IMPORT_SYM(uintptr_t, __SPMD_LP_DESCS_END__,	SPMD_LP_DESCS_END);

#define SPMD_LP_DESCS_COUNT ((SPMD_LP_DESCS_END - SPMD_LP_DESCS_START) \
			  / sizeof(struct spmd_lp_desc))
CASSERT(sizeof(struct spmd_lp_desc) == 40, assert_spmd_lp_desc_size_mismatch);

/*
 * Reserve 63 IDs for SPMD Logical Partitions. Currently, 0xFFC0 to 0xFFFE
 * is reserved.
 */
#define SPMD_LP_ID_END		(SPMD_DIRECT_MSG_ENDPOINT_ID - 1)
#define SPMD_LP_ID_START	(SPMD_LP_ID_END - 62)

/*
 * TODO: Arbitrary number. Can make this platform specific in the future,
 * no known use cases for more LPs at this point.
 */
#define EL3_SPMD_MAX_NUM_LP	U(5)

static inline bool is_spmd_lp_id(unsigned int id)
{
#if ENABLE_SPMD_LP
	return (id >= SPMD_LP_ID_START && id <= SPMD_LP_ID_END);
#else
	return false;
#endif
}

static inline bool is_ffa_error(struct ffa_value *retval)
{
	return retval->func == FFA_ERROR;
}

static inline bool is_ffa_success(struct ffa_value *retval)
{
	return (retval->func == FFA_SUCCESS_SMC32) ||
		(retval->func == FFA_SUCCESS_SMC64);
}

static inline bool is_ffa_direct_msg_resp(struct ffa_value *retval)
{
	return (retval->func == FFA_MSG_SEND_DIRECT_RESP_SMC32) ||
		(retval->func == FFA_MSG_SEND_DIRECT_RESP_SMC64);
}

static inline uint16_t ffa_partition_info_regs_get_last_idx(
	struct ffa_value args)
{
	return (uint16_t)(args.arg2 & 0xFFFFU);
}

static inline uint16_t ffa_partition_info_regs_get_curr_idx(
	struct ffa_value args)
{
	return (uint16_t)((args.arg2 >> 16) & 0xFFFFU);
}

static inline uint16_t ffa_partition_info_regs_get_tag(struct ffa_value args)
{
	return (uint16_t)((args.arg2 >> 32) & 0xFFFFU);
}

static inline uint16_t ffa_partition_info_regs_get_desc_size(
	struct ffa_value args)
{
	return (uint16_t)(args.arg2 >> 48);
}

uint64_t spmd_el3_populate_logical_partition_info(void *handle, uint64_t x1,
						  uint64_t x2, uint64_t x3);

bool ffa_partition_info_regs_get_part_info(
	struct ffa_value args, uint8_t idx,
	struct ffa_partition_info_v1_1 *partition_info);

bool spmd_el3_invoke_partition_info_get(
				const uint32_t target_uuid[4],
				const uint16_t start_index,
				const uint16_t tag,
				struct ffa_value *retval);
void spmd_logical_sp_set_spmc_initialized(void);
void spmc_logical_sp_set_spmc_failure(void);

int32_t spmd_logical_sp_init(void);
bool is_spmd_logical_sp_dir_req_in_progress(
		spmd_spm_core_context_t *ctx);

bool is_spmd_logical_sp_info_regs_req_in_progress(
		spmd_spm_core_context_t *ctx);

bool spmd_el3_ffa_msg_direct_req(uint64_t x1,
				 uint64_t x2,
				 uint64_t x3,
				 uint64_t x4,
				 void *handle,
				 struct ffa_value *retval);

uintptr_t plat_spmd_logical_sp_smc_handler(unsigned int smc_fid,
		u_register_t x1,
		u_register_t x2,
		u_register_t x3,
		u_register_t x4,
		void *cookie,
		void *handle,
		u_register_t flags);

#endif /* EL3_SPMD_LOGICAL_SP_H */
