blob: 71570a963c9466ea2d6c35357fb4c22a27c0d30a [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: DownloadMode.c
21 *
22 * PURPOSE: Contains BootLoader's DownloadMode Code. Mainly handles the
23 * Software Upgrade and Download Mode functions of the BootLoader
24 * by calling either TIMDownload or FBFDownload functions.
25 *
26******************************************************************************/
27
28
29//////////////////////////////////////////////////////////////////////
30// Library Support for the DownloadMode.c
31// Include any shared libraries in the DownloadMode.h file to keep this
32// code clean.
33//////////////////////////////////////////////////////////////////////
34#include "DownloadMode.h"
35
36//////////////////////////////////////////////////////////////////////
37// Global Variables
38//////////////////////////////////////////////////////////////////////
39UINT_T isDownload = FALSE; // Used to differentiate from UPLOAD.
40UINT_T time_count_enable = TRUE; // used for timeout
41UINT8_T time_count_in_sec = 5;
42UINT_T upload_nand_spare = FALSE; // not upload nand spare areas when default upload
43UINT_T upload_disable_ecc = FALSE;
44extern UINT8_T upload_times;
45extern UINT8_T ResetUE;
46extern UINT8_T ResetDelay;
47
48//////////////////////////////////////////////////////////////////////
49// This is the entry point for the Download Mode.
50//
51// Inputs: Fuses (platformsettings) which contain info about which port to use
52// and the TIM which can contain port overrides.
53// Outputs: Returns a pointer to the next image which we will transfer control to.
54//
55// It mainly functions as following:
56// 1) Download the description file and determine if we have a
57// TIM or FBF download
58// 2) Download all the TIM or FBF images
59// 3) If UPLOAD, we continue with booting.
60//////////////////////////////////////////////////////////////////////
61pIMAGE_INFO_3_4_0 DownloadModeMain( pFUSE_SET pFuses, pTIM pTIM_h, OPERATING_MODE_T BootMode)
62{
63 pIMAGE_INFO_3_4_0 pBootImageInfo = NULL;
64
65 // Download the description file. Depending on its identifier, select
66 // TIMDownload or FBFDownload. Download all the images and return a
67 // pointer to the next image which we will transfer control to.
68 pBootImageInfo = DetermineModeAndDownload( pFuses, pTIM_h);
69
70 // At this point, the images have been downloaded and burnt to flash.
71 // Also note that the last image downloaded is still in ddr. Upon
72 // return from this routine, that image will be copied to its base
73 // location and executed.
74
75 // If UPLOAD, we continue with booting.
76 if ( !isDownload )
77 {
78 if (ResetUE != 0 || IsTim4DKBI(pTIM_h) /* empty board upload */ )
79 {
80 if (ResetDelay != 0)
81 Delay(1000 * 1000 * ResetDelay);
82
83 if (ResetUE)
84 PlatformSetForceUSBEnumFlag();
85
86 do_wdt_reset();
87 }
88 else
89 {
90 // After the upload, we continue with regular boot mode.
91 pBootImageInfo = BootModeMain( pTIM_h, BootMode, pFuses );
92 }
93 }
94
95 return pBootImageInfo;
96}
97
98#if TRUSTED && SECURE_DOWNLOAD
99
100static pTIM pTIM_h_Boot = NULL;
101
102pTIM GetBootTIMH(VOID)
103{
104 return pTIM_h_Boot;
105}
106
107VOID BackupTIMH4Download(pTIM pTIM_h)
108{
109 UINT_T Retval = NoError;
110 pTIM pTIM_h_Tmp;
111 UINT8_T *TimBuf;
112 pTIM_h_Tmp = malloc(sizeof(TIM));
113 if (!pTIM_h_Tmp)
114 return;
115
116 TimBuf = malloc(pTIM_h->pImg->ImageSize);
117 if (!TimBuf) {
118 free(pTIM_h_Tmp);
119 return;
120 }
121
122 memcpy(TimBuf, pTIM_h->pConsTIM, pTIM_h->pImg->ImageSize);
123
124 Retval = SetTIMPointers(TimBuf, pTIM_h_Tmp);
125
126 if (Retval != NoError) {
127 free(pTIM_h_Tmp);
128 free(TimBuf);
129 return;
130 }
131
132 pTIM_h_Boot = pTIM_h_Tmp;
133}
134#endif
135
136//////////////////////////////////////////////////////////////////////
137// This is the high level download function for the Download Mode.
138//
139// Inputs: Fuses (platformsettings) and the TIM.
140// Outputs: Returns a pointer to the next image which we will transfer
141// control to.
142//
143// It mainly determines the download mode (TIM or FBF) and calls the
144// appropriate download routine.
145//////////////////////////////////////////////////////////////////////
146pIMAGE_INFO_3_4_0 DetermineModeAndDownload( pFUSE_SET pFuses, pTIM pTIM_h)
147{
148 pIMAGE_INFO_3_4_0 pBootImageInfo = NULL;
149 UINT_T Retval;
150 volatile pProtocolISR pPortInterrupt;
151 volatile pProtocolCmd pCommand;
152 UINT_T UploadAddr = 0;
153
154 int start_time =0, cur_time=0;
155 Retval = GeneralError;
156
157 // Initialize structures required by the protocol / download manager.
158 InitProtocol();
159
160 InitDefaultPort( pFuses );
161
162 // The download port is opened. Get all the images and burn them to flash.
163 // Start by trying to get a TIM followed by individual files.
164 // If that fails, then try getting an FBF bundle.
165 // If that fails as well, then treat this a a fatal error.
166 start_time = GetOSCR0();
167 do
168 {
169 pPortInterrupt = getProtocolISR();
170 if(time_count_enable)
171 {
172 cur_time = GetOSCR0();
173 /* Wait 5s for ImageDownloadWaiting(30) to be True */
174 if(OSCR0IntervalInSec(start_time, cur_time) > time_count_in_sec)
175 {
176 pBootImageInfo = NULL;
177 goto shutdown;
178 }
179 }
180
181 if (upload_times == 0)
182 {
183 goto disconnect; // no upload any more
184 }
185
186 if(ImageDownloadWaiting(30) == FALSE)
187 {
188 Retval = SeqError;
189 continue;
190 }
191
192 time_count_enable = 0;
193
194 start_time = GetOSCR0();
195 while (pPortInterrupt->CommandReceived == FALSE)
196 {
197 cur_time = GetOSCR0();
198 if(OSCR0IntervalInSec(start_time, cur_time) > PROTOCOL_WAITTIME) // wait 4s for connection
199 {
200 pBootImageInfo = NULL;
201 goto shutdown;
202 }
203 }
204
205 #if TRUSTED && SECURE_DOWNLOAD
206 if (pFuses->bits.SBE) {
207 BackupTIMH4Download(pTIM_h);
208 }
209 #endif
210
211 pCommand = getProtocolCmd();
212 switch(pCommand->Command)
213 {
214 case GetVersionCmd:
215 // Used to differentiate from UPLOAD.
216 isDownload = TRUE;
217
218 // Request the TIM first as originally implemented.
219 // The new TIM is stored at pTIM_h->pConstTIM.
220 Retval = PM_ReceiveImage( NULL, (UINT_T)pTIM_h->pConsTIM, MAX_TIM_SIZE, TIMIDENTIFIER );
221 if (Retval == NoError)
222 {
223 // Before we call the TIM Download function which actually does the downloading,
224 // copy the tim from its download location to its load address.
225 memcpy((void*)pTIM_h->pImg->LoadAddr, pTIM_h->pConsTIM, pTIM_h->pImg->ImageSize);
226 // pTIM_h is the newly downloaded TIM.
227 // It has a list of all the images that need to be downloaded and burned.
228 // The DownloadImages function will use DDR to hold the images while writing them to flash.
229 pBootImageInfo = TIMDownloadMain(pFuses, pTIM_h);
230 }
231 else // download failed
232 {
233 FatalError(Retval, "DMD", 1);
234 }
235 break;
236
237 case UploadDataHeaderCmd:
238 // upload size limitted 0x20000000
239 UploadAddr = malloc(0x2000000);
240 if(UploadAddr == 0)
241 return HeapExhaustedError;
242 Retval = HandleRequest( UploadAddr, NULL, NULL, NULL );
243 if (Retval == NoError) // upload successfully
244 {
245 upload_times--;
246 Retval = GeneralError; // wait for next upload
247 upload_nand_spare = FALSE; // clear it
248 }
249 else // upload failed
250 {
251 FatalError(Retval, "DMD", 2);
252 }
253 // Does not matter if we had an error. Boot anyway.
254 free(UploadAddr);
255 break;
256 default:
257 //unknown_protocol_command(getProtocolCmd());
258 FatalError(UnknownProtocolCmd, "DMD", 3);
259 break;
260 }
261 }while (Retval != NoError);
262
263disconnect:
264 HandleDisconnect();
265
266shutdown:
267 ShutdownPort();
268
269 return pBootImageInfo;
270}