1 /******************************************************************************
\r
2 ** File Name: module_test.c *
\r
4 ** DATE: 15/01/2010 *
\r
5 ** Copyright: 2003 Spreatrum, Incoporated. All Rights Reserved. *
\r
6 ** Description: define trace interface just for testing usage *
\r
7 ******************************************************************************
\r
9 ******************************************************************************
\r
11 ** ------------------------------------------------------------------------- *
\r
12 ** DATE NAME DESCRIPTION *
\r
13 ** 15/01/2010 Yong.Li Create *
\r
14 ******************************************************************************/
\r
15 #include "asm/arch/sprd_reg.h"
\r
16 #include "asm/arch/efuse_drv.h"
\r
17 #include "asm/arch/chip_drv_common_io.h"
\r
19 #define EFUSE_MAX_BLOCK (8)
\r
20 #define GR_SOFT_REST (0x4b00004c)
\r
21 #define EFUSE_REG_BASE (SPRD_UIDEFUSE_PHYS)
\r
22 #define EFUSE_EB BIT_7
\r
23 #define EFUSE_SOFT_RST BIT_28
\r
25 #define EFUSE_DATA_RD (EFUSE_REG_BASE + 0x0000)
\r
26 #define EFUSE_DATA_WR (EFUSE_REG_BASE + 0x0004)
\r
28 #define EFUSE_BLOCK_INDEX (EFUSE_REG_BASE + 0x0008)
\r
29 #define EFUSE_MODE_CTRL (EFUSE_REG_BASE + 0x000c)
\r
30 #define EFUSE_PGM_PARA (EFUSE_REG_BASE + 0x0010)
\r
31 #define EFUSE_STATUS (EFUSE_REG_BASE + 0x0014)
\r
32 #define EUSE_MEM_BLOCK_FLAGS (EFUSE_REG_BASE + 0x0018)
\r
33 #define EUSE_MEM_BLOCK_FLAGS_CLR (EFUSE_REG_BASE + 0x001c)
\r
34 #define EFUSE_MAGIC_NUMBER (EFUSE_REG_BASE + 0x0020)
\r
36 #define EFuse_LOCK_BIT BIT_31
\r
37 //efuse mode ctrl register bit define
\r
38 #define EFUSE_PG_START BIT_0
\r
39 #define EFUSE_RD_START BIT_1
\r
40 #define EFUSE_BIST_START BIT_31
\r
42 //efuse block index bit define
\r
43 #define READ_INDEX_OFFSET (0)
\r
44 #define PGM_INDEX_OFFSET (16)
\r
45 #define BIST_START_INDEX_OFFSET (26)
\r
46 #define BIST_END_INDEX_OFFSET (29)
\r
48 //PGM_PARA register bit define
\r
49 #define EFUSE_AUTO_TEST_EN BIT_16
\r
50 #define CLK_EFS_EN BIT_28
\r
51 #define EFS_VDD_ON BIT_29
\r
52 #define PGM_EN BIT_31
\r
54 //efuse status register bit define
\r
55 #define EFUSE_PRG_BUSY BIT_0
\r
56 #define EFUSE_READ_BUSY BIT_1
\r
57 #define EFUSE_BIST_FAIL BIT_4
\r
58 #define EFUSE_BIST_BUSY BIT_5
\r
60 //Mem_block_flags register bit define
\r
61 #define EFUSE_BLOCK_ERR_FLAG BIT_8
\r
62 #define WDG_EB_BIT (1 << 2)
\r
63 #define RTC_WDG_EB_BIT (1 << 10)
\r
66 #define EFUSE_READ_TIMEOUT 5 //ms
\r
67 #define EFUSE_WRITE_TIMEOUT 5 //ms
\r
69 PUBLIC EFuse_RETURN_E IsEfuseLock(int block_id)
\r
73 ret = EFuseRead(block_id, (unsigned int *)&read_data);
\r
74 //if read fail return
\r
75 if(ret != EFuse_RESULT_SUCCESS)
\r
77 return EFuse_READ_FAIL;
\r
79 // if the lock bit is set return locked else return not locked
\r
80 if((read_data & (EFuse_LOCK_BIT)) == EFuse_LOCK_BIT)
\r
82 return EFuse_LOCKED;
\r
86 return EFuse_NOT_LOCK;
\r
90 PUBLIC EFuse_RETURN_E EFuseWrite(
\r
91 unsigned int block_id, // the selected EFuse block id
\r
92 unsigned int data // the data to be writen into the EFuse block
\r
95 uint32 old_tick = 0;
\r
96 uint32 new_tick = 0;
\r
97 uint32 sts = 0; //states of efuse
\r
98 unsigned int read_data;
\r
101 EFuse_RETURN_E result = EFuse_RESULT_SUCCESS; // return value
\r
103 if(((int32)block_id < EFuse_MIN_ID) || ((int32)block_id > EFuse_MAX_ID))
\r
105 return EFuse_ID_ERROR;
\r
108 /* if the block has locked return now */
\r
109 if(IsEfuseLock(block_id) == EFuse_LOCKED)
\r
111 return EFuse_LOCKED;
\r
114 REG32(EFUSE_MAGIC_NUMBER) = 0x8810;// Enable program
\r
115 REG32(EFUSE_BLOCK_INDEX) = (block_id << READ_INDEX_OFFSET) | (block_id << PGM_INDEX_OFFSET);
\r
116 REG32(EFUSE_DATA_WR) = data & (~(EFuse_LOCK_BIT));
\r
117 REG32(EFUSE_PGM_PARA) |= (EFUSE_AUTO_TEST_EN << block_id);
\r
118 REG32(EFUSE_MODE_CTRL) |= EFUSE_PG_START;
\r
120 sts = (*(volatile uint32 *)EFUSE_STATUS) & EFUSE_PRG_BUSY;
\r
121 old_tick = SCI_GetTickCount();
\r
123 while((EFUSE_PRG_BUSY == sts))
\r
125 sts = (*(volatile uint32 *)EFUSE_STATUS) & EFUSE_PRG_BUSY;
\r
126 new_tick = SCI_GetTickCount();
\r
127 if((new_tick - old_tick) > EFUSE_WRITE_TIMEOUT)
\r
131 if(sts == EFUSE_PRG_BUSY)
\r
133 *(volatile uint32 *)EFUSE_MAGIC_NUMBER = 0; // disable program
\r
134 return EFuse_WRITE_FAIL;
\r
138 // get the hardware compare result
\r
139 sts = (*(volatile uint32 *)EUSE_MEM_BLOCK_FLAGS) & (EFUSE_BLOCK_ERR_FLAG << block_id);
\r
141 /* read data and compare */
\r
142 result = EFuseRead(block_id, &read_data);
\r
143 if(EFuse_RESULT_SUCCESS != result)
\r
145 ret = EFuse_WRITE_VERIFY_FAIL;
\r
149 //compare write and read data
\r
150 if((data & (((unsigned int)~EFuse_LOCK_BIT))) == (read_data & ((unsigned int)(~EFuse_LOCK_BIT))))
\r
153 ret = EFuse_WRITE_HARD_COMPARE_FAIL;
\r
155 ret = EFuse_RESULT_SUCCESS;
\r
160 ret = EFuse_WRITE_SOFT_HARD_COMPARE_FAIL;
\r
162 ret = EFuse_WRITE_SOFT_COMPARE_FAIL;
\r
166 REG32(EFUSE_MAGIC_NUMBER) = 0;// disable program
\r
170 PUBLIC EFuse_RETURN_E EFuseLock(
\r
171 unsigned int block_id // the selected EFuse block id
\r
174 unsigned int read_data;
\r
175 EFuse_RETURN_E ret;
\r
176 ret = EFuseRead(block_id, &read_data);
\r
177 if(ret != EFuse_RESULT_SUCCESS)
\r
180 if((read_data & ((unsigned int)EFuse_LOCK_BIT)) == ((unsigned int)EFuse_LOCK_BIT))
\r
181 return EFuse_RESULT_SUCCESS;
\r
183 read_data |= (unsigned int)EFuse_LOCK_BIT;
\r
184 return EFuseWrite(block_id, read_data);
\r
187 PUBLIC void EFuseInitilize(void)
\r
190 REG32(REG_AON_APB_APB_EB0) |= BIT_13; // enable efuse clock
\r
193 REG32(REG_AON_APB_APB_RST0) |= BIT_14; // enable efuse clock
\r
194 for(i = 0; i < 100; i++);
\r
195 REG32(REG_AON_APB_APB_RST0) &= ~BIT_14; // enable efuse clock
\r
196 /* power on effuse */
\r
197 REG32(EFUSE_PGM_PARA) |= EFS_VDD_ON;
\r
200 REG32(REG_AON_APB_PWR_CTRL) |= BIT_3;
\r
203 *(volatile uint32 *)EFUSE_PGM_PARA |= CLK_EFS_EN; // open efuse clk
\r
204 *(volatile uint32 *)EFUSE_PGM_PARA |= PGM_EN; // Enable program
\r
205 *(volatile uint32 *)EFUSE_MAGIC_NUMBER = 0x8810; // Enable program
\r
209 PUBLIC EFuse_RETURN_E EFuseRead(
\r
210 unsigned int block_id, // the selected efuse block id
\r
211 unsigned int *r_data_ptr // pointer of block data read from EFuse block
\r
214 uint32 old_tick = 0;
\r
215 uint32 new_tick = 0;
\r
216 uint32 sts = 0; //states of efuse
\r
217 EFuse_RETURN_E result = EFuse_RESULT_SUCCESS; // return value
\r
219 /* check the block_id */
\r
220 if(((int32)block_id < EFuse_MIN_ID) || ((int32)block_id > EFuse_MAX_ID))
\r
221 return EFuse_ID_ERROR;
\r
223 /* read index must be the same of the write index */
\r
224 *(volatile uint32 *)EFUSE_BLOCK_INDEX = (block_id << READ_INDEX_OFFSET) | (block_id << PGM_INDEX_OFFSET);
\r
225 *(volatile uint32 *)EFUSE_MODE_CTRL |= EFUSE_RD_START; // send read commmand
\r
226 sts = (*(volatile uint32 *)EFUSE_STATUS) & EFUSE_READ_BUSY;
\r
228 old_tick = SCI_GetTickCount();
\r
229 while((EFUSE_READ_BUSY == sts))
\r
231 sts = (*(volatile uint32 *)EFUSE_STATUS) & EFUSE_READ_BUSY;
\r
232 new_tick = SCI_GetTickCount();
\r
233 if((new_tick - old_tick) > EFUSE_READ_TIMEOUT)
\r
236 if(sts == EFUSE_READ_BUSY)
\r
237 result = EFuse_READ_FAIL;
\r
239 *r_data_ptr = *(volatile uint32 *)(EFUSE_DATA_RD);
\r
243 LOCAL void EFuseClose(void)
\r
245 REG32(EFUSE_PGM_PARA) &= ~CLK_EFS_EN; // close efuse clk
\r
246 REG32(EFUSE_PGM_PARA) &= ~PGM_EN; // disable program
\r
247 REG32(REG_AON_APB_PWR_CTRL) &= ~BIT_3;
\r
248 /* shut down the efuse power */
\r
249 REG32(EFUSE_PGM_PARA) &= ~EFS_VDD_ON;
\r
250 REG32(REG_AON_APB_APB_EB0) &= ~BIT_13; // enable efuse clock
\r
251 *(volatile uint32 *)EFUSE_MAGIC_NUMBER = 0; // Enable program
\r
254 typedef struct SHA1Context32
\r
256 unsigned int Intermediate_Hash[5]; /* Message Digest */
\r
257 unsigned int Length_Low; /* Message length in bits */
\r
258 unsigned int Length_High; /* Message length in bits */
\r
259 /* Index into message block array */
\r
260 unsigned int Message_Block_Index;
\r
261 unsigned int W[80]; /* 512-bit message blocks */
\r
264 struct ROM_CALLBACK_TABLE {
\r
265 unsigned int version; //version number
\r
266 #define SHA1_SUPPORT BIT_0
\r
267 #define MD5_SUPPORT BIT_1
\r
268 #define RSA_256_SUPPORT BIT_2
\r
269 #define RSA_512_SUPPORT BIT_3
\r
270 #define RSA_1024_SUPPORT BIT_4
\r
271 #define RSA_2048_SUPPORT BIT_5
\r
272 unsigned int cap;//capability
\r
273 void (*Efuse_Init) (void);
\r
274 void (*Efuse_Close) (void);
\r
275 int (*Efuse_Read) (unsigned int block_id, unsigned int* r_data_ptr);
\r
276 int (*SHA1Reset_32) (SHA1Context_32 *);
\r
277 int (*SHA1Input_32) (SHA1Context_32 *,const unsigned int *message, unsigned int len);
\r
278 int (*SHA1Result_32)(SHA1Context_32 *context,unsigned char * Message_Digest);
\r
279 void (*RSA_ModPower) (unsigned int *p, unsigned int *m, unsigned int *r2, unsigned int e);
\r
284 uint32 mVersion; // 1
\r
285 uint32 mMagicNum; // 0xaa55a5a5
\r
286 uint32 mCheckSum;//check sum value for bootloader header
\r
287 uint32 mHashLen;//word length
\r
288 uint32 mSectorSize; // sector size 1-1024
\r
289 uint32 mAcyCle; // 0, 1, 2
\r
290 uint32 mBusWidth; // 0--8 bit, 1--16bit
\r
291 uint32 mSpareSize; // spare part size for one sector
\r
292 uint32 mEccMode; // 0--1bit, 1-- 2bit, 2--4bit, 3--8bit, 4--12bit, 5--16bit, 6--24bit
\r
293 uint32 mEccPostion; // ECC postion at spare part
\r
294 uint32 mSectPerPage; // sector per page
\r
297 uint32 mECCValue[27];
\r
302 uint32 mVersion; // 1
\r
303 uint32 mMagicNum; // 0xaa55a5a5
\r
304 uint32 mCheckSum;//check sum value for bootloader header
\r
305 uint32 mHashLen;//word length
\r
308 PUBLIC void EfuseHashWrite(uint8 *bsc_code, uint32 hash_len)
\r
310 uint32 block_index, ret, softHashValue[8], readHashValue[8];
\r
311 NBLHeader* eblheader = (NBLHeader *)(bsc_code+ 0x20);
\r
312 SHA1Context_32 sha;
\r
313 struct ROM_CALLBACK_TABLE *rom_callback;
\r
315 printf("EfuseHashWrite\r\n");
\r
317 rom_callback = (struct ROM_CALLBACK_TABLE*)(*((unsigned int *)0xFFFF0020));
\r
319 memset(eblheader, 0, sizeof(NBLHeader));
\r
320 memset(softHashValue, 0, sizeof(softHashValue));
\r
321 memset(readHashValue, 0, sizeof(readHashValue));
\r
323 eblheader->mHashLen = hash_len>>2;
\r
324 rom_callback->SHA1Reset_32 (&sha);
\r
325 rom_callback->SHA1Input_32 (&sha, (unsigned int*)bsc_code, hash_len>>2);
\r
326 rom_callback->SHA1Result_32(&sha, (unsigned char*)(&softHashValue[2]));
\r
335 //softHashValue[1] = BIT_18;
\r
336 for(block_index = 2; block_index < 7; block_index++)
\r
338 ret = EFuseWrite(block_index, softHashValue[block_index]);
\r
339 printf("block : %d", block_index);
\r
342 case EFuse_ID_ERROR:
\r
343 printf("EFuse_ID_ERROR\r\n");
\r
346 printf("EFuse_LOCKED\r\n");
\r
348 case EFuse_WRITE_FAIL:
\r
349 printf("EFuse_WRITE_FAIL\r\n");
\r
351 case EFuse_WRITE_VERIFY_FAIL:
\r
352 printf("EFuse_WRITE_VERIFY_FAIL\r\n");
\r
354 case EFuse_WRITE_HARD_COMPARE_FAIL:
\r
355 printf("EFuse_WRITE_SOFT_HARD_COMPARE_FAIL\r\n");
\r
357 case EFuse_RESULT_SUCCESS:
\r
358 printf("EFuse_RESULT_SUCCESS\r\n");
\r
360 case EFuse_WRITE_SOFT_COMPARE_FAIL:
\r
361 printf("EFuse_WRITE_SOFT_COMPARE_FAIL\r\n");
\r
364 printf("UNKOWN Error.\r\n");
\r
367 if (ret != EFuse_RESULT_SUCCESS)
\r
375 for(block_index = 0; block_index < 8; block_index++)
\r
377 ret = EFuseRead(block_index, &readHashValue[block_index]);
\r
379 printf("[%d] write: %08x, read: %08x\r\n", block_index, softHashValue[block_index], readHashValue[block_index]);
\r
383 for(block_index = 0; block_index < 8; block_index++)
\r
385 ret = EFuseRead(block_index, &readHashValue[block_index]);
\r
387 printf("[%d] write: %08x, read: %08x\r\n", block_index, softHashValue[block_index], readHashValue[block_index]);
\r
390 for (block_index=0; block_index<8; block_index++)
\r
392 ret = EFuseWrite(block_index, 0);
\r