blob: 288c5b4be773d1f558ac50321bfd7b2371293a11 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001
2/******************************************************************************
3 *
4 * (C)Copyright 2011 Marvell. All Rights Reserved.
5 *
6 * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MARVELL.
7 * The copyright notice above does not evidence any actual or intended
8 * publication of such source code.
9 * This Module contains Proprietary Information of Marvell and should be
10 * treated as Confidential.
11 * The information in this file is provided for the exclusive use of the
12 * licensees of Marvell.
13 * Such users have the right to use, modify, and incorporate this code into
14 * products for purposes authorized by the license agreement provided they
15 * include this notice and the associated copyright notice with any such
16 * product.
17 * The information in this file is provided "AS IS" without warranty.
18 *
19 *
20 * FILENAME: TIMDownload.c
21 *
22 * PURPOSE: Contains BootLoader's TIM based download code.
23 *
24******************************************************************************/
25
26
27//////////////////////////////////////////////////////////////////////
28// Library Support for the TIMDownload.c
29// Include any shared libraries in the TIMDownload.h file to keep this
30// code clean.
31//////////////////////////////////////////////////////////////////////
32#include "TIMDownload.h"
33#include "obm2osl.h"
34#include "fota.h"
35#include "tim.h"
36#include "ProtocolManager.h"
37
38UINT_T NandID = 0x0; // make sure the nand ID OBM detected is the equals to the nand ID OBM got from SWD
39UINT_T Reset = 1;
40UINT_T Flash_size = 0x01000000; // default 16MB
41extern UINT8_T FlashInitDone;
42extern FOTA_Info FOTAInfo;
43
44extern UINT_T ddr_id_update_with_crc;
45static INT_T DownloadReadBackCRC = IMAGE_READ_BACK_CRC_DISABLED;
46static ImageCRCInfo AllImageCRCInfo __attribute__ ((aligned (4)));
47
48SkipBlocksInfoStruct *pSkipAddress = NULL;
49UINT_T All_FF_flag = 0;
50INT_T AB_DL = 0; //Indicate if AB system download
51
52pTIM pTIM_DTIM = NULL;
53
54Platform_ID Lookup_ChipID(UINT_T chipID)
55{
56 Platform_ID ID = PLAT_UNKNOWN;
57
58 switch (chipID)
59 {
60 //SWD treat below SoCs as 1826 for now
61 case 0x1829:
62 case 0x1901:
63 case 0x1803:
64 case 0x1802:
65 case 0x1806:
66 case 0x1906:
67 case 0x1903:
68 case 0x1826:
69 ID = PLAT_NEZHA3;
70 break;
71 case 0x1822:
72 ID = PLAT_NEZHA2;
73 break;
74 default:
75 break;
76 }
77
78 return ID;
79}
80
81UINT_T PlatformCheckChipID(Platform_ID chip_ID_num)
82{
83 UINT_T ChipID_value;
84 Platform_ID ID_num, ID_numV2;
85
86 ChipID_value = PlatformGetChipID();
87
88 if (chip_ID_num == PLAT_UNKNOWN)
89 return 1;
90
91 ID_num = Lookup_ChipID(ChipID_value & 0xffff);
92
93 if (ID_num == chip_ID_num)
94 return 0;
95 else
96 return 1; // chip ID check fail
97}
98
99UINT32 PlatformGetPlatId(void)
100{
101 UINT_T ChipID_value, PlatId;
102 ChipID_value = PlatformGetChipID();
103
104 PlatId = ChipID_value & 0xFFFF;
105
106 if(ChipID_value == 0x1829)
107 PlatId = 0x1828;
108
109 if(ChipID_value == 0x1802)
110 {
111 if(PlatformCoreIsCR5())
112 PlatId = 0x531802; //1802S
113 else
114 PlatId = 0x4C531802; //1802SL
115 }
116
117
118 return PlatId;
119}
120
121/* return value: 0 : CHIP and OS are both matched, 1: not matched*/
122INT PlatformFBFDevCheckChipOS(PDeviceHeader_11 pDevHeader)
123{
124 UINT32 FFOSTypeInFbf, ChipIDinFbf, FFOSType, ChipIDinDevPara;
125
126 FFOSTypeInFbf = pDevHeader->DeviceParameters[1];
127 ChipIDinFbf = pDevHeader->ChipID;
128
129 //FFOS_Type is not supported yet, old way, only check chip ID
130 if(FFOSTypeInFbf == 0)
131 {
132 return PlatformCheckChipID(ChipIDinFbf);
133 }
134
135 if(PlatformCoreIsCR5())
136 FFOSType = RTOS;
137 else
138 FFOSType = OWRT;
139
140 if(FFOSType != FFOSTypeInFbf){
141 return 1; //OS doesn't match
142 }
143
144 /* ChipID mismatch, return */
145 if(PlatformCheckChipID(ChipIDinFbf)){
146 return 1;
147 }
148
149 /* ChipID in FBF of 1826/1826S/1901/1803/1802SL are all PLAT_NEZHA3,
150 * need to check detail in DeviceParameters[0]
151 */
152 if(ChipIDinFbf == PLAT_NEZHA3)
153 {
154 ChipIDinDevPara = pDevHeader->DeviceParameters[0];
155 if(ChipIDinDevPara == PlatformGetPlatId()){
156 return 0;
157 }
158 else{
159 return 1;
160 }
161 }
162 return 0;
163}
164
165/* return value: 0: CMOD matched, 1: not matched*/
166UINT_T PlatformFBFCheckCMOD(pTIM pTIM_FBF, PDeviceHeader_11 pDevHeader_11)
167{
168 UINT_T imagenum;
169 INT_T temp_p;
170 TIM FlashTim;
171 pTIM pTIM_H_DL;;
172 pTIM pTIM_H_Flash = &FlashTim;
173 PImageStruct_11 pImage_11 = NULL;
174 pCMOD_INFO pCmodDlTim, pCmodFlashTim;
175 UINT_T Retval = NoError;
176 pWTP_RESERVED_AREA_HEADER pWRAH = NULL;
177 INT NoDLTimCMOD = 0;
178 INT NoDLTIM = 0;
179 INT i;
180 UCHAR *TempBuffer = 0;
181
182 TempBuffer = malloc(0x4000);
183
184 if(TempBuffer == NULL)
185 return HeapExhaustedError;
186
187 pTIM_H_DL = pTIM_FBF;
188
189 ReadFlash(0, TempBuffer, 0x4000, BOOT_FLASH); //Read TIM in flash, max tim is 16KB for all platforms
190
191 SetTIMPointers((UINT8_T *)TempBuffer, pTIM_H_Flash);
192
193 if(pTIM_H_DL->pConsTIM->VersionBind.Identifier != TIMIDENTIFIER){
194 //obm_printf("Warning: No valid TIM in FBF\n\r");
195 NoDLTIM = 1;
196 }
197
198 if(NoDLTIM == 0) {
199 pWRAH = FindPackageInReserved(&Retval, pTIM_H_DL, CMODID);
200 if ((pWRAH == NULL) || (Retval != NoError))
201 {
202 //obm_printf("No CMODID in DL TIM\n\r");
203 NoDLTimCMOD = 1;
204 }
205 else
206 {
207 pCmodDlTim = (pCMOD_INFO) pWRAH;
208 }
209 } else {
210 NoDLTimCMOD == 1;
211 }
212
213 /* If CMOD is "ASRCMODFORCEERASE", only erase all only is allowed */
214 if( (NoDLTimCMOD == 0) &&
215 (pCmodDlTim->Length == 17) &&
216 (memcmp(pCmodDlTim->CMOD, "ASRCMODFORCEERASE", 17) == 0))
217 {
218 free(TempBuffer);
219 if(pDevHeader_11->FlashOpt.EraseAll == 2){
220 obm_printf("Magic CMOD to force erase\n\r");
221 return 0;
222 }else{
223 return 1;
224 }
225 }
226
227 if(pTIM_H_Flash->pConsTIM->VersionBind.Identifier != TIMIDENTIFIER){
228 //obm_printf("No valid Flash TIM\n\r");
229 free(TempBuffer);
230 return 0; //Allow to burn any version to an empty board except CMOD is ASRCMODFORCEERASE
231 }
232
233 pWRAH = FindPackageInReserved(&Retval, pTIM_H_Flash, CMODID);
234 if ((pWRAH == NULL) || (Retval != NoError))
235 {
236 //obm_printf("No CMOD in In Flash TIM\n\r");
237 free(TempBuffer);
238 return 0;
239 }
240 else
241 {
242 if(NoDLTimCMOD == 1 || NoDLTIM == 1){
243 //obm_printf("Flash TIM has CMOD, No DL TIM or No CMOD in DL TIM\n\r");
244 free(TempBuffer);
245 return 1;
246 }
247 pCmodFlashTim = (pCMOD_INFO) pWRAH;
248 }
249
250 obm_printf("CMOD in DL TIM: ");
251 for(i =0; i < pCmodDlTim->Length; i++)
252 obm_printf("%c", pCmodDlTim->CMOD[i]);
253 obm_printf("\n\r");
254
255 obm_printf("CMOD in In Flash TIM:");
256 for(i =0; i < pCmodFlashTim->Length; i++)
257 obm_printf("%c", pCmodFlashTim->CMOD[i]);
258 obm_printf("\n\r");
259
260 free(TempBuffer);
261
262 if(pCmodDlTim->Length != pCmodFlashTim->Length)
263 return 1;
264
265 if(memcmp(pCmodDlTim->CMOD, pCmodFlashTim->CMOD, pCmodFlashTim->Length) == 0)
266 return 0;
267 else
268 return 1;
269}
270
271UINT32 PlatformFBFCheckDownload(pTIM pTIM_FBF, PDeviceHeader_11 pDevHeader_11)
272{
273 UINT32 Retval = NoError;
274
275 if(PlatformFBFCheckCMOD(pTIM_FBF, pDevHeader_11))
276 Retval = CMODMISMATCH;
277
278 if(PlatformFBFDevCheckChipOS(pDevHeader_11))
279 Retval = CHIPIDMISMATCH;
280
281 if(Retval != NoError)
282 {
283 ASRFlag_DLStatus_Update(pTIM_FBF, 0, 0);
284
285 FatalError(Retval, "PFCD", NULL);
286 }
287
288 return Retval;
289}
290
291UINT32 PlatformFBFCheckSWDVersion(PDeviceHeader_11 pDevHeader_11)
292{
293 UINT_T LegacySWDNotSupported = 0;
294 UINT32 SWDVerInFBF = pDevHeader_11->DeviceParameters[3];
295
296#if defined(CONFIG_AB_SYSTEM) || (ENABLE_ATRB)
297 /* legacy SWD is the one older than 4.9.1.9
298 * which doesn't support SWD version in FBF
299 */
300 LegacySWDNotSupported = 1;
301#endif
302
303 if(LegacySWDNotSupported && (SWDVerInFBF == 0))
304 {
305 goto swd_out_of_date;
306 }
307
308 if (SWDVerInFBF != 0)
309 {
310 obm_printf("SWDownloader used: %s\n\r", HexToSwdObmVersion(SWDVerInFBF));
311
312 if(SWDVerInFBF < SWD_VERSION) {
313 goto swd_out_of_date;
314 }
315 }
316
317 return NoError;
318
319swd_out_of_date:
320 obm_printf("SWDownloader is out of date\n\r");
321 obm_printf("Please upgrade to %s\n\r", HexToSwdObmVersion(SWD_VERSION));
322 return SWD_OUTOFDATE;
323}
324
325#if ENABLE_ATRB
326/* For Downloading, only check major version anti-rollback */
327UINT_T TIMDownloadAntiRollbackCheck(pTIM pTIM_h)
328{
329 UINT_T Retval = NoError;
330 UINT_T MajorVersionInTIM = 0;
331 UINT_T AntiRollbackTimEnabled;
332 UINT_T AntiRollbackFuseEnabled;
333 INT_T AntiRollbackFuseVersion;
334
335 AntiRollbackTimEnabled = CheckAntiRollbackPackage(pTIM_h, &MajorVersionInTIM);
336 AntiRollbackTimEnabled &= MAJOR_ATRB_ENABLED;
337
338 AntiRollbackFuseEnabled = GEU_MajorAntiRollBackEnabled();
339 if(AntiRollbackFuseEnabled)
340 {
341 /* The chip is already burned to enable anti-rollback */
342 AntiRollbackFuseVersion = GEU_ReadMajorVersion();
343 if(AntiRollbackTimEnabled == 0 || MajorVersionInTIM < AntiRollbackFuseVersion)
344 {
345 obm_printf("Anti-rollback error: %d %d %d\n\r", AntiRollbackTimEnabled,
346 MajorVersionInTIM, AntiRollbackFuseVersion);
347 FatalError(ATRB_MajorRollbackError, "ATRB", 1);
348 return ATRB_MajorRollbackError;
349 }
350
351 if(MajorVersionInTIM > AntiRollbackFuseVersion)
352 {
353 Retval = GEU_ProgramMajorVersion(pTIM_h);
354 if(Retval != NoError)
355 FatalError(Retval, "ATRB", 2);
356 }
357 return Retval;
358 }
359
360 /* The chip is not already burned to enable anti-rollback, burn it here */
361 if(AntiRollbackTimEnabled)
362 {
363 Retval = GEU_ProgramMajorVersion(pTIM_h);
364 if(Retval != NoError)
365 FatalError(Retval, "ATRB", 3);
366 obm_printf("ATRB: burn major version as %d\n\r", MajorVersionInTIM);
367 }
368
369 return Retval;
370}
371#endif
372
373INT_T IsDLImageDTIM(PImageStruct_11 pImage_11)
374{
375#if BURN_DTIM_LAST
376 if (((pImage_11->Image_ID & 0xFFFFFF00) == TIM_TYPE))
377 {
378 switch(pImage_11->Image_In_TIM) {
379 case 0: /* NTIM */
380 case 1: /* TIMH */
381 case 5: /* TIMH recovery */
382 return 0;
383 default: /* differnet DTIMs */
384 return 1;
385 }
386 }
387
388#if defined(CONFIG_ASR_SDTIM) && OUM4DFOTA
389 /* If SDTIM is enabled and OUM is used,
390 * OUM locates in first 10 blocks and has a SDTIM ahead.
391 * Then OUM also needs to be burned after TIMH/OBMI
392 */
393 if (pImage_11->Image_ID == OUMIDENTIFIER)
394 return 1;
395#endif
396
397#endif
398
399 return 0;
400}
401
402static pDtimDlInfo_t DtimDLInfo[MAX_DL_DTIM_NUM];
403static INT_T DtimDLNums = 0;
404
405VOID SaveDTIMs2Memory(PImageStruct_11 pImage_11, UINT_T FbfLoadAddr)
406{
407 pDtimDlInfo_t pDtimDLInfo = NULL;
408
409 pDtimDLInfo = malloc(sizeof(DtimDlInfo_t) + pImage_11->length);
410 if(pDtimDLInfo == NULL)
411 FatalError(HeapExhaustedError, NULL, NULL);
412
413 pDtimDLInfo->Image_ID = pImage_11->Image_ID;
414 pDtimDLInfo->Length = pImage_11->length;
415 pDtimDLInfo->FlashOffsetA = pImage_11->Flash_Start_Address;
416 pDtimDLInfo->FlashOffsetB = pImage_11->Flash_Start_Address_B;
417
418 memcpy(pDtimDLInfo->Buffer, FbfLoadAddr+(pImage_11->First_Sector<<12), pImage_11->length);
419
420 DtimDLInfo[DtimDLNums] = pDtimDLInfo;
421 DtimDLNums ++;
422
423 if (DtimDLNums == MAX_DL_DTIM_NUM)
424 FatalError(TooMuchDlDTims, NULL, NULL);
425}
426
427VOID BurnDTIMs2Flash(VOID)
428{
429 INT_T i;
430 UINT_T Retval = NoError;
431 pDtimDlInfo_t pDtimDLInfo = NULL;
432
433 if (DtimDLNums == 0)
434 return;
435
436 for (i = 0; i < DtimDLNums; i ++)
437 {
438 pDtimDLInfo = DtimDLInfo[i];
439 Retval = WriteFlash(pDtimDLInfo->FlashOffsetA, pDtimDLInfo->Buffer, pDtimDLInfo->Length, BOOT_FLASH);
440 if(Retval == NoError && pDtimDLInfo->FlashOffsetB != 0xFFFFFFFF) {
441 Retval = WriteFlash(pDtimDLInfo->FlashOffsetB, pDtimDLInfo->Buffer, pDtimDLInfo->Length, BOOT_FLASH);
442 }
443 if(Retval)
444 obm_printf("Write %s fails\n\r", ImageID2String(pDtimDLInfo->Image_ID));
445 free(pDtimDLInfo);
446 }
447}
448
449//////////////////////////////////////////////////////////////////////
450// This is the entry point for the TIM based download functionality.
451//
452// Inputs: Pointer to the TIM we just downloaded.
453// Outputs: Returns the next image (OBM) that we will transfer the control to.
454//
455// It mainly functions as following:
456// 1) Sets the TIM pointers.
457// 2) Validates the downloaded TIM.
458// 3) Configures the Flashes.
459// 4) Wipes the whole Flash device.
460// 5) Checks if there is already a FBBT on the Flash. If there is
461// NO FBBT on the Flash, creates it.
462// 6) Checks if there is a PT being downloaded. If so, it first
463// tries to validate it with the existing HW partitions on the
464// Flash. If they don't match, re-creates the HW partitions.
465// If HW partitions are not supported, these functions will do
466// nothing and return. Next, the downloaded PT is loaded into
467// Flash Management (FM).
468// 7) Runtime-BBT is generated.
469// 8) Writes the downloaded TIM, created FBBT, PT to Flash.
470// 9) Download TIM Images LOOP implements the following:
471// i. Download Image
472// ii. Validate Image
473// iii. Set Partition
474// iv. Erase Image Area from Flash
475// v. Write the image to Flash
476// vi. Verify the Flash write
477// 10) The RBBT is written to the Flash.
478//////////////////////////////////////////////////////////////////////
479pIMAGE_INFO_3_4_0 TIMDownloadMain(pFUSE_SET pFuses, pTIM pTIM_h)
480{
481 pIMAGE_INFO_3_4_0 pImageInfo = NULL;
482 UINT_T Retval = NoError;
483 UINT8_T FlashNumber = 0;
484 pWTP_RESERVED_AREA_HEADER pWRAH = NULL;
485 pImage_CRC_Check crcCheck;
486
487 // setup the TIM pointers in pTIM_h
488 Retval = LoadTim((UINT8_T*)pTIM_h->pConsTIM, pTIM_h, TRUE);
489 if (Retval != NoError)
490 {
491 FatalError(Retval, "TDM", 1);
492 }
493
494 #if ENABLE_ATRB
495 Retval = TIMDownloadAntiRollbackCheck(pTIM_h);
496 if (Retval != NoError)
497 {
498 FatalError(Retval, "TDM", 2);
499 }
500 #endif
501
502 Retval = PlatformInitFlash(pTIM_h);
503 if( Retval != NoError)
504 FatalError(Retval, "TDM", 3);
505
506
507#if IMG_RBC
508 pWRAH = FindPackageInReserved(&Retval, pTIM_h, CRCS);
509 if ((pWRAH == NULL) || (Retval != NoError))
510 {
511 DownloadReadBackCRC = IMAGE_READ_BACK_CRC_DISABLED;
512 }
513 else
514 {
515 crcCheck = (pImage_CRC_Check) pWRAH;
516 if(crcCheck->Enabled)
517 DownloadReadBackCRC = IMAGE_READ_BACK_CRC_ENABLED;
518 else
519 DownloadReadBackCRC = IMAGE_READ_BACK_CRC_DISABLED;
520 }
521
522 if(IMAGE_READ_BACK_CRC_ENABLED == DownloadReadBackCRC)
523 obm_printf("Image RB/CRC Enabled\n\r");
524 else
525 obm_printf("Image RB/CRC disabled\n\r");
526#endif
527
528 ASRFlag_DLStatus_Update(pTIM_h, DLFLG, 0);
529
530 obm_printf("Download...\n\r");
531
532 // At this point, we can start downloading images one by one.
533 // IMPORTANT: For now, we download all the images to their load address that is
534 // specified in the TIM. We assume that the images will not overwrite the existing
535 // DKB code that is already running.
536 //
537 // KDA TO DO:
538 // Potentially, we might want to download all the images to a specific
539 // DOWNLOAD_AREAD in the DDR.
540 pImageInfo = DownloadTIMImages(pFuses, pTIM_h);
541
542 return pImageInfo;
543}
544
545UINT_T ValidateTIMInFBF(UINT_T address, PImageStruct_11 pTIM_Image, TIMIncluded_Type type, UINT_T verify_aux)
546{
547 pTIM pTIM_h = NULL;
548#if TRUSTED && SECURE_DOWNLOAD
549 pTIM pTIM_h_boot = NULL;
550#endif
551 UINT_T Retval = NoError;
552
553 if (type == TIMH_NOTINC)
554 return NoError;
555 else
556 pTIM_h = (pTIM_DTIM + type);
557
558 Retval = SetTIMPointers((UINT8_T *)(address + (pTIM_Image->First_Sector << 12)), pTIM_h);
559 if (Retval != NoError)
560 return 1;
561
562#if TRUSTED && SECURE_DOWNLOAD
563 if (verify_aux) {
564 switch(type) {
565 case DTIM_PRIMARY_INC:
566 case DTIM_RECOVERY_INC:
567 pTIM_h_boot = GetBootTIMH();
568 if (pTIM_h_boot == NULL)
569 return 4;
570 Retval = ValiateDTIM(pTIM_h, pTIM_h_boot);
571 if (Retval!= NoError)
572 return 5;
573 return NoError;
574 break;
575 case TIMH_RECOVERY_INC:
576 case TIMH_INC:
577 Retval = VerifyPlatformKey(pTIM_h);
578 if (Retval != NoError)
579 return 3;
580 break;
581 default:
582 break;
583 }
584 }
585#endif
586
587 if (pTIM_h->pConsTIM->VersionBind.Trusted)
588 {
589 Retval = ValidateTIMSignature(pTIM_h); // validate TIMH
590 if (Retval != NoError)
591 return 2;
592 }
593
594 return Retval;
595}
596
597UINT_T ValidateImageInTIM(UINT_T address, PImageStruct_11 pImage, pTIM pTIM_h)
598{
599 UINT_T Retval = NoError;
600 UINT_T ImageAddr;
601#ifdef CONFIG_ASR_SDTIM
602 pIMAGE_INFO_3_4_0 pSDtimImageInfo = NULL;
603 pTIM pSDTim_h = NULL;
604#endif
605 pIMAGE_INFO_3_4_0 pImageInfo = NULL;
606 pTIM pTIM_V = NULL;
607 UINT8_T *ImageBuff = NULL;
608 UINT_T ImageType;
609 UINT_T DecompressLen = 0;
610
611#if XZ_SUPPORT || XZDEC_SUPPORT
612 VOID *nextInBuf = NULL;
613 INT_T compressed = 0;
614#endif
615
616
617 if ((pTIM_h != NULL) && (pImage->Image_In_TIM != TIMH_NOTINC))
618 {
619 if ((pImage->Image_ID & 0xFFFFFF00) != TIM_TYPE) // this is not TIMx in FBF file
620 {
621 if (pTIM_h->pConsTIM->VersionBind.Trusted)
622 {
623 ImageAddr = address + (pImage->First_Sector << 12);
624 #ifdef CONFIG_ASR_SDTIM
625 pImageInfo = FindImageInTIM(pTIM_h, pImage->Image_ID);
626 if(pImageInfo == NULL)
627 return Retval;
628
629 if(ImageIsSDTIMIncluded(pImageInfo)) {
630 pSDTim_h = malloc(sizeof(TIM));
631 if(pSDTim_h == NULL)
632 return HeapExhaustedError;
633
634 Retval = SetTIMPointers(ImageAddr, pSDTim_h);
635 if(Retval)
636 return TIMNotFound;
637
638 pSDtimImageInfo = FindImageInTIM(pSDTim_h, SDTIM);
639 if(pSDtimImageInfo == NULL) {
640 free(pSDTim_h);
641 return Retval;
642 }
643
644 if (0 == GetSDTimSecureConfig(pSDtimImageInfo))
645 goto exit;
646 ImageAddr += GetSDTimSpaceSize(pSDtimImageInfo);
647 pTIM_V = pSDTim_h;
648
649 } else
650 #endif
651 {
652 pTIM_V = pTIM_h;
653 }
654
655 #if LZMA_SUPPORT
656 ImageType = IMAGE_TYPE(pImage->commands);
657 if (DLCMD_IMG_LZMA_IMAGE_TYPE == ImageType) {
658 pImageInfo = FindImageInTIM(pTIM_V, pImage->Image_ID);
659 if (pImageInfo == NULL)
660 {
661 Retval = ImageNotFound;
662 goto exit;
663 }
664 DecompressLen = pImageInfo->ImageSizeToHash;
665 ImageBuff = malloc(DecompressLen);
666 if(ImageBuff == NULL) {
667 Retval = HeapExhaustedError;
668 goto exit;
669 }
670 Retval = LZMA_Decompress(ImageBuff,
671 &DecompressLen,
672 ImageAddr,
673 pImage->length,
674 0x0);
675 if(Retval != NoError) {
676 obm_printf("LZMA Decompress error\n\r");
677 goto exit;
678 }
679 ImageAddr = ImageBuff;
680 }
681 #endif
682
683 #if XZ_SUPPORT || XZDEC_SUPPORT
684 ImageType = IMAGE_TYPE(pImage->commands);
685 if (DLCMD_IMG_MXZ_IMAGE_TYPE == ImageType) {
686 pImageInfo = FindImageInTIM(pTIM_V, pImage->Image_ID);
687 if (pImageInfo == NULL)
688 {
689 Retval = ImageNotFound;
690 goto exit;
691 }
692 ImageBuff = malloc(pImageInfo->ImageSizeToHash);
693 if(ImageBuff == NULL) {
694 Retval = HeapExhaustedError;
695 goto exit;
696 }
697 DecompressLen = pImageInfo->ImageSizeToHash;
698 Retval = xz_decompress(ImageAddr, pImage->length, ImageBuff, &DecompressLen, &nextInBuf, &compressed);
699 if(Retval) {
700 Retval = XZDecodeError;
701 goto exit;
702 }
703 ImageAddr = ImageBuff;
704 }
705 #endif
706
707 Retval = ValidateImage(ImageAddr, pImage->Image_ID, pTIM_V);
708 if (Retval != NoError)
709 FatalError(Retval, "VIIT", NULL);
710
711 return Retval;
712 }
713 }
714 }
715
716exit:
717
718#ifdef CONFIG_ASR_SDTIM
719 if(pSDTim_h) free(pSDTim_h);
720#endif
721
722 return Retval;
723}
724
725UINT_T DLEraseFlashToBurnImage(PImageStruct_11 pImage_11)
726{
727 UINT_T Retval = NoError;
728 P_FOTA_Info pFOTAInfo = &FOTAInfo;
729
730#if MMC_CODE
731 if (((pImage_11->commands & 0xF) == 2) || //erase only for eMMC, NAND needs to erase before writing
732 (pImage_11->Flash_erase_size > pImage_11->length) // erase eMMC if user set erase size in blf
733 )
734#endif
735 {
736 Retval = EraseFlash(pImage_11->Flash_Start_Address, pImage_11->Flash_erase_size, BOOT_FLASH );
737 if(AB_DL && (pImage_11->Flash_Start_Address_B != 0xFFFFFFFF))
738 Retval |= EraseFlash(pImage_11->Flash_Start_Address_B, pImage_11->Flash_erase_size, BOOT_FLASH );
739 }
740
741 if(Retval != NoError )
742 FatalError(Retval, "DLEF", NULL);
743
744 if(pFOTAInfo->FOTA_Addr >= pImage_11->Flash_Start_Address &&
745 (pFOTAInfo->FOTA_Addr+sizeof(FOTA_Firmware)) <= (pImage_11->Flash_Start_Address+pImage_11->Flash_erase_size))
746 {
747 //Force ASR flag re-init later.
748 pFOTAInfo->InitFlag = 0;
749 }
750
751 if(AB_DL && (pFOTAInfo->FOTA_Addr >= pImage_11->Flash_Start_Address_B) &&
752 (pFOTAInfo->FOTA_Addr+sizeof(FOTA_Firmware)) <= (pImage_11->Flash_Start_Address_B+pImage_11->Flash_erase_size))
753 {
754 //Force ASR flag re-init later.
755 pFOTAInfo->InitFlag = 0;
756 }
757
758 return Retval;
759}
760
761UINT_T DLBurnImageToFlash(PImageStruct_11 pImage_11, UINT_T loadAddr)
762{
763 UINT_T Retval = NoError;
764 UINT_T imageType = DLCMD_RAW_BINARY_IMAGE_TYPE;
765#if NZAS
766 P_FlashProperties_T pFlashP = GetFlashProperties(BOOT_FLASH);
767 UINT_T Temp1 = 0, Temp2 = 0, Len1, Len2;
768#endif
769
770#if DUAL_TIM
771 UINT8_T *TmpBuf = NULL;
772 pIMAGE_INFO_3_4_0 pTimInfo = NULL;
773 pIMAGE_INFO_3_4_0 pObmInfo = NULL;
774 UINT_T TimOBMLen = 0;
775 pTIM pTIM_h;
776#endif
777
778 imageType = IMAGE_TYPE(pImage_11->commands);
779 #if NAND_CODE
780 if ( imageType == DLCMD_YAFFS_IMAGE_TYPE)
781 {
782 SetUseSpareArea( TRUE, BOOT_FLASH );
783 All_FF_flag = 1;
784 }
785 else if(imageType == DLCMD_UBIFS_IMAGE_TYPE)
786 {
787 SetUseSpareArea( FALSE, BOOT_FLASH);
788 All_FF_flag = 1;
789 }
790 else
791 {
792 SetUseSpareArea( FALSE, BOOT_FLASH );
793 All_FF_flag = 0;
794 }
795 #endif
796
797 #if MMC_CODE
798 if (imageType == DLCMD_SPARSE_IMAGE_TYPE)
799 {
800 Retval = HandleSparseImage(loadAddr+(pImage_11->First_Sector<<12),
801 pImage_11->Flash_Start_Address,
802 pImage_11->length,
803 BOOT_FLASH);
804 }
805 else
806 #endif
807 { /* not MMC_CODE */
808#if NZAC
809 //To workaroud the issue that 1802SL BootROM miss a word when OBM size is bigger than 0x1df88 in SPI-NOR
810 if(PlatformIsNezhac() && (pImage_11->Image_ID == OBMIDENTIFIER) && (pFlashP->FlashType == SPI_FLASH)
811 && (pImage_11->length > 0x1df88))
812 {
813 Temp1 = loadAddr+(pImage_11->First_Sector<<12);
814 Temp2 = malloc(256*1024);
815 if(Temp2 == NULL)
816 return HeapExhaustedError;
817 Len1 = Len2 = pImage_11->length;
818 while(Len1)
819 {
820 memcpy((void *)Temp2, (void *)Temp1, 0x1df88);
821 Temp1 += 0x1df88;
822 Temp2 += 0x1df88;
823 *(UINT_T *)Temp2 = 0xdeadbeef;//This word will not be read by BootROM
824 Temp2 += 4;
825 Len2 += 4;
826 Len1 -= 0x1df88;
827 if(Len1 <= 0x1df88){
828 memcpy((void *)Temp2, (void *)Temp1, Len1);
829 break;
830 }
831 }
832 Retval = WriteFlash( pImage_11->Flash_Start_Address,
833 Temp2,
834 Len2, BOOT_FLASH );
835 free(Temp2);
836 goto read_back_check;
837 }
838#endif /* NZAS */
839
840 #if DUAL_TIM
841 if((pImage_11->Image_ID == OBMIDENTIFIER) && DualTimEnabled() && !DualTimIsEqual())
842 {
843 pTIM_h = pTIM_DTIM + TIMH_INC; /* main TIMH */
844 if(pTIM_h->pConsTIM->VersionBind.Identifier != TIMIDENTIFIER)
845 FatalError(TIMNotFound, "DLB", 1);
846 pTimInfo = FindImageInTIM(pTIM_h, TIMIDENTIFIER);
847 pObmInfo = FindImageInTIM(pTIM_h, OBMIDENTIFIER);
848 if(pTimInfo == NULL || pObmInfo == NULL)
849 FatalError(ImageNotFound, "DLB", 2);
850 TimOBMLen = pImage_11->length + pTimInfo->ImageSize;
851#if MMC_CODE
852 if(TimOBMLen > MAX_OBM_SIZE)
853#else
854 if(TimOBMLen > GetFlashProperties(BOOT_FLASH)->BlockSize)
855#endif
856 obm_printf("Warning :OBM may be too big for Dual-TIM\n\r");
857
858 TmpBuf = malloc(TimOBMLen);
859 if(TmpBuf == NULL)
860 return HeapExhaustedError;
861
862 memset(TmpBuf, 0, TimOBMLen);
863 memcpy(TmpBuf, loadAddr+(pImage_11->First_Sector<<12), pImage_11->length);
864#if MMC_CODE
865 if (pImage_11->Flash_partition == MMC_SD_BOOT_PARTITION) {
866#else
867 if (pObmInfo->FlashEntryAddr == pImage_11->Flash_Start_Address) {
868#endif
869 pTIM_h = pTIM_DTIM + TIMH_RECOVERY_INC;
870 memcpy(TmpBuf+pImage_11->length, pTIM_h->pConsTIM, pTimInfo->ImageSize);
871 }
872 else {
873 memcpy(TmpBuf+pImage_11->length, pTIM_h->pConsTIM, pTimInfo->ImageSize);
874 }
875 Retval = WriteFlash( pImage_11->Flash_Start_Address,
876 TmpBuf,
877 TimOBMLen, BOOT_FLASH);
878 free(TmpBuf);
879 } else if(pImage_11->Image_ID == TIMIDENTIFIER &&
880 pImage_11->Image_In_TIM == TIMH_RECOVERY_INC &&
881 DualTimIsEqual())
882 {
883 pTIM_h = pTIM_DTIM + TIMH_INC; /* main TIMH */
884 Retval = WriteFlash( pImage_11->Flash_Start_Address,
885 pTIM_h->pConsTIM,
886 pImage_11->length, BOOT_FLASH);
887 }else
888 #endif
889 {
890 Retval = WriteFlash( pImage_11->Flash_Start_Address,
891 loadAddr+(pImage_11->First_Sector<<12),
892 pImage_11->length, BOOT_FLASH);
893
894
895 if(AB_DL && (pImage_11->Flash_Start_Address_B != 0xFFFFFFFF)) {
896 Retval |= WriteFlash( pImage_11->Flash_Start_Address_B,
897 loadAddr+(pImage_11->First_Sector<<12),
898 pImage_11->length, BOOT_FLASH);
899 }
900 }
901
902read_back_check:
903#if IMG_RBC
904 if(Retval == NoError && DownloadReadBackCRC == IMAGE_READ_BACK_CRC_ENABLED)
905 {
906 Retval = ImageReadBackAndCRC(pImage_11);
907 }
908#else
909 ; //do nothing, avoid "label at end of compound statement" error
910#endif
911 } /* not MMC_CODE */
912
913 return Retval;
914}
915
916//////////////////////////////////////////////////////////////////////
917// This is the actual image downloading function for the TIM based
918// download mode.
919//
920// Inputs: TIM which includes a list of all the images that will be
921// downloaded.
922// Outputs: Returns the OBM image to whom we will trasfer control to.
923//
924// It mainly iterates through all the images listed in the TIM and
925// 1) If NOT TIM, downloads the image.
926// 2) Validates the image.
927// 3) Calls the Erase and Write function for this image.
928// 4) Finally, finds the OBM image in the TIM and returns it.
929//////////////////////////////////////////////////////////////////////
930pIMAGE_INFO_3_4_0 DownloadTIMImages (pFUSE_SET pFuses, pTIM pTIM_h)
931{
932 UINT_T Retval = NoError;
933 UINT_T ImageSize;
934 pIMAGE_INFO_3_4_0 pImageInfo = NULL, pNextImageInfo = NULL;
935 UINT_T NumImages;
936 UINT_T loadAddr = 0;
937 UINT_T OKtoErase = 1;
938 MasterBlockHeader* pMasterHeader = NULL;
939 PDeviceHeader_11 pDevHeader_11=NULL;
940 PImageStruct_11 pImage_11 = NULL;
941 UINT_T imagenum, i, skip_blocks;
942 UINT_T temp_p = NULL;
943 UINT_T NandID_Right;
944 UINT_T OBMFlashAddr;
945 P_FOTA_Info pFOTAInfo = &FOTAInfo;
946 INT_T TIMHLoaded = 0;
947 CHAR MVersionStr[128];
948 CHAR *PStr = NULL;
949 INT_T MVersionInFbf = 0;
950 P_FOTA_Firmware pFOTA_T = NULL;
951
952 // Depending on the version of the TIM, determine the size of each image in bytes.
953 // We will use this size to iterate through the TIM binary from image to image.
954 if (pTIM_h->pConsTIM->VersionBind.Version >= TIM_3_4_00)
955 ImageSize = sizeof(IMAGE_INFO_3_4_0);
956 else
957 ImageSize = sizeof(IMAGE_INFO_3_2_0);
958
959 // This is the very initial TIM image! Assumes that the TIM image is located at the top of the
960 // TIM file. Otherwise, we would skip images.
961 NumImages = pTIM_h->pConsTIM->NumImages;
962 pImageInfo = (IMAGE_INFO_3_4_0*)((unsigned char*)pTIM_h->pImg + (NumImages-1)*ImageSize); // index to last image info record.
963
964 // For each image, download, validate and copy
965 while (NumImages && (Retval == NoError))
966 {
967 if (NumImages > 1)
968 {
969 loadAddr = malloc(pImageInfo->ImageSize + 0x20000);
970 if(loadAddr == 0)
971 return HeapExhaustedError;
972 Retval = PM_ReceiveImage(NULL, loadAddr, pImageInfo->ImageSize, pImageInfo->ImageID);
973 if(Retval == UnknownImageError)
974 {
975 Retval = NoError;
976 goto nextimage;
977 }
978 if (Retval != NoError)
979 FatalError(Retval, "DTI", 1);
980 }
981 else loadAddr = (UINT_T)(pTIM_h->pConsTIM); // first image, TIM. use the address provided by caller.
982
983 #if COPYIMAGESTOFLASH
984 if(pImageInfo->FlashEntryAddr == 0xFFFFFFFF)
985 goto nextimage;
986 // Copy the Image
987 AddMessageError(REPORT_NOTIFICATION, PlatformBusy);
988
989 if ((pImageInfo->ImageID & 0xFFFFFF00) == FBFIDENTIFIER0)
990 {
991 Retval = PlatfromFBFBoundaryScan(pImageInfo);
992 if (Retval != NoError)
993 FatalError(Retval, "DTI", 2);
994
995 pMasterHeader = (MasterBlockHeader*)loadAddr;
996
997 if ((pMasterHeader->Format_Version != 11))
998 FatalError(FBF_VersionNotMatch, "DTI", 3);
999
1000 if (pMasterHeader->nOfDevices != 1)
1001 FatalError(FBF_DeviceMoreThanOne, "DTI", 4);
1002
1003 temp_p = pMasterHeader->deviceHeaderOffset[0] + loadAddr;
1004 pDevHeader_11 = (PDeviceHeader_11)temp_p;
1005 AB_DL = pDevHeader_11->DeviceParameters[2];
1006 if(AB_DL)
1007 obm_printf("AB system Downloading\n\r");
1008
1009 Retval = PlatformFBFCheckSWDVersion(pDevHeader_11);
1010 if(Retval != NoError)
1011 FatalError(Retval, "DTI", 5);
1012
1013 // check nand ID
1014 #if NAND_CODE
1015 NandID_Right = pDevHeader_11->FlashOpt.NandID;
1016 obm_printf("NandID: 0x%x\n\r", NandID);
1017 if (NandID_Right != 0xFFFF && NandID != NandID_Right)
1018 {
1019 #if (!NEZHA701)
1020 FatalError(NANDIDDISMATCH, "DTI", 6);
1021 #endif
1022 }
1023
1024 for ( imagenum = 0; imagenum < pDevHeader_11->nOfImages; imagenum++ )
1025 {
1026 temp_p = (UINT_T)&pDevHeader_11->imageStruct_11[imagenum];
1027 pImage_11 = (PImageStruct_11)temp_p;
1028
1029 if(pImage_11->Image_ID == OBMIDENTIFIER) //OBMI
1030 {
1031 OBMFlashAddr = pImage_11->Flash_Start_Address;
1032 //To word around the issue that BootROM disable sprare area
1033 DisableSpareAreaForOBM(pImage_11->Flash_Start_Address, pImage_11->length);
1034 }
1035 }
1036 #endif
1037
1038 #if SPINOR_CODE
1039 AddMessageError(REPORT_FLASH_SIZE_NOTIFICATION, Flash_size);
1040 #endif
1041
1042 // skip blocks
1043 skip_blocks = pDevHeader_11->FlashOpt.Skip_Blocks_Struct.Total_Number_Of_SkipBlocks;
1044 if (skip_blocks > 0)
1045 pSkipAddress = &pDevHeader_11->FlashOpt.Skip_Blocks_Struct;
1046 else
1047 pSkipAddress = NULL;
1048
1049// productMode = pDevHeader_11->ProductMode;
1050 Reset = pDevHeader_11->OptValue;
1051
1052 /* Check if FBF package is right for this platform */
1053 PlatformFBFCheckDownload(pTIM_h, pDevHeader_11);
1054
1055 pTIM_DTIM = (TIM *)malloc(DTIM_CUSTMOZIED_MAX*sizeof(TIM));
1056 if ( pTIM_DTIM == NULL )
1057 return HeapExhaustedError;
1058
1059 memset(pTIM_DTIM, 0, DTIM_CUSTMOZIED_MAX*sizeof(TIM));
1060 // find out all TIMH and DTIM for secured download)
1061 for (imagenum = 0; imagenum < pDevHeader_11->nOfImages; imagenum++)
1062 {
1063 temp_p = (UINT_T)&pDevHeader_11->imageStruct_11[imagenum];
1064 pImage_11= (PImageStruct_11)temp_p;
1065
1066 if (!ImageIsTIM(pImage_11->Image_ID))
1067 continue;
1068
1069 switch (pImage_11->Image_In_TIM)
1070 {
1071 case TIMH_NOTINC: /* NTIM */
1072 break;
1073 case TIMH_INC: /* TIMH */
1074 TIMHLoaded = 1;
1075 case TIMH_RECOVERY_INC: /* backup TIMH */
1076 default: /* Other TIMs */
1077 Retval = ValidateTIMInFBF(loadAddr, pImage_11, pImage_11->Image_In_TIM, pFuses->bits.SBE);
1078 if (Retval != NoError) {
1079 ASRFlag_DLStatus_Update(pTIM_h, 0, 0);
1080 FatalError(InvalidTIMImageError, "VTIF", Retval);
1081 }
1082 break;
1083 }
1084 }
1085
1086 if (OKtoErase)
1087 {
1088 if (pDevHeader_11->FlashOpt.EraseAll == 2) // erase all flash partition without burning
1089 {
1090 #if PRODUCT_BUILD
1091 if (pFuses->bits.SBE == 1) {
1092 ASRFlag_DLStatus_Update(pTIM_h, 0, 0);
1093 FatalError(NotSupportedError, "DTI", 12);
1094 }
1095 #endif
1096
1097 AddMessageError(REPORT_NOTIFICATION, PlatformEraseAllFlashWithoutBurn); // notify SWD
1098
1099 Retval = EraseAllFlashWithoutBurn(BOOT_FLASH);
1100 if (Retval != NoError)
1101 {
1102 FatalError(Retval, "DTI", 7);
1103 }
1104
1105 //Force ASR flag re-init later.
1106 pFOTAInfo->InitFlag = 0;
1107
1108 AddMessageError(REPORT_NOTIFICATION, PlatformEraseAllFlashWithoutBurnDone); // notify SWD
1109 AddMessageError(REPORT_NOTIFICATION, PlatformReady);
1110
1111 break;
1112 }
1113
1114 // check erase all flag
1115 if (pDevHeader_11->FlashOpt.EraseAll == 1) // erase user partition with burning
1116 {
1117 // check reset BBT flag
1118 if (pDevHeader_11->FlashOpt.ResetBBT)
1119 {
1120 AddMessageError(REPORT_NOTIFICATION, PlatformResetBBT); // notify SWD that OBM/flasher will reset BBT
1121 ResetBBT();
1122 //After BBT is reset, OBM start address need to be updated, too.
1123 #if NAND_CODE //To word around the issue that BootROM disable sprare area
1124 DisableSpareAreaForOBM(OBMFlashAddr, 0);
1125 #endif
1126 }
1127
1128 AddMessageError(REPORT_NOTIFICATION, PlatformEraseAllFlash); // notify SWD that OBM/flasher will erase all flash
1129 Retval = EraseAllFlash(BOOT_FLASH);
1130 if (Retval != NoError)
1131 {
1132 FatalError(Retval, "DTI", 8);
1133 }
1134
1135 //Force ASR flag re-init later.
1136 pFOTAInfo->InitFlag = 0;
1137
1138 OKtoErase = 0;
1139 AddMessageError(REPORT_NOTIFICATION, PlatformEraseAllFlashDone); // notify SWD that OBM/flasher erases all flash done
1140 }
1141 }
1142
1143 for ( imagenum = 0; imagenum < pDevHeader_11->nOfImages; imagenum++ )
1144 {
1145 temp_p = (UINT_T)&pDevHeader_11->imageStruct_11[imagenum];
1146 pImage_11 = (PImageStruct_11)temp_p;
1147
1148 #if TRUSTED && SECURE_DOWNLOAD
1149 if (pFuses->bits.SBE)
1150 {
1151 switch (pImage_11->Image_In_TIM)
1152 {
1153 case TIMH_NOTINC:
1154 break;
1155 default:
1156 ValidateImageInTIM(loadAddr, pImage_11, (pTIM_DTIM + pImage_11->Image_In_TIM));
1157 break;
1158 }
1159 }
1160 #endif
1161
1162 if(pImage_11->Image_ID == FOTA_FBFVERSION_IMAGEID)
1163 {
1164 memset(MVersionStr, 0, 128);
1165 PStr = (CHAR *)( loadAddr + (pImage_11->First_Sector << 12) );
1166 if(strcmpl(PStr, "OTA0", 4) == 0) {
1167 PStr += 4;
1168 for( i = 0; i < 128 && *PStr != ';'; i++)
1169 MVersionStr[i] = *PStr++;
1170
1171 if(i < 128) {
1172 MVersionInFbf = 1;
1173 obm_printf("Download to: %s\n\r", MVersionStr);
1174 }
1175 }
1176 continue;
1177 }
1178
1179 #if MMC_CODE
1180 if((pTIM_h->pConsTIM->VersionBind.Version) >= TIM_3_2_00)
1181 {
1182 Retval = SetPartition(pImage_11->Flash_partition, BOOT_FLASH);
1183 if (Retval != NoError)
1184 {
1185 FatalError(Retval, "DTI", 9);
1186 }
1187 }
1188 #endif
1189
1190 if(OKtoErase && (pImage_11->commands & DLCMD_DO_ERASE_BLOCKS) )
1191 {
1192 Retval = DLEraseFlashToBurnImage(pImage_11);
1193 }
1194
1195 //if ((pImage_11->commands & 0xF) == 2) //erase only
1196 // continue;
1197
1198 if(pImage_11->commands & DLCMD_DO_VERIFY_WRITE) {
1199 if (!IsDLImageDTIM(pImage_11)) {
1200 Retval = DLBurnImageToFlash(pImage_11, loadAddr);
1201 if(Retval != NoError )
1202 FatalError(Retval, "DTI", 10);
1203
1204 AddMessageError(REPORT_BURNT_IMAGE_LENGTH, pImage_11->length); // report burnt image length
1205 }
1206 #if BURN_DTIM_LAST
1207 else{
1208 SaveDTIMs2Memory(pImage_11, loadAddr);
1209 }
1210 #endif
1211 }
1212 }
1213
1214 #if IMG_RBC
1215 if(DownloadReadBackCRC == IMAGE_READ_BACK_CRC_ENABLED){
1216 DownloadReadBackCRC = IMAGE_READ_BACK_CRC_DONE;
1217 AllImageCRCInfo.MCPID = ((NandID & 0xFF) << 16) | (ddr_id_update_with_crc & 0xFF);
1218 }
1219 #endif
1220
1221 if (TIMHLoaded) { /* TIMH is loaded and parsed in pTIM_DTIM */
1222 Retval = ProvisionPlatform(pFuses, pTIM_DTIM + TIMH_INC);
1223 // If ProvisionPlatform() returned an error, this means that an error occurred
1224 // during fuse burning. So stop booting and go to Fatal Error.
1225 if (Retval != NoError)
1226 {
1227 FatalError(Retval, "DTI", 11);
1228 }
1229 TIMHLoaded = 0;
1230 }
1231 } /* FBF */
1232
1233 pNextImageInfo = (IMAGE_INFO_3_4_0*)((unsigned char*)pImageInfo - ImageSize);
1234
1235 /* Last FBF is handled, update DL flag as DLDONE */
1236 if (NumImages == 2 /* FBF0(current) and TIMH, */
1237 && pNextImageInfo->ImageID == TIMIDENTIFIER) {
1238
1239 #if BURN_DTIM_LAST
1240 BurnDTIMs2Flash();
1241 #endif
1242
1243 if(MVersionInFbf == 1) {
1244 pFOTA_T = OTAGetConfig(pTIM_h);
1245 memset(pFOTA_T->MVersion, 0, sizeof(pFOTA_T->MVersion));
1246 memcpy(pFOTA_T->MVersion, MVersionStr, strlen(MVersionStr));
1247#ifdef CONFIG_AB_SYSTEM
1248 memset(pFOTA_T->MVersion_B, 0, sizeof(pFOTA_T->MVersion_B));
1249 memcpy(pFOTA_T->MVersion_B, MVersionStr, strlen(MVersionStr));
1250#endif
1251 }
1252 ASRFlag_DLStatus_Update(pTIM_h, DLFLG, DLDONE);
1253 free(pTIM_DTIM);
1254
1255 UpdateBBT();
1256
1257 }
1258
1259 AddMessageError(REPORT_NOTIFICATION, PlatformReady);
1260 #endif /* end of COPYIMAGESTOFLASH */
1261
1262nextimage:
1263 NumImages--;
1264 pImageInfo = (IMAGE_INFO_3_4_0*)((unsigned char*)pImageInfo - ImageSize); // index to previous image info record.
1265 if(NumImages != 0)
1266 free(loadAddr);
1267 loadAddr = 0;
1268 } // end WHILE
1269
1270 #if NAND_CODE
1271 SetUseSpareArea( FALSE, BOOT_FLASH );
1272 #endif
1273 UpdateBBT();
1274
1275 #if SPINOR_CODE
1276 SPINOR_Disable4BytesMode();
1277 #endif
1278
1279 return NULL;
1280}
1281
1282INT_T ImageReadBackAndCRC(PImageStruct_11 pImage_11)
1283{
1284 UINT_T * Buffer = NULL;
1285 INT_T Retval = NoError;
1286 UINT_T Len = 0;
1287
1288#if NZAC
1289 UINT_T Temp1 = 0, Temp2 = 0;
1290 P_FlashProperties_T pFlashP = GetFlashProperties(BOOT_FLASH);
1291#endif
1292
1293 if(DownloadReadBackCRC != IMAGE_READ_BACK_CRC_ENABLED){
1294 return NotSupportedError;
1295 }
1296
1297 if(AllImageCRCInfo.ImageNum >= CRC_MAX_IMAGE_NUM)
1298 {
1299 obm_printf("No more CRC buffer for 0x%08x\n\r", pImage_11->Image_ID);
1300 return NotSupportedError;
1301 }
1302
1303 if(DTIM_PPSETTING == pImage_11->Image_ID)
1304 {
1305 AllImageCRCInfo.ImageCRC[AllImageCRCInfo.ImageNum].ImageID = pImage_11->Image_ID;
1306 //CRC of DTim.PPsetting
1307 AllImageCRCInfo.ImageCRC[AllImageCRCInfo.ImageNum].CRC32 = 0xc3751676;
1308 AllImageCRCInfo.ImageNum++;
1309 return Retval;
1310 }
1311
1312 Len = pImage_11->length;
1313
1314#if NZAC
1315 if(PlatformIsNezhac() && (pImage_11->Image_ID == OBMIDENTIFIER) && (pFlashP->FlashType == SPI_FLASH)
1316 && (pImage_11->length > 0x1df88))
1317 Len += (pImage_11->length/0x1df88)*4;
1318#endif
1319
1320 Buffer = malloc(Len);
1321 if(Buffer == NULL)
1322 return HeapExhaustedError;
1323
1324 Retval = ReadFlash( pImage_11->Flash_Start_Address, Buffer, Len, BOOT_FLASH);
1325
1326 if(Retval != NoError){
1327 DownloadReadBackCRC = IMAGE_READ_BACK_CRC_FAIL;
1328 free(Buffer);
1329 return Retval;
1330 }
1331
1332#if NZAC
1333 //To workaroud the issue that 1802SL BootROM miss a word when OBM size is bigger than 0x1df88 in SPI-NOR
1334 if(PlatformIsNezhac() && (pImage_11->Image_ID == OBMIDENTIFIER) && (pFlashP->FlashType == SPI_FLASH)
1335 && (pImage_11->length > 0x1df88))
1336 {
1337 Len = pImage_11->length;
1338 Temp1 = Buffer;
1339 Temp2 = malloc(256*1024);
1340 if(Temp2 == NULL)
1341 return HeapExhaustedError;
1342
1343 while(Len)
1344 {
1345 memcpy((void *)Temp2, (void *)Temp1, 0x1df88);
1346 Temp1 += 0x1df88;
1347 Temp2 += 0x1df88;
1348 Temp1 += 4; //Ignore the extra word added to workaourd BootROM SPINOR read issue
1349 Len -= 0x1df88;
1350 if(Len <= 0x1df88){
1351 memcpy((void *)Temp2, (void *)Temp1, Len);
1352 break;
1353 }
1354 }
1355 Buffer = Temp2;
1356 }
1357#endif
1358
1359 AllImageCRCInfo.ImageCRC[AllImageCRCInfo.ImageNum].ImageID = pImage_11->Image_ID;
1360 AllImageCRCInfo.ImageCRC[AllImageCRCInfo.ImageNum].CRC32 = CalcCRC32(Buffer, pImage_11->length, 0xFFFFFFFF);
1361 AllImageCRCInfo.ImageNum++;
1362
1363 if(AB_DL && (pImage_11->Flash_Start_Address_B != 0xFFFFFFFF))
1364 {
1365 Retval = ReadFlash( pImage_11->Flash_Start_Address_B, Buffer, Len, BOOT_FLASH);
1366
1367 if(Retval != NoError){
1368 DownloadReadBackCRC = IMAGE_READ_BACK_CRC_FAIL;
1369 #if NZAC
1370 if(Temp2) free(Temp2);
1371 #endif
1372 free(Buffer);
1373 return Retval;
1374 }
1375 AllImageCRCInfo.ImageCRC[AllImageCRCInfo.ImageNum].ImageID = pImage_11->Image_ID;
1376 AllImageCRCInfo.ImageCRC[AllImageCRCInfo.ImageNum].CRC32 = CalcCRC32(Buffer, pImage_11->length, 0xFFFFFFFF);
1377 AllImageCRCInfo.ImageNum++;
1378 }
1379
1380#if NZAC
1381 if(Temp2) free(Temp2);
1382#endif
1383
1384 free(Buffer);
1385 return Retval;
1386}
1387
1388
1389INT_T GetImageReadBackCrcBuffer(UINT_T *BufferAddr, INT_T *BufferLen)
1390{
1391 int i;
1392 if(DownloadReadBackCRC != IMAGE_READ_BACK_CRC_DONE)
1393 {
1394 return CRCFailedError;
1395 }
1396
1397 *BufferAddr = (UINT_T)(&AllImageCRCInfo);
1398 *BufferLen = sizeof(ImageCRCInfo);
1399 return NoError;
1400}
1401