Files
banban/ql-bootloader/boot33/src/ota.c
T

835 lines
25 KiB
C

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cpu.h"
#include "qspi.h"
#include "reg.h"
#include "system.h"
//#include "uart.h"
#include "ptable.h"
#include "loadtable.h"
#include "sdio.h"
#include "pmic.h"
#include "ff.h"
#include "version_block.h"
#include "bspatch.h"
#include "fip.h"
#include "LzmaDec.h"
#include "FreqChange.h"
#include "fbf_parse.h"
#include "ota.h"
#include "tinyalloc.h"
#include "asr_property.h"
#include "secboot.h"
#include "updater_table.h"
#ifdef BOOT33_FOTA_SUPPORT
#define QUEC_SUPPORT_FULL_FOTA_NAND 1
extern void TransferControl(unsigned int);
extern int crane_qspi_read(unsigned int addr, unsigned int buf_addr, unsigned int size);
extern int crane_qspi_write(unsigned int addr, unsigned int buf_addr,unsigned int size);
extern int crane_qspi_erase(unsigned int addr, unsigned int size);
extern int malloc_init(unsigned int ta_base, unsigned int length);
extern unsigned int get_fota_param_end_addr(void);
extern unsigned int get_fota_param_start_addr(void);
extern unsigned int get_ddr_ro_exec_length(void);
extern unsigned int get_ddr_ro_exec_addr(void);
extern unsigned long mini_system_enable;
unsigned int get_ps_ncah_address(void)
{
char region_compress_mark[8];
unsigned schedule_count = 0;
rw_region_item region_info;
char * rw_cpz_struct_addr=(char*)get_rw_cpz_struct_addr();
//load region compressed struct
memcpy(region_compress_mark,
rw_cpz_struct_addr,
sizeof(region_compress_mark));
if(!strncmp(region_compress_mark, RW_REGION_MARK_PRE_STRING ,strlen(RW_REGION_MARK_PRE_STRING)-1)){
while(1){
//read NEXT region cpz info struct
memcpy(&region_info
,(void*)(rw_cpz_struct_addr + (sizeof(rw_region_item)*schedule_count++))
,sizeof(rw_region_item));
//dump region info
//uart_printf("[CP ] decompress [%8s] from [%.08x] to [%.08x]\r\n",
// region_info.RW_REGION_NAME,
// region_info.RW_REGION_COMPRESSED_ADDR,
// region_info.RW_REGION_EXEC_ADDR
// );
if(!strncmp(region_info.RW_REGION_NAME,"PS_NCAH",7)){
return region_info.RW_REGION_EXEC_ADDR;
}
}
}
else
{
uart_printf("[CP ] Region CPZ struct not detected from loadtable\r\n");
}
return 0;
}
static void fota_uudelay(int us)
{
volatile uint32_t i;
for(i=0; i<us*100;i++)
i = i+1;
}
static void fota_mdelay(int ms){
volatile uint32_t i;
for(i=0; i<ms;i++)
fota_uudelay(100);
}
static UINT32 CalcImageChecksum( UINT32* DownloadArea, UINT32 ImageLength,UINT32 checksum)
{
UINT32 ImageChecksum = checksum;
UINT32* ptr32 = DownloadArea;
UINT32* pEnd = ptr32 + (ImageLength / sizeof(UINT32));
UINT32 BytesSummed = 0;
while ( ptr32 < pEnd )
{
// checksum format version 2 algorithm as defined by flasher
ImageChecksum ^= (*ptr32);
ptr32++;
BytesSummed += sizeof(UINT32);
}
return ImageChecksum;
}
#if (!defined(BOOT33_FOTA_NO_UPDATER) || !defined(LTEONLY_SINGLE_SIM))
#if (!defined(CRANEM_SINGLE_SIM))
UINT32 OTA_Check_FotaImage(UINT32 buf, UINT32 size, UINT32 flash_Addr)
{
UINT32 old_checksum = 0,new_checksum = 0;
char *temp=NULL;
temp =(char *) tiny_malloc(size);
memset(temp,0,size);
memcpy(temp,flash_Addr+QSPI_FLASH_BASE,size);
old_checksum = CalcImageChecksum((UINT32*)buf,size,0);
new_checksum = CalcImageChecksum((UINT32*)temp,size,0);
if(old_checksum != new_checksum){
uart_printf("OTA_Check_FotaImage,failed!!![0x%08X]:[0x%08X]\n\r",old_checksum,new_checksum);
}else{
tiny_free(temp);
return NoError;
}
tiny_free(temp);
return DFota_WriteFlashCheckFailed;
}
static UINT32 OTA_Update_FotaParam(UINT32 buf, UINT32 size, UINT32 flash_Addr)
{
UINT32 Retval = 0;
int i=0;
//char temp[FLASH_4K_SIZE];
uart_printf("OTA_Update_FotaParam, flash_Addr[0x%08X],size[0x%08X]\n\r", flash_Addr,size);
//temp =(char *) malloc(FLASH_4K_SIZE);
//memcpy(temp,(char *)buf,size);
start:
Retval=crane_qspi_erase(flash_Addr, FLASH_4K_SIZE);
if (Retval != 0)
goto exit;
Retval = crane_qspi_write(flash_Addr, buf, FLASH_4K_SIZE);
if (Retval != 0)
goto exit;
exit:
Retval=OTA_Check_FotaImage(buf,size,flash_Addr);
if(NoError!=Retval ){
if(i>10){
uart_printf("OTA_Check_FotaImage filed,Wait...\n\r");
while(1){
fota_mdelay(10*1000);
}
}
uart_printf("OTA_Check_FotaImage filed,Wait (%d)sec ...\n\r",(i+1)*10);
fota_mdelay((i+1)*10*1000);
uart_printf("OTA_Check_FotaImage filed,Wait (%d)sec end\n\r",(i+1)*10);
i++;
goto start;
}
uart_printf("OTA_Update_FotaParam end\n\r");
return Retval;
}
static UINT32 OTA_Update_FotaImage(UINT32 buf, UINT32 size, UINT32 flash_Addr)
{
UINT32 Retval = 1;
char *temp=NULL;
UINT32 index=0;
UINT32 tempsize = size;
int i=0;
uart_printf("OTA_Update_FotaImage: flash_Addr[0x%08x], size: 0x%08x\n\r", flash_Addr, size);
start:
temp =(char *) tiny_malloc(FLASH_4K_SIZE);
while(size > FLASH_4K_SIZE){
memcpy(temp,(char *)(buf+index),FLASH_4K_SIZE);
Retval=crane_qspi_erase(flash_Addr + index, FLASH_4K_SIZE);
if (Retval != 0)
goto error;
if(index==0){
#if 0
uart_printf("+++++++++++++++++++++++++++++OTA_Update_FotaImage,delay for poweroff test++++++++++++++\n\r");
fota_delay();
uart_printf("-----------------------------OTA_Update_FotaImage,delay end----------------------------\n\r");
#endif
}
if(index%FLASH_1M_SIZE==0){
uart_printf("\r\n");
}
if(index%CRANE_NOR_BLOCKSIZE==0){
uart_printf("...");
}
Retval = crane_qspi_write(flash_Addr + index, (UINT32)temp, FLASH_4K_SIZE);
if (Retval != 0)
goto error;
index += FLASH_4K_SIZE;
size -= FLASH_4K_SIZE;
}
if(size>0){
memset(temp,0,FLASH_4K_SIZE);
memcpy(temp,(char *)(buf+index),size);
Retval=crane_qspi_erase(flash_Addr + index, FLASH_4K_SIZE);
if (Retval != 0)
goto error;
Retval = crane_qspi_write(flash_Addr + index, (UINT32)temp, FLASH_4K_SIZE);
if (Retval != 0)
goto error;
index += size;
size -= size;
}
Retval = 0;
error:
if(temp) tiny_free(temp);
Retval=OTA_Check_FotaImage(buf,tempsize,flash_Addr);
if(NoError!=Retval ){
if(i>10){
uart_printf("OTA_Check_FotaImage filed,Wait...\n\r");
while(1){
fota_mdelay(10*1000);
}
}
uart_printf("OTA_Check_FotaImage filed,Wait (%d)sec ...\n\r",(i+1)*10);
fota_mdelay((i+1)*10*1000);
uart_printf("OTA_Check_FotaImage filed,Wait (%d)sec end\n\r",(i+1)*10);
i++;
goto start;
}
uart_printf("OTA_Update_FotaImage end\n\r");
return Retval;
}
static UINT32 System_ota_updater(struct fota_firmwar_flag* pFOTA_T,struct fota_param *param,unsigned long FotaParamStartAddress)
{
UINT32 Retval = GeneralError;
UINT32 LoadAddr = 0;
MasterBlockHeader *pMasterHeader = NULL;
PDeviceHeader_11 pDevHeader_11=NULL;
PImageStruct_11 pImage_11 = NULL;
UINT32 temp_p = NULL;
UINT32 imageChecksum = 0;
UINT32 imagenum;
UINT32 ImageAddr;
UINT32 updaterSize=0,updateImageSize=0;
_ptentry * fota_pkg=ptable_find_entry("fota_pkg");
if(fota_pkg==NULL){
uart_printf("[OTA] not found fota_pkg\r\n");
return NotFoundError;
}
if (pFOTA_T->header != FOTA_HEADER_MAGIC)
{
uart_printf("[OTA] FBF Flag mismatch,Header[%.08x]\r\n",pFOTA_T->header);
return NotFoundError;
}
if (pFOTA_T->upgrade_flag != 1)
{
uart_printf("[OTA] No need to upgrade[%d]\r\n",pFOTA_T->upgrade_flag);
return NotFoundError;
}
if(pFOTA_T->upgrade_method != 1)
{
uart_printf("[OTA] Not ota upgrader\r\n");
return NotOtaUpdaterError;
}
#if QUEC_SUPPORT_FULL_FOTA_NAND
if(pFOTA_T->fbf_file_size > 0x32000)/*fbf bigger then 200k exit*/
{
uart_printf("[OTA] FBF greater than 200k,is not updater\r\n");
return NotFoundError;
}
#endif
LoadAddr = (UINT32)tiny_malloc(pFOTA_T->fbf_file_size);
if(LoadAddr == 0){
uart_printf("[OTA] tiny_malloc error\n\r");
return InvalidSizeError;
}
//uart_printf("LoadAddr: 0x%08x\n\r", LoadAddr);
memset((void *)LoadAddr,0,pFOTA_T->fbf_file_size);
//fota_dump_buffer("MasterBlockHeader",(unsigned char *)pFOTA_T->fbf_flash_address+QSPI_FLASH_BASE,0,sizeof(MasterBlockHeader));
memcpy((void *)LoadAddr,(void*)(pFOTA_T->fbf_flash_address+QSPI_FLASH_BASE),pFOTA_T->fbf_file_size);
pMasterHeader = (MasterBlockHeader *)LoadAddr;
if (pMasterHeader->Format_Version != 11){
Retval = FBF_VersionNotMatch;
goto error;
}
if (pMasterHeader->nOfDevices != 1){
Retval = FBF_DeviceMoreThanOne;
goto error;
}
temp_p = pMasterHeader->deviceHeaderOffset[0] + LoadAddr;
pDevHeader_11 = (PDeviceHeader_11)temp_p;
for ( imagenum = pDevHeader_11->nOfImages; imagenum > 0; imagenum -- )
{
temp_p = (UINT32)&pDevHeader_11->imageStruct_11[imagenum - 1];
pImage_11 = (PImageStruct_11)temp_p;
updaterSize = get_updater_copy_size();
updateImageSize = pImage_11->length;
uart_printf("[OTA] Flash_Start_Address: 0x%08x length: 0x%08x\n\r", pImage_11->Flash_Start_Address,updateImageSize);
uart_printf("[OTA] get_updater_start_addr: 0x%08x get_updater_copy_size: 0x%08x\n\r", get_updater_start_addr(),updaterSize);
if(updateImageSize & (FLASH_4K_SIZE-1)){
updateImageSize += (FLASH_4K_SIZE - updateImageSize & (FLASH_4K_SIZE-1));
}
if(get_updater_start_addr()!=(pImage_11->Flash_Start_Address+QSPI_FLASH_BASE) || updaterSize < updateImageSize)
{
Retval = NotOtaUpdaterError;
goto error;
}
uart_printf("[OTA] boot ota updater, nOfImages: %d\n\r",pDevHeader_11->nOfImages);
ImageAddr = LoadAddr+((pImage_11->First_Sector+7)<<ALIGN_1K_SIZE);
// add checksum for images in FBF file
imageChecksum = CalcImageChecksum((UINT32*)ImageAddr, pImage_11->length,0);
if (imageChecksum != pImage_11->ChecksumFormatVersion2){
Retval = CRCFailedError;
uart_printf("[OTA]fbf file CORRUPT,checksum failed\n\r");
goto error;
}
if(pImage_11->ChecksumFormatVersion2==0){
continue;
}
uart_printf("[OTA] Flash_Start_Address: 0x%08X, EraseLen: 0x%08X, length=0x%08X\n\r",
pImage_11->Flash_Start_Address,pImage_11->Flash_erase_size,pImage_11->length);
Retval=OTA_Update_FotaImage( ImageAddr, pImage_11->length, pImage_11->Flash_Start_Address);
if (Retval != NoError )
goto error;
}
tiny_free((void*)LoadAddr);
LoadAddr=0;
memset(param->fotaFlag,0,ASR_FOTA_FLAG_LEN_MAX);
param->mini_sys_enable = 0;
OTA_Update_FotaParam((UINT32)param, sizeof(struct fota_param),get_fota_param_start_addr()-QSPI_FLASH_BASE);
uart_printf("[OTA] Clear upgrade flag OK\r\n");
pFOTA_T->header = 0;
pFOTA_T->upgrade_flag = 0;
pFOTA_T->upgrade_method = 0;
pFOTA_T->checksum = 0;
Retval = OTA_Update_FotaParam((UINT32)pFOTA_T, sizeof(struct fota_firmwar_flag),FotaParamStartAddress);
if (Retval != NoError)
return Retval;
Retval = OTA_Update_FotaParam((UINT32)pFOTA_T, sizeof(struct fota_firmwar_flag),FotaParamStartAddress + FLASH_4K_SIZE);
if (Retval != NoError)
return Retval;
uart_printf("[OTA] Clear fota param OK\r\n");
return NoError;
error:
//free buffers
uart_printf("[OTA]ota updater,Retval=%x\n\r", Retval);
if(LoadAddr) tiny_free((void*)LoadAddr);
return Retval;
}
#endif
#endif
#define UpdaterExecAddress 0x7E040000//bind on updater build sct loader config
#define UpdaterVersionIndex 0x00800//bind on updater build sct loader config
UpdaterHeaderInfo updater_version_vb={0};
extern _ptentry *updater_Entry;
void get_updater_vb(void)
{
#ifdef SUPPORT_EXTERNAL_NORFLASH
_ptentry *fipEntry = ptable_find_entry("updater");
#endif
#ifdef BOOT33_SECBOOT_SUPPORT
#ifdef BOOT33_SECBOOT_V2
if(secboot_is_fuse_enabled()==1){
#endif
fip_image_t fip_item;
//[sec.0]secboot init from updater partition
// which is updater.bin with a secboot ToC struct with only one FIP header
// for updater.bin
//
// |----------------|
// | FIP Header |
// |----------------|
// | Updater.bin |
// |----------------|
#ifdef SUPPORT_EXTERNAL_NORFLASH
unsigned char * updater_buf = NULL;
if(fipEntry->vstart >= 0x90000000){ //����updater������flash
updater_buf = malloc(fipEntry->size);
memset(updater_buf, 0, fipEntry->size);
crane_ext_spi_read(fipEntry->start, (unsigned int)updater_buf, fipEntry->vsize);
fip_open((void*)updater_buf);
}else
#endif
{ //updater������flash
secboot_init("updater");
}
//[sec.1]do updater verify
//Timer0_enable(TRUE);
//secboot_item_check(ITEM_UPDATER);
//Timer0_enable(FALSE);
//[sec.2]get info from fip of updater.bin
secboot_item_get_img_addr_size(ITEM_UPDATER,(fip_image_handle)&fip_item);
//[sec.3]for debug to dump header of real updater.bin
//display_binary((void *)(fip_item.start+fip_item.offset),256);
//[sec.4]load updater_a or updater_b to psram
memcpy(&updater_version_vb,
(void *)(fip_item.start+fip_item.offset),
sizeof(UpdaterHeaderInfo));
//memcpy( (void *)UpdaterExecAddress,
// (void *)(fip_item.start+fip_item.offset),
// fip_item.size
// );
#ifdef BOOT33_SECBOOT_V2
secboot_deinit();
}
else{
#ifdef SUPPORT_EXTERNAL_NORFLASH
if(fipEntry->vstart >= 0x90000000){ //����updater������flash
crane_ext_spi_read(fipEntry->start, (unsigned int)&updater_version_vb, sizeof(UpdaterHeaderInfo));
}else
#endif
memcpy(&updater_version_vb,get_updater_start_addr(),sizeof(UpdaterHeaderInfo));
}
#endif
#else
#ifdef SUPPORT_EXTERNAL_NORFLASH
if(fipEntry->vstart >= 0x90000000){ //����updater������flash
crane_ext_spi_read(fipEntry->start, (unsigned int)&updater_version_vb, sizeof(UpdaterHeaderInfo));
}else
#endif
memcpy(&updater_version_vb,get_updater_start_addr(),sizeof(UpdaterHeaderInfo));
#endif
asr_property_set("updater.version",updater_version_vb.version_union.version_info_block.string);
asr_property_set("updater.solution",updater_version_vb.fota_solution_union.fota_solution_block.string);
CP_LOGD("[OTA] get updater version %s !\r\n",updater_version_vb.version_union.version_info_block.string);
CP_LOGD("[OTA] get updater solution %s !\r\n",updater_version_vb.fota_solution_union.fota_solution_block.string);
}
UINT32 UncompressUpdater(struct fota_firmwar_flag *fotaPara,unsigned char * address)
{
UINT32 res = NoError;
int outLen = -1;
unsigned int inLen = fotaPara->ota_header.mini_ota_head.nonDiffInfo.updater_size;
unsigned int offset = fotaPara->ota_header.mini_ota_head.nonDiffInfo.updater_offset;
unsigned char * inAddr = NULL,*dfota_buf=NULL;
if(inLen==0){
return NotFoundError;
}
CP_LOGD("[OTA] updater_addr [0x%.08x]\r\n", fotaPara->ota_header.mini_ota_head.nonDiffInfo.updater_addr);
if(fotaPara->ota_header.mini_ota_head.nonDiffInfo.updater_addr){
inAddr = fotaPara->ota_header.mini_ota_head.nonDiffInfo.updater_addr;
inAddr += QSPI_FLASH_BASE;
}else{
CP_LOGD("[OTA] first_flash_addr[0x%.08x], first_file_size[0x%.08x]\r\n", fotaPara->ota_header.mini_ota_head.first_flash_addr,fotaPara->ota_header.mini_ota_head.first_file_size);
CP_LOGD("[OTA] second_flash_address[0x%.08x], second_file_size[0x%.08x]\r\n", fotaPara->ota_header.mini_ota_head.second_flash_address,fotaPara->ota_header.mini_ota_head.second_file_size);
dfota_buf = (unsigned char *)tiny_malloc(fotaPara->ota_header.mini_ota_head.first_file_size + fotaPara->ota_header.mini_ota_head.second_file_size);
crane_qspi_read(fotaPara->ota_header.mini_ota_head.first_flash_addr - QSPI_FLASH_BASE, dfota_buf, fotaPara->ota_header.mini_ota_head.first_file_size);
if(fotaPara->ota_header.mini_ota_head.second_flash_address && fotaPara->ota_header.mini_ota_head.second_file_size){
crane_qspi_read(fotaPara->ota_header.mini_ota_head.second_flash_address - QSPI_FLASH_BASE, dfota_buf + fotaPara->ota_header.mini_ota_head.first_file_size, fotaPara->ota_header.mini_ota_head.second_file_size);
}
inAddr = dfota_buf + offset;
}
if(!LzmaUncompress((unsigned char *)address,(size_t *)&outLen, (const unsigned char *)inAddr, (size_t *)&inLen))
{
CP_LOGD("[OTA] released updater size [0x%.08x] inLen[0x%.08x]\r\n", outLen,inLen);
memcpy(&updater_version_vb,address,sizeof(UpdaterHeaderInfo));
if(updater_version_vb.loadtable_union.loadtable_block.magic != UPDATER_VALID_MAGIC){
res = UpdaterMagicError;
}else{
res=check_updater_ram(address,outLen);
if(res){
res = CheckUpdaterError;
}
}
}else{
res = UnpressedUpdaterError;
}
return res;
}
void ota_entry(void) {
volatile unsigned long FotaParamStartAddress;
volatile unsigned long FotaParamEndAddress;
struct fota_param param;
unsigned long entry_mini_system_only=0;
struct fota_firmwar_flag *fotaPara_1=NULL;
struct fota_firmwar_flag *fotaPara_2=NULL;
struct fota_firmwar_flag *fotaPara=NULL;
UINT32 Retval = NoError;
UpdaterHeaderInfo updater_version;
#ifdef SUPPORT_EXTERNAL_NORFLASH
_ptentry *fipEntry = ptable_find_entry("updater");
#endif
//detect whether fota partition supported
FotaParamStartAddress = get_fota_param_start_addr();
FotaParamEndAddress = get_fota_param_end_addr();
if(FotaParamStartAddress == FotaParamEndAddress){
CP_LOGE("[OTA] FotaParamStartAddress == FotaParamEndAddress , FOTA not supported\r\n");
return;
}
#if (!defined(BOOT33_FOTA_NO_UPDATER) || !defined(LTEONLY_SINGLE_SIM))
#if (!defined(CRANEM_SINGLE_SIM))
if(updater_Entry){
get_updater_vb();
asr_property_dump();
}
#endif
#endif
//check OTA flag or
memcpy(&param,(void *)FotaParamStartAddress,sizeof(struct fota_param));
//if(!strncmp(fota_flag,"ASROTA",6) || Keypad_OTA_Flag_Check_B()){
if(!strncmp((char *)param.fotaFlag,"ASROTA",6) ){
UINT32 stack=0x7e200000;
//The bspatch/lzma lib needs malloc/free APIs
UINT32 poolLen = 0x00600000;
malloc_init(stack, poolLen);
#if (!defined(BOOT33_FOTA_NO_UPDATER) || !defined(LTEONLY_SINGLE_SIM))
#if (!defined(CRANEM_SINGLE_SIM))
if(updater_Entry){
#ifdef SUPPORT_EXTERNAL_NORFLASH
if(get_updater_start_addr() >= 0x90000000){
crane_ext_spi_read(get_updater_start_addr()-0x90000000, (unsigned int)&updater_version, sizeof(UpdaterHeaderInfo));
}else
#endif
memcpy(&updater_version,get_updater_start_addr(),sizeof(UpdaterHeaderInfo));
CP_LOGD("[OTA] get updater version %s !\r\n",updater_version.version_union.version_info_block.string);
}
#endif
#endif
fotaPara_1=(struct fota_firmwar_flag*)tiny_malloc(sizeof(struct fota_firmwar_flag));
fotaPara_2=(struct fota_firmwar_flag*)tiny_malloc(sizeof(struct fota_firmwar_flag));
memcpy(fotaPara_1,(void *)(FotaParamStartAddress+FLASH_4K_SIZE),sizeof(struct fota_firmwar_flag));
memcpy(fotaPara_2,(void *)(FotaParamStartAddress+2*FLASH_4K_SIZE),sizeof(struct fota_firmwar_flag));
if(fotaPara_1->checksum!=CalcImageChecksum((UINT32*)fotaPara_1,sizeof(struct fota_firmwar_flag)-sizeof(unsigned int),0)
|| fotaPara_1->header != FOTA_HEADER_MAGIC){
if(fotaPara_2->checksum!=CalcImageChecksum((UINT32*)fotaPara_2,sizeof(struct fota_firmwar_flag)-sizeof(unsigned int),0)
|| fotaPara_2->header != FOTA_HEADER_MAGIC){
CP_LOGD("[OTA] fotaPara error!!!\r\n");
goto done;
}else{
CP_LOGD("[OTA]using fotaPara_2,not copy temp flash\r\n");
fotaPara = fotaPara_2;
}
}else{
if(fotaPara_2->checksum!=CalcImageChecksum((UINT32*)fotaPara_2,sizeof(struct fota_firmwar_flag)-sizeof(unsigned int),0)
|| fotaPara_2->header != FOTA_HEADER_MAGIC){
fotaPara = fotaPara_1;
CP_LOGD("[OTA]using fotaPara_1,need copy temp flash\r\n");
}else{
if(fotaPara_1->index > fotaPara_2->index){
fotaPara = fotaPara_1;
CP_LOGD("[OTA]using fotaPara_1,need copy temp flash\r\n");
}else{
fotaPara = fotaPara_2;
CP_LOGD("[OTA]using fotaPara_2,not copy temp flash,checksum[%08x]\r\n",fotaPara_2->checksum);
}
}
}
if(param.mini_sys_enable==1){
mini_system_enable=1;
if(fotaPara->ota_header.mini_ota_head.mini_dfota_status==MINI_SYS_DFOTA_START){
CP_LOGD("[OTA]MINI_SYS_DFOTA_START\r\n");
entry_mini_system_only = 1;
}else if(fotaPara->ota_header.mini_ota_head.mini_dfota_status>=MINI_SYS_DFOTA_DONE){
entry_mini_system_only = 1;
CP_LOGD("[OTA]MINI_SYS_DFOTA_DONE\r\n");
}
if(entry_mini_system_only==1){
asr_property_set("mini.sys.enable","1");
tiny_free(fotaPara_1);
tiny_free(fotaPara_2);
uart_printf("[OTA]ENTRY MINI SYSTEM ONLY\r\n");
return;
}
#if defined(BOOT33_FOTA_NO_UPDATER)
if(!updater_Entry){
Retval=UncompressUpdater(fotaPara,UpdaterExecAddress);
CP_LOGD("[OTA]UncompressUpdater[%d] %s !!!\r\n",Retval,Retval?"error":"success");
if(Retval != NoError){
CP_LOGE("[OTA] no updater paritition,parse updater failed[%02x]!!!\r\n",Retval);
tiny_free(fotaPara_1);
tiny_free(fotaPara_2);
return;
}
}
#endif
tiny_free(fotaPara_1);
tiny_free(fotaPara_2);
}
#if (!defined(BOOT33_FOTA_NO_UPDATER) || !defined(LTEONLY_SINGLE_SIM))
#if (!defined(CRANEM_SINGLE_SIM))
else{
Retval=System_ota_updater(fotaPara,&param,FotaParamStartAddress+FLASH_4K_SIZE-QSPI_FLASH_BASE);
if(Retval==0){
CP_LOGD("[OTA]System_ota_updater success!\r\n");
#ifdef SUPPORT_EXTERNAL_NORFLASH
if(get_updater_start_addr() >= 0x90000000){
crane_ext_spi_read(get_updater_start_addr()-0x90000000, (unsigned int)&updater_version, sizeof(UpdaterHeaderInfo));
}else
#endif
memcpy(&updater_version,get_updater_start_addr(),sizeof(UpdaterHeaderInfo));
CP_LOGD("[OTA] get new updater version %s !\r\n",updater_version.version_union.version_info_block.string);
tiny_free(fotaPara_1);
tiny_free(fotaPara_2);
return;
}
tiny_free(fotaPara_1);
tiny_free(fotaPara_2);
}
#endif
#endif
done:
#if (!defined(BOOT33_FOTA_NO_UPDATER) || !defined(LTEONLY_SINGLE_SIM))
#if (!defined(CRANEM_SINGLE_SIM))
#ifdef ADD_VIBRATOR_IN_CODE
//[0] Before jump to updater, disable vibrator
NingboVibratorDisable();
#endif
//[1] TODO:detect ADUPS flags
CP_LOGD("[OTA] ASROTA prefix detected or Keypad Flag detect!\r\n");
if(!updater_Entry){
if(Retval != NoError){
CP_LOGE("[OTA] no updater paritition,parse updater failed[%02x]!!!\r\n",Retval);
return;
}
goto jump;
}
#ifdef BOOT33_SECBOOT_SUPPORT
#ifdef BOOT33_SECBOOT_V2
if(secboot_is_fuse_enabled()==1){
#endif
fip_image_t fip_item;
//[sec.0]secboot init from updater partition
// which is updater.bin with a secboot ToC struct with only one FIP header
// for updater.bin
//
// |----------------|
// | FIP Header |
// |----------------|
// | Updater.bin |
// |----------------|
#ifdef SUPPORT_EXTERNAL_NORFLASH
unsigned char * updater_buf = NULL;
if(fipEntry->vstart >= 0x90000000){ //����updater������flash
updater_buf = malloc(fipEntry->size);
memset(updater_buf, 0, fipEntry->size);
crane_ext_spi_read(fipEntry->start, (unsigned int)updater_buf, fipEntry->vsize);
fip_open((void*)updater_buf);
}else
#endif
{ //updater������flash
secboot_init("updater");
}
//[sec.1]do updater verify
Timer0_enable(TRUE);
secboot_item_check(ITEM_UPDATER);
Timer0_enable(FALSE);
//[sec.2]get info from fip of updater.bin
secboot_item_get_img_addr_size(ITEM_UPDATER,(fip_image_handle)&fip_item);
//[sec.3]for debug to dump header of real updater.bin
//display_binary((void *)(fip_item.start+fip_item.offset),256);
//[sec.4]load updater_a or updater_b to psram
memcpy( (void *)UpdaterExecAddress,
(void *)(fip_item.start+fip_item.offset),
fip_item.size
);
#ifdef BOOT33_SECBOOT_V2
}else{
//[2] TODO:load updater_a or updater_b to psram
#ifdef SUPPORT_EXTERNAL_NORFLASH
if(fipEntry->vstart >= 0x90000000){ //����updater������flash
crane_ext_spi_read(fipEntry->start, (unsigned int)UpdaterExecAddress, get_updater_copy_size());
}else
#endif
{
memcpy( (void *)UpdaterExecAddress,
(void *)get_updater_start_addr(),
get_updater_copy_size());
}
}
#endif
#else
//[2] TODO:load updater_a or updater_b to psram
#ifdef SUPPORT_EXTERNAL_NORFLASH
if(fipEntry->vstart >= 0x90000000){ //����updater������flash
crane_ext_spi_read(fipEntry->start, (unsigned int)UpdaterExecAddress, get_updater_copy_size());
}else
#endif
{
memcpy( (void *)UpdaterExecAddress,
(void *)get_updater_start_addr(),
get_updater_copy_size());
}
#endif
#endif
#endif
jump:
//[3] jump to execute updater
CP_LOGD("\r\n >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
CP_LOGD("\r\n >> BOOTLOADER DONE JUMP TO UPDATER");
CP_LOGD("\r\n >> PC : 0x%x",UpdaterExecAddress);
CP_LOGD("\r\n >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\r\n");
TransferControl(UpdaterExecAddress);
}else{
CP_LOGD("[OTA] NO FOTA FLAG DETECTED \r\n");
}
}
#endif