📄 firm_update.c
字号:
/******************************************************************************
* Filename : Firm_update.c
* Start : 2003. 8. 22
* By : Taejin Kwon
* Contact : eric.kwon@samsung.com
* Description :
******************************************************************************
*/
/******************************************************
* INCLUDES
*****************************************************/
#include <string.h>
#include <stdio.h>
#include "Basic_typedefs.h"
#include "CUSTOM/Custom_option.h"
#include "OS/OS_abstract.h"
#include "API/SH_types.h"
#include "API/SH_api.h"
#include "COMMON/Common.h"
#include "MAIN/Global_state.h"
#include "MAIN/Appl_types.h"
#include "CUSTOM/Osd_types.h"
#include "CUSTOM/Osd_if.h"
#include "CUSTOM/Key_handler_setup.h"
#include "CUSTOM/Key_receive.h"
#include "CUSTOM/Key_defs.h"
#include "MAIN/DVD/Dvd_predef.h"
#include "MAIN/DVD/Dvd_common.h"
#include "DRIVER/FS/Fs_api.h"
#include "CUSTOM/FP_handle.h"
#include "CUSTOM/Firm_update.h"
#include "DRIVER/FLASH/Flash_api.h"
/******************************************************
* Global variables / functions
*****************************************************/
volatile BOOL gCd_firm_upgrading = FALSE; /* To check firmware upgrade */
BYTE1 *gFirm_down_addr;
NCHAR gFirm_new_ver[17];
NCHAR gFirm_new_id[17];
UINT gFirm_rom_addr = 0;
SysQueue_t *gQ_firm = NULL;
/******************************************************
* Extern variables / functions
*****************************************************/
extern volatile BOOL gbMain_loop;
extern volatile BOOL gTray_open;
extern volatile BOOL gLoading_on;
extern LBA giReserved_file_lba;
extern UINT giReserved_file_size;
extern void Door_Open(void);
#if _APP_CAP_FUNC_FIRMUP_BY_USB
FS_Drive_et gpstFirm_mount = FS_DRV_NULL;
FS_Entry_st *gpstFirm_files = NULL;
FS_File_t giFirm_fid = 0;
STATIC BOOL DownloadFirmwareImage( FS_File_t fid, LBA start, UINT size )
{
UINT remain_size = size;
FS_RETURN ret;
BYTE1 *dst;
UINT req_size = 0, byteoffset = 0;
#if _API_CAP_USE_USB_HOST
if( GetDiscState() == FIRM_USB )
{
req_size = FIRM_SECTOR_SIZE * FIRM_DUMP_NUMBER_DVD;
} else
#endif
{
if( SH_FE_GetMediaType() == SH_MEDIA_CD_ROM )
{
req_size = FIRM_SECTOR_SIZE * FIRM_DUMP_NUMBER_CD;
} else {
req_size = FIRM_SECTOR_SIZE * FIRM_DUMP_NUMBER_DVD;
}
}
/* Set destination address */
gFirm_down_addr = (BYTE1 *)S5H_GetFrameBufferAddress();
dst = gFirm_down_addr;
SysPrintf("[FIRM] Start address for downloading: 0x%x", dst);
while( remain_size > 0 )
{
if( remain_size >= req_size )
{
if( GetDiscState() == FIRM_USB )
ret = FAT_Read(fid, dst, byteoffset, req_size, 0,0,0);
else
ret = FS_Read(fid, dst, byteoffset, req_size, FS_READ_MODE_DUMP);
if( ret != FS_RET_NO_ERROR )
break;
/* set next info */
remain_size = remain_size - req_size;
byteoffset += req_size;
dst = (BYTE1 *)(dst + req_size);
} else {
if( GetDiscState() == FIRM_USB )
ret = FAT_Read(fid, dst, byteoffset, remain_size, 0,0,0);
else
ret = FS_Read(fid, dst, byteoffset, remain_size, FS_READ_MODE_DUMP);
if( ret != FS_RET_NO_ERROR )
break;
remain_size = 0;
}
SysPrintf( "\n[FIRM] 0x%x image downloaded", size - remain_size );
}
if( remain_size == 0 )
return TRUE;
else
return FALSE;
}
/******************************************************************************
* Function name : FirmFileListCheck
* Arguments :
* IN SH_MediaType_et disc
* OUT
* I/O
* Return : STATIC BOOL
*
* By : Taejin Kwon
* Description :
* Revision : 1.0
******************************************************************************
*/
STATIC BOOL FirmFileListCheck( SH_MediaType_et disc )
{
/*
Mount media
*/
if( disc == SH_MEDIA_CD_ROM )
{
if( FS_Mount( FS_DEVICE_CD, FS_JOLIET, &gpstFirm_mount ) != FS_RET_NO_ERROR )
{
if( FS_Mount( FS_DEVICE_CD, FS_UDF, &gpstFirm_mount ) != FS_RET_NO_ERROR )
{
return FALSE;
}
}
}
#if _API_CAP_USE_USB_HOST
else if( disc == SH_MEDIA_USB_HOST )
{
if(FS_Mount( FS_DEVICE_USB, FS_FAT, &gpstFirm_mount ) != FS_RET_NO_ERROR )
{
return FALSE;
}
}
#endif
else
{
if( FS_Mount( FS_DEVICE_DVD, FS_UDF, &gpstFirm_mount ) != FS_RET_NO_ERROR )
{
if( FS_Mount( FS_DEVICE_DVD, FS_JOLIET, &gpstFirm_mount ) != FS_RET_NO_ERROR )
{
return FALSE;
}
}
}
/*
Check files
*/
gpstFirm_files = FS_ListEntry(gpstFirm_mount, NULL, FS_SELF_DIR_NAME,
0, FS_CAP_LIST_FILE|FS_CAP_FILE_FW);
if( gpstFirm_files == NULL )
{
FS_Unmount(gpstFirm_mount);
return FALSE;
}
return TRUE;
}
#else
/******************************************************************************
* Function name : FirmwareBlockCopy
* Arguments :
* IN addr: start lba
* num : number of sectors
* *dst : destination address
* OUT
* INOUT
* Return :
* TRUE :
* FALSE:
* By : Taejin Kwon
* Description :
******************************************************************************
*/
BOOL FirmwareBlockCopy( LBA addr, UINT num, BYTE1 *dst )
{
UINT timeout = 0;
UINT sector_cnt = 0;
BYTE1 *temp_dump;
BYTE1 *dump_addr;
SH_RETURN dump_ret;
UINT cd_mode;
S5H_SectorFormat_et sector_mode;
UINT header_size;
BOOL err_result = FALSE; /* final result is error in TRUE */
SH_FeParam_st param;
temp_dump = SysAppMalloc( FIRM_DUMP_NUMBER * FIRM_DUMP_SECTOR_SIZE * sizeof(UCHAR) );
if( temp_dump == NULL )
{
SysPrintf("\n[FIRM] Dump location error %s %d", __FILE__, __LINE__);
return FALSE;
}
timeout = 0;
while( timeout < FIRM_DUMP_RETRY_COUNT )
{
dump_addr = temp_dump;
param.addr = dump_addr;
param.end_offset = 0;
param.start_offset = 0;
param.read_option = SH_FE_READ_MODE_DUMP;
param.is_last = TRUE;
param.mode = SH_PLAY_NORMAL;
dump_ret = SH_FE_ReadCD( addr, num, param );
if( dump_ret == SH_RET_NO_ERROR )
{
err_result = FALSE;
/* Check CD Mode Information */
cd_mode = GetCdModeInfo( dump_addr );
if( cd_mode != 1 && cd_mode != 2 )
{
if( timeout == FIRM_DUMP_RETRY_COUNT - 1)
{
err_result = TRUE;
}
/* retry */
timeout++;
continue;
}
if( cd_mode == 1 )
sector_mode = SECTOR_CD_RAW_2352;
else if( cd_mode == 2 )
sector_mode = SECTOR_CD_RAW_2352_XA;
else
sector_mode = SECTOR_CD_RAW_2352;
/* Check EDC */
if( EDCCheck( (UCHAR *)dump_addr, FIRM_DUMP_NUMBER/*, sector_mode */ ) != 0 )
{
SysPrintf("\n[FIRM] Downloaded data EDC error. >%d<", sector_cnt+1);
err_result = TRUE;
break;
}
if( err_result == FALSE )
break;
}
timeout++;
}
if( timeout == FIRM_DUMP_RETRY_COUNT )
{
SysPrintf("\n[FIRM] Block Copy: Cannot dump. %s %d",
__FILE__, __LINE__);
SysFree( temp_dump );
return FALSE;
}
/* Extract User Data from dumped data and coyp to downloading arrea */
if( cd_mode == 1 ) header_size = 16;
else if( cd_mode == 2 ) header_size = 24;
dump_addr = temp_dump;
for( sector_cnt = 0; sector_cnt < FIRM_DUMP_NUMBER; sector_cnt++ )
{
memcpy( dst, dump_addr+header_size, FIRM_SECTOR_SIZE );
dst += FIRM_SECTOR_SIZE;
dump_addr += FIRM_DUMP_SECTOR_SIZE;
}
SysFree( temp_dump );
return TRUE;
}
/******************************************************************************
* Function name : DownloadFirmwareImage
* Arguments :
* IN
* OUT
* INOUT
* Return :
* TRUE : it has dummy file
* FALSE: it has no dummy file.
* By : Taejin Kwon
* Description :
******************************************************************************
*/
BOOL DownloadFirmwareImage( LBA start, UINT size )
{
LBA next_lba = start;
UINT remain_size = size;
UINT num_sec = 0, mod;
BOOL ret = TRUE;
BYTE1 *dst;
/* Set destination address */
gFirm_down_addr = (BYTE1 *)S5H_GetFrameBufferAddress();
dst = gFirm_down_addr;
SysPrintf("[FIRM] Start address for downloading: 0x%x", dst);
while( remain_size > 0 )
{
if( remain_size >= (FIRM_SECTOR_SIZE*FIRM_DUMP_NUMBER) )
{
SysPrintf( "\n[FIRM] 0x%x image downloaded", size - remain_size );
ret = FirmwareBlockCopy( next_lba, FIRM_DUMP_NUMBER, dst );
if( ret == FALSE )
break;
/* set next info */
remain_size = remain_size - (FIRM_SECTOR_SIZE*FIRM_DUMP_NUMBER);
next_lba = next_lba + FIRM_DUMP_NUMBER;
dst = (BYTE1 *)(dst + (FIRM_SECTOR_SIZE*FIRM_DUMP_NUMBER));
} else {
num_sec = remain_size / FIRM_SECTOR_SIZE;
mod = remain_size % FIRM_SECTOR_SIZE;
if( mod > 0 )
num_sec = num_sec + 1;
ret = FirmwareBlockCopy( next_lba, num_sec, dst);
if( ret == FALSE )
break;
remain_size = 0;
}
}
if( remain_size == 0 )
return TRUE;
else
return FALSE;
}
#endif
/******************************************************************************
* Function name : IsThisRightFirmImage
* Arguments :
* IN addr : downloaded memory
* OUT
* INOUT
* Return :
* TRUE : it has firmware source.
* FALSE: it has no firmware source.
* By : Taejin Kwon
* Description :
* Firmware check data(Header data for firmware image is defined in
* the 3rd sector of the source image. Ref. DT#7
*
* id : from FIRM_CHECK_LOCATION_ADDR to 16bytes
* version : from end of id to 16 bytes
* checkbytes : from end of version to 16 bytes
* reserved : 16 bytes
*
* 0 15
* +----------------------------+
* | |
* | id |
* +----------------------------+
* | |
* | version |
* +----------------------------+
* | |
* | check bytes |
* +----------------------------+
* | |
* | reserved |
* +----------------------------+
*
* 2005.12.12 : ROM file format changed by Rommaker
*
* 0xFBFC0 0 8 12 15
* +-------------+-------+--------+
* | | addr1 | addr 0 |
* +------------------------------+
* | Check byte |
* +------------------------------+
* | Version string |
* +------------------------------+
* |A5A5A5A55A5A5A5A |
* +------------------------------+
******************************************************************************
*/
BOOL IsThisRightFirmImage( BYTE1 *src, UINT size )
{
UINT i;
NCHAR pszId[17], pszVer[17], pszCheck[17];
NCHAR *pStr = (NCHAR*)CURRENT_FIRM_ID;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -