/**
 * @file   fcTIMA.h
 * @brief  Contains common definitions for TIMA
 *
 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
 */

#ifndef __FCTIMA_H__
#define __FCTIMA_H__

#ifndef SIZE_2KB
	#define SIZE_2KB		(1 << 11U)
#endif

/* SHA256 digest length */
#define SHA256_DIGEST_LEN 32

/* Special Virtual address for TIMA */
#define SRAM_HASH_TABLE_VA		((uint32_t)0x43000)	/* HASH table in iRAM */
#define DRAM_HASH_TABLE_VA		((uint32_t)0x44000)	/* HASH table in DRAM */
#define KERNEL_HASH_VALUE_VA	((uint32_t)0x45000)	/* HASH value of kernel */
#define TZASC_VA			((uint32_t)0x46000)	/* TZASC */
#define GOOD_MEASUREMENT_VA	((uint32_t)0x4F000)	/* HASH values at build time */
#define SECURE_BOOT_ENABLE_VA ((uint32_t)0x52000)
#define ICCC_SECURE_PARAMETER_VA ((uint32_t)0x4E000)

/* Special Physical address and Feature for TIMA 
 *
 * TIMA_TBOOT_CTX: This feature used when kernel hash, magic string and warranty 
 *     string addresses are passed through tboot_ctx structure by sboot
 *
 * TIMA_KERNEL_HASH_IN_SRAM: This feature is used kernel Hash is already in IRAM 
 *     which is calculated in by EL3.
 *
 * TIMA_HAVE_GOOD_MEASUREMENT: Used for project which have Good measurement support
 *
 * TIMA_FEATURE_FOR_64BIT: Used for project which have 64 bit architecture
 *
*/
#if defined(CONFIG_EXYNOS5410)
#define SRAM_HASH_TABLE_PA		((uint32_t)0x0202D000)	/* HASH table in iRAM */
#define KERNEL_HASH_VALUE_PA	((uint32_t)0x7F9FF000)	/* HASH value of kernel */
#elif defined(CONFIG_EXYNOS5420) || defined(CONFIG_EXYNOS5422)
#define SRAM_HASH_TABLE_PA		((uint32_t)0x02026000)	/* HASH table in iRAM */
#define KERNEL_HASH_VALUE_PA	((uint32_t)0x9F9FF000)	/* HASH value of kernel */
#if defined(CONFIG_EXYNOS5420)
#define ICCC_SECURE_PARAMETERS_AREA
#endif
#elif defined(CONFIG_4X12)
#define KERNEL_HASH_VALUE_PA	((uint32_t)0x7F9FF000)	/* HASH value of kernel */
#elif defined(CONFIG_EXYNOS5260) || defined(CONFIG_EXYNOS5430)  || defined(CONFIG_EXYNOS3470)
#define SRAM_HASH_TABLE_PA		((uint32_t)0x02025C00)	/* HASH table in iRAM */
#if defined(CONFIG_TBASE302)
#define TIMA_TBOOT_CTX
#else
#define KERNEL_HASH_VALUE_PA	((uint32_t)0x9F9FF000)	/* HASH value of kernel */
#endif
#if defined(CONFIG_EXYNOS5430) || defined(CONFIG_EXYNOS3470)
#define ICCC_SECURE_PARAMETERS_AREA
#endif
#elif defined(CONFIG_EXYNOS3475)
#define SRAM_HASH_TABLE_PA		((uint32_t)0x02025C00)	/* HASH table in iRAM */
#define TIMA_TBOOT_CTX
#define ICCC_SECURE_PARAMETERS_AREA
#elif defined(CONFIG_EXYNOS3472) || defined(CONFIG_EXYNOS4415) || defined(CONFIG_EXYNOS3250)
#define SRAM_HASH_TABLE_PA		((uint32_t)0x02025C00)	/* HASH table in iRAM */
#define TIMA_TBOOT_CTX
#elif defined(CONFIG_EXYNOS5433) 
#define SRAM_HASH_TABLE_PA		((uint32_t)0x02023800) /* HASH table in iRAM */ 
#define TIMA_TBOOT_CTX
#define TIMA_KERNEL_HASH_IN_SRAM
#define TIMA_FEATURE_FOR_64BIT
#define TIMA_SHARED_INFO
#define ICCC_SECURE_PARAMETERS_AREA
#elif defined(CONFIG_EXYNOS7420)  /* TODO Mukesh */
#define SRAM_HASH_TABLE_PA		((uint32_t) 0x02103800) /* HASH table in iRAM */ 
#define TIMA_TBOOT_CTX
#define TIMA_KERNEL_HASH_IN_SRAM
#define TIMA_FEATURE_FOR_64BIT
#define TIMA_CMBIN_HASH_IN_SRAM
#define TIMA_SHARED_INFO
#define TUI_MULTI_RESOLUTION_SUPPORT
#define TIMA_MST_DRV
#define SECURE_BOOT_ENABLE_PA		(0x101E01E0)
#define TIMA_RUNTIME_SKIP_MSR
#define ICCC_SECURE_PARAMETERS_AREA
#define PAY_MINI_IN_SERVER_SIGNED_NONCE
#define ICCC_ADD_CPUID			// after O OS
#elif defined(CONFIG_EXYNOS8890)  /* Exynos8890 */
#define SRAM_HASH_TABLE_PA		((uint32_t) 0x02023800) /* HASH table in iRAM */ 
#define TIMA_TBOOT_CTX
#define TIMA_KERNEL_HASH_IN_SRAM
#define TIMA_FEATURE_FOR_64BIT
#define TIMA_CMBIN_HASH_IN_SRAM
//#define TIMA_SHARED_INFO
#define TIMA_MST_DRV
#define TUI_MULTI_RESOLUTION_SUPPORT
#define SECURE_BOOT_ENABLE_PA		(0x101E1000)
#define TIMA_RUNTIME_SKIP_MSR
#define ICCC_SECURE_PARAMETERS_AREA
#define ICCC_ADD_CPUID			// after O OS
#define CONFIG_ROT_IN_ICCC		// after O OS
#define CONFIG_PARAMEXPANSION_ICCC	// after O OS
#elif defined(CONFIG_EXYNOS7580)  
#define SRAM_HASH_TABLE_PA      ((uint32_t) 0x02023800) /* HASH table in iRAM */
#define TIMA_TBOOT_CTX
#define ICCC_SECURE_PARAMETERS_AREA
#define TIMA_KERNEL_HASH_IN_SRAM
#define TIMA_FEATURE_FOR_64BIT
#define TIMA_CMBIN_HASH_IN_SRAM
//#define TIMA_SHARED_INFO
#define TIMA_MST_DRV
//#define DYNAMIC_TIMA_DUMP_LOG
#define SECURE_BOOT_ENABLE_PA       (0x10050000)
#define TIMA_RUNTIME_SKIP_MSR
#define PAY_MINI_IN_SERVER_SIGNED_NONCE
#elif defined(CONFIG_EXYNOS7870)  /* Exynos7870 */
#define SRAM_HASH_TABLE_PA		((uint32_t) 0x02023800) /* HASH table in iRAM */ 
#define TIMA_TBOOT_CTX
#define TIMA_KERNEL_HASH_IN_SRAM
#define TIMA_FEATURE_FOR_64BIT
#define TIMA_CMBIN_HASH_IN_SRAM
//#define TIMA_SHARED_INFO
#define TIMA_MST_DRV
#define SECURE_BOOT_ENABLE_PA		(0x100D1000)
#define TIMA_RUNTIME_SKIP_MSR
#define ICCC_SECURE_PARAMETERS_AREA
#define PAY_MINI_IN_SERVER_SIGNED_NONCE
#define ICCC_ADD_CPUID			// after O OS
#define CONFIG_ROT_IN_ICCC		// after O OS
#define CONFIG_PARAMEXPANSION_ICCC	// after O OS
#elif defined(CONFIG_EXYNOS7570)  /* Exynos7570 */
#define SRAM_HASH_TABLE_PA		((uint32_t) 0x02023800) /* HASH table in iRAM */ 
#define TIMA_TBOOT_CTX
#define TIMA_KERNEL_HASH_IN_SRAM
#define TIMA_FEATURE_FOR_64BIT
#define TIMA_CMBIN_HASH_IN_SRAM
//#define TIMA_SHARED_INFO
//#define TIMA_MST_DRV
#define SECURE_BOOT_ENABLE_PA		(0x100D1000)
#define TIMA_RUNTIME_SKIP_MSR
#define ICCC_SECURE_PARAMETERS_AREA
#define PAY_MINI_IN_SERVER_SIGNED_NONCE
#define ICCC_ADD_CPUID			// after O OS
#define CONFIG_ROT_IN_ICCC		// after O OS
#define CONFIG_PARAMEXPANSION_ICCC	// after O OS
#elif defined(CONFIG_EXYNOS7880)  /* Exynos7880 */
#define SRAM_HASH_TABLE_PA		((uint32_t) 0x02023800) /* HASH table in iRAM */ 
#define TIMA_TBOOT_CTX
#define TIMA_KERNEL_HASH_IN_SRAM
#define TIMA_FEATURE_FOR_64BIT
#define TIMA_CMBIN_HASH_IN_SRAM
//#define TIMA_SHARED_INFO
#define TIMA_MST_DRV
#define SECURE_BOOT_ENABLE_PA		(0x100D1000)
#define TIMA_RUNTIME_SKIP_MSR
#define ICCC_SECURE_PARAMETERS_AREA
#define ICCC_ADD_CPUID			// after O OS
#define CONFIG_ROT_IN_ICCC		// after O OS
#define CONFIG_PARAMEXPANSION_ICCC	// after O OS
#elif defined(CONFIG_EXYNOS8895)  /* Exynos8895 */
#define SRAM_HASH_TABLE_PA		((uint32_t) 0x02023800) /* HASH table in iRAM */ 
#define TIMA_TBOOT_CTX
#define TIMA_KERNEL_HASH_IN_SRAM
#define TIMA_FEATURE_FOR_64BIT
#define TIMA_CMBIN_HASH_IN_SRAM
#define TIMA_MST_DRV
#define TIMA_MST_MFC_CHIP
#define TUI_MULTI_RESOLUTION_SUPPORT
#define SECURE_BOOT_ENABLE_PA		(0x10001000)
#define TIMA_RUNTIME_SKIP_MSR
#define ICCC_SECURE_PARAMETERS_AREA
#define ICCC_ADD_CPUID			// after O OS
#define CONFIG_ROT_IN_ICCC		// after O OS
#define CONFIG_PARAMEXPANSION_ICCC	// after O OS
#elif defined(CONFIG_EXYNOS7885)  /* Exynos7885 */
#define SRAM_HASH_TABLE_PA		((uint32_t) 0x02023800) /* HASH table in iRAM */ 
#define TIMA_TBOOT_CTX
#define TIMA_KERNEL_HASH_IN_SRAM
#define TIMA_FEATURE_FOR_64BIT
#define TIMA_CMBIN_HASH_IN_SRAM
#define TIMA_MST_DRV
#define PAY_MINI_IN_SERVER_SIGNED_NONCE
//#define TUI_MULTI_RESOLUTION_SUPPORT
#define SECURE_BOOT_ENABLE_PA		(0x10001000)
#define TIMA_RUNTIME_SKIP_MSR
#define ICCC_SECURE_PARAMETERS_AREA
#define ICCC_ADD_CPUID			// after O OS
#define CONFIG_ROT_IN_ICCC		// after O OS
#define CONFIG_PARAMEXPANSION_ICCC	// after O OS
#elif defined(CONFIG_EXYNOS9810)  /* Exynos9810 */
#define SRAM_HASH_TABLE_PA		((uint32_t) 0x02023800) /* HASH table in iRAM */ 
#define TIMA_TBOOT_CTX
#define TIMA_KERNEL_HASH_IN_SRAM
#define TIMA_FEATURE_FOR_64BIT
#define TIMA_CMBIN_HASH_IN_SRAM
#define TIMA_MST_DRV
#define TIMA_MST_MFC_CHIP
#define TUI_MULTI_RESOLUTION_SUPPORT
#define SECURE_BOOT_ENABLE_PA		(0x10001000)
#define TIMA_RUNTIME_SKIP_MSR
#define ICCC_SECURE_PARAMETERS_AREA
#define ICCC_ADD_CPUID
#define CONFIG_ROT_IN_ICCC
#define TIMA_DRAMEL3_HASH_IN_SRAM
#define CONFIG_PARAMEXPANSION_ICCC
#endif

