/**
 * @file protocol.h
 * @brief SWd - NWd communication protocol definitions
 * @author Iaroslav Makarchuk (i.makarchuk@samsung.com)
 * @date Created Oct 3, 2016
 * @par In Samsung Ukraine R&D Center (SURC) under a contract between
 * @par LLC "Samsung Electronics Ukraine Company" (Kiev, Ukraine) and
 * @par "Samsung Elecrtronics Co", Ltd (Seoul, Republic of Korea)
 * @par Copyright: (c) Samsung Electronics Co, Ltd 2015. All rights reserved.
 *
 * This software is proprietary of Samsung Electronics.
 * No part of this software, either material or conceptual may be copied
 * or distributed, transmitted, transcribed, stored in a retrieval system
 * or translated into any human or computer language in any form by any means,
 * electronic, mechanical, manual or otherwise, or disclosed to third parties
 * without the express written permission of Samsung Electronics.
 */

#ifndef PROTOCOL_H_
#define PROTOCOL_H_

#include <stdint.h>
#include <tee_internal_api.h>

#define min(a,b) ((a)<(b))?(a):(b)

#define PROTOCOL_COMMAND_UNLOAD         0xFF01
#define PROTOCOL_COMMAND_LOAD           0xFF02
#define PROTOCOL_COMMAND_READF          0xFF03
#define PROTOCOL_COMMAND_WRITEF         0xFF04
#define PROTOCOL_COMMAND_READMD         0xFF05
#define PROTOCOL_COMMAND_WRITEMD        0xFF06
#define PROTOCOL_COMMAND_DELETE         0xFF07
#define PROTOCOL_COMMAND_INIT_UPDATE    0xFF08
#define PROTOCOL_COMMAND_ABORT_UPDATE   0xFF09
#define PROTOCOL_COMMAND_COMMIT_UPDATE  0xFF0A
#define PROTOCOL_COMMAND_LIST           0xFF0B
#define PROTOCOL_COMMAND_READATTR       0xFF0C
#define PROTOCOL_COMMAND_WRITEATTR      0xFF0D

#define PROTOCOL_COMMAND_GETREETIME     0xFF0E
#define PROTOCOL_COMMAND_GETCANCELFLAG  0xFF0F

#define PARAMS_NUM                      4
#define MAX_PERSISTENT_OBJECT_ID_LEN    TEE_OBJECT_ID_MAX_LEN

#ifdef SHRINK_PROTOCOL_BUFFER
  /*
   * Size of command buffer for Linux kernel as a client on kinibi must be less
   * than 32 KBytes (8 pages):
   *  | struct ProcolCmd | struct PersObjectCmd |
   *  | 20544 bytes      | 4180 bytes           | = 24724 bytes (7 pages)
   *
   * The size of persistent object data should be comparable to the size of one
   * command parameter.
   *
   * MAX_SHAREDMEM_SIZE is allocated for QSEE platform to emulate
   * TEEC_AllocateSharedMemory.
   *   ION heap 1: struct ProcolCmd + MAX_SHAREDMEM_SIZE
   *   ION heap 2: struct PersObjectCmd
   * To check the heaps run `cat /d/ion/heaps/qsecom`, size is rounded up
   * to a page size.
   */
  #define PROTOCOL_MAX_PARAM_DATA_LEN    (4096 + 1024)
  #define MAX_PERSISTENT_OBJECT_DATA_LEN (4096)
  #define MAX_SHAREDMEM_SIZE             (PARAMS_NUM * PROTOCOL_MAX_PARAM_DATA_LEN)
#else
  #define PROTOCOL_MAX_PARAM_DATA_LEN    (12 * 4096)
  #define MAX_PERSISTENT_OBJECT_DATA_LEN (TEE_DATA_MAX_POSITION + 1)
  #define MAX_SHAREDMEM_SIZE             (TEEC_CONFIG_SHAREDMEM_MAX_SIZE)
#endif

typedef enum {
    MB_FS_STORE_DATA = 0,
    MB_FS_STORE_METADATA,
    MB_FS_STORE_ATTRIB
} MultibuildFsStoreDataType;

typedef union {
    struct {
        uint32_t buffer;
        uint32_t size;
    } IW_STRUCTURE memref;
    struct {
        uint32_t a, b;
    } IW_STRUCTURE value;
} IW_STRUCTURE ProtocolParam;

typedef union {
   uint64_t val;
   struct{
     uint32_t low;
     uint32_t high;
   };
} IW_STRUCTURE U64;

/*
 * Size of ProtocolCmdStruct should be aligned to size_t, so we added
 * dummy field to keep alignment
 */
typedef struct ProtocolCmdStruct {
  uint32_t cmd_id;
  uint32_t service_data; /* Platform-specific, may be used for short data */
  uint32_t param_types;
  ProtocolParam params[PARAMS_NUM];
  uint8_t param_buffers[PARAMS_NUM][PROTOCOL_MAX_PARAM_DATA_LEN];
  TEE_Result cmd_ret;
  uint32_t return_origin;
  uint32_t dummy;
  U64 teec_oper;
} IW_STRUCTURE ProtocolCmd;

typedef struct PersObjectCmdStruct {
  uint32_t cmd_id;
  uint32_t data_len;
  uint32_t id_len;
  uint8_t  id[MAX_PERSISTENT_OBJECT_ID_LEN];
  uint8_t  data[MAX_PERSISTENT_OBJECT_DATA_LEN];
  U64 teec_oper;
} IW_STRUCTURE PersObjectCmd;

typedef TEE_Time MB_Time;

#endif /* !PROTOCOL_H */
