#include <common.h>
#include <asm/io.h>
#include <asm/cache.h>
#include "secure_firmware.dat"
#include "../arch/arm/cpu/aml_meson/m6/firmware/secure/config.h"
/*#ifdef CONFIG_AUTH_RSA_IN_SPINOR
#include <spi_flash.h>
#define CONFIG_SECURE_SPI_BUS  0
#define CONFIG_SECURE_SPI_CS 	0
#define CONFIG_SECURE_SPI_MAX_HZ 1000000
#define CONFIG_SECURE_SPI_MODE SPI_MODE_3 
#define CONFIG_SECURE_SPI_SECTOR_SIZE 0x1000
#define CONFIG_SECURE_RSA_OFFSET 0xF0000
#endif*/

#ifdef CONFIG_AUTH_RSA_IN_SRAM
#define AUTH_RSA_N_OFFSET		(0x7e60+0x100)
#define AUTH_RSA_E_OFFSET		(0x7e60+0x100+128)	
#endif

#define RAM_START 0xd9000000
#define SECU_RSA_N_OFFSET		(0x7e60)
#define SECU_RSA_E_OFFSET		(0x7e60+128)
#define CONFIG_SECURE_RSA_SIZE  0x100

//#define SECURE_DEBUG 1


void init_secure_firmware(void)
{
	int i;	
	unsigned *paddr;
	unsigned size;
	
	//1. load source code to memory
	paddr = (unsigned*)0x9FE00000;
	size = sizeof(secure_firmware_code)/sizeof(unsigned);	
	
	for(i = 0; i < size; i++){
		*paddr = secure_firmware_code[i];
		paddr++;
	}
	
	dcache_flush();
	icache_invalid();		
	printf("load rsa firmware done. \n");		

	// xxx set debug information
#ifdef SECURE_DEBUG
//	unsigned char szTxtN[] = {0xB9,0x14,0xF5,0x2B,0x27,0x16,0x97,0x8A,0x19,0x54,0x8C,0x38,0xB9,0xA5,0xA9,0xA1,0x6C,0x8A,0x3A,0x2A,0x8D,0x1D,0x10,0x44,0x8B,0x53,0x8A,0xA4,0xE4,0x49,0x82,0xA1,0xD5,0x1D,0x3B,0x0A,0x2B,0xA0,0x48,0x0A,0x9D,0xBA,0xF7,0x79,0xC9,0xF2,0x17,0xE2,0x6B,0x32,0x8F,0xC9,0xED,0x13,0xA8,0x38,0xD1,0x27,0x2A,0xBD,0xE1,0xE8,0x8C,0xAF,0x0A,0x15,0x58,0xF7,0xF5,0x8D,0xAA,0x85,0xBB,0xEB,0x51,0x74,0x66,0x8C,0x00,0xB4,0x1E,0x97,0x14,0xD6,0x1B,0x3A,0x3E,0x54,0xED,0x8C,0x82,0xDA,0x3E,0x06,0x68,0xFB,0x51,0x0C,0x72,0xF6,0xE3,0x0F,0x09,0xF2,0xB3,0xFF,0xD7,0xF2,0xF5,0x5D,0x06,0x58,0xFC,0x9D,0xB3,0x53,0x5F,0x45,0x2F,0x22,0x17,0x1E,0x4A,0x4F,0x0A,0xBF,0x04,0x73};
	unsigned char szTxtN[] = {0x91,0xf8,0x17,0x89,0x8e,0x33,0x0d,0x9b,0x18,0xa2,0x23,0x6b,0x55,0xd5,0xa8,0xa4,0x4c,0xef,0x78,0x18,0xff,0x94,0x3a,0xde,0xab,0x1f,0x08,0x00,0x34,0x0b,0xed,0xb5,0x66,0x25,0xc3,0x72,0x52,0x4f,0x63,0x37,0x14,0x53,0x04,0xcd,0x94,0xd3,0xe9,0x77,0x29,0xbb,0xfb,0x29,0xef,0xf4,0x8f,0x4d,0x71,0xb7,0xe0,0x11,0xce,0x3b,0x96,0x02,0xa3,0x7f,0x37,0x55,0xf7,0xef,0xad,0xd4,0xcf,0xe0,0x28,0x76,0x66,0x76,0x86,0x3b,0xc1,0xaa,0xbe,0x59,0xd1,0x26,0x21,0xd7,0x00,0xcf,0xbc,0x28,0xbc,0xb2,0xd4,0x74,0xbb,0xa5,0x61,0x9b,0x34,0x34,0xa3,0x37,0x25,0xbf,0x9d,0xca,0x73,0x52,0x3a,0x4d,0x99,0xfa,0xa7,0x23,0x4d,0xe5,0xe8,0x72,0xb6,0x38,0xe5,0xd2,0xe9,0xcd,0xa1,0xac};
	unsigned char szTxtE[] = {0x01,0x00,0x01};
	unsigned char szTxtD[] = {0xCF,0x8D,0xF9,0xC9,0x57,0x53,0x4D,0xD7,0x36,0xFD,0x27,0x3E,0xA9,0x3A,0x76,0xE8,0xC1,0x50,0x7F,0x95,0x65,0xF8,0x99,0x14,0xD7,0x6C,0x3F,0x1A,0x9D,0x50,0xD3,0x95,0x7C,0xC8,0xFE,0xE3,0x04,0x85,0xF9,0x5A,0xCF,0x48,0x42,0x15,0x83,0x0E,0xE2,0xB6,0xC6,0xC8,0x4F,0xB8,0xA3,0x9B,0xF2,0xAB,0x95,0x20,0xE0,0x0D,0x10,0x16,0x6D,0xFB,0x95,0x38,0x15,0x24,0x82,0x15,0xEC,0x4F,0xF1,0xCF,0xFA,0x76,0x83,0x74,0x8F,0x0B,0xA4,0x79,0x45,0xEB,0x61,0xA8,0xD5,0x26,0x60,0x3D,0x6C,0x8D,0x46,0x9A,0xDE,0xFB,0x5C,0x26,0x77,0x5F,0x2A,0xCD,0x97,0xD6,0x13,0x90,0x72,0xAF,0x4E,0x6F,0x54,0x63,0xFE,0xCB,0xF6,0x69,0x97,0xB1,0x5C,0xA3,0xD6,0x7A,0xDA,0xDF,0x74,0xC9,0x35,0x4F};
	unsigned char *pdest = RAM_START+SECU_RSA_N_OFFSET;
	
	//unsigned char szTxtN_comm[] = {0x81, 0xB4, 0xCF, 0x76, 0x12, 0x30, 0x6A, 0x09, 0xA1, 0x7A, 0x97, 0x1D, 0x0B, 0x2D, 0x9A, 0x7C,0x72, 0x0E, 0x11, 0x31, 0xB0, 0xB9, 0x25, 0x21, 0xD6, 0x2C, 0xBB, 0xEB, 0xA7, 0x09, 0xED, 0xD4, 0x22, 0x29, 0xEA, 0xF9, 0xE6, 0x9E, 0x4E, 0x3D, 0x09, 0x5B, 0x9E, 0xC7, 0x5C, 0xFF, 0xD8, 0xD4, 0x98, 0x14, 0x89, 0xCC, 0xDC, 0xB3, 0x2D, 0x3E, 0xD8, 0x4A, 0xE5, 0x36, 0x69, 0xC5, 0xE2, 0xDE, 0xA2, 0xAB, 0x0D, 0x59, 0x67, 0xF6, 0x4B, 0x2B, 0xC1, 0xA8, 0xDF, 0xAA, 0xE2, 0xD3, 0xDB, 0xFE, 0xAA, 0x58, 0x18, 0x68, 0x5A, 0xFF, 0x67, 0x02, 0xF2, 0x37, 0x08, 0x3E, 0x44, 0x55, 0x34, 0xDE, 0xD7, 0x63, 0xEE, 0x05, 0xA1, 0xEC, 0x7D, 0xF0, 0x35, 0x9B, 0x28, 0xC8, 0x69, 0x2A, 0x26, 0x96, 0x72, 0xE5, 0xDC, 0xCC, 0xFA, 0x5A, 0x46, 0x81, 0xD8, 0xF1, 0x4E, 0xE2, 0x06, 0xAB, 0xDF, 0xB7}; 	
	unsigned char szTxtN_comm[] = {0xfd,0xeb,0xb9,0xcb,0x15,0xfd,0xf5,0x64,0x7f,0xd1,0x6c,0xac,0x95,0x2c,0xfa,0x78,0x94,0x1f,0xb8,0x84,0x48,0xd3,0x3c,0x47,0xf2,0x1f,0x26,0xd4,0x37,0x56,0x2d,0x70,0x8a,0x9e,0xb8,0x5a,0xd5,0x98,0x33,0x56,0x82,0xff,0x60,0xaa,0xb0,0xf0,0x86,0xef,0x1a,0x02,0xf8,0x4f,0xd0,0xec,0x21,0xf6,0x32,0xe6,0x90,0x61,0x5d,0x7a,0x5a,0x2f,0xc0,0x79,0x97,0x92,0x92,0x39,0x20,0x3e,0xe1,0x64,0x19,0xcf,0xe9,0x7f,0x2d,0x7b,0x92,0x02,0xca,0x5a,0xe8,0x01,0x60,0x27,0x22,0xee,0xd5,0x3e,0x0c,0xe2,0x0c,0xd0,0x3a,0xa7,0xb9,0xe1,0x1b,0x37,0xd3,0x88,0x41,0xaf,0x9c,0x6a,0x0b,0x16,0x2e,0xd8,0x71,0x5c,0x73,0x4e,0x07,0xf6,0xdb,0xf7,0x16,0x4e,0xda,0x94,0xe4,0x04,0xbc,0xb0};
	unsigned char szTxtE_comm[] = {0x01, 0x00, 0x01};
		
	memset(pdest, 0, 256);
	memcpy(pdest, szTxtN, sizeof(szTxtN));
	pdest = RAM_START+SECU_RSA_E_OFFSET;
	memcpy(pdest, szTxtE, sizeof(szTxtE));	
	
	pdest = RAM_START+AUTH_RSA_N_OFFSET;
	memset(pdest, 0, 256);
	memcpy(pdest, szTxtN_comm, sizeof(szTxtN_comm));
	pdest = RAM_START+AUTH_RSA_E_OFFSET;
	memcpy(pdest, szTxtE_comm, sizeof(szTxtE_comm));		
#endif	
	
	//2. load RSA encrypt from SPI flash to 0x9FE00000, size 256B		
	char buf[CONFIG_SECURE_RSA_SIZE];
	int ret=-1;	
	
/*#ifdef CONFIG_AUTH_RSA_IN_SPINOR	
	struct spi_flash *secure_flash;
	secure_flash = spi_flash_probe(CONFIG_SECURE_SPI_BUS, CONFIG_SECURE_SPI_CS, 
														CONFIG_SECURE_SPI_MAX_HZ, CONFIG_SECURE_SPI_MODE);
	if(secure_flash)
		ret = spi_flash_read(secure_flash, CONFIG_SECURE_RSA_OFFSET, CONFIG_SECURE_RSA_SIZE, buf);			
	
	if(ret == 0){
		spi_flash_free(secure_flash);
		for(i=0; i<CONFIG_SECURE_RSA_SIZE; i++){
			if(buf[i] != 0xFF)
				break;
		}
		if(i == CONFIG_SECURE_RSA_SIZE)
			ret = -1;
	}				
#endif*/

#ifdef CONFIG_AUTH_RSA_IN_SRAM
	memset(buf, 0, CONFIG_SECURE_RSA_SIZE);
	memcpy(buf, (void*)(RAM_START+AUTH_RSA_N_OFFSET), CONFIG_SECURE_RSA_SIZE);
#endif	

	dcache_flush();
	icache_invalid();			

	// 3 secure domain init to store SECURE/AUTH RSA KEYS		
/*#ifdef 	CONFIG_AUTH_RSA_IN_SPINOR
	void (*entry)(char *pSRC, int nDataLen);	
	entry = (void (*)(char*, int))0x9FE00000;	
	if(ret == 0)
		entry(buf, CONFIG_SECURE_RSA_SIZE);	
	else	
		entry(NULL, 0);
#endif*/

#ifdef CONFIG_AUTH_RSA_IN_SRAM	
	void (*entry)();	
	entry = (void (*)())0x9FE00000;		
	entry();
#endif

	dcache_flush();
	printf("init rsa encrypt data done. \n");
	
	// 4. debug information output
#ifdef SECURE_DEBUG	
//#if 1
	//unsigned char *pdest;
	printf("\nEFUSE : \n");
	pdest = 0x99006000;
	for(i=0; i<32; i++){
		printf("%02X  ", *pdest);
		pdest++;
		if(i%16 == 15)
			printf("\n");
	}
	printf("\n");
	
printf("SHA SUM: \n");
	pdest= 0x99006080;
	for(i=0; i<32; i++){
		printf("%02X  ", *pdest);
		pdest++;
		if(i%16 == 15)
			printf("\n");
	}
	printf("\n");
	
	printf("RSA dectypt: \n");
	pdest=0x99005000;
	for(i=0; i<133; i++){
		printf("%02X  ", *pdest);
		pdest++;
		if(i%16 == 15)
			printf("\n");
	}
	printf("\n");	


	printf("SN show: \n");
	pdest = 0x99006100;
	for(i=0; i<24; i++){
		printf("%02X  ", *pdest);
		pdest++;
		if(i%16 == 15)
			printf("\n");
	}
	printf("\n");		

	printf("IN show: \n");
	pdest = 0x99006120;
	for(i=0; i<24; i++){
		printf("%02X  ", *pdest);
		pdest++;
		if(i%16 == 15)
			printf("\n");
	}
	printf("\n");	
		
	printf("CI show: \n");
	pdest = 0x99006140;
	for(i=0; i<4; i++){
		printf("%02X  ", *pdest);
		pdest++;
		if(i%16 == 15)
			printf("\n");
	}
	printf("\n");	
	
#endif
	
}