/*
   *  Object %name    : CC_MNG_Functions.c
   *  State           :  %state%
   *  Creation date   :  Aug 4 17:39:24 2004
   *  Last modified   :  %modify_time%
   */
  /** @file
   *  \brief Generic Secure Boot implemtation of CC functions
   *
   *  \version 
   *  \author Danb
   *  \remarks Copyright (C) 2004 by Discretix Technologies Ltd.
   *           All Rights reserved
   */
#include "CRYS_RSA_Types.h"
#include "MNG_Functions.h"
#include "GeneralHwDefs.h"
#include "mng_host_op_code.h"
#include "gen.h"
#include "error.h"
#include "SEPDriver.h"


/*---------------------
    FUNCTIONS
-----------------------*/

/*
*   @brief This function receives the RKEK , calculates the ECC and burns both to the RKEK OTP bits.
*          This function is valid only on chip manufacture or chip device LCS states.
*
*   @param[in] Rkek_len - The RKEK to burn. 
*   @param[in] Rkek_ptr - The RKEK to burn.
*
*   Returns:  Status of the operation.
*/
DxError_t DX_MNG_SetRkekOtp(DxUint16_t    RKEK_len,
                               DxUint8_t     *RKEK_ptr)
{
  /* The return error identifier */
  DxError_t           Error;
  
  /* offset */
  DxUint32_t          sramOffset;
   
  /* read param */
  DxUint32_t          messageParam[2];
  
  /*----------------------------------
      CODE
  ------------------------------------*/
   
  /* .................. initializing local variables ................... */
  /* ------------------------------------------------------------------- */   
   
  /* initializing the Error to O.K */
  Error = DX_OK;      
                         
   /* lock access to the SEP */
   Error = SEPDriver_Lock();
   
   if(Error != DX_OK)
   {
       goto end_function;
   }
  
  /*----------------------------
      start sending message to SEP 
  -----------------------------*/
  sramOffset = 0;
   
  /* start the message */
  SEPDriver_StartMessage(&sramOffset);
  
  /* prepare params */
  messageParam[0] = DX_SEP_HOST_SEP_PROTOCOL_HOST_SET_RKEK_OTP_OP_CODE;
  messageParam[1] = RKEK_len;
  
  /* send params */
  Error = SEPDriver_WriteParamater((DxUint32_t)messageParam ,
                           sizeof(DxUint32_t) * 2 ,
                           sizeof(DxUint32_t) * 2 ,
                           &sramOffset , 
                           DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }

  /* send RKEK data */
  Error = SEPDriver_WriteParamater((DxUint32_t)RKEK_ptr,
                           RKEK_len ,
                           sizeof(DxUint32_t) * 8 ,
                           &sramOffset , 
                           DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }

  
  SEPDriver_EndMessage(sramOffset);
            
  /* wait for the response */
  Error = SEPDriver_POLL_FOR_REPONSE();
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
  
                                            
  /*-------------------
    start reading message from the SEP 
  ---------------------*/
   
  /* start the message */
  Error = SEPDriver_StartIncomingMessage(&sramOffset);
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
   
  /* read opcode + status  */
  Error = SEPDriver_ReadParamater((DxUint32_t)messageParam ,
                          sizeof(DxUint32_t) * 2,
                          sizeof(DxUint32_t) * 2,
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
   
  /* check the opcode */
  if(messageParam[0] != DX_SEP_HOST_SEP_PROTOCOL_HOST_SET_RKEK_OTP_OP_CODE)
  {
    Error = DX_WRONG_OPCODE_FROM_SEP_ERR;
    goto end_function_unlock;
  }
   
  /* check the status */
  if(messageParam[1] != DX_OK)
  {
    Error = messageParam[1];
    goto end_function_unlock;
  }
                                           
  /* ...................... end of function ................................ */   

end_function_unlock:   

  /* lock access to the SEP */
  SEPDriver_Unlock();

end_function:

  return Error;                                  

}/* DX_CC_MNG_SetRkekOtp */



/*
*   @brief The functions execution steps:
*            1.	calculate HASH of the keyType(OEM | Sjtag) RSA public key - SHA2 - 256 on { E || N }
*            2.	calculate ECC of the SHA2-256 digest.
*            3.	burn the SHA256 digest and the ECC to the OTP.
*   
*   @param[in] keyType - the key type : 0 - OEM , 1 - SJTAG.
*   @param[in] E[in]- The public exponent.
*   @param[in] N_len[in] - the modulus length.
*   @param[in] N_ptr[in] - the modulus vector.
*
*   Returns:  Status of the operation.
*/
DxError_t _DX_MNG_SetRsaPubKeyHashOtp(
                             DxUint32_t    keyType, 
                             DxUint32_t    E,
							               DxUint32_t    N_len,
                             DxUint8_t     *N_ptr)
{
  /* The return error identifier */
  DxError_t           Error;
  
  /* offset */
  DxUint32_t          sramOffset;
   
  /* read param */
  DxUint32_t          messageParam[4];
  
  /*----------------------------------
      CODE
  ------------------------------------*/
   
  /* .................. initializing local variables ................... */
  /* ------------------------------------------------------------------- */   
   
  /* initializing the Error to O.K */
  Error = DX_OK;      
                         
   /* lock access to the SEP */
   Error = SEPDriver_Lock();
   
   if(Error != DX_OK)
   {
       goto end_function;
   }
  
  /*----------------------------
      start sending message to SEP 
  -----------------------------*/
  sramOffset = 0;
   
  /* start the message */
  SEPDriver_StartMessage(&sramOffset);
  
  /* prepare params */
  messageParam[0] = DX_SEP_HOST_SEP_PROTOCOL_HOST_SET_RSA_PUB_KEY_HASH_OTP_OP_CODE;
  messageParam[1] = keyType;
  messageParam[2] = E;
  messageParam[3] = N_len;
  
  /* send params */
  Error = SEPDriver_WriteParamater((DxUint32_t)messageParam ,
                           sizeof(DxUint32_t) * 4 ,
                           sizeof(DxUint32_t) * 4 ,
                           &sramOffset , 
                           DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
                           
  /* send N */
  Error = SEPDriver_WriteParamater((DxUint32_t)N_ptr ,
                           N_len ,
                           sizeof(DxUint32_t) * 64 ,
                           &sramOffset , 
                           DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
                           
  
  SEPDriver_EndMessage(sramOffset);
            
  /* wait for the response */
  Error = SEPDriver_POLL_FOR_REPONSE();
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
                                            
  /*-------------------
    start reading message from the SEP 
  ---------------------*/
   
  /* start the message */
  Error = SEPDriver_StartIncomingMessage(&sramOffset);
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
   
  /* read opcode + status  */
  Error = SEPDriver_ReadParamater((DxUint32_t)messageParam ,
                          sizeof(DxUint32_t) * 2,
                          sizeof(DxUint32_t) * 2,
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
   
  /* check the opcode */
  if(messageParam[0] != DX_SEP_HOST_SEP_PROTOCOL_HOST_SET_RSA_PUB_KEY_HASH_OTP_OP_CODE)
  {
    Error = DX_WRONG_OPCODE_FROM_SEP_ERR;
    goto end_function_unlock;
  }
   
  /* check the status */
  if(messageParam[1] != DX_OK)
  {
    Error = messageParam[1];
    goto end_function_unlock;
  }

  /* ...................... end of function ................................ */   

end_function_unlock:   

  /* lock access to the SEP */
  SEPDriver_Unlock();

end_function:

  return Error;                                  

}/* _DX_CC_MNG_SetRsaPubKeyHashOtp */




/*
*   @brief This function creates the AES sub key used for wrapping the CA platform keys and the state file.
*   
*   @param[out] WrappedAesSubKey_ptr - The sub key that was created by the SeP.
*   @param[in/out] SubKeyLen_ptr - On the input: the size of the WrappedAesSubKey buffer allocated for the key.
*                                  On the output: the actual size of the wrapped key - if the size of the buffer 
*                                  allocated is not sufficient the function will return an error. 
*
*   Returns:  Status of the operation.
*/
DxError_t DX_MNG_CreatePlatformWrapperKey (
                   DxUint32_t    *PlatformWrapperKeySize_ptr,        
                   DxUint8_t     *PlatformWrapperKey)
{
  /* The return error identifier */
  DxError_t           Error;
  
  /* offset */
  DxUint32_t          sramOffset;
   
  /* read param */
  DxUint32_t          messageParam[2];

    /* max length */
  DxUint32_t          maxLength;
 
  /*----------------------------------
      CODE
  ------------------------------------*/
   
  /* .................. initializing local variables ................... */
  /* ------------------------------------------------------------------- */   
   
  /* initializing the Error to O.K */
  Error = DX_OK;      
                         
   /* lock access to the SEP */
   Error = SEPDriver_Lock();
   
   if(Error != DX_OK)
   {
       goto end_function;
   }
  
  /*----------------------------
      start sending message to SEP 
  -----------------------------*/
  sramOffset = 0;
   
  /* start the message */
  SEPDriver_StartMessage(&sramOffset);
  
  /* prepare params */
  messageParam[0] = DX_SEP_HOST_SEP_PROTOCOL_HOST_CREATE_PLATFORM_WRAPPER_KEY_OP_CODE;
  
  /* send params */
  Error = SEPDriver_WriteParamater((DxUint32_t)messageParam ,
                           sizeof(DxUint32_t) * 1 ,
                           sizeof(DxUint32_t) * 1 ,
                           &sramOffset , 
                           DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
  
  SEPDriver_EndMessage(sramOffset);
            
  /* wait for the response */
  Error = SEPDriver_POLL_FOR_REPONSE();
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
  
                                            
  /*-------------------
    start reading message from the SEP 
  ---------------------*/
   
  /* start the message */
  Error = SEPDriver_StartIncomingMessage(&sramOffset);
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
   
  /* read opcode + status  */
  Error = SEPDriver_ReadParamater((DxUint32_t)messageParam ,
                          sizeof(DxUint32_t) * 2,
                          sizeof(DxUint32_t) * 2,
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
   
  /* check the opcode */
  if(messageParam[0] != DX_SEP_HOST_SEP_PROTOCOL_HOST_CREATE_PLATFORM_WRAPPER_KEY_OP_CODE)
  {
    Error = DX_WRONG_OPCODE_FROM_SEP_ERR;
    goto end_function_unlock;
  }
   
  /* check the status */
  if(messageParam[1] != DX_OK)
  {
    Error = messageParam[1];
    goto end_function_unlock;
  }

  /* read key Len */
  Error = SEPDriver_ReadParamater((DxUint32_t)messageParam ,
                          sizeof(DxUint32_t),
                          sizeof(DxUint32_t),
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
  
  if((*PlatformWrapperKeySize_ptr) < messageParam[0])
  {
    Error = DX_INVALID_PARAMETERS_ERR;
    goto end_function_unlock;
  }
  
  (*PlatformWrapperKeySize_ptr) =  messageParam[0];
  
  maxLength = ((*PlatformWrapperKeySize_ptr +3 ) / 4 ) * 4 ;
  Error = SEPDriver_ReadParamater((DxUint32_t)PlatformWrapperKey ,
                          *PlatformWrapperKeySize_ptr,
                          maxLength,
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }

  /* ...................... end of function ................................ */   

end_function_unlock:   

  /* lock access to the SEP */
  SEPDriver_Unlock();

end_function:

  return Error;                                  

}/* DX_CC_MNG_CreatePlatformWrapperKey */


/*
*   @brief This function retrieves from the user the current monotonic counter that is wrapped by the monotonic counter wrapper key and returns the updated monotonic counter wrapped by the same wrapper key.
*          The CC executes the following: 
*           1. unwraps the MTC wrapper key that is wrapped by the RKEK.
*           2. Unwraps the monotonic counter that is received with wrapper key.
*           3. Increments the monotonic counter.
*           4. Wraps the updated monotonic counter with the wrapper key.
*           5. Returns the updated monotonic counter wrapped by the wrapper key.
*           6. Returns the value of the new counter.
*
*   @param[in] PlatformWrapperKey  - the wrapper key used to unwrapp the monotonic counter . This key is created by the DX_CC_MNG_CreatePlatformWrapperKey API and wrapped by the RKEK.
*   @param[in] PlatformWrapperKeySize - the platform wrapper key size in bytes
*   @param[in/out] WrappedMtc - input : the current monotonic counter wrapped by the platform wrapper key the monotonic counter is defined as a big integer ( Big Endian ).
                                Output: the updated monotonic counter wrapped by the platform key.
*   @param[in] MtcLen - the length on the monotonic counter in bytes.
*   @param[out] Counter_ptr[out] - the updated counter value ( plaintext ).
*   @param[in/out] CounterLen_ptr - input the size of the allocated buffer for the counter if the size is not sufficient the function will return an error.
*
*   Returns:  the actual size of the updated counter + Status of the operation.
*/
DxError_t DX_MNG_IncAndGetMonCounter (
                        DxUint8_t     *PlatformWrapperKey,
                        DxUint32_t    PlatformWrapperKeySize, 
                        DxUint8_t     *WrappedMtc,
                        DxUint32_t    MtcLen,
                        DxUint8_t     *Counter_ptr,
                        DxUint32_t    *CounterLen_ptr)
{
  /* The return error identifier */
  DxError_t           Error;
  
  /* offset */
  DxUint32_t          sramOffset;
   
  /* read param */
  DxUint32_t          messageParam[2];
  
  /*----------------------------------
      CODE
  ------------------------------------*/
   
  /* .................. initializing local variables ................... */
  /* ------------------------------------------------------------------- */   
   
  /* initializing the Error to O.K */
  Error = DX_OK;      
                         
   /* lock access to the SEP */
   Error = SEPDriver_Lock();
   
   if(Error != DX_OK)
   {
       goto end_function;
   }
  
  /*----------------------------
      start sending message to SEP 
  -----------------------------*/
  sramOffset = 0;
   
  /* start the message */
  SEPDriver_StartMessage(&sramOffset);
  
  /* prepare params */
  messageParam[0] = DX_SEP_HOST_SEP_PROTOCOL_HOST_INC_AND_GET_MON_COUNTER_OP_CODE;
  messageParam[1] = PlatformWrapperKeySize;
  
  /* send params */
  Error = SEPDriver_WriteParamater((DxUint32_t)messageParam ,
                           sizeof(DxUint32_t) * 2 ,
                           sizeof(DxUint32_t) * 2 ,
                           &sramOffset , 
                           DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
  
  /* send wrapped key */
  Error = SEPDriver_WriteParamater((DxUint32_t)PlatformWrapperKey ,
                          PlatformWrapperKeySize,
                          sizeof(DxUint32_t) * 14,
                          &sramOffset,
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
  
  /* send wrapped CTR length */
  Error = SEPDriver_WriteParamater((DxUint32_t)&MtcLen ,
                           sizeof(DxUint32_t),
                           sizeof(DxUint32_t),
                           &sramOffset , 
                           DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
  
  /* send wrapped CTR */
  Error = SEPDriver_WriteParamater((DxUint32_t)WrappedMtc ,
                            MtcLen,
                            sizeof(DxUint32_t) * 8,
                            &sramOffset,
                            DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }

  SEPDriver_EndMessage(sramOffset);
            
  /* wait for the response */
  Error = SEPDriver_POLL_FOR_REPONSE();
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
                                              
  /*-------------------
    start reading message from the SEP 
  ---------------------*/
   
  /* start the message */
  Error = SEPDriver_StartIncomingMessage(&sramOffset);
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
   
  /* read opcode + status  */
  Error = SEPDriver_ReadParamater((DxUint32_t)messageParam ,
                          sizeof(DxUint32_t) * 2,
                          sizeof(DxUint32_t) * 2,
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
   
  /* check the opcode */
  if(messageParam[0] != DX_SEP_HOST_SEP_PROTOCOL_HOST_INC_AND_GET_MON_COUNTER_OP_CODE)
  {
    Error = DX_WRONG_OPCODE_FROM_SEP_ERR;
    goto end_function_unlock;
  }
   
  /* check the status */
  if(messageParam[1] != DX_OK)
  {
    Error = messageParam[1];
    goto end_function_unlock;
  }
                                           
  /* read Wraped CTR len */
  Error = SEPDriver_ReadParamater((DxUint32_t)MtcLen ,
                          sizeof(DxUint32_t),
                          sizeof(DxUint32_t),
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
  
  /* read Wrapped CTR */
  Error = SEPDriver_ReadParamater((DxUint32_t)WrappedMtc ,
                          MtcLen,
                          sizeof(DxUint32_t) * 8,
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
  
  /* read UnWraped CTR len */
  Error = SEPDriver_ReadParamater((DxUint32_t)CounterLen_ptr ,
                          sizeof(DxUint32_t),
                          sizeof(DxUint32_t),
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
  
  /* read UnWrapped CTR */
  Error = SEPDriver_ReadParamater((DxUint32_t)Counter_ptr,
                          *CounterLen_ptr,
                          sizeof(DxUint32_t) * 6,
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
  
  /* ...................... end of function ................................ */   

end_function_unlock:   

  /* lock access to the SEP */
  SEPDriver_Unlock();

end_function:

  return Error;                                  

}/* DX_CC_MNG_IncAndGetMonCounter */


/*
*   @brief This function retrieves from the user the current monotonic counter that is wrapped by the monotonic counter wrapper key and returns the counter value.
*          The CC executes the following: 
*          1. unwraps the MTC wrapper key that is wrapped by the RKEK.
*          2. Unwraps the monotonic counter that is received with wrapper key.
*          3. Returns the value of the counter.
*   @param[in] PlatformWrapperKey  - the wrapper key used to unwrapp the monotonic counter . This key is created by the DX_CC_MNG_CreatePlatformWrapperKey API and wrapped by the RKEK.
*   @param[in] PlatformWrapperKeySize - the platform wrapper key size in bytes
*   @param[in] WrappedMtc- the current monotonic counter wrapped by the platform wrapper key the monotonic counter is defined as a big integer ( Big Endian ).
*   @param[in] MtcLen - the length on the monotonic counter in bytes.
*   @param[out] Counter_ptr[out] - the counter value ( plaintext ).
*   @param[in/out] CounterLen_ptr[in/out] - input the size of the allocated buffer for the counter if the size is not sufficient the function will return an error.
*                  output: the actual size of the updated counter
*
*   Returns:  Status of the operation.
*/
DxError_t DX_MNG_GetMonCounterVal(
                        DxUint8_t  *PlatformWrapperKey,
                        DxUint32_t PlatformWrapperKeySize,  
                        DxUint8_t  *WrappedMtc,
                        DxUint32_t MtcLen,
                        DxUint8_t  *Counter_ptr,
                        DxUint32_t *CounterLen_ptr)
{
  /* The return error identifier */
  DxError_t           Error;
  
  /* offset */
  DxUint32_t          sramOffset;
   
  /* read param */
  DxUint32_t          messageParam[2];
  
  /*----------------------------------
      CODE
  ------------------------------------*/
   
  /* .................. initializing local variables ................... */
  /* ------------------------------------------------------------------- */   
   
  /* initializing the Error to O.K */
  Error = DX_OK;      
                         
   /* lock access to the SEP */
   Error = SEPDriver_Lock();
   
   if(Error != DX_OK)
   {
       goto end_function;
   }
     
  /*----------------------------
      start sending message to SEP 
  -----------------------------*/
  sramOffset = 0;
   
  /* start the message */
  SEPDriver_StartMessage(&sramOffset);
  
  /* prepare params */
  messageParam[0] = DX_SEP_HOST_SEP_PROTOCOL_HOST_GET_MON_COUNTER_VAL_OP_CODE;
  messageParam[1] = PlatformWrapperKeySize;
  
  /* send params */
  Error = SEPDriver_WriteParamater((DxUint32_t)messageParam ,
                           sizeof(DxUint32_t) * 2 ,
                           sizeof(DxUint32_t) * 2 ,
                           &sramOffset , 
                           DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
  
  /* send wrapped key */
  Error = SEPDriver_WriteParamater((DxUint32_t)PlatformWrapperKey ,
                          PlatformWrapperKeySize,
                          sizeof(DxUint32_t) * 14,
                          &sramOffset,
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
  
  /* send wrapped CTR length */
  Error = SEPDriver_WriteParamater((DxUint32_t)&MtcLen ,
                           sizeof(DxUint32_t),
                           sizeof(DxUint32_t),
                           &sramOffset , 
                           DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
  
  /* send wrapped CTR */
  Error = SEPDriver_WriteParamater((DxUint32_t)WrappedMtc ,
                            MtcLen,
                            sizeof(DxUint32_t) * 8,
                            &sramOffset,
                            DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }

  SEPDriver_EndMessage(sramOffset);
            
  /* wait for the response */
  Error = SEPDriver_POLL_FOR_REPONSE();
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
                                              
  /*-------------------
    start reading message from the SEP 
  ---------------------*/
   
  /* start the message */
  Error = SEPDriver_StartIncomingMessage(&sramOffset);
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
   
  /* read opcode + status  */
  Error = SEPDriver_ReadParamater((DxUint32_t)messageParam ,
                          sizeof(DxUint32_t) * 2,
                          sizeof(DxUint32_t) * 2,
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
   
  /* check the opcode */
  if(messageParam[0] != DX_SEP_HOST_SEP_PROTOCOL_HOST_GET_MON_COUNTER_VAL_OP_CODE)
  {
    Error = DX_WRONG_OPCODE_FROM_SEP_ERR;
    goto end_function_unlock;
  }
   
  /* check the status */
  if(messageParam[1] != DX_OK)
  {
    Error = messageParam[1];
    goto end_function_unlock;
  }
  
  /* read UnWraped CTR len */
  Error = SEPDriver_ReadParamater((DxUint32_t)CounterLen_ptr ,
                          sizeof(DxUint32_t),
                          sizeof(DxUint32_t),
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
  
  /* read UnWrapped CTR */
  Error = SEPDriver_ReadParamater((DxUint32_t)Counter_ptr,
                          *CounterLen_ptr,
                          sizeof(DxUint32_t) * 6,
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
  
  /* ...................... end of function ................................ */   

end_function_unlock:   

  /* lock access to the SEP */
  SEPDriver_Unlock();

end_function:

  return Error;                                  

}/* DX_CC_MNG_GetMonCounterVal */


/*
*   @brief This function creates a monotonic counter with the value 0. the monotonic counter wrapped by the platform key is returned to the user. 
*          The CC executes the following: 
*          1. unwraps the MTC wrapper key that is wrapped by the RKEK.
*          2  creates a monotonic counter with the value 0.
*          3. Wraps the updated monotonic counter with the wrapper key.
*          4. Returns the updated monotonic counter wrapped by the wrapper key.
*          5. Returns the value of the new counter.
*   @param[in] PlatformWrapperKey  - the wrapper key used to unwrapp the monotonic counter . This key is created by the DX_CC_MNG_CreatePlatformWrapperKey API and wrapped by the RKEK.
*   @param[in] PlatformWrapperKeySize - the platform wrapper key size in bytes.
*   @param[out] *MtcLen_ptr[out] - the length on the monotonic that is created counter in bytes.
*   @param[out] UpdatedWrappedMtc[out] - the updated monotonic counter wrapped by the platform key.
*   @param[out] Counter_ptr[out] - the updated counter value ( plaintext ).
*   @param[in/out] CounterLen_ptr[in/out] - input the size of the allocated buffer for the counter if the size is not sufficient the function will return an error.
*              output: the actual size of the updated counter.
*
*   Returns:  Status of the operation.
*/
DxError_t DX_MNG_CreateMonotonicCounter(
                        DxUint8_t  *PlatformWrapperKey,
                        DxUint32_t PlatformWrapperKeySize, 
                        DxUint32_t *MtcLen_ptr,
                        DxUint8_t  *UpdatedWrappedMtc,  
                        DxUint8_t  *Counter_ptr,
                        DxUint32_t *CounterLen_ptr)
{
  /* The return error identifier */
  DxError_t           Error;
  
  /* offset */
  DxUint32_t          sramOffset;
   
  /* read param */
  DxUint32_t          messageParam[2];
  
  /*----------------------------------
      CODE
  ------------------------------------*/
   
  /* .................. initializing local variables ................... */
  /* ------------------------------------------------------------------- */   
   
  /* initializing the Error to O.K */
  Error = DX_OK;      
                         
   /* lock access to the SEP */
   Error = SEPDriver_Lock();
   
   if(Error != DX_OK)
   {
       goto end_function;
   }
  
  /*----------------------------
      start sending message to SEP 
  -----------------------------*/
  sramOffset = 0;
   
  /* start the message */
  SEPDriver_StartMessage(&sramOffset);
  
  /* prepare params */
  messageParam[0] = DX_SEP_HOST_SEP_PROTOCOL_HOST_CREATE_MON_COUNTER_OP_CODE;
  messageParam[1] = PlatformWrapperKeySize;
  
  /* send params */
  Error = SEPDriver_WriteParamater((DxUint32_t)messageParam ,
                           sizeof(DxUint32_t) * 2 ,
                           sizeof(DxUint32_t) * 2 ,
                           &sramOffset , 
                           DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
  
  /* send wrapped key */
  Error = SEPDriver_WriteParamater((DxUint32_t)PlatformWrapperKey ,
                          PlatformWrapperKeySize,
                          sizeof(DxUint32_t) * 24,
                          &sramOffset,
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }

  SEPDriver_EndMessage(sramOffset);
            
  /* wait for the response */
  Error = SEPDriver_POLL_FOR_REPONSE();
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
                                              
  /*-------------------
    start reading message from the SEP 
  ---------------------*/
   
  /* start the message */
  Error = SEPDriver_StartIncomingMessage(&sramOffset);
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
   
  /* read opcode + status  */
  Error = SEPDriver_ReadParamater((DxUint32_t)messageParam ,
                          sizeof(DxUint32_t) * 2,
                          sizeof(DxUint32_t) * 2,
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
   
  /* check the opcode */
  if(messageParam[0] != DX_SEP_HOST_SEP_PROTOCOL_HOST_CREATE_MON_COUNTER_OP_CODE)
  {
    Error = DX_WRONG_OPCODE_FROM_SEP_ERR;
    goto end_function_unlock;
  }
   
  /* check the status */
  if(messageParam[1] != DX_OK)
  {
    Error = messageParam[1];
    goto end_function_unlock;
  }
  
  /* read Wraped Key len */
  Error = SEPDriver_ReadParamater((DxUint32_t)MtcLen_ptr ,
                          sizeof(DxUint32_t),
                          sizeof(DxUint32_t),
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
  
  /* read Wrapped Key */
  Error = SEPDriver_ReadParamater((DxUint32_t)UpdatedWrappedMtc,
                          *MtcLen_ptr,
                          sizeof(DxUint32_t) * 8,
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }


  /* read UnWraped Key len */
  Error = SEPDriver_ReadParamater((DxUint32_t)CounterLen_ptr ,
                          sizeof(DxUint32_t),
                          sizeof(DxUint32_t),
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
  
  /* read UnWrapped Key */
  Error = SEPDriver_ReadParamater((DxUint32_t)Counter_ptr,
                          *CounterLen_ptr,
                          sizeof(DxUint32_t) * 6,
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
  
  /* ...................... end of function ................................ */   

end_function_unlock:   

  /* lock access to the SEP */
  SEPDriver_Unlock();

end_function:

  return Error;                                  

}/* DX_CC_MNG_CreateMonotonicCounter */



/*
*   @brief  The CC executes the following:
*               1) verifying that the SHA256 of { E||N } is correlate with the value stored in the OTP according to the key type.
*               2) Executes the CRYS RSA build operation and returns the UserPubKey object
*   
*   @param[in] keyType - the key type : 1 - OEM , 0 - SJTAG.
*   @param[in] keyIndex - in case of the OEM key, the index of the key
*   @param[in] E[in]- The public exponent.
*   @param[in] N_len[in] - the modulus length.
*   @param[in] N_ptr[in] - the modulus vector.
*   @param[out] UserPubKey_ptr[out] - the RSA public key object.
*
*   Returns:  Status of the operation.
*/
DxError_t DX_MNG_RSA_BuildPlatformPubKey(DxUint32_t             keyType,
                                         DxUint32_t             keyIndex, 
                                         CRYS_RSAUserPubKey_t*  UserPubKey_ptr,
                                         DxUint8_t*             E_ptr,					
                                         DxUint32_t             E_len,
                                 		     DxUint32_t             N_len,
                                         DxUint8_t*             N_ptr)
{
  /* The return error identifier */
  DxError_t           Error;
  
  /* offset */
  DxUint32_t          sramOffset;
   
  /* read param */
  DxUint32_t          messageParam[4];
  
  /* max length */
  DxUint32_t          maxLength;
  
  /*----------------------------------
      CODE
  ------------------------------------*/
   
  /* .................. initializing local variables ................... */
  /* ------------------------------------------------------------------- */   
   
  /* initializing the Error to O.K */
  Error = DX_OK;      
                         
   /* lock access to the SEP */
   Error = SEPDriver_Lock();
   
   if(Error != DX_OK)
   {
       goto end_function;
   }
  
  /*----------------------------
      start sending message to SEP 
  -----------------------------*/
  sramOffset = 0;
   
  /* start the message */
  SEPDriver_StartMessage(&sramOffset);
  
  /* prepare params */
  messageParam[0] = DX_SEP_HOST_SEP_PROTOCOL_HOST_MNG_RSA_BUILD_VERIFY_PUB_KEY_OP_CODE;
  messageParam[1] = keyType;
  messageParam[2] = keyIndex;
  messageParam[3] = E_len;
  
  /* send params */
  Error = SEPDriver_WriteParamater((DxUint32_t)messageParam ,
                           sizeof(DxUint32_t) * 4 ,
                           sizeof(DxUint32_t) * 4 ,
                           &sramOffset , 
                           DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
                           
  /* send E */
  Error = SEPDriver_WriteParamater((DxUint32_t)E_ptr ,
                           E_len ,
                           sizeof(DxUint32_t) * 64 ,
                           &sramOffset , 
                           DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }

  /* Send N length */
  Error = SEPDriver_WriteParamater((DxUint32_t)&N_len ,
                           sizeof(DxUint32_t),
                           sizeof(DxUint32_t),
                           &sramOffset , 
                           DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }


  /* send N */
  Error = SEPDriver_WriteParamater((DxUint32_t)N_ptr ,
                           N_len ,
                           sizeof(DxUint32_t) * 64 ,
                           &sramOffset , 
                           DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
                           
  
  SEPDriver_EndMessage(sramOffset);
            
  /* wait for the response */
  Error = SEPDriver_POLL_FOR_REPONSE();
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
                                            
  /*-------------------
    start reading message from the SEP 
  ---------------------*/
   
  /* start the message */
  Error = SEPDriver_StartIncomingMessage(&sramOffset);
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
   
  /* read opcode + status  */
  Error = SEPDriver_ReadParamater((DxUint32_t)messageParam ,
                          sizeof(DxUint32_t) * 2,
                          sizeof(DxUint32_t) * 2,
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
   
  /* check the opcode */
  if(messageParam[0] != DX_SEP_HOST_SEP_PROTOCOL_HOST_MNG_RSA_BUILD_VERIFY_PUB_KEY_OP_CODE)
  {
    Error = DX_WRONG_OPCODE_FROM_SEP_ERR;
    goto end_function_unlock;
  }
   
  /* check the status */
  if(messageParam[1] != DX_OK)
  {
    Error = messageParam[1];
    goto end_function_unlock;
  }
  
  /* read Pub Key data out */
  maxLength = ((sizeof(CRYS_RSAUserPubKey_t) + 3) / sizeof(DxUint32_t)) * sizeof(DxUint32_t);
  Error = SEPDriver_ReadParamater((DxUint32_t)UserPubKey_ptr,
                          sizeof(CRYS_RSAUserPubKey_t),
                          maxLength,
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
  

  /* ...................... end of function ................................ */   

end_function_unlock:   

  /* lock access to the SEP */
  SEPDriver_Unlock();

end_function:

  return Error;                                  

}/* DX_CC_MNG_RSA_BuildPlatformPubKey */


/*
*   @brief This function updates the LCS 
*          
*
*   @param[in] NewLcs - New LCS value. 
*
*   Returns:  Status of the operation.
*/
DxError_t DX_MNG_ChangeLCS(DxUint8_t    NewLcs)
{

  /* The return error identifier */
  DxError_t           Error;
  
  /* offset */
  DxUint32_t          sramOffset;
   
  /* read param */
  DxUint32_t          messageParam[2];
  
  /*----------------------------------
      CODE
  ------------------------------------*/
   
  /* .................. initializing local variables ................... */
  /* ------------------------------------------------------------------- */   
   
  /* initializing the Error to O.K */
  Error = DX_OK;      
                         
   /* lock access to the SEP */
   Error = SEPDriver_Lock();
   
   if(Error != DX_OK)
   {
       goto end_function;
   }
  
  /*----------------------------
      start sending message to SEP 
  -----------------------------*/
  sramOffset = 0;
   
  /* start the message */
  SEPDriver_StartMessage(&sramOffset);
  
  /* prepare params */
  messageParam[0] = DX_SEP_HOST_SEP_PROTOCOL_HOST_MNG_UPDATE_LCS_CODE;
  messageParam[1] = NewLcs;
  
  /* send params */
  Error = SEPDriver_WriteParamater((DxUint32_t)messageParam ,
                           sizeof(DxUint32_t) * 2 ,
                           sizeof(DxUint32_t) * 2 ,
                           &sramOffset , 
                           DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }

  
  SEPDriver_EndMessage(sramOffset);
            
  /* wait for the response */
  Error = SEPDriver_POLL_FOR_REPONSE();
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
  
                                            
  /*-------------------
    start reading message from the SEP 
  ---------------------*/
   
  /* start the message */
  Error = SEPDriver_StartIncomingMessage(&sramOffset);
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
   
  /* read opcode + status  */
  Error = SEPDriver_ReadParamater((DxUint32_t)messageParam ,
                          sizeof(DxUint32_t) * 2,
                          sizeof(DxUint32_t) * 2,
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
   
  /* check the opcode */
  if(messageParam[0] != DX_SEP_HOST_SEP_PROTOCOL_HOST_MNG_UPDATE_LCS_CODE)
  {
    Error = DX_WRONG_OPCODE_FROM_SEP_ERR;
    goto end_function_unlock;
  }
   
  /* check the status */
  if(messageParam[1] != DX_OK)
  {
    Error = messageParam[1];
    goto end_function_unlock;
  }
                                           
  /* ...................... end of function ................................ */   

end_function_unlock:   

  /* lock access to the SEP */
  SEPDriver_Unlock();

end_function:

  return Error;                                  

}/* DX_MNG_ChangeLCS */


/*
*   @brief This function reads the LCS from SEP
*          
*
*   @param[out] LCS_ptr - The current life cycle state.
*
*   Returns:  Status of the operation.
*/
DxError_t DX_MNG_GetLCS(DxUint32_t    *LCS_ptr)
{

  /* The return error identifier */
  DxError_t           Error;
  
  /* offset */
  DxUint32_t          sramOffset;
   
  /* read param */
  DxUint32_t          messageParam[2];
  
  DxUint32_t regVal;
  /*----------------------------------
      CODE
  ------------------------------------*/
   
  /* .................. initializing local variables ................... */
  /* ------------------------------------------------------------------- */   
   
  /* initializing the Error to O.K */
  Error = DX_OK;      
                         
   /* lock access to the SEP */
   Error = SEPDriver_Lock();
   
   if (Error == DX_MNG_SEP_IS_DISABLE_ERR)
   {
		/*get the status of the SEP*/
		SEPDriver_ReadRegister(GEN_HW_HOST_SEP_HOST_GPR3_REG_ADDR,&regVal);
		if(regVal != 0x2) /*first phase*/
		{
			Error = DX_MNG_LCS_SECURITY_DISABLE_ERR;	
		}
		else
		{
			SEPDriver_WriteRegister(GEN_HW_SRAM_ADDR_REG_ADDR,HW_CC_SRAM_LCS_ADDRESS);
			/*dummy read*/
			SEPDriver_ReadRegister(GEN_HW_SRAM_DATA_REG_ADDR,&regVal);
			regVal = 0;
			do
			{
				SEPDriver_ReadRegister(GEN_HW_SRAM_DATA_READY_REG_ADDR,&regVal);
			}while(!(regVal&0x1));
			/*read the LCS */
			SEPDriver_ReadRegister(GEN_HW_SRAM_DATA_REG_ADDR,LCS_ptr);
			do
			{
				SEPDriver_ReadRegister(GEN_HW_SRAM_DATA_READY_REG_ADDR,&regVal);
			}while(!(regVal&0x1));
		}
   		goto end_function;
   }
   	
   if(Error != DX_OK)
   {
       goto end_function;
   }
  
  /*----------------------------
      start sending message to SEP 
  -----------------------------*/
  sramOffset = 0;
   
  /* start the message */
  SEPDriver_StartMessage(&sramOffset);
  
  /* prepare params */
  messageParam[0] = DX_SEP_HOST_SEP_PROTOCOL_HOST_GET_LCS_OP_CODE ;
  
  /* send params */
  Error = SEPDriver_WriteParamater((DxUint32_t)messageParam ,
                           sizeof(DxUint32_t) * 1 ,
                           sizeof(DxUint32_t) * 1 ,
                           &sramOffset , 
                           DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }

  
  SEPDriver_EndMessage(sramOffset);
            
  /* wait for the response */
  Error = SEPDriver_POLL_FOR_REPONSE();
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
  
                                            
  /*-------------------
    start reading message from the SEP 
  ---------------------*/
   
  /* start the message */
  Error = SEPDriver_StartIncomingMessage(&sramOffset);
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
   
  /* read opcode + status  */
  Error = SEPDriver_ReadParamater((DxUint32_t)messageParam ,
                          sizeof(DxUint32_t) * 2,
                          sizeof(DxUint32_t) * 2,
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
   
  /* check the opcode */
  if(messageParam[0] != DX_SEP_HOST_SEP_PROTOCOL_HOST_GET_LCS_OP_CODE)
  {
    Error = DX_WRONG_OPCODE_FROM_SEP_ERR;
    goto end_function_unlock;
  }
   
  /* check the status */
  if(messageParam[1] != DX_OK)
  {
    Error = messageParam[1];
    goto end_function_unlock;
  }
                                           
  /* read key Len */
  Error = SEPDriver_ReadParamater((DxUint32_t)LCS_ptr ,
                          sizeof(DxUint32_t),
                          sizeof(DxUint32_t),
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
  /* ...................... end of function ................................ */   

end_function_unlock:   

  /* lock access to the SEP */
  SEPDriver_Unlock();

end_function:

  return Error;                                  

}/* DX_CC_MNG_SetRkekOtp */


/*
*   @brief This function Generate random vector up to 4K
*          
*
*   @param[in] RNDSize - The size of the generated vector. 
*   @param[in] output_ptr - The buffer for the vector.
*
*   Returns:  Status of the operation.
*/
DxError_t DX_MNG_GenerateDRNGVector(DxUint32_t RNDSize, DxUint8_t* output_ptr)
{

  /* The return error identifier */
  DxError_t           Error;
  
  /* offset */
  DxUint32_t          sramOffset;
   
  /* read param */
  DxUint32_t          messageParam[2];
  
  /* max length */
  DxUint32_t          maxLength;
  
  /*----------------------------------
      CODE
  ------------------------------------*/
   if(output_ptr == DX_NULL)
   {
   		return DX_KMNG_INVALID_INPUT_POINTER_ERR;
   }


  /* .................. initializing local variables ................... */
  /* ------------------------------------------------------------------- */   
   
  /* initializing the Error to O.K */
  Error = DX_OK;      
                         
   /* lock access to the SEP */
   Error = SEPDriver_Lock();
   
   if(Error != DX_OK)
   {
       goto end_function;
   }
  
  /*----------------------------
      start sending message to SEP 
  -----------------------------*/
  sramOffset = 0;
   
  /* start the message */
  SEPDriver_StartMessage(&sramOffset);
  
  /* prepare params */
  messageParam[0] = DX_SEP_HOST_SEP_PROTOCOL_HOST_MNG_GENERATE_VECTOR_OP_CODE ;
  messageParam[1] = RNDSize ;
  
  /* send params */
  Error = SEPDriver_WriteParamater((DxUint32_t)messageParam ,
                           sizeof(DxUint32_t) * 2 ,
                           sizeof(DxUint32_t) * 2 ,
                           &sramOffset , 
                           DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }

  
  SEPDriver_EndMessage(sramOffset);
            
  /* wait for the response */
  Error = SEPDriver_POLL_FOR_REPONSE();
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
  
                                            
  /*-------------------
    start reading message from the SEP 
  ---------------------*/
   
  /* start the message */
  Error = SEPDriver_StartIncomingMessage(&sramOffset);
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
   
  /* read opcode + status  */
  Error = SEPDriver_ReadParamater((DxUint32_t)messageParam ,
                          sizeof(DxUint32_t) * 2,
                          sizeof(DxUint32_t) * 2,
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
   
  /* check the opcode */
  if(messageParam[0] != DX_SEP_HOST_SEP_PROTOCOL_HOST_MNG_GENERATE_VECTOR_OP_CODE)
  {
    Error = DX_WRONG_OPCODE_FROM_SEP_ERR;
    goto end_function_unlock;
  }
   
  /* check the status */
  if(messageParam[1] != DX_OK)
  {
    Error = messageParam[1];
    goto end_function_unlock;
  }
                                           
  maxLength = ((RNDSize + 3)/sizeof(DxUint32_t))*sizeof(DxUint32_t);
  /* read key Len */
  Error = SEPDriver_ReadParamater((DxUint32_t)output_ptr ,
                          RNDSize,
                          maxLength,
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
  /* ...................... end of function ................................ */   

end_function_unlock:   

  /* lock access to the SEP */
  SEPDriver_Unlock();

end_function:

  return Error;                                  

}/* DX_CC_MNG_SetRkekOtp */


/*
*   @brief This function Gets the ROM version
*          
*
*   @param[in] version - buffer to hold the version. 
*
*   Returns:  Status of the operation.
*/
DxError_t DX_MNG_GetROMVersion(SEP_Version_t *version)
{

  /* The return error identifier */
  DxError_t           Error;
  
  /* offset */
  DxUint32_t          sramOffset;
   
  /* read param */
  DxUint32_t          messageParam[2];
  
  /* offset */
  DxUint32_t          maxReadLen;
  /*----------------------------------
      CODE
  ------------------------------------*/
   if(version == DX_NULL)
   {
   		return DX_KMNG_INVALID_INPUT_POINTER_ERR;
   }


  /* .................. initializing local variables ................... */
  /* ------------------------------------------------------------------- */   
   
  /* initializing the Error to O.K */
  Error = DX_OK;      
                         
   /* lock access to the SEP */
   Error = SEPDriver_Lock();
   
   if(Error != DX_OK)
   {
       goto end_function;
   }
  
  /*----------------------------
      start sending message to SEP 
  -----------------------------*/
  sramOffset = 0;
   
  /* start the message */
  SEPDriver_StartMessage(&sramOffset);
  
  /* prepare params */
  messageParam[0] = DX_SEP_HOST_SEP_PROTOCOL_HOST_MNG_GET_ROM_VERSION_OP_CODE ;
  
  /* send params */
  Error = SEPDriver_WriteParamater((DxUint32_t)messageParam ,
                           sizeof(DxUint32_t) * 1 ,
                           sizeof(DxUint32_t) * 1 ,
                           &sramOffset , 
                           DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }

  
  SEPDriver_EndMessage(sramOffset);
            
  /* wait for the response */
  Error = SEPDriver_POLL_FOR_REPONSE();
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
  
                                            
  /*-------------------
    start reading message from the SEP 
  ---------------------*/
   
  /* start the message */
  Error = SEPDriver_StartIncomingMessage(&sramOffset);
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
   
  /* read opcode + status  */
  Error = SEPDriver_ReadParamater((DxUint32_t)messageParam ,
                          sizeof(DxUint32_t) * 2,
                          sizeof(DxUint32_t) * 2,
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
   
  /* check the opcode */
  if(messageParam[0] != DX_SEP_HOST_SEP_PROTOCOL_HOST_MNG_GET_ROM_VERSION_OP_CODE)
  {
    Error = DX_WRONG_OPCODE_FROM_SEP_ERR;
    goto end_function_unlock;
  }
   
  /* check the status */
  if(messageParam[1] != DX_OK)
  {
    Error = messageParam[1];
    goto end_function_unlock;
  }
                                           
  maxReadLen = ((sizeof(SEP_Version_t)+3)/4)*4;
  /* read key Len */
  Error = SEPDriver_ReadParamater((DxUint32_t)version ,
                          sizeof(SEP_Version_t),
                          maxReadLen,
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
  /* ...................... end of function ................................ */   

end_function_unlock:   

  /* lock access to the SEP */
  SEPDriver_Unlock();

end_function:

  return Error;                                  

}/* DX_CC_MNG_SetRkekOtp */

/*
*   @brief This function Gets the ROM version
*          
*
*   @param[in] version - buffer to hold the version. 
*
*   Returns:  Status of the operation.
*/
DxError_t DX_MNG_GetRAMVersion(SEP_Version_t *version)
{

  /* The return error identifier */
  DxError_t           Error;
  
  /* offset */
  DxUint32_t          sramOffset;
   
  /* read param */
  DxUint32_t          messageParam[2];
  
  /* offset */
  DxUint32_t          maxReadLen;
  /*----------------------------------
      CODE
  ------------------------------------*/
   if(version == DX_NULL)
   {
   		return DX_KMNG_INVALID_INPUT_POINTER_ERR;
   }


  /* .................. initializing local variables ................... */
  /* ------------------------------------------------------------------- */   
   
  /* initializing the Error to O.K */
  Error = DX_OK;      
                         
   /* lock access to the SEP */
   Error = SEPDriver_Lock();
   
   if(Error != DX_OK)
   {
       goto end_function;
   }
  
  /*----------------------------
      start sending message to SEP 
  -----------------------------*/
  sramOffset = 0;
   
  /* start the message */
  SEPDriver_StartMessage(&sramOffset);
  
  /* prepare params */
  messageParam[0] = DX_SEP_HOST_SEP_PROTOCOL_HOST_MNG_GET_RAM_VERSION_OP_CODE ;
  
  /* send params */
  Error = SEPDriver_WriteParamater((DxUint32_t)messageParam ,
                           sizeof(DxUint32_t) * 1 ,
                           sizeof(DxUint32_t) * 1 ,
                           &sramOffset , 
                           DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }

  
  SEPDriver_EndMessage(sramOffset);
            
  /* wait for the response */
  Error = SEPDriver_POLL_FOR_REPONSE();
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
  
                                            
  /*-------------------
    start reading message from the SEP 
  ---------------------*/
   
  /* start the message */
  Error = SEPDriver_StartIncomingMessage(&sramOffset);
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
   
  /* read opcode + status  */
  Error = SEPDriver_ReadParamater((DxUint32_t)messageParam ,
                          sizeof(DxUint32_t) * 2,
                          sizeof(DxUint32_t) * 2,
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
   
  /* check the opcode */
  if(messageParam[0] != DX_SEP_HOST_SEP_PROTOCOL_HOST_MNG_GET_RAM_VERSION_OP_CODE)
  {
    Error = DX_WRONG_OPCODE_FROM_SEP_ERR;
    goto end_function_unlock;
  }
   
  /* check the status */
  if(messageParam[1] != DX_OK)
  {
    Error = messageParam[1];
    goto end_function_unlock;
  }
                                           
  maxReadLen = ((sizeof(SEP_Version_t)+3)/4)*4;
  /* read key Len */
  Error = SEPDriver_ReadParamater((DxUint32_t)version ,
                          sizeof(SEP_Version_t),
                          maxReadLen,
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
  /* ...................... end of function ................................ */   

end_function_unlock:   

  /* lock access to the SEP */
  SEPDriver_Unlock();

end_function:

  return Error;                                  

}/* DX_CC_MNG_SetRkekOtp */


/*
*   @brief This function set the mode of the API's. If the mode is blocking, then the API will be blocked until it aquires 
*          access to SEP, and receives a response to SEP. If non-blocking - then if the SEP is currently busy with another transaction, an API will fail with appropriate error
*          and will not block
*          
*
*   @param[in] blockingMode - 1 - blocking mode, 0 - non-blocking mode. 
*
*   Returns:  Status of the operation.
*/
DxError_t DX_MNG_SetAPIBlockingMode(DxUint32_t blockingMode)
{
  /* error */
  DxError_t error;
  
  /*-------------------------
      CODE
  ---------------------------*/
  
  error = SEPDriver_SetAPIBlockingMode(blockingMode);

  return error;
}


/*
*   @brief This function clear the warm boot idnetification
*          
*
*   Returns:  Status of the operation.
*/
DxError_t DX_MNG_ClearWarmBootIndication()
{

  /* The return error identifier */
  DxError_t           Error;
  
  /* offset */
  DxUint32_t          sramOffset;
   
  /* read param */
  DxUint32_t          messageParam[2];
  
  /*----------------------------------
      CODE
  ------------------------------------*/
   
  /* .................. initializing local variables ................... */
  /* ------------------------------------------------------------------- */   
   
  /* initializing the Error to O.K */
  Error = DX_OK;      
                         
   /* lock access to the SEP */
   Error = SEPDriver_Lock();
   
   if (Error == DX_MNG_SEP_IS_DISABLE_ERR)
   {
   	  /*In case the SEP is stuck mark the force cold boot indication */
   	  SEPDriver_ReadRegister(GEN_HW_HOST_SEP_HOST_GPR3_REG_ADDR ,&messageParam[0]);
   	  if(messageParam[0] == 0x1)
   	  {
	   	  SEPDriver_WriteRegister(GEN_HW_HOST_HOST_SEP_GPR0_REG_ADDR , 0x8);
		  return DX_OK;
   	  }
   	  else
   	  {
   	     Error = DX_MNG_LCS_SECURITY_DISABLE_ERR;
    	 goto end_function;   	  	
   	  }
   }
   	
   if(Error != DX_OK)
   {
       goto end_function;
   }
  
  /*----------------------------
      start sending message to SEP 
  -----------------------------*/
  sramOffset = 0;
   
  /* start the message */
  SEPDriver_StartMessage(&sramOffset);
  
  /* prepare params */
  messageParam[0] = DX_SEP_HOST_SEP_PROTOCOL_HOST_MNG_RESET_WARM_BOOT_IND_OP_CODE ;
  
  /* send params */
  Error = SEPDriver_WriteParamater((DxUint32_t)messageParam ,
                           sizeof(DxUint32_t) * 1 ,
                           sizeof(DxUint32_t) * 1 ,
                           &sramOffset , 
                           DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }

  
  SEPDriver_EndMessage(sramOffset);
            
  /* wait for the response */
  Error = SEPDriver_POLL_FOR_REPONSE();
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
  
                                            
  /*-------------------
    start reading message from the SEP 
  ---------------------*/
   
  /* start the message */
  Error = SEPDriver_StartIncomingMessage(&sramOffset);
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
   
  /* read opcode + status  */
  Error = SEPDriver_ReadParamater((DxUint32_t)messageParam ,
                          sizeof(DxUint32_t) * 2,
                          sizeof(DxUint32_t) * 2,
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
   
  /* check the opcode */
  if(messageParam[0] != DX_SEP_HOST_SEP_PROTOCOL_HOST_MNG_RESET_WARM_BOOT_IND_OP_CODE)
  {
    Error = DX_WRONG_OPCODE_FROM_SEP_ERR;
    goto end_function_unlock;
  }
   
  /* check the status */
  if(messageParam[1] != DX_OK)
  {
    Error = messageParam[1];
    goto end_function_unlock;
  }
                                           
  /* ...................... end of function ................................ */   

end_function_unlock:   

  /* lock access to the SEP */
  SEPDriver_Unlock();

end_function:

  return Error;                                  

}/* DX_CC_MNG_SetRkekOtp */


/*
*   @brief This function reset the internal random seed.
*          
*
*   @param[in] rndSampleCnt - The counter for the random sample. 
*
*   Returns:  Status of the operation.
*/
DxError_t DX_CC_MNG_resetSeed(DxUint32_t rndSampleCnt)
{

  /* The return error identifier */
  DxError_t           Error;
  
  /* offset */
  DxUint32_t          sramOffset;
   
  /* read param */
  DxUint32_t          messageParam[2];
  
  /*----------------------------------
      CODE
  ------------------------------------*/

  /* .................. initializing local variables ................... */
  /* ------------------------------------------------------------------- */   
   
  /* initializing the Error to O.K */
  Error = DX_OK;      
                         
   /* lock access to the SEP */
   Error = SEPDriver_Lock();
   
   if(Error != DX_OK)
   {
       goto end_function;
   }
  
  /*----------------------------
      start sending message to SEP 
  -----------------------------*/
  sramOffset = 0;
   
  /* start the message */
  SEPDriver_StartMessage(&sramOffset);
  
  /* prepare params */
  messageParam[0] = DX_SEP_HOST_SEP_PROTOCOL_HOST_MNG_RESET_SEED_OP_CODE ;
  messageParam[1] = rndSampleCnt ;
  
  /* send params */
  Error = SEPDriver_WriteParamater((DxUint32_t)messageParam ,
                           sizeof(DxUint32_t) * 2 ,
                           sizeof(DxUint32_t) * 2 ,
                           &sramOffset , 
                           DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }

  
  SEPDriver_EndMessage(sramOffset);
            
  /* wait for the response */
  Error = SEPDriver_POLL_FOR_REPONSE();
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
  
                                            
  /*-------------------
    start reading message from the SEP 
  ---------------------*/
   
  /* start the message */
  Error = SEPDriver_StartIncomingMessage(&sramOffset);
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
   
  /* read opcode + status  */
  Error = SEPDriver_ReadParamater((DxUint32_t)messageParam ,
                          sizeof(DxUint32_t) * 2,
                          sizeof(DxUint32_t) * 2,
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
   
  /* check the opcode */
  if(messageParam[0] != DX_SEP_HOST_SEP_PROTOCOL_HOST_MNG_RESET_SEED_OP_CODE)
  {
    Error = DX_WRONG_OPCODE_FROM_SEP_ERR;
    goto end_function_unlock;
  }
   
  /* check the status */
  if(messageParam[1] != DX_OK)
  {
    Error = messageParam[1];
    goto end_function_unlock;
  }
                                           
  /* ...................... end of function ................................ */   

end_function_unlock:   

  /* lock access to the SEP */
  SEPDriver_Unlock();

end_function:

  return Error;                                  

}/* DX_CC_MNG_resetSeed */

/*
*   @brief This function notify the SEP that the cache was reloaded and it can start the 
*          cold warm boot procedure
*		   Since the SEP is stuck in endless loop till it get the notification,
*          the notification is passed via register and not shared area message.
*   Returns:  Status of the operation.
*/
DxError_t DX_MNG_RecoverFromIcacheViolation( void )
{

  /* The return error identifier */
  DxError_t           Error;
  
  /* offset */
  DxUint32_t          regVal;
   
  
  /*----------------------------------
      CODE
  ------------------------------------*/
   
  /* .................. initializing local variables ................... */
  /* ------------------------------------------------------------------- */   
   
  /* initializing the Error to O.K */
  Error = DX_OK;      
                         
   /* lock access to the SEP */
   Error = SEPDriver_Lock();
   
   if (Error == DX_MNG_SEP_IS_DISABLE_ERR)
   {
   	  /*In case the SEP is stuck mark the force cold boot indication */
   	  SEPDriver_ReadRegister(GEN_HW_HOST_SEP_HOST_GPR3_REG_ADDR ,&regVal);
   	  if(regVal == 0x20)/*I-Cache violation error*/
   	  {
	   	  /* set the force cold boot flag */
	   	  SEPDriver_WriteRegister(GEN_HW_HOST_HOST_SEP_GPR0_REG_ADDR , 0x4);
		  return DX_OK;
   	  }
   	  else
   	  {
   	     Error = DX_MNG_NO_I_CACHE_VIOLATION_ERR;
    	 goto end_function;   	  	
   	  }
   }
   	
  /* ...................... end of function ................................ */   
  Error = DX_MNG_NO_I_CACHE_VIOLATION_ERR;

  /* lock access to the SEP */
  SEPDriver_Unlock();

end_function:

  return Error;                                  

}/* DX_CC_MNG_SetRkekOtp */



/*
*   @brief This function reads the images verification status from SEP
*          
*
*   @param[out] Status_ptr - The latest verification status (only after cold boot).
*
*   Returns:  Status of the operation.
*/
DxError_t DX_CC_MNG_IsImageVerifySucceed(DxUint32_t    *Status_ptr)
{

  
  DxUint32_t regVal;
  /*----------------------------------
      CODE
  ------------------------------------*/
   
  /* .................. initializing local variables ................... */
  /* ------------------------------------------------------------------- */   
   
  *Status_ptr = 0x0;                       
  /*get the status of the SEP*/
  SEPDriver_ReadRegister(GEN_HW_HOST_SEP_HOST_GPR3_REG_ADDR,&regVal);
  if(regVal != 0x4) 
  {
	/*If we are not after cold boot there is no verification status*/
	return DX_MNG_WRONG_SEP_STATUS_ERR;	
  }   	
  
  /*get the verification status*/
  SEPDriver_ReadRegister(GEN_HW_HOST_SEP_HOST_GPR0_REG_ADDR,&regVal);

  if(!(regVal&(DX_CC_MNG_GPR0_HOST_RESIDENT_ERROR|DX_CC_MNG_GPR0_HOST_RESIDENT_ERROR)))
  {
  	/*no verification warinig*/
  	*Status_ptr = DX_IMAGE_VERIFY_SUCCEED; 
  }
  else
  if(regVal&DX_CC_MNG_GPR0_HOST_RESIDENT_ERROR)
  {
  	*Status_ptr = DX_IMAGE_VERIFY_RESIDENT_IMAGE_FAIL;   	
  }
  if(regVal&DX_CC_MNG_GPR0_HOST_RESIDENT_ERROR)
  {
  	*Status_ptr |= DX_IMAGE_VERIFY_CACHE_IMAGE_FAIL;   	
  }
  
  return DX_OK;

}/* DX_CC_MNG_SetRkekOtp */


/*
*   @brief This function updates the ext interrupt status register address 
*          
*
*   @param[in] InStatusAddr - address of the input status register. 
*   @param[in] OutStatusAddr - address of the output status register. 
*   The register must be accessiable to the SEP.In case of 0x0 teh register address is not updated
*   Returns:  Status of the operation.
*/
DxError_t DX_MNG_SetExtIntStatusRegsAddr(DxUint32_t InStatusAddr,DxUint32_t OutStatusAddr)
{

  /* The return error identifier */
  DxError_t           Error;
  
  /* offset */
  DxUint32_t          sramOffset;
   
  /* read param */
  DxUint32_t          messageParam[3];
  
  /*----------------------------------
      CODE
  ------------------------------------*/
   
  /* .................. initializing local variables ................... */
  /* ------------------------------------------------------------------- */   
   
  /* initializing the Error to O.K */
  Error = DX_OK;      
                         
   /* lock access to the SEP */
   Error = SEPDriver_Lock();
   
   if(Error != DX_OK)
   {
       goto end_function;
   }
  
  /*----------------------------
      start sending message to SEP 
  -----------------------------*/
  sramOffset = 0;
   
  /* start the message */
  SEPDriver_StartMessage(&sramOffset);
  
  /* prepare params */
  messageParam[0] = DX_SEP_HOST_SEP_PROTOCOL_HOST_SET_EXT_APP_STATUS_REG_OP_CODE;
  messageParam[1] = (DxUint32_t)InStatusAddr;
  messageParam[2] = (DxUint32_t)OutStatusAddr;
  
  /* send params */
  Error = SEPDriver_WriteParamater((DxUint32_t)messageParam ,
                           sizeof(DxUint32_t) * 3 ,
                           sizeof(DxUint32_t) * 3 ,
                           &sramOffset , 
                           DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }

  
  SEPDriver_EndMessage(sramOffset);
            
  /* wait for the response */
  Error = SEPDriver_POLL_FOR_REPONSE();
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
  
                                            
  /*-------------------
    start reading message from the SEP 
  ---------------------*/
   
  /* start the message */
  Error = SEPDriver_StartIncomingMessage(&sramOffset);
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
   
  /* read opcode + status  */
  Error = SEPDriver_ReadParamater((DxUint32_t)messageParam ,
                          sizeof(DxUint32_t) * 2,
                          sizeof(DxUint32_t) * 2,
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
   
  /* check the opcode */
  if(messageParam[0] != DX_SEP_HOST_SEP_PROTOCOL_HOST_SET_EXT_APP_STATUS_REG_OP_CODE)
  {
    Error = DX_WRONG_OPCODE_FROM_SEP_ERR;
    goto end_function_unlock;
  }
   
  /* check the status */
  if(messageParam[1] != DX_OK)
  {
    Error = messageParam[1];
    goto end_function_unlock;
  }
                                           
  /* ...................... end of function ................................ */   

end_function_unlock:   

  /* lock access to the SEP */
  SEPDriver_Unlock();

end_function:

  return Error;                                  

}/* DX_MNG_ChangeLCS */

/*
*   @brief This function Update the shared area base address in the SEP
*          
*
*   @param[in] newSharedAreaAddress - The new address of the shared area.
*
*   Returns:  0 in case of success else -1.
*/
DxError_t DX_CC_MNG_UpdateSharedAreaAddress(DxUint32_t  newSharedAreaAddress)
{

  
  DxUint32_t regVal;
  /*----------------------------------
      CODE
  ------------------------------------*/
   
  /* .................. initializing local variables ................... */
  /* ------------------------------------------------------------------- */   
   
  /*Write the new Address to the SEP via register 1*/
  SEPDriver_WriteRegister(GEN_HW_HOST_HOST_SEP_GPR1_REG_ADDR,newSharedAreaAddress);
  
  /*get the Update status*/
  do
  {
	  SEPDriver_ReadRegister(GEN_HW_HOST_SEP_HOST_GPR1_REG_ADDR,&regVal);
  }while(regVal == 0x0);
  
  if(regVal != newSharedAreaAddress)
  {
  	return regVal;
  }

  return DX_OK;

}/* DX_CC_MNG_SetRkekOtp */

/*
*   @brief This function is used for reseting and configuring the 3 cache counters. 
*   Each counter can be one of the 9 options defined in the enumerator DX_CC_MNG_CacheCounterType_t.       
*
*   @param[in] cfgCnt1 - cache counter configuration for counter1. 
*   @param[in] cfgCnt2 - cache counter configuration for counter2. 
*   @param[in] cfgCnt3 - cache counter configuration for counter3. 
*   Returns:  Status of the operation.
*/

DxError_t DX_CC_MNG_ConfigureAndResetCacheCounters(DX_CC_MNG_CacheCounterType_t       cacheType,
                                                   DX_CC_MNG_CacheCounterConfigType_t cfgCnt1,
                                                   DX_CC_MNG_CacheCounterConfigType_t cfgCnt2,
                                                   DX_CC_MNG_CacheCounterConfigType_t cfgCnt3)
{
  /* The return error identifier */
  DxError_t           Error;
  
  /* offset */
  DxUint32_t          sramOffset;
   
  /* read param */
  DxUint32_t          messageParam[5];
  
  /*----------------------------------
      CODE
  ------------------------------------*/
   
  /* .................. initializing local variables ................... */
  /* ------------------------------------------------------------------- */   
   
  /* initializing the Error to O.K */
  Error = DX_OK;      
                         
   /* lock access to the SEP */
   Error = SEPDriver_Lock();
   
   if(Error != DX_OK)
   {
       goto end_function;
   }
  
  /*----------------------------
      start sending message to SEP 
  -----------------------------*/
  sramOffset = 0;
   
  /* start the message */
  SEPDriver_StartMessage(&sramOffset);
  
  /* prepare params */
  messageParam[0] = DX_SEP_HOST_SEP_PROTOCOL_HOST_SET_CACHE_CNTS_CONFIG_ID_OP_CODE;
  messageParam[1] = (DxUint32_t)cacheType;
  messageParam[2] = (DxUint32_t)cfgCnt1;
  messageParam[3] = (DxUint32_t)cfgCnt2;
  messageParam[4] = (DxUint32_t)cfgCnt3;
  
  /* send params */
  Error = SEPDriver_WriteParamater((DxUint32_t)messageParam ,
                           sizeof(DxUint32_t) * 5 ,
                           sizeof(DxUint32_t) * 5 ,
                           &sramOffset , 
                           DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }

  
  SEPDriver_EndMessage(sramOffset);
            
  /* wait for the response */
  Error = SEPDriver_POLL_FOR_REPONSE();
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
  
                                            
  /*-------------------
    start reading message from the SEP 
  ---------------------*/
   
  /* start the message */
  Error = SEPDriver_StartIncomingMessage(&sramOffset);
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
   
  /* read opcode + status  */
  Error = SEPDriver_ReadParamater((DxUint32_t)messageParam ,
                          sizeof(DxUint32_t) * 2,
                          sizeof(DxUint32_t) * 2,
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
   
  /* check the opcode */
  if(messageParam[0] != DX_SEP_HOST_SEP_PROTOCOL_HOST_SET_CACHE_CNTS_CONFIG_ID_OP_CODE)
  {
    Error = DX_WRONG_OPCODE_FROM_SEP_ERR;
    goto end_function_unlock;
  }
   
  /* check the status */
  if(messageParam[1] != DX_OK)
  {
    Error = messageParam[1];
    goto end_function_unlock;
  }
                                           
  /* ...................... end of function ................................ */   

end_function_unlock:   

  /* lock access to the SEP */
  SEPDriver_Unlock();

end_function:

  return Error;                                  

}


/*
*   @brief This function is used for reading the 3 cache counters. 
*   The read is not reseting the counters so counter can be read few times        
*   during the tests flow without reconfiguration.
*
*
*   @param[in] cnt1Val - buffer for counter1. 
*   @param[in] cnt2Val - buffer for counter2. 
*   @param[in] cnt3Val - buffer for counter3. 
*   Returns:  Status of the operation.
*/

DxError_t DX_CC_MNG_GetCacheCounters(DX_CC_MNG_CacheCounterType_t       cacheType,
                                     DxUint32_t                         *cnt1Val,
                                     DxUint32_t                         *cnt2Val,
                                     DxUint32_t                         *cnt3Val)
{
  /* The return error identifier */
  DxError_t           Error;
  
  /* offset */
  DxUint32_t          sramOffset;
   
  /* read param */
  DxUint32_t          messageParam[4];
  
  /*----------------------------------
      CODE
  ------------------------------------*/
   
  /* .................. initializing local variables ................... */
  /* ------------------------------------------------------------------- */   
   
  /* initializing the Error to O.K */
  Error = DX_OK;      
                         
   /* lock access to the SEP */
   Error = SEPDriver_Lock();
   
   if(Error != DX_OK)
   {
       goto end_function;
   }
  
  /*----------------------------
      start sending message to SEP 
  -----------------------------*/
  sramOffset = 0;
   
  /* start the message */
  SEPDriver_StartMessage(&sramOffset);
  
  /* prepare params */
  messageParam[0] = DX_SEP_HOST_SEP_PROTOCOL_HOST_READ_CACHE_CNTS_ID_OP_CODE;
  messageParam[1] = cacheType;
  
  /* send params */
  Error = SEPDriver_WriteParamater((DxUint32_t)messageParam ,
                           sizeof(DxUint32_t) * 2 ,
                           sizeof(DxUint32_t) * 2 ,
                           &sramOffset , 
                           DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }

  
  SEPDriver_EndMessage(sramOffset);
            
  /* wait for the response */
  Error = SEPDriver_POLL_FOR_REPONSE();
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
  
                                            
  /*-------------------
    start reading message from the SEP 
  ---------------------*/
   
  /* start the message */
  Error = SEPDriver_StartIncomingMessage(&sramOffset);
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
   
  /* read opcode + status  */
  Error = SEPDriver_ReadParamater((DxUint32_t)messageParam ,
                          sizeof(DxUint32_t) * 2,
                          sizeof(DxUint32_t) * 2,
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
   
  /* check the opcode */
  if(messageParam[0] != DX_SEP_HOST_SEP_PROTOCOL_HOST_READ_CACHE_CNTS_ID_OP_CODE)
  {
    Error = DX_WRONG_OPCODE_FROM_SEP_ERR;
    goto end_function_unlock;
  }
   
  /* check the status */
  if(messageParam[1] != DX_OK)
  {
    Error = messageParam[1];
    goto end_function_unlock;
  }

  /* read counters  */
  Error = SEPDriver_ReadParamater((DxUint32_t)messageParam ,
                          sizeof(DxUint32_t) * 3,
                          sizeof(DxUint32_t) * 3,
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
   
  *cnt1Val = messageParam[0];
  *cnt2Val = messageParam[1]; 
  *cnt3Val = messageParam[2]; 
                                           
  /* ...................... end of function ................................ */   

end_function_unlock:   

  /* lock access to the SEP */
  SEPDriver_Unlock();

end_function:

  return Error;                                  

	
	
}