#if defined(CONFIG_EXYNOS5422) || defined(CONFIG_EXYNOS5430) || defined(CONFIG_EXYNOS3470) || defined(CONFIG_EXYNOS3475) || \
	defined(CONFIG_EXYNOS3472) || defined(CONFIG_EXYNOS3250) || defined(CONFIG_EXYNOS4415) || defined(CONFIG_EXYNOS5433) || \
	defined(CONFIG_EXYNOS7420) || defined(CONFIG_EXYNOS7580) || defined(CONFIG_EXYNOS5260) || defined(CONFIG_EXYNOS3250) || \
	defined(CONFIG_EXYNOS8890) || defined(CONFIG_EXYNOS7870) || defined(CONFIG_EXYNOS7570) || defined(CONFIG_EXYNOS7880) || \
	defined(CONFIG_EXYNOS5420) || defined(CONFIG_EXYNOS5410) || defined(CONFIG_EXYNOS8895) || defined(CONFIG_EXYNOS7885) || \
	defined(CONFIG_EXYNOS9810)
#define TIMA_HAVE_GOOD_MEASUREMENT
#define GOOD_MEASUREMENT_OFFSET	((uint32_t)0xFFC00)	/* The offset of HASH values at build time */
#endif

// KAP
#if defined(CONFIG_EXYNOS7580) || defined(CONFIG_EXYNOS7870) || defined(CONFIG_EXYNOS7880) || \
    defined(CONFIG_EXYNOS7885) || defined(CONFIG_EXYNOS8895) || defined(CONFIG_EXYNOS9810)
