/**
 * @file tee_sys.c
 * @brief GP System API implementation for <t-base driver
 * @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.
 */

#include <tee_internal_api.h>

#include <drStd.h>
#include <DrApi/DrApi.h>
#include <DrApi/DrApiHeap.h>
#include <setjmp.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <tees_log.h>

#define USEC_PER_MILLIS  1000
#define USEC_PER_SEC     1000000

static void *g_instance_data = NULL;
extern jmp_buf g_panic_jmp_buf;

void TEE_SetInstanceData(void *instanceData) {
  g_instance_data = instanceData;
}

void *TEE_GetInstanceData(void) {
  return g_instance_data;
}

void *TEE_Malloc(uint32_t size, uint32_t hint) {
  void *retval = NULL;

  retval = drApiMalloc(size, 0);

  if (retval && HINT_FILL_WITH_ZEROS == hint) {
    memset(retval, 0x00, size);
  }

  return retval;
}

void *TEE_Realloc(const void *buffer, uint32_t newSize) {
  return drApiRealloc((void *)buffer, newSize);
}

void TEE_Free(void *buffer) {
  drApiFree(buffer);
}

void TEE_MemMove(void *dest, const void *src, uint32_t size) {
  memmove(dest, src, size);
}

int32_t TEE_MemCompare(const void *buffer1,
                       const void *buffer2,
                       uint32_t size) {
  return memcmp(buffer1, buffer2, size);
}

void TEE_MemFill(void *buffer, uint32_t x, uint32_t size) {
  memset(buffer, x, size);
}

void TEE_GetSystemTime(TEE_Time *time) {
  timestamp_t p_time;

  if (DRAPI_OK == drApiGetSecureTimestamp(&p_time)) {
    time->seconds = p_time / USEC_PER_SEC;
    time->millis = (p_time % USEC_PER_SEC) / USEC_PER_MILLIS;
  }
}

void _TEE_Panic(TEE_Result panic_code, const char *szSrcFuncName,
                int nSrcFileLine) {
  TEES_LOG(TEES_LOG_LEVEL_ERROR, "TEE_Panic(%x) in %s:%d\n",
           panic_code, szSrcFuncName, nSrcFileLine);
  longjmp(g_panic_jmp_buf, panic_code);
}
