tizen 2.4 release
[kernel/u-boot-tm1.git] / nand_fdl / fdl-2 / src / fdl_emmc_operate.c
1 #include "sci_types.h"
2 #include "fdl_conf.h"
3 #ifdef CONFIG_EMMC_BOOT
4 #include "card_sdio.h"
5 #include "packet.h"
6 #include "fdl_crc.h"
7 #include "fdl_stdio.h"
8 #include "asm/arch/sci_types.h"
9 #include <linux/crc32b.h>
10 #include <malloc.h>
11 #include <asm/arch/secure_boot.h>
12 #include "fdl_common.h"
13 #include "fdl_emmc_operate.h"
14 #include <ext_common.h>
15
16 #ifdef CONFIG_SECURE_BOOT
17 #include "secure_verify.h"
18 #endif
19 #define EFI_SECTOR_SIZE                 (512)
20 #define EMMC_MAX_MUTIL_WRITE  (0x8000)
21 #define ERASE_SECTOR_SIZE               ((64 * 1024) / EFI_SECTOR_SIZE)
22 #define EMMC_BUF_SIZE                   (((216 * 1024 * 1024) / EFI_SECTOR_SIZE) * EFI_SECTOR_SIZE)
23
24 #if defined(CONFIG_SPX30G) || defined(CONFIG_SC9630)
25 #define SPL_CHECKSUM_LEN        0x8000
26 #else
27 #define SPL_CHECKSUM_LEN        0x6000
28 #endif
29 #define MAX_GPT_PARTITION_SUPPORT  (50)
30 #define EMMC_ERASE_ALIGN_LENGTH  (0x800)
31
32 static DL_EMMC_FILE_STATUS g_status;
33 static DL_EMMC_STATUS g_dl_eMMCStatus = {0, 0, 0xffffffff,0, 0, 0,0};
34
35 static unsigned long g_checksum;
36 static unsigned long g_sram_addr;
37
38 #if defined (CONFIG_SC8825) || defined (CONFIG_TIGER) || defined (CONFIG_SC8830) ||defined(CONFIG_SC9630)
39 unsigned char *g_eMMCBuf = (unsigned char*)0x82000000;
40 #else
41 unsigned char *g_eMMCBuf = (unsigned char*)0x2000000;
42 #endif
43
44 unsigned int g_total_partition_number = 0;
45
46 static wchar_t s_uboot_partition[MAX_UTF_PARTITION_NAME_LEN] = L"uboot";
47 static wchar_t s_spl_loader_partition[MAX_UTF_PARTITION_NAME_LEN] = L"splloader";
48
49 static int uefi_part_info_ok_flag = 0;
50 static PARTITION_CFG uefi_part_info[MAX_GPT_PARTITION_SUPPORT] = {0};
51 static PARTITION_CFG s_sprd_emmc_partition_cfg[MAX_GPT_PARTITION_SUPPORT] = {0};
52
53 #ifdef CONFIG_SECURE_BOOT
54 static int check_secure_flag = 0;
55 static int secure_image_flag = 0;
56
57 static wchar_t* const s_force_secure_check[]={
58         L"boot",L"recovery",L"uboot",L"tdmodem",L"tddsp",L"wmodem",L"wdsp",L"wcnmodem",L"wl_modem", L"wl_ldsp", L"wl_gdsp", L"wl_warm", L"pm_sys", L"sml",L"tl_gdsp",L"tl_ldsp",L"tl_modem",NULL
59 };
60 #endif
61
62 /**
63         partitions not for raw data or normal usage(e.g. nv and prodinfo) should config here.
64         partitions not list here mean raw data/normal usage.
65 */
66 static SPECIAL_PARTITION_CFG const s_special_partition_cfg[]={
67         {{L"fixnv1"},{L"fixnv2"},IMG_RAW,PARTITION_PURPOSE_NV},
68         {{L"runtimenv1"},{L"runtimenv2"},IMG_RAW,PARTITION_PURPOSE_NV},
69         {{L"tdfixnv1"},{L"tdfixnv2"},IMG_RAW,PARTITION_PURPOSE_NV},
70         {{L"tdruntimenv1"},{L"tdruntimenv2"},IMG_RAW,PARTITION_PURPOSE_NV},
71         {{L"g_fixnv1"},{L"g_fixnv2"},IMG_RAW,PARTITION_PURPOSE_NV},
72         {{L"g_runtimenv1"},{L"g_runtimenv2"},IMG_RAW,PARTITION_PURPOSE_NV},
73         {{L"l_fixnv1"},{L"l_fixnv2"},IMG_RAW,PARTITION_PURPOSE_NV},
74         {{L"l_runtimenv1"},{L"l_runtimenv2"},IMG_RAW,PARTITION_PURPOSE_NV},
75         {{L"tl_fixnv1"},{L"tl_fixnv2"},IMG_RAW,PARTITION_PURPOSE_NV},
76         {{L"tl_runtimenv1"},{L"tl_runtimenv2"},IMG_RAW,PARTITION_PURPOSE_NV},
77         {{L"lf_fixnv1"},{L"lf_fixnv2"},IMG_RAW,PARTITION_PURPOSE_NV},
78         {{L"lf_runtimenv1"},{L"lf_runtimenv2"},IMG_RAW,PARTITION_PURPOSE_NV},
79         {{L"wfixnv1"},{L"wfixnv2"},IMG_RAW,PARTITION_PURPOSE_NV},
80         {{L"wruntimenv1"},{L"wruntimenv2"},IMG_RAW,PARTITION_PURPOSE_NV},
81         {{L"wl_fixnv1"},{L"wl_fixnv2"},IMG_RAW,PARTITION_PURPOSE_NV},
82         {{L"wl_runtimenv1"},{L"wl_runtimenv2"},IMG_RAW,PARTITION_PURPOSE_NV},
83         {{L"wcnfixnv1"},{L"wcnfixnv2"},IMG_RAW,PARTITION_PURPOSE_NV},
84         {{L"wcnruntimenv1"},{L"wcnruntimenv2"},IMG_RAW,PARTITION_PURPOSE_NV},
85         {{L"system"},NULL,IMG_RAW,PARTITION_PURPOSE_NORMAL},
86         {{L"userdata"},NULL,IMG_WITH_SPARSE,PARTITION_PURPOSE_NORMAL},
87         {{L"cache"},NULL,IMG_WITH_SPARSE,PARTITION_PURPOSE_NORMAL},
88         {{L"prodnv"},NULL,IMG_RAW,PARTITION_PURPOSE_NORMAL},
89         {NULL,NULL,IMG_TYPE_MAX,PARTITION_PURPOSE_MAX}
90 };
91
92 static __inline void FDL2_eMMC_SendRep (unsigned long err)
93 {
94         FDL_SendAckPacket (convert_err (err));
95 }
96
97 /**
98         just convert partition name wchar to char with violent.
99 */
100 LOCAL __inline char* _w2c(wchar_t *wchar)
101 {
102         static char buf[73]={0};
103         unsigned int i=0;
104         while((NULL != wchar[i]) && (i<72))
105         {
106                 buf[i] = wchar[i]&0xFF;
107                 i++;
108         }
109         buf[i]=0;
110
111         return buf;
112 }
113
114 LOCAL unsigned short eMMCCheckSum(const unsigned int *src, int len)
115 {
116     unsigned int   sum = 0;
117     unsigned short *src_short_ptr = PNULL;
118
119     while (len > 3)
120     {
121         sum += *src++;
122         len -= 4;
123     }
124
125     src_short_ptr = (unsigned short *) src;
126
127     if (0 != (len&0x2))
128     {
129         sum += * (src_short_ptr);
130         src_short_ptr++;
131     }
132
133     if (0 != (len&0x1))
134     {
135         sum += * ( (unsigned char *) (src_short_ptr));
136     }
137
138     sum  = (sum >> 16) + (sum & 0x0FFFF);
139     sum += (sum >> 16);
140
141     return (unsigned short) (~sum);
142 }
143 LOCAL unsigned int get_pad_data(const unsigned int *src, int len, int offset, unsigned short sum)
144 {
145         unsigned int sum_tmp;
146         unsigned int sum1 = 0;
147         unsigned int pad_data;
148         unsigned int i;
149         sum = ~sum;
150         sum_tmp = sum & 0xffff;
151         sum1 = 0;
152         for(i = 0; i < offset; i++) {
153                 sum1 += src[i];
154         }
155         for(i = (offset + 1); i < len; i++) {
156                 sum1 += src[i];
157         }
158         pad_data = sum_tmp - sum1;
159         return pad_data;
160 }
161
162 LOCAL void splFillCheckData(unsigned int * splBuf,  int len)
163 {
164         #define MAGIC_DATA      0xAA55A5A5
165         #define CHECKSUM_START_OFFSET   0x28
166         #define MAGIC_DATA_SAVE_OFFSET  (0x20/4)
167         #define CHECKSUM_SAVE_OFFSET    (0x24/4)
168
169 #if defined(CONFIG_TIGER) || defined(CONFIG_SC7710G2) || defined(CONFIG_SC8830) || defined(CONFIG_SC9630)
170         EMMC_BootHeader *header;
171 #if defined(CONFIG_SC8830) || defined(CONFIG_SC9630)
172         unsigned int pad_data;
173         unsigned int w_len;
174         unsigned int w_offset;
175         w_len = (SPL_CHECKSUM_LEN-(BOOTLOADER_HEADER_OFFSET+sizeof(*header))) / 4;
176         w_offset = w_len - 1;
177         //pad the data inorder to make check sum to 0
178         pad_data = (unsigned int)get_pad_data((unsigned char*)splBuf+BOOTLOADER_HEADER_OFFSET+sizeof(*header), w_len, w_offset, 0);
179         *(volatile unsigned int *)((unsigned char*)splBuf+SPL_CHECKSUM_LEN - 4) = pad_data;
180 #endif
181         header = (EMMC_BootHeader *)((unsigned char*)splBuf+BOOTLOADER_HEADER_OFFSET);
182         header->version  = 0;
183         header->magicData= MAGIC_DATA;
184         header->checkSum = (unsigned int)eMMCCheckSum((unsigned char*)splBuf+BOOTLOADER_HEADER_OFFSET+sizeof(*header), SPL_CHECKSUM_LEN-(BOOTLOADER_HEADER_OFFSET+sizeof(*header)));
185 #ifdef CONFIG_SECURE_BOOT
186         header->hashLen  = CONFIG_SPL_HASH_LEN>>2;
187 #else
188         header->hashLen  = 0;
189 #endif
190
191 #else
192         *(splBuf + MAGIC_DATA_SAVE_OFFSET) = MAGIC_DATA;
193         *(splBuf + CHECKSUM_SAVE_OFFSET) = (unsigned int)eMMCCheckSum((unsigned int *)&splBuf[CHECKSUM_START_OFFSET/4], SPL_CHECKSUM_LEN - CHECKSUM_START_OFFSET);
194 //      *(splBuf + CHECKSUM_SAVE_OFFSET) = splCheckSum(splBuf);
195 #endif
196 }
197
198 LOCAL int _uefi_get_part_info(void)
199 {
200         block_dev_desc_t *dev_desc = NULL;
201         disk_partition_t info;
202         int i;
203         int part_num = 1;
204
205         if(uefi_part_info_ok_flag)
206                 return 1;
207
208         dev_desc = get_dev("mmc", 1);
209         if (dev_desc==NULL) {
210                 return 0;
211         }
212
213         debugf("%s:GPT PARTITION \n",__FUNCTION__);
214
215         if (get_all_partition_info(dev_desc, uefi_part_info, &g_total_partition_number) != 0)
216                 return 0;
217
218         uefi_part_info_ok_flag = 1;
219         return 1;
220 }
221
222 LOCAL unsigned long efi_GetPartBaseSec(wchar_t *partition_name)
223 {
224         int i;
225
226         _uefi_get_part_info();
227
228         for(i=0;i<g_total_partition_number;i++)
229         {
230                 if(wcscmp(partition_name, uefi_part_info[i].partition_name) == 0)
231                 {
232                         return uefi_part_info[i].partition_offset;
233                 }
234         }
235
236         //Can't find the specified partition
237         debugf("%s: Can't find partition:%s!\n", __FUNCTION__,_w2c(partition_name));
238         FDL_SendAckPacket (BSL_INCOMPATIBLE_PARTITION);
239         return 0;
240 }
241
242 LOCAL unsigned long efi_GetPartSize(wchar_t *partition_name)
243 {
244         int i;
245
246         _uefi_get_part_info();
247
248         for(i=0;i<g_total_partition_number;i++)
249         {
250                 if(wcscmp(partition_name, uefi_part_info[i].partition_name) == 0)
251                         return (EFI_SECTOR_SIZE * uefi_part_info[i].partition_size);
252         }
253
254         //Can't find the specified partition
255         debugf("%s: Can't find partition:%s!\n", __FUNCTION__,_w2c(partition_name));
256         FDL_SendAckPacket (BSL_INCOMPATIBLE_PARTITION);
257         return 0;
258 }
259
260 LOCAL void _parser_repartition_cfg(unsigned short* partition_cfg, unsigned short total_partition_num)
261 {
262         int i, j;
263         unsigned long partition_size;
264
265         /*Decode String: Partition Name(72Byte)+SIZE(4Byte)+...*/
266         for(i=0;i<total_partition_num;i++)
267         {
268                 partition_size = *(unsigned long *)(partition_cfg+38*(i+1)-2);
269                 s_sprd_emmc_partition_cfg[i].partition_index = i+1;
270                 //the partition size received from tool is MByte.
271                 if(MAX_SIZE_FLAG == partition_size)
272                         s_sprd_emmc_partition_cfg[i].partition_size = partition_size;
273                 else
274                         s_sprd_emmc_partition_cfg[i].partition_size = 1024*partition_size;
275                 s_sprd_emmc_partition_cfg[i].partition_attr = PARTITION_RAW;//TODO
276                 s_sprd_emmc_partition_cfg[i].partition_offset = 0;
277                 for(j=0;j<MAX_UTF_PARTITION_NAME_LEN;j++)
278                 {
279                         s_sprd_emmc_partition_cfg[i].partition_name[j] = *(partition_cfg+38*i+j);
280                 }
281
282                 debugf("%s:partition name:%s,partition_size:0x%x\n",__FUNCTION__,_w2c(s_sprd_emmc_partition_cfg[i].partition_name),s_sprd_emmc_partition_cfg[i].partition_size);
283         }
284         return;
285 }
286
287 /**
288         Get the partition's target image type(raw data or others) and purpose(nv/prodinfo/normal).
289 */
290 LOCAL void _get_partition_attribute(wchar_t* partition_name)
291 {
292         int i;
293
294         for(i=0;s_special_partition_cfg[i].partition != NULL;i++)
295         {
296                 if(wcscmp(s_special_partition_cfg[i].partition, partition_name) == 0)
297                 {
298                         g_dl_eMMCStatus.curImgType = s_special_partition_cfg[i].imgattr;
299                         g_dl_eMMCStatus.partitionpurpose = s_special_partition_cfg[i].purpose;
300                         debugf("%s:partition %s image type is %d,partitionpurpose:%d\n", __FUNCTION__,_w2c(partition_name),g_dl_eMMCStatus.curImgType,g_dl_eMMCStatus.partitionpurpose);
301                         return;
302                 }
303         }
304         //default type is IMG_RAW
305         g_dl_eMMCStatus.curImgType = IMG_RAW;
306         g_dl_eMMCStatus.partitionpurpose = PARTITION_PURPOSE_NORMAL;
307         debugf("%s:partition %s image type is RAW, normal partition!\n", __FUNCTION__,_w2c(partition_name));
308         return;
309 }
310
311 /**
312         Check whether the partition to be operated is compatible.
313 */
314 LOCAL BOOLEAN _get_compatible_partition(wchar_t* partition_name)
315 {
316         int i;
317
318         //get special partition attr
319         _get_partition_attribute(partition_name);
320         //Get user partition info from eMMC
321         _uefi_get_part_info();
322
323         //Try to find the partition specified
324         if(wcscmp(partition_name, L"uboot") == 0)
325         {
326                 g_dl_eMMCStatus.curUserPartitionName = s_uboot_partition;
327                 return TRUE;
328         }
329         if(wcscmp(partition_name, L"splloader") == 0)
330         {
331                 g_dl_eMMCStatus.curUserPartitionName = s_spl_loader_partition;
332                 return TRUE;
333         }
334
335         for(i=0;i<g_total_partition_number;i++)
336         {
337                 if(wcscmp(partition_name, uefi_part_info[i].partition_name) == 0)
338                 {
339                         g_dl_eMMCStatus.curUserPartitionName = uefi_part_info[i].partition_name;
340                         return TRUE;
341                 }
342         }
343         //Can't find the specified partition
344         g_dl_eMMCStatus.curUserPartitionName = NULL;
345         debugf("%s:Can't find partition:%s \n", __FUNCTION__,_w2c(partition_name));
346         return FALSE;
347 }
348
349 /**
350         Get the backup partition name
351 */
352 LOCAL wchar_t * _get_backup_partition_name(wchar_t *partition_name)
353 {
354         int i = 0;
355
356         for(i=0;s_special_partition_cfg[i].partition != NULL;i++)
357         {
358                 if(wcscmp(partition_name, s_special_partition_cfg[i].partition) == 0)
359                 {
360                         return s_special_partition_cfg[i].bak_partition;
361                 }
362         }
363
364         return NULL;
365 }
366
367 /**
368         Partition Check Function
369         Return:
370                 0:No partition table or not same with New
371                 1:Same with new partition
372 */
373 LOCAL int _fdl2_check_partition_table(PARTITION_CFG* new_cfg, PARTITION_CFG* old_cfg, unsigned short total_partition_num)
374 {
375         int i;
376         debugf("_fdl2_check_partition_table -----\n");
377
378         uefi_part_info_ok_flag = 0;
379
380         if (!_uefi_get_part_info())
381         {
382                 return 0;
383         }
384
385         //we may modify starting LBA of first partition,so we should check it.
386         if(STARTING_LBA_OF_FIRST_PARTITION != old_cfg[0].partition_offset)
387                 return 0;
388
389         if(total_partition_num == g_total_partition_number)
390         {
391                 for(i=0;i<total_partition_num;i++)
392                 {
393                         if(0 !=wcscmp(new_cfg[i].partition_name,old_cfg[i].partition_name))
394                         {
395                                 return 0;
396                         }
397                         else
398                         {
399                                 /*
400                                         the new_cfg partition size get from tool is xx kbyte, 
401                                         the old_cfg partition size read from disk is yy*sector_size byte.
402                                 */
403                                 if(2*new_cfg[i].partition_size != old_cfg[i].partition_size && new_cfg[i].partition_size !=0xffffffff)
404                                         return 0;
405                         }
406                 }
407         }
408         else{
409                 return 0;
410         }
411
412         return 1;
413 }
414
415 LOCAL int _format_sd_partition(void)
416 {
417         unsigned long part_size = 0;
418         unsigned long sd_data_size = 0;
419         unsigned long base_sector = 0;
420
421         part_size = efi_GetPartSize(g_dl_eMMCStatus.curUserPartitionName);
422         if(0 == part_size){
423                 return -1;
424         }
425         sd_data_size = newfs_msdos_main(g_eMMCBuf,part_size);
426         g_dl_eMMCStatus.curEMMCArea = PARTITION_USER;
427         base_sector = efi_GetPartBaseSec(g_dl_eMMCStatus.curUserPartitionName);
428
429         if (!Emmc_Erase(g_dl_eMMCStatus.curEMMCArea,base_sector,part_size / EFI_SECTOR_SIZE))  {
430                 return -1;
431         }
432
433         if (!Emmc_Write(g_dl_eMMCStatus.curEMMCArea, base_sector,sd_data_size / EFI_SECTOR_SIZE, g_eMMCBuf)) {
434                 return -1;
435         }
436         return 0;
437 }
438
439 /**
440         Erase the whole partition.
441 */
442 LOCAL int _emmc_real_erase_partition(wchar_t *partition_name)
443 {
444         unsigned long count=0, base_sector=0;
445         uint8 curArea = 0;
446
447         if(NULL == partition_name)
448                 return 0;
449
450         if (wcscmp(L"splloader", partition_name) == 0){
451                 if(secureboot_enabled()){
452                         return 1;
453                 }
454                 count = Emmc_GetCapacity(PARTITION_BOOT1);
455                 curArea = PARTITION_BOOT1;
456                 base_sector = 0;
457         }else if (wcscmp(L"uboot", partition_name) == 0){
458                 count = Emmc_GetCapacity(PARTITION_BOOT2);
459                 curArea = PARTITION_BOOT2;
460                 base_sector = 0;
461         }
462         else{
463                 curArea = PARTITION_USER;
464                 count = efi_GetPartSize(partition_name); /* partition size : in bytes */
465                 count = count / EFI_SECTOR_SIZE; /* partition size : in blocks */
466                 base_sector = efi_GetPartBaseSec(partition_name);
467         }
468
469         if(count < EMMC_ERASE_ALIGN_LENGTH)
470         {
471                 unsigned char buf[EMMC_ERASE_ALIGN_LENGTH*EFI_SECTOR_SIZE] = {0xFF};
472                 if (!Emmc_Write(curArea, base_sector,count,buf))
473                         return 0;
474         }
475         else
476         {
477                 if(base_sector%EMMC_ERASE_ALIGN_LENGTH)
478                 {
479                         unsigned char buf[EMMC_ERASE_ALIGN_LENGTH*EFI_SECTOR_SIZE] = {0xFF};
480                         unsigned long base_sector_offset = 0;
481
482                         base_sector_offset = EMMC_ERASE_ALIGN_LENGTH - base_sector%EMMC_ERASE_ALIGN_LENGTH;
483                         if (!Emmc_Write(curArea, base_sector,base_sector_offset,buf))
484                                 return 0;
485                         count = ((count-base_sector_offset)/EMMC_ERASE_ALIGN_LENGTH)*EMMC_ERASE_ALIGN_LENGTH;
486                         base_sector = base_sector + base_sector_offset;
487                 }
488                 else
489                         count = (count/EMMC_ERASE_ALIGN_LENGTH)*EMMC_ERASE_ALIGN_LENGTH;
490
491                 if(count == 0)
492                         return 1;
493
494                 if (!Emmc_Erase(curArea, base_sector,count))
495                         return 0;       
496         }
497
498         return 1;
499 }
500
501 /**
502         Fast erase userpartition use emmc_write .
503 */
504 LOCAL int _emmc_fast_erase_userpartition(wchar_t *partition_name)
505 {
506         unsigned long i, count, len,  base_sector;
507         uint8 curArea;
508
509         curArea = PARTITION_USER;
510         len = efi_GetPartSize(partition_name);
511         count = len / EFI_SECTOR_SIZE;
512         base_sector = efi_GetPartBaseSec(partition_name);
513         count = (count > ERASE_SECTOR_SIZE)?ERASE_SECTOR_SIZE:count;
514         memset(g_eMMCBuf, 0xff, count * EFI_SECTOR_SIZE);               
515         if (!Emmc_Write(curArea, base_sector, count, (unsigned char *)g_eMMCBuf))
516                  return 0;
517
518         return 1;
519 }
520
521 LOCAL int _emmc_erase_allflash(void)
522 {
523         int i;
524         uint32 count;
525
526         _uefi_get_part_info();
527         memset(g_eMMCBuf, 0xff, ERASE_SECTOR_SIZE*EFI_SECTOR_SIZE);
528         //erase user partitions
529         for (i = 0; i < g_total_partition_number; i++) {
530                 if (!_emmc_fast_erase_userpartition(uefi_part_info[i].partition_name))
531                         return 0;
532         }
533         //erase gpt header and partition entry table
534         if (!Emmc_Write(PARTITION_USER, 0, ERASE_SECTOR_SIZE, (unsigned char *)g_eMMCBuf))
535                  return 0;
536         //erase backup gpt header
537         count = Emmc_GetCapacity(PARTITION_USER);
538         if (!Emmc_Write(PARTITION_USER, count - 1, 1, (unsigned char *)g_eMMCBuf))
539                  return 0;
540         //erase boot1 partition
541         if(!_emmc_real_erase_partition(L"splloader"))
542                 return 0;
543         //erase boot2 partition
544         if(!_emmc_real_erase_partition(L"uboot"))
545                 return 0;
546
547         return 1;
548 }
549
550 #ifdef CONFIG_SECURE_BOOT
551 int _check_secure_part(wchar_t *partition_name)
552 {
553         int i = 0;
554         do
555         {
556                 if(0 == wcscmp(s_force_secure_check[i], partition_name))
557                         return 1;
558                 i++;
559         }while(s_force_secure_check[i]!=0);
560
561         return 0;
562 }
563
564 LOCAL int _emmc_secure_download(wchar_t* partition_name)
565 {
566         unsigned long count = 0;
567         unsigned int saved = 0;
568         unsigned int each ;
569         unsigned int base_sector = g_dl_eMMCStatus.base_sector;
570
571         //verify the code
572         if(secure_image_flag == 0)
573                 return 1;
574         else if(secure_image_flag == 1) {
575                 if (wcscmp(L"uboot", partition_name) == 0){
576                         secure_verify(L"splloader",g_eMMCBuf,0);
577                 }
578                 else {
579                         secure_verify(L"fdl2",g_eMMCBuf,0);
580                 }
581         }
582         else if(secure_image_flag == 2)
583                 secure_verify(L"splloader0",g_eMMCBuf,0);
584
585         //download the image
586         if (0 == (g_status.unsave_recv_size % EFI_SECTOR_SIZE))
587                 count = g_status.unsave_recv_size / EFI_SECTOR_SIZE;
588         else
589                 count = g_status.unsave_recv_size / EFI_SECTOR_SIZE + 1;
590
591         //write code
592         while(count){
593                 each = MIN(count,EMMC_MAX_MUTIL_WRITE);
594                 if (!Emmc_Write(g_dl_eMMCStatus.curEMMCArea, base_sector,
595                                 each, (unsigned char *) (g_eMMCBuf+(saved*EFI_SECTOR_SIZE)))) 
596                 {
597                         g_status.unsave_recv_size = 0;
598                         SEND_ERROR_RSP (BSL_WRITE_ERROR);
599                         return 0;
600                 }
601                 base_sector += each;
602                 saved += each;
603                 count -= each;
604         }
605
606         //write vlr
607         /*
608         if (!Emmc_Write(g_dl_eMMCStatus.curEMMCArea, efi_GetPartSize(g_dl_eMMCStatus.curUserPartitionName)/EFI_SECTOR_SIZE-8,
609                         8, vlr_buf))
610         {
611                 g_status.unsave_recv_size = 0;
612                 SEND_ERROR_RSP (BSL_WRITE_ERROR);
613                 return 0;
614         }
615         */
616
617         g_status.unsave_recv_size = 0;
618         secure_image_flag = 0;
619         return 1;
620 }
621 #endif
622
623 LOCAL int _emmc_download_image(unsigned long nSectorCount, unsigned long each_write_block, int is_total_recv)
624 {
625         unsigned long cnt, base_sector, trans_times, remain_block;
626         unsigned char *point;
627         int retval;
628
629 #ifdef CONFIG_SECURE_BOOT
630         if(secure_image_flag >= 1)
631                 return 1;
632 #endif
633
634         if (IMG_WITH_SPARSE == g_dl_eMMCStatus.curImgType){
635                 retval = write_simg2emmc("mmc", 1, g_dl_eMMCStatus.curUserPartitionName,
636                         g_eMMCBuf, g_status.unsave_recv_size);
637                 if (retval == -1) {
638                         g_status.unsave_recv_size = 0;
639                         SEND_ERROR_RSP (BSL_WRITE_ERROR);
640                         return 0;
641                 }
642         } else{
643                 unsigned long count = nSectorCount;
644                 unsigned int saved = 0;
645                 unsigned int each;
646                 unsigned int base_sector = g_dl_eMMCStatus.base_sector;
647                 while(count){
648                         each = MIN(count,each_write_block);
649                         if (!Emmc_Write(g_dl_eMMCStatus.curEMMCArea, base_sector,
650                                         each, (unsigned char *) (g_eMMCBuf+(saved*EFI_SECTOR_SIZE)))) {
651                                 g_status.unsave_recv_size = 0;
652                                 SEND_ERROR_RSP (BSL_WRITE_ERROR);
653                                 return 0;
654                         }
655                         base_sector += each;
656                         saved += each;
657                         count -= each;
658                 }
659         }
660
661         if (IMG_WITH_SPARSE == g_dl_eMMCStatus.curImgType){
662                 if (retval > 0) {
663                         memmove(g_eMMCBuf, g_eMMCBuf + retval, g_status.unsave_recv_size - retval);
664                         g_status.unsave_recv_size -= retval;
665                         g_sram_addr = (unsigned long)(g_eMMCBuf+g_status.unsave_recv_size);
666                 } else {
667                         g_status.unsave_recv_size = 0;
668                         g_sram_addr = (unsigned long)g_eMMCBuf;
669                 }
670         } else {
671                 g_status.unsave_recv_size = 0;
672                 if(!is_total_recv){
673                         g_dl_eMMCStatus.base_sector += nSectorCount;
674                         g_sram_addr = (unsigned long)g_eMMCBuf;
675                 }
676         }
677         return 1;
678 }
679
680 /**
681         Function used for reading nv partition which has crc protection.
682 */
683 LOCAL BOOLEAN _read_nv_with_backup(wchar_t *partition_name, uint8* buf, uint32 size)
684 {
685         wchar_t *backup_partition_name = NULL;
686         uint8  header_buf[EFI_SECTOR_SIZE];
687         u32 base_sector;
688         uint16 checkSum = 0;
689         uint32 magic = 0,len = 0;
690         nv_header_t * header_p = NULL;
691
692         header_p = header_buf;
693         base_sector = efi_GetPartBaseSec(partition_name);
694         //read origin image header
695         memset(header_buf, 0, EFI_SECTOR_SIZE);
696         if(!Emmc_Read(PARTITION_USER, base_sector, 1, header_buf)){
697                 debugf("_read_nv_with_backup read origin image header failed\n");
698                 return 0;
699         }
700         memcpy(&magic,header_buf,4);
701         if(NV_HEAD_MAGIC == magic){
702                 base_sector++;
703         }
704         debugf("_read_nv_with_backup origin image magic = 0x%x\n",magic);
705         //------
706         //read origin image
707         memset(buf, 0xFF, size);
708         if(Emmc_Read(PARTITION_USER, base_sector, (size>>9)+1, (uint8*)buf)){
709                 // get length and checksum
710                 if(NV_HEAD_MAGIC == magic){
711                         len = header_p->len;
712                         checkSum = header_p->checksum;
713                 }
714                 else{
715                         len = size-4;
716                         checkSum = (uint16)((((uint16)buf[size-3])<<8) | ((uint16)buf[size-4]));
717                 }
718                 //check crc
719                 if(fdl_check_crc(buf, len,checkSum)){
720                         return 1;
721                 }
722         }
723
724         //----
725         //get the backup partition name
726         backup_partition_name = _get_backup_partition_name(partition_name);
727         if(NULL== backup_partition_name){
728                 return 0;
729         }
730         base_sector = efi_GetPartBaseSec(backup_partition_name);
731
732         //read backup header
733         memset(header_buf, 0, EFI_SECTOR_SIZE);
734         if(!Emmc_Read(PARTITION_USER, base_sector, 1, header_buf)){
735                 debugf("_read_nv_with_backup read backup image header failed\n");
736                 return 0;
737         }
738         memcpy(&magic,header_buf,4);
739         if(NV_HEAD_MAGIC == magic){
740                 base_sector++;
741         }
742         debugf("_read_nv_with_backup backup image magic = 0x%x\n",magic);
743
744         //read bakup image
745         memset(buf, 0xFF, size);
746         if(Emmc_Read(PARTITION_USER, base_sector, (size>>9)+1, (uint8*)buf)){
747                 //get length and checksum
748                 if(NV_HEAD_MAGIC == magic){
749                         len = header_p->len;
750                         checkSum = header_p->checksum;
751                 }
752                 else{
753                         len = size-4;
754                         checkSum = (uint16)((((uint16)buf[size-3])<<8) | ((uint16)buf[size-4]));
755                 }
756                 //check crc
757                 if(!fdl_check_crc(buf, len,checkSum)){
758                         debugf("read backup image checksum error \n");;
759                         return 0;
760                 }
761         }
762         return 1;
763 }
764
765 LOCAL int _nv_img_check_and_write(wchar_t* partition, unsigned long size)
766 {
767         unsigned long  nSectorCount, nSectorBase;
768         unsigned short sum = 0, *dataaddr;
769         wchar_t *backup_partition_name = NULL;
770         uint8  header_buf[EFI_SECTOR_SIZE];
771         nv_header_t * nv_header_p = NULL;
772         //uint32 checksum = 0;
773
774         if (0 == ((size + 4) % EFI_SECTOR_SIZE))
775                 nSectorCount = (size + 4) / EFI_SECTOR_SIZE;
776         else
777                 nSectorCount = (size + 4) / EFI_SECTOR_SIZE + 1;
778
779         memset(header_buf,0x00,EFI_SECTOR_SIZE);
780         nv_header_p = header_buf;
781         nv_header_p->magic = NV_HEAD_MAGIC;
782         nv_header_p->len = size;
783         nv_header_p->checksum = (unsigned long)fdl_calc_checksum(g_eMMCBuf,size);
784         nv_header_p->version = NV_VERSION;
785         //write the original partition
786         _emmc_real_erase_partition(partition);
787         if (!Emmc_Write(g_dl_eMMCStatus.curEMMCArea, g_dl_eMMCStatus.base_sector,
788         1, (unsigned char *)header_buf)) {
789                 debugf("%s:original header %s write error! \n", __FUNCTION__,_w2c(partition));
790                 SEND_ERROR_RSP (BSL_WRITE_ERROR);
791                 return 0;
792         }
793         g_dl_eMMCStatus.base_sector++;
794         if (!Emmc_Write(g_dl_eMMCStatus.curEMMCArea, g_dl_eMMCStatus.base_sector,
795         nSectorCount, (unsigned char *)g_eMMCBuf)) {
796                 debugf("%s:original %s write error! \n", __FUNCTION__,_w2c(partition));
797                 SEND_ERROR_RSP (BSL_WRITE_ERROR);
798                 return 0;
799         }
800
801         //write the backup partition
802         backup_partition_name = _get_backup_partition_name(partition);
803         nSectorBase = efi_GetPartBaseSec(backup_partition_name);
804         _emmc_real_erase_partition(backup_partition_name);
805         if (!Emmc_Write(g_dl_eMMCStatus.curEMMCArea, nSectorBase, 1,
806         (unsigned char *)header_buf)) {
807                 debugf("%s:backup header %s write error! \n", __FUNCTION__,_w2c(partition));
808                 SEND_ERROR_RSP (BSL_WRITE_ERROR);
809                 return 0;
810         }
811         nSectorBase++;
812         if (!Emmc_Write(g_dl_eMMCStatus.curEMMCArea, nSectorBase, nSectorCount,
813         (unsigned char *)g_eMMCBuf)) {
814                 debugf("%s:backup %s write error! \n", __FUNCTION__,_w2c(partition));
815                 SEND_ERROR_RSP (BSL_WRITE_ERROR);
816                 return 0;
817         }
818         g_status.unsave_recv_size = 0;
819         return 1;
820 }
821
822 PUBLIC int fdl2_download_start(wchar_t* partition_name, unsigned long size, unsigned long nv_checksum)
823 {
824         int i = 0;
825
826         debugf("Enter %s,partition:%s,size:0x%x \n", __FUNCTION__,_w2c(partition_name),size);
827
828         g_status.total_size  = size;
829
830 #ifdef CONFIG_SECURE_BOOT
831         if(_check_secure_part(partition_name))
832         {
833                 check_secure_flag = 1;
834                 secure_image_flag = 0;
835         }else
836         {
837                 check_secure_flag = 0;
838                 secure_image_flag = 0;
839         }
840 #endif
841
842         if(!_get_compatible_partition(partition_name))
843         {
844                 FDL_SendAckPacket (convert_err (EMMC_INCOMPATIBLE_PART));
845                 return 0;
846         }
847
848         if (PARTITION_PURPOSE_NV == g_dl_eMMCStatus.partitionpurpose)
849         {
850                 g_dl_eMMCStatus.curEMMCArea = PARTITION_USER;
851                 g_dl_eMMCStatus.part_total_size = efi_GetPartSize(g_dl_eMMCStatus.curUserPartitionName);
852
853                 if ((size > g_dl_eMMCStatus.part_total_size) || (size > FIXNV_SIZE)) {
854                         debugf("%s:size(0x%x) beyond max,size:0x%x,FIXNV_SIZE:0x%x !\n", __FUNCTION__,size,g_dl_eMMCStatus.part_total_size,FIXNV_SIZE);
855                         FDL2_eMMC_SendRep (EMMC_INVALID_SIZE);
856                         return 0;
857                 }
858                 g_dl_eMMCStatus.base_sector = efi_GetPartBaseSec(g_dl_eMMCStatus.curUserPartitionName);
859                 memset(g_eMMCBuf, 0xff, FIXNV_SIZE + EFI_SECTOR_SIZE);
860                 g_checksum = nv_checksum;
861         }
862         else if (wcscmp(L"splloader", g_dl_eMMCStatus.curUserPartitionName) == 0)
863         {
864         #ifdef CONFIG_SECURE_BOOT
865                 secure_image_flag = 2;
866         #endif
867                 //need to check secure
868                 g_dl_eMMCStatus.curEMMCArea = PARTITION_BOOT1;
869                 g_dl_eMMCStatus.part_total_size = EFI_SECTOR_SIZE * Emmc_GetCapacity(PARTITION_BOOT1);
870                 g_dl_eMMCStatus.base_sector =  0;
871                 memset(g_eMMCBuf, 0xff, g_dl_eMMCStatus.part_total_size);
872                 if (size > g_dl_eMMCStatus.part_total_size) {
873                         debugf("%s:size(0x%x) beyond max size:0x%x!\n", __FUNCTION__,size,g_dl_eMMCStatus.part_total_size);
874                         FDL2_eMMC_SendRep (EMMC_INVALID_SIZE);
875                         return 0;
876                 }
877         }
878         else if (wcscmp(L"uboot", g_dl_eMMCStatus.curUserPartitionName) == 0)
879         {
880                 g_dl_eMMCStatus.curEMMCArea = PARTITION_BOOT2;
881                 g_dl_eMMCStatus.part_total_size = EFI_SECTOR_SIZE * Emmc_GetCapacity(PARTITION_BOOT2);
882                 g_dl_eMMCStatus.base_sector =  0;
883                 memset(g_eMMCBuf, 0xff, g_dl_eMMCStatus.part_total_size);
884                 if (size > g_dl_eMMCStatus.part_total_size) {
885                         debugf("%s:size(0x%x) beyond max size:0x%x!\n", __FUNCTION__,size,g_dl_eMMCStatus.part_total_size);
886                         FDL2_eMMC_SendRep (EMMC_INVALID_SIZE);
887                         return 0;
888                 }
889         }
890         else
891         {
892                 g_dl_eMMCStatus.curEMMCArea = PARTITION_USER;
893 /*
894                 if (IMG_WITH_SPARSE != g_dl_eMMCStatus.curImgType)
895                         _emmc_real_erase_partition(g_dl_eMMCStatus.curUserPartitionName);
896                 else
897                         memset(g_eMMCBuf, 0, EMMC_BUF_SIZE);
898 */
899                 g_dl_eMMCStatus.part_total_size = efi_GetPartSize(g_dl_eMMCStatus.curUserPartitionName);
900                 if (size > g_dl_eMMCStatus.part_total_size) {
901                         debugf("%s:size(0x%x) beyond max size:0x%x!\n", __FUNCTION__,size,g_dl_eMMCStatus.part_total_size);
902                         FDL2_eMMC_SendRep (EMMC_INVALID_SIZE);
903                         return 0;
904                 }
905                 g_dl_eMMCStatus.base_sector = efi_GetPartBaseSec(g_dl_eMMCStatus.curUserPartitionName);
906         }
907
908         g_status.total_recv_size   = 0;
909         g_status.unsave_recv_size   = 0;
910         g_sram_addr = (unsigned long)g_eMMCBuf;
911         FDL_SendAckPacket (BSL_REP_ACK);
912         return 1;
913 }
914
915 PUBLIC int fdl2_download_midst(unsigned short size, char *buf)
916 {
917         unsigned long lastSize, nSectorCount;
918         unsigned long each_write_block = EMMC_MAX_MUTIL_WRITE;
919
920         if ((g_status.total_recv_size + size) > g_status.total_size) {
921                 debugf("%s,size+recvd>total_size!\n", __FUNCTION__);
922                 FDL2_eMMC_SendRep (EMMC_INVALID_SIZE);
923                 return 0;
924         }
925
926         g_status.total_recv_size += size;
927
928 #ifdef CONFIG_SECURE_BOOT
929         if(check_secure_flag == 1)
930         {
931                 check_secure_flag = 0;
932                 if(secure_header_parser(buf) != 1)
933                 {
934                         secure_image_flag = 0;
935                         SEND_ERROR_RSP(BSL_WRITE_ERROR);
936                         return 0;
937                 }
938                 else
939                         secure_image_flag = 1;
940         }
941 #endif
942
943         if (EMMC_BUF_SIZE >= (g_status.unsave_recv_size + size)) 
944         {
945                 memcpy((unsigned char *)g_sram_addr, buf, size);
946                 g_sram_addr += size;
947                 g_status.unsave_recv_size += size;
948
949                 if (EMMC_BUF_SIZE == g_status.unsave_recv_size)
950                 {
951                         if (0 == (EMMC_BUF_SIZE % EFI_SECTOR_SIZE))
952                                 nSectorCount = EMMC_BUF_SIZE / EFI_SECTOR_SIZE;
953                         else
954                                 nSectorCount = EMMC_BUF_SIZE / EFI_SECTOR_SIZE + 1;
955
956                         if(!_emmc_download_image(nSectorCount, each_write_block, FALSE))
957                                 return 0;
958                 }
959                 else if (g_status.total_recv_size == g_status.total_size) 
960                 {
961                         if (PARTITION_PURPOSE_NV == g_dl_eMMCStatus.partitionpurpose)
962                         {
963                                 unsigned long  fix_nv_checksum;
964                                 fix_nv_checksum = Get_CheckSum((unsigned char *) g_eMMCBuf, g_status.total_recv_size);
965                                 if (fix_nv_checksum != g_checksum) {
966                                         //may data transfer error
967                                         debugf("%s:nv data transfer error,checksum error!\n", __FUNCTION__);
968                                         SEND_ERROR_RSP(BSL_CHECKSUM_DIFF);
969                                         return 0;
970                                 }
971                                 if(!_nv_img_check_and_write(g_dl_eMMCStatus.curUserPartitionName,FIXNV_SIZE))
972                                         return 0;
973                         }
974                         else
975                         {
976                                 if (g_status.unsave_recv_size != 0) {
977                                         if (0 == (g_status.unsave_recv_size % EFI_SECTOR_SIZE))
978                                                 nSectorCount = g_status.unsave_recv_size / EFI_SECTOR_SIZE;
979                                         else
980                                                 nSectorCount = g_status.unsave_recv_size / EFI_SECTOR_SIZE + 1;
981                                         
982                                         if (wcscmp(L"splloader", g_dl_eMMCStatus.curUserPartitionName) == 0){
983                                                 if (g_status.total_recv_size < SPL_CHECKSUM_LEN)
984                                                         nSectorCount = SPL_CHECKSUM_LEN / EFI_SECTOR_SIZE;
985                                                 splFillCheckData((unsigned int *) g_eMMCBuf, (int)g_status.total_recv_size);
986                                         }
987
988                                         if(!_emmc_download_image(nSectorCount, each_write_block, TRUE))
989                                                 return 0;
990                                 }
991                         }
992                 } 
993         } 
994         else
995         {
996                 lastSize = EMMC_BUF_SIZE - g_status.unsave_recv_size;
997                 memcpy((unsigned char *)g_sram_addr, buf, lastSize);
998                 g_status.unsave_recv_size = EMMC_BUF_SIZE;
999                 if (0 == (EMMC_BUF_SIZE % EFI_SECTOR_SIZE))
1000                         nSectorCount = EMMC_BUF_SIZE / EFI_SECTOR_SIZE;
1001                 else
1002                         nSectorCount = EMMC_BUF_SIZE / EFI_SECTOR_SIZE + 1;
1003
1004                 if(!_emmc_download_image(nSectorCount, each_write_block, FALSE))
1005                         return 0;
1006
1007                 g_sram_addr = (unsigned long)(g_eMMCBuf + g_status.unsave_recv_size);
1008                 memcpy((unsigned char *)g_sram_addr, (char *)(&buf[lastSize]), size - lastSize);
1009                 g_status.unsave_recv_size += size - lastSize;
1010                 g_sram_addr = (unsigned long)(g_eMMCBuf + g_status.unsave_recv_size);
1011          }
1012
1013         FDL2_eMMC_SendRep (EMMC_SUCCESS);
1014         return  1; 
1015 }
1016
1017 PUBLIC int fdl2_download_end(void)
1018 {
1019 #ifdef CONFIG_SECURE_BOOT
1020         if(_emmc_secure_download(g_dl_eMMCStatus.curUserPartitionName) != 1)
1021         {
1022                 debugf("%s:_emmc_secure_download error!\n", __FUNCTION__);
1023                 FDL2_eMMC_SendRep (EMMC_SYSTEM_ERROR);
1024                 return 0;
1025         }
1026 #endif
1027         if(g_status.unsave_recv_size != 0)
1028         {
1029                 debugf("%s:unsaved size is not zero!\n", __FUNCTION__);
1030                 FDL2_eMMC_SendRep (EMMC_SYSTEM_ERROR);
1031                 return 0;
1032         }
1033
1034         FDL2_eMMC_SendRep (EMMC_SUCCESS);
1035         g_status.total_size  = 0;       
1036         return 1;
1037 }
1038
1039 PUBLIC int fdl2_read_start(wchar_t* partition_name, unsigned long size)
1040 {
1041         debugf("Enter %s,partition:%s,size:0x%x \n", __FUNCTION__,_w2c(partition_name),size);
1042
1043         if(!_get_compatible_partition(partition_name))
1044         {
1045                 FDL_SendAckPacket (convert_err (EMMC_INCOMPATIBLE_PART));
1046                 return FALSE;
1047         }
1048
1049         g_dl_eMMCStatus.curEMMCArea = PARTITION_USER;
1050
1051         if(PARTITION_PURPOSE_NV == g_dl_eMMCStatus.partitionpurpose)
1052         {
1053                 g_dl_eMMCStatus.part_total_size = efi_GetPartSize(g_dl_eMMCStatus.curUserPartitionName);
1054                 if ((size > g_dl_eMMCStatus.part_total_size) /*|| (size > FIXNV_SIZE)*/){
1055                         debugf("%s:size(0x%x) beyond max size:0x%x!\n", __FUNCTION__,size,g_dl_eMMCStatus.part_total_size);
1056                         FDL2_eMMC_SendRep (EMMC_INVALID_SIZE);
1057                         return FALSE;
1058                 }
1059                 g_dl_eMMCStatus.base_sector = efi_GetPartBaseSec(g_dl_eMMCStatus.curUserPartitionName);
1060         }
1061         else  if (wcscmp(L"splloader", g_dl_eMMCStatus.curUserPartitionName) == 0)
1062         {
1063                 g_dl_eMMCStatus.curEMMCArea = PARTITION_BOOT1;
1064                 g_dl_eMMCStatus.part_total_size = EFI_SECTOR_SIZE * Emmc_GetCapacity(PARTITION_BOOT1);
1065                 g_dl_eMMCStatus.base_sector =  0;
1066         }
1067         else if (wcscmp(L"uboot", g_dl_eMMCStatus.curUserPartitionName) == 0)
1068         {
1069                 g_dl_eMMCStatus.curEMMCArea = PARTITION_BOOT2;
1070                 g_dl_eMMCStatus.part_total_size = EFI_SECTOR_SIZE * Emmc_GetCapacity(PARTITION_BOOT2);
1071                 g_dl_eMMCStatus.base_sector =  0;
1072         }
1073         else
1074         {
1075                 g_dl_eMMCStatus.part_total_size = efi_GetPartSize(g_dl_eMMCStatus.curUserPartitionName);
1076                 g_dl_eMMCStatus.base_sector = efi_GetPartBaseSec(g_dl_eMMCStatus.curUserPartitionName);
1077         }
1078
1079         if (size > g_dl_eMMCStatus.part_total_size)
1080         {
1081                 debugf("%s:size(0x%x) beyond max size:0x%x!\n", __FUNCTION__,size,g_dl_eMMCStatus.part_total_size);
1082                 FDL2_eMMC_SendRep (EMMC_INVALID_SIZE);
1083                 return FALSE;
1084         }
1085
1086         if (wcscmp(L"prodnv", g_dl_eMMCStatus.curUserPartitionName) == 0)
1087         {
1088                 struct ext2_sblock *sblock=NULL;
1089                 sblock = malloc(MAX(EFI_SECTOR_SIZE,sizeof(struct ext2_sblock)));
1090                 if(!sblock){
1091                         debugf("malloc sblock failed\n");
1092                         goto err;
1093                 }
1094
1095                 if (!Emmc_Read(g_dl_eMMCStatus.curEMMCArea,
1096                                 g_dl_eMMCStatus.base_sector + 2,/*superblock offset 2 sect*/
1097                                 1,/*superblock take one sect*/
1098                                 sblock)){
1099                         free(sblock);
1100                         goto err;
1101                 }
1102
1103                 if(sblock->magic != EXT2_MAGIC){
1104                         debugf("bad prodnv image magic\n");
1105                         free(sblock);
1106                         goto err;
1107                 }
1108                 free(sblock);
1109         }
1110
1111         FDL_SendAckPacket (BSL_REP_ACK);
1112         return TRUE;
1113 err:
1114         FDL2_eMMC_SendRep (EMMC_SYSTEM_ERROR);
1115         return FALSE;
1116 }
1117
1118 PUBLIC int fdl2_read_midst(unsigned long size, unsigned long off, unsigned char *buf)
1119 {
1120         unsigned long nSectorCount, nSectorOffset;
1121
1122         if ((size +off) > g_dl_eMMCStatus.part_total_size)
1123         {
1124                 debugf("%s:size(0x%x)+off(0x%x) beyond max size(0x%x)!\n", __FUNCTION__,size,off,g_dl_eMMCStatus.part_total_size);
1125                 FDL2_eMMC_SendRep (EMMC_INVALID_SIZE);
1126                 return FALSE;
1127         }
1128
1129         if(PARTITION_PURPOSE_NV == g_dl_eMMCStatus.partitionpurpose)
1130         {
1131                 if(_read_nv_with_backup(g_dl_eMMCStatus.curUserPartitionName, g_eMMCBuf, FIXNV_SIZE))
1132                 {
1133                         memcpy(buf, (unsigned char *)(g_eMMCBuf + off), size);
1134                         return TRUE;
1135                 }
1136                 else
1137                 {
1138                         FDL2_eMMC_SendRep (EMMC_SYSTEM_ERROR);
1139                         return FALSE;
1140                 }
1141         }
1142         else
1143         {
1144                 if (0 == (size % EFI_SECTOR_SIZE))
1145                          nSectorCount = size / EFI_SECTOR_SIZE;
1146                 else
1147                          nSectorCount = size / EFI_SECTOR_SIZE + 1;
1148                 nSectorOffset = off / EFI_SECTOR_SIZE;
1149                 if (!Emmc_Read(g_dl_eMMCStatus.curEMMCArea, g_dl_eMMCStatus.base_sector + nSectorOffset,  nSectorCount, buf ))
1150                 {
1151                         debugf("%s: read error!\n", __FUNCTION__);
1152                         FDL2_eMMC_SendRep (EMMC_SYSTEM_ERROR);
1153                         return FALSE;
1154                 }
1155         }
1156
1157         return TRUE;
1158 }
1159 LOCAL void _checkNVPartition(void){
1160         uint8 *ori_buf;
1161         uint8 *backup_buf;
1162         wchar_t *backup_partition_name = NULL;
1163         uint8  ori_header_buf[EFI_SECTOR_SIZE];
1164         uint8  backup_header_buf[EFI_SECTOR_SIZE];
1165         u32 base_sector;
1166         uint16 checkSum = 0;
1167         uint32 len = 0;
1168         nv_header_t * header_p = NULL;
1169         uint8 status = 0;
1170         uint32 size = FIXNV_SIZE;
1171
1172         debugf("check nv partition enter\n");
1173         ori_buf = malloc(size+EFI_SECTOR_SIZE);
1174         if(!ori_buf){
1175                 debugf("check nv partition malloc oribuf failed\n");
1176                 return;
1177         }
1178         debugf("check nv partition ori_buf 0x%x\n",ori_buf);
1179         backup_buf = malloc(size+EFI_SECTOR_SIZE);
1180         if(!backup_buf){
1181                 debugf("check nv partition malloc backup_buf failed\n");
1182                 free(ori_buf);
1183                 return;
1184         }
1185         debugf("check nv partition backup_buf 0x%x\n",backup_buf);
1186         header_p = ori_header_buf;
1187         base_sector = efi_GetPartBaseSec(g_dl_eMMCStatus.curUserPartitionName);
1188         //read origin image header
1189         memset(ori_header_buf, 0, EFI_SECTOR_SIZE);
1190         if(!Emmc_Read(PARTITION_USER, base_sector, 1, ori_header_buf)){
1191                 debugf("_checkNVPartition read origin image header failed\n");
1192                 free(ori_buf);
1193                 free(backup_buf);
1194                 return;
1195         }
1196         if(NV_HEAD_MAGIC == header_p->magic){
1197                 base_sector++;
1198         }
1199         debugf("_checkNVPartition origin image magic = 0x%x\n",header_p->magic);
1200         //------
1201         //read origin image
1202         memset(ori_buf, 0xFF, size+EFI_SECTOR_SIZE);
1203         if(Emmc_Read(PARTITION_USER, base_sector, ((size+EFI_SECTOR_SIZE-1)&~(EFI_SECTOR_SIZE-1))>>9, (uint8*)ori_buf)){
1204                 // get length and checksum
1205                 if(NV_HEAD_MAGIC == header_p->magic){
1206                         len = header_p->len;
1207                         checkSum = header_p->checksum;
1208                 }
1209                 else{
1210                         len = size-4;
1211                         checkSum = (uint16)((((uint16)ori_buf[size-3])<<8) | ((uint16)ori_buf[size-4]));
1212                 }
1213                 //check ecc
1214                 if(fdl_check_crc(ori_buf, len,checkSum)){
1215                         status |= 1;
1216                 }
1217         }
1218
1219         //----
1220         //get the backup partition name
1221         backup_partition_name = _get_backup_partition_name(g_dl_eMMCStatus.curUserPartitionName);
1222         if(NULL== backup_partition_name){
1223                 free(ori_buf);
1224                 free(backup_buf);
1225                 return;
1226         }
1227         base_sector = efi_GetPartBaseSec(backup_partition_name);
1228         //read backup header
1229         header_p = backup_header_buf;
1230         memset(backup_header_buf, 0, EFI_SECTOR_SIZE);
1231         if(!Emmc_Read(PARTITION_USER, base_sector, 1, backup_header_buf)){
1232                 debugf("_read_nv_with_backup read backup image header failed\n");
1233                 free(ori_buf);
1234                 free(backup_buf);
1235                 return;
1236         }
1237
1238         if(NV_HEAD_MAGIC == header_p->magic){
1239                 base_sector++;
1240         }
1241         debugf("_read_nv_with_backup backup image magic = 0x%x\n",header_p->magic);
1242
1243         //read bakup image
1244         memset(backup_buf, 0xFF, size+EFI_SECTOR_SIZE);
1245         if(Emmc_Read(PARTITION_USER, base_sector, ((size+EFI_SECTOR_SIZE-1)&~(EFI_SECTOR_SIZE-1))>>9, (uint8*)backup_buf)){
1246                 //get length and checksum
1247                 if(NV_HEAD_MAGIC == header_p->magic){
1248                         len = header_p->len;
1249                         checkSum = header_p->checksum;
1250                 }
1251                 else{
1252                         len = size-4;
1253                         checkSum = (uint16)((((uint16)backup_buf[size-3])<<8) | ((uint16)backup_buf[size-4]));
1254                 }
1255                 //check ecc
1256                 if(fdl_check_crc(backup_buf, len,checkSum)){
1257                         status |= 2;//four status:00,01,10,11
1258                 }
1259         }
1260         switch(status){
1261                 case 0:
1262                         debugf("%s:both org and bak partition are damaged!\n",__FUNCTION__);
1263                         break;
1264                 case 1:
1265                         debugf("%s:bak partition is damaged!\n",__FUNCTION__);
1266                         base_sector = efi_GetPartBaseSec(backup_partition_name);
1267                         header_p = ori_header_buf;
1268                         if(NV_HEAD_MAGIC == header_p->magic){
1269                                 if(Emmc_Write(PARTITION_USER, base_sector, 1, ori_header_buf)){
1270                                         debugf("write backup nv header success\n");
1271                                         base_sector++;
1272                                 }
1273                         }
1274                         //write one more sector
1275                         if(Emmc_Write(PARTITION_USER, base_sector, ((size+EFI_SECTOR_SIZE-1)&~(EFI_SECTOR_SIZE-1))>>9, (uint8*)ori_buf)){
1276                                 debugf("write backup nv body success\n");
1277                         }
1278                         break;
1279                 case 2:
1280                         debugf("%s:org partition is damaged!\n!",__FUNCTION__);
1281                         base_sector = efi_GetPartBaseSec(g_dl_eMMCStatus.curUserPartitionName);
1282                         header_p = backup_header_buf;
1283                         if(NV_HEAD_MAGIC == header_p->magic){
1284                                 if(Emmc_Write(PARTITION_USER, base_sector, 1, backup_header_buf)){
1285                                         debugf("write original partition header success\n");
1286                                         base_sector++;
1287                                 }
1288                         }
1289                         if(Emmc_Write(PARTITION_USER, base_sector, ((size+EFI_SECTOR_SIZE-1)&~(EFI_SECTOR_SIZE-1))>>9, (uint8*)backup_buf)){
1290                                 debugf("write original partition body success\n");
1291                         }
1292                         break;
1293                 case 3:
1294                         debugf("%s:both org and bak partition are ok!\n",__FUNCTION__);
1295                         break;
1296                 default:
1297                         debugf("%s: status error!\n",__FUNCTION__);
1298                         break;
1299         }
1300         free(backup_buf);
1301         free(ori_buf);
1302         return;
1303 }
1304
1305
1306 PUBLIC int fdl2_read_end(void)
1307 {
1308         //Just send ack to tool in emmc
1309         printf("g_dl_eMMCStatus.partitionpurpose = %d\n",g_dl_eMMCStatus.partitionpurpose);
1310         if(PARTITION_PURPOSE_NV == g_dl_eMMCStatus.partitionpurpose){
1311                 _checkNVPartition();
1312         }
1313         FDL_SendAckPacket (BSL_REP_ACK);
1314         return TRUE;
1315 }
1316
1317 PUBLIC int fdl2_erase(wchar_t* partition_name, unsigned long size)
1318 {
1319         int retval;
1320         unsigned long part_size;
1321         wchar_t *backup_partition_name = NULL;
1322
1323         if ((wcscmp(partition_name, L"erase_all") == 0) && (size = 0xffffffff)) {
1324                 debugf("%s:Erase all!\n", __FUNCTION__);
1325                 if (!_emmc_erase_allflash()) {
1326                         SEND_ERROR_RSP (BSL_WRITE_ERROR);                       
1327                         return 0;
1328                 }
1329         } else {
1330                 debugf("%s:erase partition %s!\n", __FUNCTION__,_w2c(partition_name));
1331                 if(!_get_compatible_partition(partition_name))
1332                 {
1333                         FDL_SendAckPacket (BSL_INCOMPATIBLE_PARTITION);
1334                         return 0;
1335                 }
1336
1337                 if (!_emmc_real_erase_partition(g_dl_eMMCStatus.curUserPartitionName)) {
1338                         SEND_ERROR_RSP (BSL_WRITE_ERROR);
1339                         return 0;
1340                 }
1341
1342                 backup_partition_name = _get_backup_partition_name(g_dl_eMMCStatus.curUserPartitionName);
1343
1344                 if(NULL != backup_partition_name)
1345                 {
1346                         if (!_emmc_real_erase_partition(backup_partition_name)) {
1347                                 SEND_ERROR_RSP (BSL_WRITE_ERROR);
1348                                 return 0;
1349                         }
1350                 }
1351
1352                 if (wcscmp(L"sd", g_dl_eMMCStatus.curUserPartitionName) == 0) {
1353                         debugf("formating sd partition, waiting for a while!\n");
1354                         if (_format_sd_partition() == -1){
1355                                 debugf("format sd partition failed\n");
1356                                 SEND_ERROR_RSP (BSL_WRITE_ERROR);
1357                                 return 0;
1358                         }
1359                 }
1360         }
1361
1362         FDL2_eMMC_SendRep (EMMC_SUCCESS);
1363         return 1;
1364 }
1365
1366 PUBLIC int fdl2_repartition(unsigned short* partition_cfg, unsigned short total_partition_num)
1367 {
1368         int i;
1369
1370         _parser_repartition_cfg(partition_cfg, total_partition_num);
1371
1372         if(_fdl2_check_partition_table(s_sprd_emmc_partition_cfg, uefi_part_info, total_partition_num))
1373         {
1374                 debugf("%s:Partition Config same with before!\n",__FUNCTION__);
1375                 FDL2_eMMC_SendRep (EMMC_SUCCESS);
1376                 return 1;
1377         }
1378
1379         for (i = 0; i < 3; i++) {
1380                 write_uefi_partition_table(s_sprd_emmc_partition_cfg);
1381                 if (_fdl2_check_partition_table(s_sprd_emmc_partition_cfg, uefi_part_info, total_partition_num))
1382                         break;
1383         }
1384
1385         if (i < 3) {
1386                 FDL2_eMMC_SendRep (EMMC_SUCCESS);
1387                 return 1;
1388         } else {
1389                 FDL2_eMMC_SendRep (EMMC_SYSTEM_ERROR);
1390                 return 0;
1391         }
1392 }
1393 #endif
1394