#define KAP_OFFSET	0x140
#else
#define KAP_OFFSET	0x1E0
#endif
#define KAP_SIZE	0x10
#define KAP_PA  	(SRAM_HASH_TABLE_PA + KAP_OFFSET)

#ifdef CONFIG_EXYNOS3250
#define KAP_STATUS_VA (KAP_OFFSET)
#else
#define KAP_STATUS_VA (0x51000 | KAP_OFFSET)
#endif
#define KAP_BOOT_STATUS_VA (KAP_STATUS_VA + sizeof(uint32_t))

// DM-Verity
#define DMVERITY_OFFSET				(KAP_OFFSET + KAP_SIZE)
#define DMVERITY_PA					(SRAM_HASH_TABLE_PA + DMVERITY_OFFSET)

#ifdef CONFIG_EXYNOS3250
#define DMVERITY_BOOT_MODE_VA		(DMVERITY_OFFSET)
#else
#define DMVERITY_BOOT_MODE_VA		(0x51000 | DMVERITY_OFFSET)
#endif
#define DMVERITY_SYSTEM_CHECK_VA	(DMVERITY_BOOT_MODE_VA + sizeof(uint32_t))

#if defined(PAY_MINI_IN_SERVER_SIGNED_NONCE)
#define PAY_MINI_SERVER_SIGNED_NONCE_OFFSET 0x400
#define PAY_MINI_SERVER_SIGNED_NONCE_SIZE 8
#endif

