tizen 2.4 release
[profile/mobile/platform/kernel/u-boot-tm1.git] / property / efuse_operate.c
1 #include <common.h>
2
3 #define DDIE_EFUSE              (0)
4 #define ADIE_EFUSE              (1)
5 #define BLOCK_SIZE              (4)
6 #define BLOCK_CHAR_COUNT        (8)
7
8 #define UID_BLOCK_START         (0)
9 #define UID_BLOCK_END           (1)
10 #define UID_BLOCK_LEN                  (UID_BLOCK_END - UID_BLOCK_START + 1)
11
12 #define HASH_BLOCK_START             (2)
13 #define HASH_BLOCK_END                  (6)
14 #define HASH_BLOCK_LEN                  (HASH_BLOCK_END - HASH_BLOCK_START + 1)
15
16 #define SECURE_BOOT_BLOCK         (1)
17 #define SECURE_BOOT_BIT                 (18)
18 #define PROTECT__BIT                    (0X80000000)
19
20 //#define MIN(a, b)                     ((a) <= (b) ? (a) : (b))
21 #define TOLOWER(x) ((x) | 0x20)
22
23 #define isxdigit(c)    (('0' <= (c) && (c) <= '9')  || ('a' <= (c) && (c) <= 'f')  || ('A' <= (c) && (c) <= 'F'))
24 #define isdigit(c)    ('0' <= (c) && (c) <= '9')
25 //#define EFUSE_DEBUG
26 #ifdef EFUSE_DEBUG
27 #define UBOOT_EFUSE_LOG(format, arg...) printf( format, ## arg)
28 #else
29 #define UBOOT_EFUSE_LOG(format, arg...)
30 #endif
31 extern u32 efuse_read(int id,int blk_index);
32 extern int efuse_prog(int id,int blk_index,u32 val);
33 unsigned long strtoul(const char *cp,char  **endp, unsigned int base)
34 {
35         unsigned long result = 0,value;
36         if (!base) {
37                 base = 10;
38                 if (*cp == '0'){
39                         base = 8;
40                         cp++;
41                         if ((TOLOWER(*cp) == 'x') && isxdigit(cp[1])){
42                                 cp++;
43                                 base = 16;
44                         }
45                 }
46         }else if (base == 16){
47                         if (cp[0] == '0' && TOLOWER(cp[1]) == 'x')
48                                 cp += 2;
49         }
50         while (isxdigit(*cp) &&(value = isdigit(*cp) ? *cp-'0' : TOLOWER(*cp)-'a'+10) < base) {
51                         result = result*base + value;
52                         cp++;
53         }
54         if (endp)
55                 *endp = (char *)cp;
56         return result;
57 }
58 void efuse_secure_enable(void)
59 {
60         efuse_prog(DDIE_EFUSE,SECURE_BOOT_BLOCK, (1 << SECURE_BOOT_BIT));
61 }
62
63 int efuse_secure_is_enabled(void)
64 {
65         u32 ret = efuse_read(DDIE_EFUSE, SECURE_BOOT_BLOCK);
66         return (ret & (1 << SECURE_BOOT_BIT)) ? 1 : 0;
67 }
68
69 int efuse_hash_write_1( char *hash, u32 count)
70 {
71         int i = 0, j = HASH_BLOCK_START, len = 0;
72         char buf[BLOCK_CHAR_COUNT+1] = { 0 };
73         char *p = hash;
74         u32 value = 0, read_hash = 0;
75         if ((0 == p) || (count < 1))
76                 return -1;
77         UBOOT_EFUSE_LOG("%s()->Line:%d; hash string = %s, len = %d \n", __FUNCTION__, __LINE__, hash, count);
78         count = MIN(count,HASH_BLOCK_LEN*BLOCK_CHAR_COUNT);
79         for (i = 0; i < count; i += BLOCK_CHAR_COUNT) {
80                 memset(buf, 0, sizeof(buf));
81                 strncpy((char*)buf, (char*)&p[i], BLOCK_CHAR_COUNT);
82                 buf[BLOCK_CHAR_COUNT]='\0';
83                 value = (u32)(strtoul(buf, 0, 16));
84                 value &= 0x7fffffff;
85                 UBOOT_EFUSE_LOG("%s()->Line :%d value=%8x\n",__FUNCTION__, __LINE__,value);
86                 efuse_prog(DDIE_EFUSE, j, value);
87                 read_hash = efuse_read(DDIE_EFUSE, j);
88                 UBOOT_EFUSE_LOG("%s()->Line :%d read_hash=%8x\n",__FUNCTION__, __LINE__,read_hash);
89                 if(read_hash != value){
90                         UBOOT_EFUSE_LOG("%s()->Line:%d READ HASH != WRITE HASH\n", __FUNCTION__, __LINE__);
91                         return -2;
92                 }
93                 value  |= PROTECT__BIT;
94                 efuse_prog(DDIE_EFUSE, j,  PROTECT__BIT );
95                 read_hash = efuse_read(DDIE_EFUSE, j);
96                 if(read_hash != value){
97                         UBOOT_EFUSE_LOG("%s()->Line:%d READ HASH !=  value\n", __FUNCTION__, __LINE__);
98                         return -2;
99                 }
100                 len += BLOCK_CHAR_COUNT ;
101                 j++;
102         }
103         return len;
104 }
105
106 int efuse_hash_read_1(char *hash, u32 count)
107 {
108         char values[HASH_BLOCK_LEN*BLOCK_CHAR_COUNT+1] = { 0 };
109         char tmp_hash[BLOCK_CHAR_COUNT + 1] = {0};
110         u32 i = 0, len = 0,read_hash=0;
111         char *p=  ( char*)&read_hash;
112         UBOOT_EFUSE_LOG("%s()->Line:%d; count = %d \n", __FUNCTION__, __LINE__, count);
113
114         if ((0 == hash) || (count < 1))
115                 return -1;
116
117         len = MIN(count, HASH_BLOCK_LEN*BLOCK_CHAR_COUNT);
118         for (i = HASH_BLOCK_START; i <= HASH_BLOCK_END; i++) {
119                 read_hash = efuse_read(DDIE_EFUSE , i );
120                 sprintf(tmp_hash,"%02x%02x%02x%02x",p[3],p[2],p[1],p[0]);
121                 tmp_hash[BLOCK_CHAR_COUNT] = '\0';
122                 UBOOT_EFUSE_LOG("%s()->Line:%d; block_id=%d,tmp_hash=%s\n", __FUNCTION__, __LINE__,i, tmp_hash);
123                 strncpy(&values[(i - HASH_BLOCK_START) * BLOCK_CHAR_COUNT], tmp_hash, BLOCK_CHAR_COUNT);
124         }
125         values[HASH_BLOCK_LEN*BLOCK_CHAR_COUNT] = '\0';
126         UBOOT_EFUSE_LOG("values=%s\n",values);
127         strncpy( hash, values, len);
128         UBOOT_EFUSE_LOG("%s()->Line:%d; hash = %s, len = %d \n", __FUNCTION__, __LINE__, hash, len-1);
129
130         return len;
131 }
132
133 int efuse_uid_read(char *uid, int count)
134 {
135         char values[UID_BLOCK_LEN*BLOCK_CHAR_COUNT+1] = { 0 };
136         char tmp_uid[BLOCK_CHAR_COUNT + 1] = {0};
137         u32 i = 0, len = 0,read_uid=0;
138         char *p=  ( char*)&read_uid;
139         UBOOT_EFUSE_LOG("%s()->Line:%d; count = %d \n", __FUNCTION__, __LINE__, count);
140
141         if ((0 == uid) || (count < 1))
142                 return -1;
143
144         len = MIN(count, UID_BLOCK_LEN*BLOCK_CHAR_COUNT);
145         for (i = UID_BLOCK_START; i <= UID_BLOCK_END; i++) {
146                 read_uid = efuse_read(DDIE_EFUSE , i );
147                 sprintf(tmp_uid,"%02x%02x%02x%02x",p[3],p[2],p[1],p[0]);
148                 tmp_uid[BLOCK_CHAR_COUNT] = '\0';
149                 UBOOT_EFUSE_LOG("%s()->Line:%d; block_id=%d,tmp_uid=%s\n", __FUNCTION__, __LINE__,i, tmp_uid);
150                 strncpy(&values[(i - UID_BLOCK_START) * BLOCK_CHAR_COUNT], tmp_uid, BLOCK_CHAR_COUNT);
151         }
152         values[UID_BLOCK_LEN*BLOCK_CHAR_COUNT] = '\0';
153         UBOOT_EFUSE_LOG("values=%s\n",values);
154         strncpy( uid, values, len);
155         UBOOT_EFUSE_LOG("%s()->Line:%d; uid = %s, len = %d \n", __FUNCTION__, __LINE__, uid, len-1);
156
157         return len;
158 }
159
160