blob: 71570a963c9466ea2d6c35357fb4c22a27c0d30a [file] [log] [blame]
/******************************************************************************
*
* (C)Copyright 2011 Marvell. All Rights Reserved.
*
* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MARVELL.
* The copyright notice above does not evidence any actual or intended
* publication of such source code.
* This Module contains Proprietary Information of Marvell and should be
* treated as Confidential.
* The information in this file is provided for the exclusive use of the
* licensees of Marvell.
* Such users have the right to use, modify, and incorporate this code into
* products for purposes authorized by the license agreement provided they
* include this notice and the associated copyright notice with any such
* product.
* The information in this file is provided "AS IS" without warranty.
*
*
* FILENAME: DownloadMode.c
*
* PURPOSE: Contains BootLoader's DownloadMode Code. Mainly handles the
* Software Upgrade and Download Mode functions of the BootLoader
* by calling either TIMDownload or FBFDownload functions.
*
******************************************************************************/
//////////////////////////////////////////////////////////////////////
// Library Support for the DownloadMode.c
// Include any shared libraries in the DownloadMode.h file to keep this
// code clean.
//////////////////////////////////////////////////////////////////////
#include "DownloadMode.h"
//////////////////////////////////////////////////////////////////////
// Global Variables
//////////////////////////////////////////////////////////////////////
UINT_T isDownload = FALSE; // Used to differentiate from UPLOAD.
UINT_T time_count_enable = TRUE; // used for timeout
UINT8_T time_count_in_sec = 5;
UINT_T upload_nand_spare = FALSE; // not upload nand spare areas when default upload
UINT_T upload_disable_ecc = FALSE;
extern UINT8_T upload_times;
extern UINT8_T ResetUE;
extern UINT8_T ResetDelay;
//////////////////////////////////////////////////////////////////////
// This is the entry point for the Download Mode.
//
// Inputs: Fuses (platformsettings) which contain info about which port to use
// and the TIM which can contain port overrides.
// Outputs: Returns a pointer to the next image which we will transfer control to.
//
// It mainly functions as following:
// 1) Download the description file and determine if we have a
// TIM or FBF download
// 2) Download all the TIM or FBF images
// 3) If UPLOAD, we continue with booting.
//////////////////////////////////////////////////////////////////////
pIMAGE_INFO_3_4_0 DownloadModeMain( pFUSE_SET pFuses, pTIM pTIM_h, OPERATING_MODE_T BootMode)
{
pIMAGE_INFO_3_4_0 pBootImageInfo = NULL;
// Download the description file. Depending on its identifier, select
// TIMDownload or FBFDownload. Download all the images and return a
// pointer to the next image which we will transfer control to.
pBootImageInfo = DetermineModeAndDownload( pFuses, pTIM_h);
// At this point, the images have been downloaded and burnt to flash.
// Also note that the last image downloaded is still in ddr. Upon
// return from this routine, that image will be copied to its base
// location and executed.
// If UPLOAD, we continue with booting.
if ( !isDownload )
{
if (ResetUE != 0 || IsTim4DKBI(pTIM_h) /* empty board upload */ )
{
if (ResetDelay != 0)
Delay(1000 * 1000 * ResetDelay);
if (ResetUE)
PlatformSetForceUSBEnumFlag();
do_wdt_reset();
}
else
{
// After the upload, we continue with regular boot mode.
pBootImageInfo = BootModeMain( pTIM_h, BootMode, pFuses );
}
}
return pBootImageInfo;
}
#if TRUSTED && SECURE_DOWNLOAD
static pTIM pTIM_h_Boot = NULL;
pTIM GetBootTIMH(VOID)
{
return pTIM_h_Boot;
}
VOID BackupTIMH4Download(pTIM pTIM_h)
{
UINT_T Retval = NoError;
pTIM pTIM_h_Tmp;
UINT8_T *TimBuf;
pTIM_h_Tmp = malloc(sizeof(TIM));
if (!pTIM_h_Tmp)
return;
TimBuf = malloc(pTIM_h->pImg->ImageSize);
if (!TimBuf) {
free(pTIM_h_Tmp);
return;
}
memcpy(TimBuf, pTIM_h->pConsTIM, pTIM_h->pImg->ImageSize);
Retval = SetTIMPointers(TimBuf, pTIM_h_Tmp);
if (Retval != NoError) {
free(pTIM_h_Tmp);
free(TimBuf);
return;
}
pTIM_h_Boot = pTIM_h_Tmp;
}
#endif
//////////////////////////////////////////////////////////////////////
// This is the high level download function for the Download Mode.
//
// Inputs: Fuses (platformsettings) and the TIM.
// Outputs: Returns a pointer to the next image which we will transfer
// control to.
//
// It mainly determines the download mode (TIM or FBF) and calls the
// appropriate download routine.
//////////////////////////////////////////////////////////////////////
pIMAGE_INFO_3_4_0 DetermineModeAndDownload( pFUSE_SET pFuses, pTIM pTIM_h)
{
pIMAGE_INFO_3_4_0 pBootImageInfo = NULL;
UINT_T Retval;
volatile pProtocolISR pPortInterrupt;
volatile pProtocolCmd pCommand;
UINT_T UploadAddr = 0;
int start_time =0, cur_time=0;
Retval = GeneralError;
// Initialize structures required by the protocol / download manager.
InitProtocol();
InitDefaultPort( pFuses );
// The download port is opened. Get all the images and burn them to flash.
// Start by trying to get a TIM followed by individual files.
// If that fails, then try getting an FBF bundle.
// If that fails as well, then treat this a a fatal error.
start_time = GetOSCR0();
do
{
pPortInterrupt = getProtocolISR();
if(time_count_enable)
{
cur_time = GetOSCR0();
/* Wait 5s for ImageDownloadWaiting(30) to be True */
if(OSCR0IntervalInSec(start_time, cur_time) > time_count_in_sec)
{
pBootImageInfo = NULL;
goto shutdown;
}
}
if (upload_times == 0)
{
goto disconnect; // no upload any more
}
if(ImageDownloadWaiting(30) == FALSE)
{
Retval = SeqError;
continue;
}
time_count_enable = 0;
start_time = GetOSCR0();
while (pPortInterrupt->CommandReceived == FALSE)
{
cur_time = GetOSCR0();
if(OSCR0IntervalInSec(start_time, cur_time) > PROTOCOL_WAITTIME) // wait 4s for connection
{
pBootImageInfo = NULL;
goto shutdown;
}
}
#if TRUSTED && SECURE_DOWNLOAD
if (pFuses->bits.SBE) {
BackupTIMH4Download(pTIM_h);
}
#endif
pCommand = getProtocolCmd();
switch(pCommand->Command)
{
case GetVersionCmd:
// Used to differentiate from UPLOAD.
isDownload = TRUE;
// Request the TIM first as originally implemented.
// The new TIM is stored at pTIM_h->pConstTIM.
Retval = PM_ReceiveImage( NULL, (UINT_T)pTIM_h->pConsTIM, MAX_TIM_SIZE, TIMIDENTIFIER );
if (Retval == NoError)
{
// Before we call the TIM Download function which actually does the downloading,
// copy the tim from its download location to its load address.
memcpy((void*)pTIM_h->pImg->LoadAddr, pTIM_h->pConsTIM, pTIM_h->pImg->ImageSize);
// pTIM_h is the newly downloaded TIM.
// It has a list of all the images that need to be downloaded and burned.
// The DownloadImages function will use DDR to hold the images while writing them to flash.
pBootImageInfo = TIMDownloadMain(pFuses, pTIM_h);
}
else // download failed
{
FatalError(Retval, "DMD", 1);
}
break;
case UploadDataHeaderCmd:
// upload size limitted 0x20000000
UploadAddr = malloc(0x2000000);
if(UploadAddr == 0)
return HeapExhaustedError;
Retval = HandleRequest( UploadAddr, NULL, NULL, NULL );
if (Retval == NoError) // upload successfully
{
upload_times--;
Retval = GeneralError; // wait for next upload
upload_nand_spare = FALSE; // clear it
}
else // upload failed
{
FatalError(Retval, "DMD", 2);
}
// Does not matter if we had an error. Boot anyway.
free(UploadAddr);
break;
default:
//unknown_protocol_command(getProtocolCmd());
FatalError(UnknownProtocolCmd, "DMD", 3);
break;
}
}while (Retval != NoError);
disconnect:
HandleDisconnect();
shutdown:
ShutdownPort();
return pBootImageInfo;
}