#if defined(ICCC_SECURE_PARAMETERS_AREA)
#define MAX_IMAGES 12			// BOOT, RECOVERY, SYSTEM, CACHE, HIDDEN, USERDATA, OMR, VENDOR, ODM, reserved(3)
#define RESERVED_BYTES 96
#define ROT_KEY_SIZE	32
#define BL_MAGIC_STR 0xFFFA
#define TA_MAGIC_STR 0xFFFB
#define KERN_MAGIC_STR 0xFFFC
#define SYS_MAGIC_STR 0xFFFD
#define ROT_MAGIC_STR 0xFFFE

//Structure which will be passed by bootloader
typedef struct {
	uint32_t rp_ver;					// possible values : 0,1,2..
	uint32_t kernel_rp;					// possible values : 0,1,2..0xFFFFFFFF (0,1,2 ... : kernel RP version , 0XFFFFFFFF :feature not present)
	uint32_t system_rp;					// possible values : 0,1,2..0xFFFFFFFF (0,1,2 ... : system RP version , 0XFFFFFFFF :feature not present)
	uint32_t test_bit;					// possible values : 0,1 (0: not blown , 1:blown)
	uint32_t sec_boot;					// possible values : 0,1 (0:disable , 1:enable)
	uint32_t react_lock;				// possible values : 0,1,0xFFFFFFFF(0:off , 1:on , 0xFFFFFFFF:feature not present)
	uint32_t kiwi_lock;					// possible values : 0,1,0xFFFFFFFF(0:off , 1:on , 0xFFFFFFFF:feature not present)
	uint32_t frp_lock;					// possible values : 0,1,0xFFFFFFFF(0:off , 1:on , 0xFFFFFFFF:feature not present)
	uint32_t cc_mode;					// possible values : 0,1,0xFFFFFFFF(0:off , 1:on , 0xFFFFFFFF:feature not present)
	uint32_t mdm_mode;					// possible values : 0,1,0xFFFFFFFF(0:off , 1:on , 0xFFFFFFFF:feature not present)
	uint32_t curr_bin_status;			// possible values : 0,1 (0:official , 1:custom)
	uint32_t afw_value;					// possible values : 0,1,0xFFFFFFFF (0:off , 1:on, 0xFFFFFFFF: Unknown/Uninitialized)
	uint32_t warranty_bit;				// possible values : 0,1 (0: not blown , 1:blown)
	uint32_t kap_status;				// possible values : 0,1,3,0xFFFFFFFF(0:KAP OFF , 1:KAP ON - No tamper , 3:Violation(RKP and/or DMVerity says device is tampered) , 0xFFFFFFFF:feature not present)
	uint32_t sysscope_flag;				// possible values : 0,1,2,0xFFFFFFFF (0:official , 1:custom , 2:Scanning , 0xFFFFFFFF : rooted/value is not present/uninitialized)
	uint32_t dmv_status;				// possible values : 0,1,0xFFFFFFFF(0:Success , 1:Failed , 0xFFFFFFFF:Uninitialized)
	uint8_t image_status[MAX_IMAGES];		// possible values : 8(factory vs market), 4(eng vs user), 2(knox), 1(custom vs official)
	uint32_t image_status_bl;			// possible values : 8(factory vs market), 4(eng vs user), 2(knox), 1(custom vs official)
	uint32_t WbHistory;
	uint32_t ap_serial_0;
	uint32_t ap_serial_1;
	uint32_t verified_boot_state;
	uint32_t device_locked;
	uint32_t os_version;
	uint32_t patch_month_year;
	uint8_t verified_boot_key[SHA256_DIGEST_LEN];
	uint32_t em_status;					/* possible values : 0(market), 1(dev) */
	uint32_t em_token;
	uint32_t boot_patch_level;
	uint32_t vendor_patch_level;
	uint32_t verified_boot_hash[8];
}smc_secure_info_t;

