/**
 * @file       config.h
 * @brief      Processing config buffer in SWD
 * @author     Oleksandr Kanievskyi (o.kanievskyi@samsung.com)
 * @version    1.0
 * @date       Created July 5, 2016
 * @copyright  In Samsung Ukraine R&D Center (SURC) under a contract between
 * @copyright  LLC "Samsung Electronics Ukraine Company" (Kiev, Ukraine) and
 * @copyright  "Samsung Electronics Co", Ltd (Seoul, Republic of Korea)
 * @copyright  Copyright: (c) Samsung Electronics Co, Ltd 2016. All rights reserved.
**/

#ifndef PA_TZ_DRV_SRC_CONFIG_H_
#define PA_TZ_DRV_SRC_CONFIG_H_

#include "crypto.h"
#include "gaf.h"
#include "memory.h"

typedef enum {
  ENG    = 0,
  USER   = 1,
  DEMO   = 2,
  CONFIG = 3
} BuildType;

typedef struct {
  KernelAddress start;  ///< Kernel address of start of hash table
  uint64_t      size;   ///< Quantity of elements in hash table
  uint32_t      shift;  ///< Shift of hash table
} HashTableConf;

typedef struct __attribute__ ((packed)) {
  uint64_t start;
  uint64_t end;
  uint64_t flags;
} MemoryRange;

enum {
  kMaxMemoryRangesNum = 64
};

typedef struct {
  uint64_t va_bits;  ///< the maximum number of bits for virtual addresses.
  uint64_t va_start; ///< the first kernel virtual address.
  uint64_t page_offset; ///< the virtual address of the start of the linear map (top (VA_BITS - 1))
  uint64_t kimage_vaddr;   ///< the virtual address of the start of the kernel image
  uint64_t kimage_voffset; ///< difference between kernel physical and virtual addresses

  MemoryRange sys_ram_ranges[kMaxMemoryRangesNum]; ///< Array of available system RAM ranges
  uint64_t sys_ram_ranges_num; ///< Actual number of system RAM ranges
} MemoryConfig;

typedef struct {
  uint32_t      kaslr_offset; ///< KASLR offset
  GafInfo       gaf;          ///< GAF structure
  HashTableConf pid_map;      ///< Hash table of proca task descriptors with PID key
  HashTableConf app_name_map; ///< Hash table of proca task descriptors with app_name key
  MemoryConfig  memory_conf;  ///< Device memory configuration needed for address translation
} PaConfig;

/* Magic code that implies FIVE is disabled */
static const unsigned long kFiveDisabledMagicNumber = 0xECEFECEF;

static const uint32_t kPaConfigVersion = 3;

/* Magic code of pa config data structure in kernel */
static const uint32_t kPaConfigMagic = 0xCD0436EA;

/**
 * @brief Initializes PA configuration
 * @return ::PA_TZ_SUCCESS if command is processed successfully,
 *         ::PA_TZ_GENERAL_ERROR if command can not be processed
 */
PaTzResult ConfigInit();

/**
 * @brief Returns PA configuration
 */
const PaConfig *GetConfig(void);

/**
 * @brief Returns 1 if config was initialized, 0 otherwise
 */
uint32_t ConfigIsInited(void);

/**
 * @bried Returns 0 if FIVE disabled magic code is found, 1 otherwise
 */
uint32_t IsFiveEnabled(void);

#endif  // PA_TZ_DRV_SRC_CONFIG_H_
