/*
 * Copyright (c) 2014, STMicroelectronics International N.V.
 * All rights reserved.
 * Copyright (c) 2015, Linaro Limited
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#ifndef TEE_CLIENT_API_2_4_H
#define TEE_CLIENT_API_2_4_H

#ifndef __KERNEL__
#include <stdint.h>
#include <stddef.h>
#endif /* __KERNEL__ */
#include <tee_client_common.h>

/**
 * struct TEEC_Context_2 - Represents a connection between a client application
 * and a TEE.
 */
typedef struct {
	/* Implementation defined */
//	int fd;
#ifdef CONFIG_ARM64
	uintptr_t fd;
#else
	int fd;
#endif
} TEEC_Context_2;

#if 0
/**
 * This type contains a Universally Unique Resource Identifier (UUID) type as
 * defined in RFC4122. These UUID values are used to identify Trusted
 * Applications.
 */
typedef struct {
	uint32_t timeLow;
	uint16_t timeMid;
	uint16_t timeHiAndVersion;
	uint8_t clockSeqAndNode[8];
} TEEC_UUID_2;
#endif

/**
 * struct TEEC_SharedMemory_2 - Memory to transfer data between a client
 * application and trusted code.
 *
 * @param buffer      The memory buffer which is to be, or has been, shared
 *                    with the TEE.
 * @param size        The size, in bytes, of the memory buffer.
 * @param flags       Bit-vector which holds properties of buffer.
 *                    The bit-vector can contain either or both of the
 *                    TEEC_MEM_INPUT and TEEC_MEM_OUTPUT flags.
 *
 * A shared memory block is a region of memory allocated in the context of the
 * client application memory space that can be used to transfer data between
 * that client application and a trusted application. The user of this struct
 * is responsible to populate the buffer pointer.
 */
typedef struct {
	void *buffer;
	size_t size;
	uint32_t flags;
	/*
	 * Implementation-Defined
	 */
	int id;
	size_t alloced_size;
	void *shadow_buffer;
	int registered_fd;
#ifdef MSOS_TYPE_LINUX_KERNEL
	//int old_fd;
#endif
} TEEC_SharedMemory_2;

/**
 * struct TEEC_TempMemoryReference_2 - Temporary memory to transfer data between
 * a client application and trusted code, only used for the duration of the
 * operation.
 *
 * @param buffer  The memory buffer which is to be, or has been shared with
 *                the TEE.
 * @param size    The size, in bytes, of the memory buffer.
 *
 * A memory buffer that is registered temporarily for the duration of the
 * operation to be called.
 */
typedef struct {
	void *buffer;
	size_t size;
} TEEC_TempMemoryReference_2;

/**
 * struct TEEC_RegisteredMemoryReference_2 - use a pre-registered or
 * pre-allocated shared memory block of memory to transfer data between
 * a client application and trusted code.
 *
 * @param parent  Points to a shared memory structure. The memory reference
 *                may utilize the whole shared memory or only a part of it.
 *                Must not be NULL
 *
 * @param size    The size, in bytes, of the memory buffer.
 *
 * @param offset  The offset, in bytes, of the referenced memory region from
 *                the start of the shared memory block.
 *
 */
typedef struct {
	TEEC_SharedMemory_2 *parent;
	size_t size;
	size_t offset;
} TEEC_RegisteredMemoryReference_2;

/**
 * struct TEEC_Value_2 - Small raw data container
 *
 * Instead of allocating a shared memory buffer this structure can be used
 * to pass small raw data between a client application and trusted code.
 *
 * @param a  The first integer value.
 *
 * @param b  The second second value.
 */
typedef struct {
	uint32_t a;
	uint32_t b;
} TEEC_Value_2;

/**
 * union TEEC_Parameter_2 - Memory container to be used when passing data between
 *                        client application and trusted code.
 *
 * Either the client uses a shared memory reference, parts of it or a small raw
 * data container.
 *
 * @param tmpref  A temporary memory reference only valid for the duration
 *                of the operation.
 *
 * @param memref  The entire shared memory or parts of it.
 *
 * @param value   The small raw data container to use
 */
typedef union {
	TEEC_TempMemoryReference_2 tmpref;
	TEEC_RegisteredMemoryReference_2 memref;
	TEEC_Value_2 value;
} TEEC_Parameter_2;

/**
 * struct TEEC_Session_2 - Represents a connection between a client application
 * and a trusted application.
 */
typedef struct {
	/* Implementation defined */
	TEEC_Context_2 *ctx;
	uint32_t session_id;
} TEEC_Session_2;

/**
 * struct TEEC_Operation_2 - Holds information and memory references used in
 * TEEC_InvokeCommand_2().
 *
 * @param   started     Client must initialize to zero if it needs to cancel
 *                      an operation about to be performed.
 * @param   paramTypes  Type of data passed. Use TEEC_PARAMS_TYPE macro to
 *                      create the correct flags.
 *                      0 means TEEC_NONE is passed for all params.
 * @param   params      Array of parameters of type TEEC_Parameter_2.
 * @param   session     Internal pointer to the last session used by
 *                      TEEC_InvokeCommand_2 with this operation.
 *
 */
typedef struct {
	uint32_t started;
	uint32_t paramTypes;
	TEEC_Parameter_2 params[TEEC_CONFIG_PAYLOAD_REF_COUNT];
	/* Implementation-Defined */
	TEEC_Session_2 *session;
} TEEC_Operation_2;

/**
 * TEEC_RegisterSharedMemory() - Register a block of existing memory as a
 * shared block within the scope of the specified context.
 *
 * @param context    The initialized TEE context structure in which scope to
 *                   open the session.
 * @param sharedMem  pointer to the shared memory structure to register.
 *
 * @return TEEC_SUCCESS              The registration was successful.
 * @return TEEC_ERROR_OUT_OF_MEMORY  Memory exhaustion.
 * @return TEEC_Result               Something failed.
 */
TEEC_Result TEEC_RegisterSharedMemory(TEEC_Context_2 *context,
                                     TEEC_SharedMemory_2 *sharedMem);

/**
 * TEEC_AllocateSharedMemory_v2() - Allocate shared memory for TEE.
 *
 * @param context     The initialized TEE context structure in which scope to
 *                    open the session.
 * @param sharedMem   Pointer to the allocated shared memory.
 *
 * @return TEEC_SUCCESS              The registration was successful.
 * @return TEEC_ERROR_OUT_OF_MEMORY  Memory exhaustion.
 * @return TEEC_Result               Something failed.
 */
TEEC_Result TEEC_AllocateSharedMemory_v2(TEEC_Context_2 *context,
                                     TEEC_SharedMemory_2 *sharedMem);

/**
 * TEEC_ReleaseSharedMemory_v2() - Free or deregister the shared memory.
 *
 * @param sharedMem  Pointer to the shared memory to be freed.
 */
void TEEC_ReleaseSharedMemory_v2(TEEC_SharedMemory_2 *sharedMemory);

#endif