//Start of ICCC data structures
typedef struct {
	uint16_t magic_str;
	uint16_t used_size;  //check what to do with it
}secure_param_header_t;

typedef struct {
	secure_param_header_t header;
	uint32_t rp_ver;
	uint32_t kernel_rp;
	uint32_t system_rp;
	uint32_t test_bit;
	uint32_t sec_boot;
	uint32_t react_lock;
	uint32_t kiwi_lock;
	uint32_t frp_lock;
	uint32_t cc_mode;
	uint32_t mdm_mode;
	uint32_t curr_bin_status;
	uint32_t afw_value;
	uint32_t warranty_bit;
	uint32_t kap_status;
	uint32_t image_status[MAX_IMAGES];
	uint32_t image_status_bl;
	uint32_t WbHistory;
	/* PHASE 3 */
	uint32_t ap_serial_0;
	uint32_t ap_serial_1;
	uint32_t em_status;
	uint32_t em_token;
	uint8_t reserved[RESERVED_BYTES - 32 - 8 - 8];
}bl_secure_info_t;

typedef struct {
	secure_param_header_t header;
	uint32_t pkm_text;				// possible values : 0,1,0xFFFFFFFF(0:Success , 1:Failed , 0xFFFFFFFF:Uninitialized)
	uint32_t pkm_ro;				// possible values : 0,1,0xFFFFFFFF(0:Success , 1:Failed , 0xFFFFFFFF:Uninitialized)
	uint32_t selinux_status;		// possible values : 0,1,0xFFFFFFFF(0:Enforcing , 1:Perimissive , 0xFFFFFFFF:Uninitialized)
	uint32_t sectimer_base;
	uint32_t sectimer_flag;
	uint32_t sectimer_status;
	uint32_t hdm_status;
	uint32_t atn_blob_hash[8];
	uint8_t reserved[RESERVED_BYTES - 48];
}ta_secure_info_t;

