/*

 * Copyright (C) 2022 Huawei Technologies Co., Ltd.

 * Decription: declarations for ffa functions and useful macros

 *

 * This software is licensed under the terms of the GNU General Public

 * License version 2, as published by the Free Software Foundation, and

 * may be copied, distributed, and modified under those terms.

 *

 * This program is distributed in the hope that it will be useful,

 * but WITHOUT ANY WARRANTY; without even the implied warranty of

 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

 * GNU General Public License for more details.

 */

#ifndef FFA_ABI_H

#define FFA_ABI_H



#include <linux/arm_ffa.h>

#include "smc_smp.h"

#include "smc_call.h"

/*

 * Normal world sends requests with FFA_MSG_SEND_DIRECT_REQ and

 * responses are returned with FFA_MSG_SEND_DIRECT_RESP for normal

 * messages.

 *

 * All requests with FFA_MSG_SEND_DIRECT_REQ and FFA_MSG_SEND_DIRECT_RESP

 * are using the AArch32 SMC calling convention with register usage as

 * defined in FF-A specification:

 * w0:	Function ID (0x8400006F or 0x84000070)

 * w1:	Source/Destination IDs

 * w2:	Reserved (MBZ)

 * w3-w7: Implementation defined, free to be used below

 */



#define TZ_FFA_VERSION_MAJOR 1

#define TZ_FFA_VERSION_MINOR 0



#define TZ_FFA_BLOCKING_CALL(id)	(id)

#define TZ_FFA_YIELDING_CALL_BIT	31

#define TZ_FFA_YIELDING_CALL(id)	((id) | BIT(TZ_FFA_YIELDING_CALL_BIT))



/*

 * Returns the API version implemented, currently follows the FF-A version.

 * Call register usage:

 * w3:	Service ID, TZ_FFA_GET_API_VERSION

 * w4-w7: Not used (MBZ)

 *

 * Return register usage:

 * w3:	TZ_FFA_VERSION_MAJOR

 * w4:	TZ_FFA_VERSION_MINOR

 * w5-w7: Not used (MBZ)

 */

#define TZ_FFA_GET_API_VERSION TZ_FFA_BLOCKING_CALL(0)



/*

 * Returns the revision of iTrustee

 *

 * Used by non-secure world to figure out which version of the Trusted OS

 * is installed. Note that the returned revision is the revision of the

 * Trusted OS, not of the API.

 *

 * Call register usage:

 * w3:	Service ID, TZ_FFA_GET_OS_VERSION

 * w4-w7: Unused (MBZ)

 *

 * Return register usage:

 * w3:	CFG_TZ_REVISION_MAJOR

 * w4:	CFG_TZ_REVISION_MINOR

 * w5:	TEE_IMPL_GIT_SHA1 (or zero if not supported)

 */

#define TZ_FFA_GET_OS_VERSION	TZ_FFA_BLOCKING_CALL(1)



/*

 * Exchange capabilities between normal world and secure world.

 *

 * Currently, there are no defined capabilities. When features are added new

 * capabilities may be added.

 *

 * Call register usage:

 * w3:	Service ID, TZ_FFA_EXCHANGE_CAPABILITIES

 * w4-w7: Not used (MBZ)

 *

 * Return register usage:

 * w3:	Error code, 0 on success

 * w4:	Bit[7:0]:  Number of parameters needed for RPC to be supplied

 *				   as the second MSG arg struct for

 *				   TZ_FFA_YIELDING_CALL_WITH_ARG.

 *		Bit[31:8]: Reserved (MBZ)

 * w5-w7: Not used (MBZ)

 */

#define TZ_FFA_EXCHANGE_CAPABILITIES TZ_FFA_BLOCKING_CALL(2)



/*

 * Unregister shared memory

 *

 * Call register usage:

 * w3:	Service ID, TZ_FFA_YIELDING_CALL_UNREGISTER_SHM

 * w4:	Shared memory handle, lower bits

 * w5:	Shared memory handle, higher bits

 * w6-w7: Not used (MBZ)

 *

 * Return register usage:

 * w3:	Error code, 0 on success

 * w4-w7: Not used (MBZ)

 */

#define TZ_FFA_UNREGISTER_SHM	TZ_FFA_BLOCKING_CALL(3)



/*

 * Call with struct TZ_msg_arg as argument in the supplied shared memory

 * with a zero internal offset and normal cached memory attributes

 * Register usage:

 * w3:	Service ID, TZ_FFA_YIELDING_CALL_WITH_ARG

 * w4:	Lower 32 bits of a 64-bit Shared memory handle

 * w5:	Upper 32 bits of a 64-bit Shared memory handle

 * w6:	Offset into shared memory pointing to a struct TZ_msg_arg

 *		right after the parameters of this struct (at offset

 *		TZ_MSG_GET_ARG_SIZE(num_params) follows a struct TZ_msg_arg

 *		for RPC, this struct has reserved space for the number of RPC

 *		parameters as returned by TZ_FFA_EXCHANGE_CAPABILITIES.

 * w7:	Not used (MBZ)

 * Resume from RPC. Register usage:

 * w3:	Service ID, TZ_FFA_YIELDING_CALL_RESUME

 * w4-w6: Not used (MBZ)

 * w7:	Resume info

 *

 * Normal return (yielding call is completed). Register usage:

 * w3:	Error code, 0 on success

 * w4:	TZ_FFA_YIELDING_CALL_RETURN_DONE

 * w5-w7: Not used (MBZ)

 *

 * RPC interrupt return (RPC from secure world). Register usage:

 * w3:	Error code == 0

 * w4:	Any defined RPC code but TZ_FFA_YIELDING_CALL_RETURN_DONE

 * w5-w6: Not used (MBZ)

 * w7:	Resume info

 *

 * Possible error codes in register w3:

 * 0:					  Success

 * FFA_DENIED:			  w4 isn't one of TZ_FFA_YIELDING_CALL_START

 *						  TZ_FFA_YIELDING_CALL_RESUME

 *

 * Possible error codes for TZ_FFA_YIELDING_CALL_START

 * FFA_BUSY:			  Number of OP-TEE OS threads exceeded,

 *						  try again later

 * FFA_DENIED:			  RPC shared memory object not found

 * FFA_INVALID_PARAMETER: Bad shared memory handle or offset into the memory

 *

 * Possible error codes for TZ_FFA_YIELDING_CALL_RESUME

 * FFA_INVALID_PARAMETER: Bad resume info

 */

#define TZ_FFA_YIELDING_CALL_WITH_ARG TZ_FFA_YIELDING_CALL(0)

#define TZ_FFA_YIELDING_CALL_RESUME TZ_FFA_YIELDING_CALL(1)



#define TZ_FFA_YIELDING_CALL_RETURN_DONE 0

#define TZ_FFA_YIELDING_CALL_RETURN_RPC_CMD 1

#define TZ_FFA_YIELDING_CALL_RETURN_INTERRUPT 2



int ffa_abi_register(void);

void ffa_abi_unregister(void);

int ffa_forward_call(struct smc_in_params *in_param, struct smc_out_params *out_param, uint8_t wait);



#endif