/*
 * SecBus - This file is part of SecBus
 * Copyright (C) 2012 - Telecom ParisTech
 * 
 * This file must be used under the terms of the CeCILL.
 * This source file is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.  The terms
 * are also available at    
 * http://www.cecill.info/licences/Licence_CeCILL_V1.1-US.txt
 *
 */

#ifndef SECBUS_TYPES_H
#define SECBUS_TYPES_H

#include "global.h"
#include "buffer.h"

// generic accessors
/*
  x source
  p field name
  t type
*/
#define __GET(x, p, t)       (((*x) >> (t##_##p##_POS)) & (t##_##p##_MASK))
/*
  x   target
  p   field name
  val source
  t   type
*/
#define __SET(x, p, val, t)  ((*x) = ((*x) & (~((t##_##p##_MASK) << (t##_##p##_POS)))) \
			      | ((val & (t##_##p##_MASK)) << (t##_##p##_POS) ))

/**
  SecBus types
 */

// SP def
#define SP_ALLOC() ((sp_t)malloc(sizeof(uint32_t)*SP_SIZE_IN_WORDS))
#define SP_DEALLOC(sp) (free(sp))
typedef uint32_t* sp_t;

enum sp_mode_c_e
{
  sp_mode_c_none,
  sp_mode_c_ctr,
  sp_mode_c_cbc
};

enum sp_mode_i_e
{
  sp_mode_i_none,
  sp_mode_i_mac,
  sp_mode_i_mactree
};

enum sp_valid_e
{
  sp_valid_false,
  sp_valid_true
};

#define KEY_ALLOC() (uint32_t*)malloc(sizeof(uint32_t)*DES_KEY_SIZE_IN_WORDS);
#define KEY_DEALLOC(x) (free(x))
typedef uint32_t*        sp_key_c_t; //< Confidentiality DES-X key (#1 #2 #3)
typedef uint32_t*        sp_key_i_t; //< Integrity DES-X key (#1 #2 #3)
typedef enum sp_mode_c_e sp_mode_c_t; //< Confidentiality mode (@see enum sp_mode_c_e)
typedef enum sp_mode_i_e sp_mode_i_t; //< Integrity mode (@see enum sp_mode_i_e)
typedef enum sp_valid_e  sp_valid_t; //< Valid SP (@see enum sp_valid_e)

// mask
#define SP_VALID_MASK 0x00000001UL
#define SP_VALID_POS  0
#define SP_MODEI_MASK 0x00000003UL
#define SP_MODEI_POS  1
#define SP_MODEC_MASK 0x00000003UL
#define SP_MODEC_POS  3

#define SP_GET(x, p)      __GET(x, p, SP)
#define SP_SET(x, p, val) __SET(x, p, val, SP)

// PSPE def
#define PSPE_ALLOC() (0)
#define PSPE_DEALLOC(pspe) do {} while (0)
typedef uint32_t pspe_t[PSPE_SIZE_IN_WORDS]; 

enum pspe_size_e
{
  pspe_size_4k,
  pspe_size_64k,
  pspe_size_1m,
  pspe_size_16m
};

enum pspe_prot_e
{
  pspe_prot_false,
  pspe_prot_true
};

enum pspe_valid_e
{
  pspe_valid_false,
  pspe_valid_true
};

typedef uint32_t          pspe_msadd_t; //< MAC set-tree page address (4096)
typedef uint8_t           pspe_msidx_t; //< MAC set-tree index in page
typedef uint32_t          pspe_ivadd_t; //< IV page address (4096)
typedef uint8_t           pspe_ividx_t; //< IV set index in page
typedef uint16_t          pspe_spidx_t; //< Security Policy index (0 to 65535)
typedef enum pspe_size_e  pspe_size_t; //< Page size (@see enum pspe_size_e)
typedef enum pspe_prot_e  pspe_prot_t; //< Protected page (@see enum pspe_prot_e)
typedef enum pspe_valid_e pspe_valid_t; //< Valid PSPE  (@see enum pspe_valid_e)
typedef uint32_t*         pspe_mac_t; //< MAC value

// mask
#define PSPE_VALID_MASK 0x00000001UL
#define PSPE_VALID_POS  0
#define PSPE_SIZE_MASK  0x00000003UL
#define PSPE_SIZE_POS   1
#define PSPE_PROT_MASK  0x00000001UL
#define PSPE_PROT_POS   3
#define PSPE_SPIDX_MASK 0x0000FFFFUL
#define PSPE_SPIDX_POS  4
#define PSPE_IVIDX_MASK 0x00000003UL
#define PSPE_IVIDX_POS  20
#define PSPE_IVADD_MASK 0x000FFFFFUL
#define PSPE_IVADD_POS  22
#define PSPE_MSIDX_MASK 0x00000003UL
#define PSPE_MSIDX_POS  42
#define PSPE_MSADD_MASK 0x000FFFFFUL
#define PSPE_MSADD_POS  44

#define PSPE_GET(x, p)      __GET(x, p, PSPE)
#define PSPE_SET(x, p, val) __SET(x, p, val, PSPE)

/**
  SecBus IO types
 */

enum io_status_errt_e
{
  io_status_e_none,
  io_status_e_pspe,
  io_status_e_sp,
  io_status_e_mac,
  io_status_e_ht
};

enum io_status_errc_e
{
  io_status_e_load,
  io_status_e_store
};

enum io_cmd_cmd_e
{
  io_cmd_none,
  io_cmd_load,
  io_cmd_store,
  io_cmd_init,
  io_cmd_continue
};

typedef enum io_status_errt_e io_status_errt_t;
typedef enum io_status_errc_e io_status_errc_t;
typedef enum io_cmd_cmd_e     io_cmd_cmd_t;

// mask
#define IO_CONFIG_MBADDR_POS   0
#define IO_CONFIG_MBADDR_MASK  0xFF
#define IO_CONFIG_EN_POS       8
#define IO_CONFIG_EN_MASK      0x1
#define IO_CONFIG_INT_POS      9
#define IO_CONFIG_INT_MASK     0x1
#define IO_CONFIG_PC_POS       10
#define IO_CONFIG_PC_MASK      0x1
#define IO_CONFIG_SPC_POS      11
#define IO_CONFIG_SPC_MASK     0x1
#define IO_CONFIG_MACC_POS     12
#define IO_CONFIG_MACC_MASK    0x1
#define IO_CONFIG_HMACC_POS    13
#define IO_CONFIG_HMACC_MASK   0x1
#define IO_CONFIG_BRAM_POS     14
#define IO_CONFIG_BRAM_MASK    0xFF
#define IO_CONFIG_SRAM_POS     22
#define IO_CONFIG_SRAM_MASK    0xFF

#define IO_STATUS_BUSY_POS     0
#define IO_STATUS_BUSY_MASK    0x1
#define IO_STATUS_ERRT_POS     1
#define IO_STATUS_ERRT_MASK    0x7
#define IO_STATUS_ERRC_POS     4
#define IO_STATUS_ERRC_MASK    0x1
#define IO_STATUS_ERRA_POS     5
#define IO_STATUS_ERRA_MASK    0x7FFFFFF

#define IO_CMD_CMD_POS         0
#define IO_CMD_CMD_MASK        0x7

#define IO_GET(x, p)      __GET(x, p, IO)
#define IO_SET(x, p, val) __SET(x, p, val, IO)

typedef uint32_t                  io_reg_32_t;
typedef uint32_t*                 io_reg_pspe_t;
typedef uint32_t*                 io_reg_sp_t;
typedef uint32_t*                 io_reg_data_t;
typedef uint32_t                  io_reg_addr_t;
typedef uint32_t                  io_addr_t;

typedef uint32_t                  addr_t;

enum cmd_mem_e
{
  READ,
  WRITE
};

typedef enum cmd_mem_e cmd_mem_t;

enum ctx_cmd_e
{
  CTX_CMD_READ,
  CTX_CMD_UPDATE
};

typedef enum ctx_cmd_e ctx_cmd_t;

enum irq_type_e
{
  irq_none,
  irq_block,
  irq_pspe,
  irq_sp,
  irq_mac,
  irq_mactree
};

typedef enum irq_type_e irq_type_t;

/****** cache properties *******/
typedef Buffer         cacheblock_t;
typedef cacheblock_t * pCacheblock_t;

template<typename _other_t> 
struct CacheSet_st 
{
  /**< Pointer to an array of cache block */
  pCacheblock_t block; 
  /**< Other information */
  _other_t other;
};

/*! \Other Information needs 1 byte : used in ALAP policy as "dirty counter" by cache set */
typedef CacheSet_st<char> CacheSet_st_t;

/*! \Cache Replacement Policy when associativity is greater than 1 */
typedef enum 
{
  LRU = 0,
  FIFO
} ReplacementPolicy_e;

enum WritePolicy_e
{
  WRITE_THROUGH = 0,
  WRITE_BACK
};

typedef struct 
{
  /**< Cache name. */
  char name[10];
  /**< Cache enabled. */
  bool enable;
  /**< Number of blocks per set */
  int associativity ; 
  /**< Size of cache block in word */
  int block_size;
  /**< Number of sets. */
  int set_number;	
  /**<Replacement Policy. */
  ReplacementPolicy_e replacement_policy;
  /**<Write Policy */
  WritePolicy_e write_policy;
  /**<treshold/set */
  int threshold;

} cache_param_s;

/** MT Cache cmd **/
enum cmd_mt_cache_e
{
  MTC_READ = 0,
  MTC_WRITE, 
  MTC_SYNCHRONIZE,
  MTC_RESTORE, 
  MTC_INVALIDATE,
  MTC_IMMEDIATE
};

typedef enum cmd_mt_cache_e cmd_mt_cache_t;

/** Integrity cmd **/
enum cmd_integrity_e
{
  CHECK = 0,
  UPDATE,
  INITIALIZE,
  INITIALIZE_PAGE,
};

typedef enum cmd_integrity_e cmd_integrity_t;

enum cmd_crypto_mode_e
{
  crypto_ctr,
  crypto_cbc,
  crypto_mac
};

typedef enum cmd_crypto_mode_e cmd_crypto_mode_t;

#endif