typedef struct {
	secure_param_header_t header;
	uint32_t dmv_status;			// possible values : 0,1,0xFFFFFFFF(0:Success , 1:Failed , 0xFFFFFFFF:Uninitialized)
	uint32_t verified_boot_hash[8];
	uint8_t reserved[RESERVED_BYTES - 32];
} kern_secure_info_t;

typedef struct {
	secure_param_header_t header;
	uint32_t sysscope_flag;			// possible values : 0,1,2,0xFFFFFFFF (0:official , 1:custom , 2:Scanning , 0xFFFFFFFF : rooted/value is not present/uninitialized)
	uint32_t trustboot_flag;		// possible values : 0,1,0xFFFFFFFF(0:Success , 1:Failed , 0xFFFFFFFF:Uninitialized)
	uint32_t tima_version_flag;		// possible values : 3,0xFFFFFFFF(3:TIMA version is 3.0 , 0xFFFFFFFF:Uninitialized)
	uint8_t reserved[RESERVED_BYTES - 4 ];
} sys_secure_info_t;

typedef struct {
	secure_param_header_t header;
	uint32_t verified_boot_state;
	uint32_t device_locked;
	uint32_t os_version;
	uint32_t patch_month_year;
	uint32_t verified_boot_key[8];
	uint32_t boot_patch_level;
	uint32_t vendor_patch_level;
	uint32_t reserved;
} rot_secure_info_t;

typedef struct {
	bl_secure_info_t  bl_secure_info;
	ta_secure_info_t  ta_secure_info;
	kern_secure_info_t kern_secure_info;
	sys_secure_info_t sys_secure_info;
	rot_secure_info_t rot_secure_info;
}iccc_secure_pamameters_info_t;

#define ICCC_SECURE_PARAMETERS_OFFSET 		((uint32_t)0x164)
#define ICCC_SECURE_PARAMETERS_LENGTH 		((uint32_t)sizeof(iccc_secure_pamameters_info_t))
#define ICCC_LOCK_FLAG_OFFSET				((uint32_t)(ICCC_SECURE_PARAMETERS_OFFSET + ICCC_SECURE_PARAMETERS_LENGTH))
#define ICCC_TRUSTBOOT_LOCK					((uint32_t)0x00000001)
#endif

typedef struct {
	uint8_t magic_string[16];
	uint8_t svb_magic[16];
	uint32_t vpcr1[SHA256_DIGEST_LEN / sizeof(uint32_t)];
	uint32_t vpcr2[SHA256_DIGEST_LEN / sizeof(uint32_t)];
	uint32_t vpcr3[SHA256_DIGEST_LEN / sizeof(uint32_t)];
	uint32_t vpcr4[SHA256_DIGEST_LEN / sizeof(uint32_t)];
	uint32_t vpcr5[SHA256_DIGEST_LEN / sizeof(uint32_t)];
#if defined(TIMA_CMBIN_HASH_IN_SRAM)
	uint32_t vpcr6[SHA256_DIGEST_LEN / sizeof(uint32_t)];
#endif
#if defined(TIMA_DRAMEL3_HASH_IN_SRAM)
	uint32_t vpcr7[SHA256_DIGEST_LEN / sizeof(uint32_t)];
#endif
	uint8_t warranty_string[32];
} tima_ctx_t;

#if defined(TIMA_SHARED_INFO)
typedef struct {
	uint32_t screen_res;
}tima_info;
#endif


#if defined(TIMA_TBOOT_CTX)
typedef struct {
#ifndef TIMA_KERNEL_HASH_IN_SRAM
	uint8_t kernel_hash[32];
#endif
	uint8_t magic_str[16];
	uint8_t warranty_str[32];
	uint8_t svb_magic[16];
	uint8_t vbmeta_hash[32];
} tboot_ctx;
#endif

#endif /* __FCTIMA_H__ */
