blob: fdf8273f9fd597f6d3e16e84de03cb23bf53fa8d [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001
2/******************************************************************************
3 *
4 * (C)Copyright 2005 - 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 *
21 *
22 * FILENAME: BootMode.c
23 *
24 * PURPOSE: Contains BootLoader's BootMode Code. Mainly handles the
25 * SINGLE and DUAL TIM MODE boot functions.
26 *
27******************************************************************************/
28
29
30//////////////////////////////////////////////////////////////////////
31// Library Support for the BootMode.c
32// Include any shared libraries in the BootMode.h file to keep this
33// code clean.
34//////////////////////////////////////////////////////////////////////
35#include "BootMode.h"
36#include "loadoffsets.h"
37#include "obm2osl.h"
38
39#if LZMA_SUPPORT
40#include "LzmaDecode.h"
41#endif
42
43pIMAGE_INFO_3_4_0 pNextImageToTransferTo = NULL; // the next image we want to transfer control to
44pIMAGE_INFO_3_4_0 pImageNsEntry = NULL;
45extern OBM2OSL *pOBM2OSL_h;
46extern UINT8_T FlashInitDone;
47
48//////////////////////////////////////////////////////////////////////
49// This is the entry point for the Boot Mode.
50//
51// Inputs: Current TIM pointer, BootMode(SINGLE or DUAL)
52// Outputs: Returns the next image that we will transfer the control to.
53//
54// It mainly functions as following depending on the BOOT MODE:
55// 1) SINGLE TIM BOOT MODE:
56// a) Configures the Flashes and Initializes the Flash Management
57// b) Loads (and validates) all the images using a loop.
58// c) If TRUSTED, provisions the platform before finishing
59// d) Returns the next image that we will transfer the control to.
60// 2) DUAL TIM BOOT MODE:
61// a) Configures the Flashes and Initializes the Flash Management
62// b) Loads (and validates) the second TIM.
63// c) Configures the Flashes and Initializes the Flash Management
64// using the new TIM.
65// d) Loads (and validates) all the images using a loop.
66// e) If TRUSTED, provisions the platform before finishing
67// f) Returns the next image that we will transfer the control to.
68//////////////////////////////////////////////////////////////////////
69pIMAGE_INFO_3_4_0 BootModeMain(pTIM pTIM_h, OPERATING_MODE_T BootMode, pFUSE_SET pFuses)
70{
71 UINT_T Retval = NoError;
72 pIMAGE_INFO_3_4_0 pBootImageInfo = NULL;
73
74 Retval = PlatformInitFlash(pTIM_h);
75 if( Retval != NoError)
76 FatalError(Retval, "BMM", 1);
77
78#if ENABLE_MMU
79 EnableDataCache();
80#endif
81
82#if TRUSTED
83 DisplayFuses();
84#endif
85
86#if EMMD_SUPPORT
87 if (PlatformCheckEMMDStatus()) {
88 pBootImageInfo = LoadAllImages(pFuses, pTIM_h);
89 #if ENABLE_MMU
90 DisableDataCache();
91 #endif
92 return pBootImageInfo;
93 }
94#endif
95
96 PlatformReleaseEMMDStatus();
97
98 Retval = fota_upgrade(pTIM_h, pFuses);
99 obm_printf("FOTA return: 0x%x\n\r", Retval);
100 if (Retval == NoError)
101 {
102 PlatformReleaseEMMDStatus();
103 PlatformSetFOTAFlag();
104 do_wdt_reset();
105 }
106 else
107 {
108 pBootImageInfo = LoadAllImages(pFuses, pTIM_h);
109 }
110
111#if TRUSTED
112 Retval = ProvisionPlatform(pFuses, pTIM_h);
113
114 // If ProvisionPlatform() returned an error, this means that an error occurred
115 // during fuse burning. So stop booting and go to Fatal Error.
116 if (Retval != NoError)
117 {
118 FatalError(Retval, "BMM", 2);
119 }
120#endif
121
122#if ENABLE_MMU
123 DisableDataCache();
124#endif
125
126 return pBootImageInfo;
127}
128
129//////////////////////////////////////////////////////////////////////
130// This function mainly loads ALL the images available in the TIM
131// (except TIM, DUALTIM, and OBM) and validates them.
132// It essentially returns the next image that we will transfer the
133// control to.
134//
135// Inputs: Current TIM pointer, BootMode(SINGLE or DUAL)
136// Outputs: Returns the next image that we will transfer the control to.
137//////////////////////////////////////////////////////////////////////
138pIMAGE_INFO_3_4_0 LoadAllImages(pFUSE_SET pFuses, pTIM pTIM_h)
139{
140 UINT_T Retval = NoError, decompressLength;
141 UINT_T ImageID = 0; // Initialize it as an invalid image
142 UINT_T ImageIndex, ImageSize;
143 pIMAGE_INFO_3_4_0 pImageInfo = NULL;
144 pWTP_RESERVED_AREA_HEADER pWRAH = NULL;
145 pTransfer_Info_PACKAGE pInfo = NULL;
146 UINT_T i;
147
148 OBM2OSL_Init(pFuses, pTIM_h);
149
150 // no need to validate TIM since it's validated by BootROM already
151
152 // Depending on the version of the TIM, determine the size of each image in bytes.
153 // We will use this size to iterate through the TIM binary from image to image.
154 if (pTIM_h->pConsTIM->VersionBind.Version >= TIM_3_4_00)
155 ImageSize = sizeof(IMAGE_INFO_3_4_0);
156 else
157 ImageSize = sizeof(IMAGE_INFO_3_2_0);
158
159 // This is the very initial TIM image! Assumes that the TIM image is located at the top of the
160 // TIM file. Otherwise, we would skip images.
161 pImageInfo = pTIM_h->pImg;
162
163 // Read in the number of images from the TIM and iterate through each of these images.
164 // We load them and we validate them.
165 for( ImageIndex = 0; ImageIndex < pTIM_h->pConsTIM->NumImages; ImageIndex++ )
166 {
167 // We skip the TIM, DUALTIM, and OBM images. We load/validate all the others.
168 if( (pImageInfo->ImageID != TIMIDENTIFIER) &&
169 (pImageInfo->ImageID != OBMIDENTIFIER) &&
170 (pImageInfo->ImageID != OBM2IDENTIFIER) &&
171 (pImageInfo->ImageID != TZIIDENTIFIER) &&
172 (pImageInfo->ImageID != OUMIDENTIFIER) &&
173 (pImageInfo->LoadAddr != 0xFFFFFFFF)
174 )
175 {
176 Retval = Loadimage(pImageInfo, pFuses, pTIM_h, 0);
177 if(Retval != NoError) {
178 obm_printf("Load %s error: 0x%x\n\r", ImageID2String(pImageInfo->ImageID), Retval);
179 pImageInfo = (IMAGE_INFO_3_4_0*)((UCHAR *)pImageInfo + ImageSize);
180 continue;
181 }
182 switch(pImageInfo->ImageID)
183 {
184 case TZSWIDENTIFIER:
185 obm_printf("Trusted OS in TIM\n\r");
186 pNextImageToTransferTo = pImageInfo;
187 break;
188 case OSLOADERID:
189 obm_printf("Uboot in TIM\n\r");
190 if(pNextImageToTransferTo == NULL)
191 pNextImageToTransferTo = pImageInfo;
192 if(pImageNsEntry == NULL)
193 pImageNsEntry = pImageInfo;
194 break;
195 }
196 }
197
198 #if SPINOR_CODE
199 if (pImageInfo->ImageID == TIMIDENTIFIER)
200 {
201 TransCITA_2_OBM2OSLO(pTIM_h, pOBM2OSL_h);
202 }
203 #endif
204
205 // Get a pointer to the next image we will load.
206 // For the last iteration (e.g. after the last image), we won't find an image.
207 // However, this is OK because pImageInfo is not used again.
208 pImageInfo = (IMAGE_INFO_3_4_0*)((UCHAR *)pImageInfo + ImageSize);
209 }
210
211 // system needs to boot up if there is no IMAP
212 LoadImagesOTA(pFuses, pTIM_h);
213
214 if(pNextImageToTransferTo == NULL) {
215 obm_printf("No Next Image to transfer to\n\r");
216 FatalError(ImageNotFound, "LAI", NULL);
217 }
218
219#if SPINOR_CODE
220 SPINOR_Disable4BytesMode();
221#endif
222
223 return pNextImageToTransferTo;
224}
225
226unsigned int GetNsEntryLoadAddress()
227{
228 unsigned int addr = 0;
229 if(pImageNsEntry)
230 addr = pImageNsEntry->LoadAddr;
231 return addr;
232}
233
234INT_T Loadimage(pIMAGE_INFO_3_4_0 pImageInfo, pFUSE_SET pFuses, pTIM pTIM_h, INT_T TimType)
235{
236 UINT_T Retval = NoError;
237 UINT_T offset;
238 UINT_T decompressLength;
239 UINT_T imgValidate = 1;
240 UINT_T AB_system = 0;
241
242#ifdef CONFIG_AB_SYSTEM
243 pWTP_RESERVED_AREA_HEADER pWRAH = NULL;
244 pABSP_INFO pABSP_info = NULL;
245 AB_system = 1;
246#endif
247
248#if MMC_CODE
249 if((pTIM_h->pConsTIM->VersionBind.Version) >= TIM_3_2_00)
250 {
251 SetPartition(pImageInfo->PartitionNumber.bits.PartitionNumber, BOOT_FLASH);
252 }
253#endif
254
255#ifdef CONFIG_AB_SYSTEM
256 if(TimType == RecoveryImage) {
257 pWRAH = FindPackageInReserved (&Retval, pTIM_h, ABSPID);
258 if (Retval != NoError) {
259 obm_printf("ABSP Package Not Found\n\r");
260 return ImageLoadError;
261 }
262 pABSP_info = (pABSP_INFO) pWRAH;
263 offset = pImageInfo->PartitionNumber.bits.Reserved << pABSP_info->FlashAddrShift;
264#if MMC_CODE
265 offset /= 512;
266#endif
267 } else
268#endif
269 {
270 offset = pImageInfo->FlashEntryAddr;
271 }
272
273#ifdef CONFIG_ASR_SDTIM
274 TIM *pSDTIM_h = NULL;
275 CHAR *SDTimBuf = NULL;
276 pIMAGE_INFO_3_4_0 pSdtimImageInfo = NULL;
277 if (ImageIsSDTIMIncluded(pImageInfo)) {
278 SDTimBuf = malloc(SDTIM_MAX_SIZE);
279 pSDTIM_h = malloc(sizeof(TIM));
280 if(SDTimBuf == NULL || pSDTIM_h == NULL)
281 return HeapExhaustedError;
282
283 Retval = ReadFlash(offset, SDTimBuf, SDTIM_MAX_SIZE, BOOT_FLASH);
284 if(Retval != NoError) {
285 free(SDTimBuf); free(pSDTIM_h);
286 return ImageLoadError;
287 }
288
289 Retval = SetTIMPointers( SDTimBuf, pSDTIM_h);
290 if(Retval)
291 return ImageLoadError;
292
293 pSdtimImageInfo = FindImageInTIM(pSDTIM_h, SDTIM);
294 if(pSdtimImageInfo == NULL) {
295 free(SDTimBuf); free(pSDTIM_h);
296 return ImageLoadError;
297 }
298
299 imgValidate = GetSDTimSecureConfig(pSdtimImageInfo);
300
301#if MMC_CODE
302 offset += GetSDTimSpaceSize(pSdtimImageInfo)/512;
303#else
304 offset += GetSDTimSpaceSize(pSdtimImageInfo);
305#endif
306 pImageInfo = FindImageInTIM(pSDTIM_h, pImageInfo->ImageID);
307 if(pImageInfo == NULL) {
308 free(SDTimBuf); free(pSDTIM_h);
309 return ImageLoadError;
310 }
311 } else {
312 pSDTIM_h = pTIM_h; /* old way, SDTIM and DTIM is equal */
313 }
314#endif
315
316#if LZMA_SUPPORT
317 if (pImageInfo->PartitionNumber.bits.ImageType == DLCMD_IMG_LZMA_IMAGE_TYPE)
318 {
319 UINT_T *DecompressBuff = NULL;
320 DecompressBuff = malloc(pImageInfo->ImageSizeToHash);
321 if(DecompressBuff == NULL)
322 return HeapExhaustedError;
323 if(PlatformCheckEMMDStatus() == 1) {
324 decompressLength = DECOMPRESS_LENGTH_RDP; /* TODO */
325 } else {
326 decompressLength = DECOMPRESS_LENGTH;
327 }
328 Retval = ReadFlash(offset, DecompressBuff, pImageInfo->ImageSize, BOOT_FLASH);
329 if (Retval != NoError)
330 {
331 free(DecompressBuff);
332 obm_printf("%s Load Error: 0x%x\n\r", ImageID2String(pImageInfo->ImageID), Retval);
333 return ImageLoadError;
334 }
335 decompressLength = DECOMPRESS_LENGTH;
336 Retval = LZMA_Decompress((UINT_T *)pImageInfo->LoadAddr,
337 &decompressLength,
338 (UINT_T *)DecompressBuff,
339 pImageInfo->ImageSize,
340 0x0);
341 if (Retval != NoError)
342 {
343 free(DecompressBuff);
344 obm_printf("%s LZMA decompress Error: 0x%x\n\r", ImageID2String(pImageInfo->ImageID), Retval);
345 return ImageLoadError;
346 }
347 free(DecompressBuff);
348 goto img_validate;
349 }
350#endif
351
352#if XZ_SUPPORT || XZDEC_SUPPORT
353 if (pImageInfo->PartitionNumber.bits.ImageType == DLCMD_IMG_MXZ_IMAGE_TYPE) {
354 CHAR *DecompressBuff = NULL;
355 UINT_T outLen = 0x2000000; /* 32MB */
356 CHAR *inBuf, *inEnd, *outBuf, *outEnd;
357 VOID *nextInBuf = NULL;
358 INT compressed = 0;
359 UINT_T i = 0;
360 UINT_T outSize;
361
362 DecompressBuff = malloc(pImageInfo->ImageSizeToHash);
363 if(DecompressBuff == NULL)
364 return HeapExhaustedError;
365 Retval = ReadFlash(offset, (UINT_T)DecompressBuff, pImageInfo->ImageSize, BOOT_FLASH);
366
367 if (Retval != NoError)
368 {
369 free(DecompressBuff);
370 obm_printf("%s Load Error: 0x%x\n\r", ImageID2String(pImageInfo->ImageID), Retval);
371 return ImageLoadError;
372 }
373 inBuf = DecompressBuff;
374 inEnd = DecompressBuff + pImageInfo->ImageSize;
375 outBuf = (CHAR *)pImageInfo->LoadAddr;
376 outEnd = (CHAR *)(pImageInfo->LoadAddr + outLen);
377
378 //obm_printf("Image info: 0x%x 0x%x 0x%x\n\r", pImageInfo->LoadAddr, pImageInfo->ImageSize, pImageInfo->ImageSizeToHash);
379 while (inBuf != inEnd)
380 {
381 outSize = outEnd - outBuf;
382 Retval = xz_decompress(inBuf, inEnd - inBuf,
383 outBuf, &outSize,
384 &nextInBuf, &compressed);
385 if (Retval)
386 {
387 FatalError(XZDecodeError, "LI", NULL);
388 }
389
390 if(!compressed)
391 break;
392
393 //obm_printf("MXZ dec loop: %d 0x%x\n\r", i, outSize);
394 ++i;
395 outBuf += outSize;
396 inBuf = (CHAR *) nextInBuf;
397 }
398 free(DecompressBuff);
399 goto img_validate;
400 }
401#endif
402
403 Retval = ReadFlash(offset, pImageInfo->LoadAddr, pImageInfo->ImageSize, BOOT_FLASH);
404 if (Retval != NoError)
405 return ImageLoadError;
406
407img_validate:
408 if (imgValidate || AB_system)
409 {
410#ifdef CONFIG_ASR_SDTIM
411 Retval = ValidateImage(pImageInfo->LoadAddr, pImageInfo->ImageID, pSDTIM_h);
412 if(SDTimBuf) free(SDTimBuf);if(pSDTIM_h) free(pSDTIM_h);
413#else
414 Retval = ValidateImage(pImageInfo->LoadAddr, pImageInfo->ImageID, pTIM_h);
415#endif
416 if (Retval != NoError){
417 obm_printf("%s Validation Error: 0x%x\n\r", ImageID2String(pImageInfo->ImageID), Retval);
418 return ImageValidationError;
419 }
420 }
421
422 return Retval;
423}
424
425#if 0 /* Deprecated */
426//////////////////////////////////////////////////////////////////////
427// This function loads uboot only for EMMD
428//////////////////////////////////////////////////////////////////////
429pIMAGE_INFO_3_4_0 LoadUboot(pFUSE_SET pFuses, pTIM pTIM_h)
430{
431 pIMAGE_INFO_3_4_0 pImageInfo = NULL;
432
433 OBM2OSL_Init(pFuses, pTIM_h);
434
435#if QSPINOR_CODE
436 TransCITA_2_OBM2OSLO(pTIM_h, pOBM2OSL_h);
437 ASRFlag_ParseCfgToOBM2OSLO(pTIM_h);
438#endif
439 pImageInfo = FindImageInTIM(pTIM_h, OSLOADERID);
440 if (pImageInfo != NULL)
441 {
442 pNextImageToTransferTo = pImageInfo;
443 Loadimage(pImageInfo, pFuses, pTIM_h, 0);
444 }
445 else
446 {
447 LoadUbootOTA(pFuses, pTIM_h);
448 }
449
450 // Return the OSLO image.
451 return pNextImageToTransferTo;
452}
453#endif
454