tizen 2.4 release
[profile/mobile/platform/kernel/u-boot-tm1.git] / nvitem / nvitem_fs.c
1 \r
2 #include "nvitem_common.h"\r
3 #include "nvitem_fs.h"\r
4 #include "nvitem_config.h"\r
5 \r
6 #define CRC_16_L_SEED                   0x80\r
7 #define CRC_16_L_POLYNOMIAL     0x8000\r
8 #define CRC_16_POLYNOMIAL               0x1021\r
9 unsigned short __crc_16_l_calc (uint8 *buf_ptr,uint32 len)\r
10 {\r
11         unsigned int i;\r
12         unsigned short crc = 0;\r
13 \r
14         while (len--!=0)        {\r
15                 for (i = CRC_16_L_SEED; i !=0 ; i = i>>1){\r
16                         if ( (crc & CRC_16_L_POLYNOMIAL) !=0){\r
17                                 crc = crc << 1 ;\r
18                                 crc = crc ^ CRC_16_POLYNOMIAL;\r
19                         }\r
20                         else    {\r
21                                 crc = crc << 1 ;\r
22                         }\r
23                         if ( (*buf_ptr & i) != 0){\r
24                                 crc = crc ^ CRC_16_POLYNOMIAL;\r
25                         }\r
26                 }\r
27                 buf_ptr++;\r
28         }\r
29         return (crc);\r
30 }\r
31 \r
32 static unsigned short calc_checksum(unsigned char *dat, unsigned long len)\r
33 {\r
34         unsigned short num = 0;\r
35         unsigned long chkSum = 0;\r
36         while(len>1){\r
37                 num = (unsigned short)(*dat);\r
38                 dat++;\r
39                 num |= (((unsigned short)(*dat))<<8);\r
40                 dat++;\r
41                 chkSum += (unsigned long)num;\r
42                 len -= 2;\r
43         }\r
44         if(len){\r
45                 chkSum += *dat;\r
46         }\r
47         chkSum = (chkSum >> 16) + (chkSum & 0xffff);\r
48         chkSum += (chkSum >> 16);\r
49         return (~chkSum);\r
50 }\r
51 \r
52 \r
53 \r
54 /*\r
55         TRUE(1): pass\r
56         FALSE(0): fail\r
57 */\r
58 BOOLEAN _chkEcc(uint8* buf, uint32 size)\r
59 {\r
60         uint16 crc,crcOri;\r
61 //      crc = __crc_16_l_calc(buf, size-2);\r
62 //      crcOri = (uint16)((((uint16)buf[size-2])<<8) | ((uint16)buf[size-1]) );\r
63 \r
64         crc = calc_checksum(buf,size-4);\r
65         crcOri = (uint16)((((uint16)buf[size-3])<<8) | ((uint16)buf[size-4]) );\r
66 \r
67         return (crc == crcOri);\r
68 }\r
69 \r
70 \r
71 void _makEcc(uint8* buf, uint32 size)\r
72 {\r
73         uint16 crc;\r
74         //crc = __crc_16_l_calc(buf, size-2);\r
75         crc = calc_checksum(buf,size-4);\r
76         buf[size-4] = (uint8)(0xFF&crc);\r
77         buf[size-3] = (uint8)(0xFF&(crc>>8));\r
78         buf[size-2] = 0;\r
79         buf[size-1] = 0;\r
80 \r
81         return;\r
82 }\r
83 \r
84 \r
85 #ifdef CONFIG_EMMC_BOOT\r
86 static block_dev_desc_t *s_block_dev = 0;\r
87 \r
88 static RAM_NV_CONFIG _ramdiskCfg[RAMNV_NUM+1] = \r
89 {\r
90         {1,     L"fixnv1",              L"fixnv2",              0x20000 },\r
91         {2,     L"runtimenv1",L"runtimenv2",0x40000     },\r
92         {0,     L"",L"",0}\r
93 };\r
94 \r
95 const RAM_NV_CONFIG*    ramDisk_Init(void)\r
96 {\r
97         s_block_dev = get_dev("mmc", 1);\r
98         return _ramdiskCfg;\r
99 }\r
100 \r
101 RAMDISK_HANDLE  ramDisk_Open(uint32 partId)\r
102 {\r
103         return (RAMDISK_HANDLE)partId;\r
104 }\r
105 \r
106 int _getIdx(RAMDISK_HANDLE handle)\r
107 {\r
108         uint32 i;\r
109         uint32 partId = (uint32)handle;\r
110 \r
111         for(i = 0; i < sizeof(_ramdiskCfg)/sizeof(RAM_NV_CONFIG); i++){\r
112                 if(0 == _ramdiskCfg[i].partId){\r
113                         return -1;\r
114                 }\r
115                 else if(partId == _ramdiskCfg[i].partId){\r
116                         return i;\r
117                 }\r
118         }\r
119         return -1;\r
120 }\r
121 \r
122 /*\r
123         1 read imagPath first, if succes return , then\r
124         2 read imageBakPath, if fail , return, then\r
125         3 fix imagePath\r
126 \r
127         note:\r
128                 first imagePath then imageBakPath\r
129 */\r
130 BOOLEAN         ramDisk_Read(RAMDISK_HANDLE handle, uint8* buf, uint32 size)\r
131 {\r
132         int idx;\r
133         disk_partition_t info;\r
134         wchar_t *firstName, *secondName;\r
135 \r
136         idx = _getIdx(handle);\r
137         if(-1 == idx){\r
138                 return 0;\r
139         }\r
140 \r
141         if(!s_block_dev){\r
142                 printf("NVITEM partId%x:image read error!\n",_ramdiskCfg[idx].partId);\r
143                 return 1;\r
144         }\r
145 // 0 get read order\r
146         if(1){\r
147                 firstName = _ramdiskCfg[idx].image_path;\r
148                 secondName = _ramdiskCfg[idx].imageBak_path;\r
149         }\r
150         else{\r
151                 secondName = _ramdiskCfg[idx].image_path;\r
152                 firstName = _ramdiskCfg[idx].imageBak_path;\r
153         }\r
154 // 1 read origin image\r
155         memset(buf, 0xFF, size);\r
156         if(!get_partition_info_by_name(s_block_dev, firstName, &info)){\r
157                 if(Emmc_Read(PARTITION_USER, info.start, (size>>9)+1, (uint8*)buf)){\r
158                         //check crc\r
159                         if(_chkEcc(buf, size)){\r
160                                 printf("NVITEM partId%x:%s read success!\n",_ramdiskCfg[idx].partId,firstName);\r
161                                 return 1;\r
162                         }\r
163                         printf("NVITEM partId%x:%s ECC error!\n",_ramdiskCfg[idx].partId,firstName);\r
164                 }\r
165         }\r
166         printf("NVITEM partId%x:%s read error!\n",_ramdiskCfg[idx].partId,firstName);\r
167 // 2 read bakup image\r
168         memset(buf, 0xFF, size);\r
169         if(get_partition_info_by_name(s_block_dev, secondName, &info)){\r
170                 printf("NVITEM partId%x:%s read error!\n",_ramdiskCfg[idx].partId,secondName);\r
171                 return 1;\r
172         }\r
173         if(!Emmc_Read(PARTITION_USER, info.start, (size>>9), (uint8*)buf))\r
174         {\r
175                 printf("NVITEM partId%x:%s read error!\n",_ramdiskCfg[idx].partId,secondName);\r
176         }\r
177         if(!_chkEcc(buf, size)){\r
178                 printf("NVITEM partId%x:%s ECC error!\n",_ramdiskCfg[idx].partId,secondName);\r
179                 return 1;\r
180         }\r
181 \r
182         if(!get_partition_info_by_name(s_block_dev, firstName, &info)){\r
183                 Emmc_Write(PARTITION_USER, info.start, (size>>9), (uint8*)buf);\r
184         }\r
185 \r
186         printf("NVITEM  partId%x:%s read success!\n",_ramdiskCfg[idx].partId,secondName);\r
187         return 1;\r
188 \r
189 }\r
190 \r
191 \r
192 /*\r
193         1 get Ecc first\r
194         2 write  imageBakPath\r
195         3 write imagePath\r
196 \r
197         note:\r
198                 first imageBakPath then imagePath\r
199 */\r
200 BOOLEAN         ramDisk_Write(RAMDISK_HANDLE handle, uint8* buf, uint32 size)\r
201 {\r
202         int idx;\r
203         BOOLEAN oriRet,bakRet;\r
204         disk_partition_t info;\r
205 \r
206         idx = _getIdx(handle);\r
207         if(-1 == idx){\r
208                 return 0;\r
209         }\r
210         if(!s_block_dev){\r
211                 printf("NVITEM partId%x:image write fail!\n",_ramdiskCfg[idx].partId);\r
212                 return 0;\r
213         }\r
214 // 1 get Ecc\r
215         _makEcc( buf, size);\r
216 // 2 write bakup image\r
217         bakRet = 0;\r
218         if(!get_partition_info_by_name(s_block_dev, _ramdiskCfg[idx].imageBak_path, &info)){\r
219                 if(Emmc_Write(PARTITION_USER, info.start, (size>>9), (uint8*)buf)){\r
220                         bakRet = 1;\r
221                 }\r
222         }\r
223         if(!bakRet){\r
224                 printf("NVITEM partId%x:bakup image write fail!\n",_ramdiskCfg[idx].partId);\r
225         }\r
226 // 3 write origin image\r
227         oriRet = 0;\r
228         if(!get_partition_info_by_name(s_block_dev, _ramdiskCfg[idx].image_path, &info)){\r
229                 if(Emmc_Write(PARTITION_USER, info.start, (size>>9), (uint8*)buf)){\r
230                         oriRet = 1;\r
231                 }\r
232         }\r
233         if(!oriRet){\r
234                 printf("NVITEM partId%x:origin image write fail!\n",_ramdiskCfg[idx].partId);\r
235         }\r
236         printf("NVITEM partId%x:image write finished %d!\n",_ramdiskCfg[idx].partId,(bakRet && oriRet));\r
237         return (bakRet && oriRet);\r
238 \r
239 }\r
240 \r
241 void            ramDisk_Close(RAMDISK_HANDLE handle)\r
242 {\r
243         return;\r
244 }\r
245 \r
246 #else\r
247 \r
248 static RAM_NV_CONFIG _ramdiskCfg[RAMNV_NUM+1] = \r
249 {\r
250         {3,     "/productinfo/productinfo.bin", "/productinfo/productinfobkup.bin",     0x4000  },
251         {1,      "/fixnv/fixnv.bin",                     "/backupfixnv/fixnv.bin",              0x20000 },\r
252         {2,     "/runtimenv/runtimenv.bin",     "/runtimenv/runtimenvbkup.bin", 0x40000 },\r
253         {0,     "",     "",                                             0               },\r
254 };\r
255 \r
256 static void _getPath(/*IN*/char *totalPath, /*OUT*/char *path)\r
257 {\r
258         char ch;\r
259         strcpy(path,totalPath);\r
260 \r
261         ch = path[strlen(path)-1];\r
262         while(ch&&('/' != ch)&&('\\' != ch))\r
263         {\r
264                 path[strlen(path)-1] = '\0';\r
265                 ch = path[strlen(path)-1];\r
266         }\r
267 }\r
268 \r
269 const RAM_NV_CONFIG*    ramDisk_Init(void)\r
270 {\r
271         return _ramdiskCfg;\r
272 }\r
273 \r
274 RAMDISK_HANDLE  ramDisk_Open(uint32 partId)\r
275 {\r
276         return (RAMDISK_HANDLE)partId;\r
277 }\r
278 \r
279 int _getIdx(RAMDISK_HANDLE handle)\r
280 {\r
281         uint32 i;\r
282         uint32 partId = (uint32)handle;\r
283 \r
284         for(i = 0; i < sizeof(_ramdiskCfg)/sizeof(RAM_NV_CONFIG); i++){\r
285                 if(0 == _ramdiskCfg[i].partId){\r
286                         return -1;\r
287                 }\r
288                 else if(partId == _ramdiskCfg[i].partId){\r
289                         return i;\r
290                 }\r
291         }\r
292         return -1;\r
293 }\r
294 \r
295 /*\r
296         1 read imagPath first, if succes return , then\r
297         2 read imageBakPath, if fail , return, then\r
298         3 fix imagePath\r
299 \r
300         note:\r
301                 first imagePath then imageBakPath\r
302 */\r
303 BOOLEAN         ramDisk_Read(RAMDISK_HANDLE handle, uint8* buf, uint32 size)\r
304 {\r
305         int idx;\r
306         char path[100];\r
307         char *firstName, *secondName;\r
308 \r
309         idx = _getIdx(handle);\r
310         if(-1 == idx){\r
311                 return 0;\r
312         }\r
313 // 0 get read order\r
314         if(1){\r
315                 firstName = _ramdiskCfg[idx].image_path;\r
316                 secondName = _ramdiskCfg[idx].imageBak_path;\r
317         }\r
318         else{\r
319                 secondName = _ramdiskCfg[idx].image_path;\r
320                 firstName = _ramdiskCfg[idx].imageBak_path;\r
321         }\r
322 // 1 read origin image\r
323         memset(buf, 0xFF, size);\r
324         _getPath(firstName,path);\r
325         cmd_yaffs_mount(path);\r
326         cmd_yaffs_mread_file(firstName, buf);\r
327 //      cmd_yaffs_umount(path);\r
328 \r
329         //check crc\r
330         if(_chkEcc(buf, size)){\r
331                 printf("NVITEM partId%x:%s read success!\n",_ramdiskCfg[idx].partId,firstName);\r
332                 return 1;\r
333         }\r
334         printf("NVITEM partId%x:%s ECC error......!\n",_ramdiskCfg[idx].partId,firstName);\r
335 // 2 read bakup image\r
336         memset(buf, 0xFF, size);\r
337         _getPath(secondName,path);\r
338         printf("secondName : %s path: %s\n",secondName,path);
339 //      cmd_yaffs_mount(path);\r
340         cmd_yaffs_mread_file(secondName, buf);\r
341 //      cmd_yaffs_umount(path);\r
342 \r
343         if(!_chkEcc(buf, size)){\r
344                 printf("NVITEM partId%x:%s ECC error!\n",_ramdiskCfg[idx].partId,secondName);\r
345                 return 1;\r
346         }\r
347 \r
348         _getPath(firstName,path);\r
349         cmd_yaffs_mount(path);\r
350         cmd_yaffs_mwrite_file(firstName, (char*)buf, _ramdiskCfg[idx].image_size);\r
351         cmd_yaffs_umount(path);\r
352 \r
353         printf("NVITEM  partId%x:%s read success!\n",_ramdiskCfg[idx].partId,secondName);\r
354         return 1;\r
355 \r
356 }\r
357 \r
358 \r
359 /*\r
360         1 get Ecc first\r
361         2 write  imageBakPath\r
362         3 write imagePath\r
363 \r
364         note:\r
365                 first imageBakPath then imagePath\r
366 */\r
367 BOOLEAN         ramDisk_Write(RAMDISK_HANDLE handle, uint8* buf, uint32 size)\r
368 {\r
369         int idx;\r
370         char path[100];\r
371 \r
372         idx = _getIdx(handle);\r
373         if(-1 == idx){\r
374                 return 0;\r
375         }\r
376 // 1 get Ecc\r
377         _makEcc( buf, size);\r
378 // 2 write bakup image\r
379         _getPath(_ramdiskCfg[idx].imageBak_path,path);\r
380         cmd_yaffs_mount(path);\r
381         cmd_yaffs_mwrite_file(_ramdiskCfg[idx].imageBak_path, (char*)buf, _ramdiskCfg[idx].image_size);\r
382         cmd_yaffs_umount(path);\r
383 // 3 write origin image\r
384         _getPath(_ramdiskCfg[idx].image_path,path);\r
385         cmd_yaffs_mount(path);\r
386         cmd_yaffs_mwrite_file(_ramdiskCfg[idx].image_path, (char*)buf, _ramdiskCfg[idx].image_size);\r
387         cmd_yaffs_umount(path);\r
388         return 1;\r
389 \r
390 }\r
391 \r
392 void            ramDisk_Close(RAMDISK_HANDLE handle)\r
393 {\r
394         return;\r
395 }\r
396 \r
397 #endif\r
398 \r