2018-07-13 01:31:50 +00:00
/*
* ( C ) Copyright 2007 - 2013
* Allwinner Technology Co . , Ltd . < www . allwinnertech . com >
* Jerry Wang < wangflord @ allwinnertech . com >
*
* See file CREDITS for list of people who contributed to this
* project .
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation ; either version 2 of
* the License , or ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston ,
* MA 02111 - 1307 USA
*/
# include <config.h>
# include <common.h>
# include <malloc.h>
# include "sparse/sparse.h"
# include <asm/arch/queue.h>
# include <sunxi_mbr.h>
# include <sys_partition.h>
# include <private_boot0.h>
# include <private_uboot.h>
2018-12-13 10:48:25 +00:00
# include <private_toc.h>
2018-07-13 01:31:50 +00:00
# include "encrypt/encrypt.h"
# include "sprite_queue.h"
# include "sprite_download.h"
# include "sprite_verify.h"
# include "firmware/imgdecode.h"
# include "dos_part.h"
# include <boot_type.h>
# include <mmc.h>
# include <sys_config.h>
# include <private_boot0.h>
# include <sunxi_board.h>
# define SPRITE_CARD_HEAD_BUFF (32 * 1024)
# if defined (CONFIG_SUNXI_SPINOR)
# define SPRITE_CARD_ONCE_DATA_DEAL (2 * 1024 * 1024)
# else
# define SPRITE_CARD_ONCE_DATA_DEAL (16 * 1024 * 1024)
# endif
# define SPRITE_CARD_ONCE_SECTOR_DEAL (SPRITE_CARD_ONCE_DATA_DEAL / 512)
static void * imghd = NULL ;
static void * imgitemhd = NULL ;
DECLARE_GLOBAL_DATA_PTR ;
//extern int sunxi_flash_mmc_phywipe(unsigned long start_block, unsigned long nblock, unsigned long *skip);
static int __download_normal_part ( dl_one_part_info * part_info , uchar * source_buff ) ;
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* function
*
* name :
*
* parmeters :
*
* return :
*
* note :
*
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
uint sprite_card_firmware_start ( void )
{
return sunxi_partition_get_offset ( 1 ) ;
}
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* function
*
* name :
*
* parmeters :
*
* return :
*
* note :
*
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
int sprite_card_firmware_probe ( char * name )
{
debug ( " firmware name %s \n " , name ) ;
imghd = Img_Open ( name ) ;
if ( ! imghd )
{
return - 1 ;
}
return 0 ;
}
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* function
*
* name :
*
* parmeters :
*
* return :
*
* note :
*
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
int sprite_card_fetch_download_map ( sunxi_download_info * dl_map )
{
imgitemhd = Img_OpenItem ( imghd , " 12345678 " , " 1234567890DLINFO " ) ;
if ( ! imgitemhd )
{
return - 1 ;
}
debug ( " try to read item dl map \n " ) ;
if ( ! Img_ReadItem ( imghd , imgitemhd , ( void * ) dl_map , sizeof ( sunxi_download_info ) ) )
{
printf ( " sunxi sprite error : read dl map failed \n " ) ;
return - 1 ;
}
Img_CloseItem ( imghd , imgitemhd ) ;
imgitemhd = NULL ;
//检查获取的dlinfo是否正确
return sunxi_sprite_verify_dlmap ( dl_map ) ;
}
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* function
*
* name :
*
* parmeters :
*
* return :
*
* note :
*
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
int sprite_card_fetch_mbr ( void * img_mbr )
{
int mbr_num = SUNXI_MBR_COPY_NUM ;
if ( get_boot_storage_type ( ) = = STORAGE_NOR )
{
mbr_num = 1 ;
}
imgitemhd = Img_OpenItem ( imghd , " 12345678 " , " 1234567890___MBR " ) ;
if ( ! imgitemhd )
{
return - 1 ;
}
debug ( " try to read item mbr \n " ) ;
if ( ! Img_ReadItem ( imghd , imgitemhd , img_mbr , sizeof ( sunxi_mbr_t ) * mbr_num ) )
{
printf ( " sunxi sprite error : read mbr failed \n " ) ;
return - 1 ;
}
Img_CloseItem ( imghd , imgitemhd ) ;
imgitemhd = NULL ;
return sunxi_sprite_verify_mbr ( img_mbr ) ;
}
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* function
*
* name :
*
* parmeters :
*
* return :
*
* note :
*
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
static int __download_udisk ( dl_one_part_info * part_info , uchar * source_buff )
{
HIMAGEITEM imgitemhd = NULL ;
u32 flash_sector ;
s64 packet_len ;
s32 ret = - 1 , ret1 ;
//打开分区镜像
imgitemhd = Img_OpenItem ( imghd , " RFSFAT16 " , ( char * ) part_info - > dl_filename ) ;
if ( ! imgitemhd )
{
printf ( " sunxi sprite error: open part %s failed \n " , part_info - > dl_filename ) ;
return - 1 ;
}
//获取分区镜像字节数
packet_len = Img_GetItemSize ( imghd , imgitemhd ) ;
if ( packet_len < = 0 )
{
printf ( " sunxi sprite error: fetch part len %s failed \n " , part_info - > dl_filename ) ;
goto __download_udisk_err1 ;
}
if ( packet_len < = FW_BURN_UDISK_MIN_SIZE )
{
printf ( " download UDISK: the data length of udisk is too small, ignore it \n " ) ;
ret = 1 ;
goto __download_udisk_err1 ;
}
//分区镜像够大,需要进行烧录
flash_sector = sunxi_sprite_size ( ) ;
if ( ! flash_sector )
{
printf ( " sunxi sprite error: download_udisk, the flash size is invalid(0) \n " ) ;
goto __download_udisk_err1 ;
}
printf ( " the flash size is %d MB \n " , flash_sector / 2 / 1024 ) ; //计算出M单位
part_info - > lenlo = flash_sector - part_info - > addrlo ;
part_info - > lenhi = 0 ;
printf ( " UDISK low is 0x%x Sectors \n " , part_info - > lenlo ) ;
printf ( " UDISK high is 0x%x Sectors \n " , part_info - > lenhi ) ;
ret = __download_normal_part ( part_info , source_buff ) ;
__download_udisk_err1 :
ret1 = Img_CloseItem ( imghd , imgitemhd ) ;
if ( ret1 ! = 0 )
{
printf ( " sunxi sprite error: __download_udisk, close udisk image failed \n " ) ;
return - 1 ;
}
return ret ;
}
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* function
*
* name :
*
* parmeters :
*
* return :
*
* note :
*
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
static int __download_normal_part ( dl_one_part_info * part_info , uchar * source_buff )
{
uint partstart_by_sector ; //分区起始扇区
uint tmp_partstart_by_sector ;
s64 partsize_by_byte ; //分区大小(字节单位)
s64 partdata_by_byte ; //需要下载的分区数据(字节单位)
s64 tmp_partdata_by_bytes ;
uint onetime_read_sectors ; //一次读写的扇区数
uint first_write_bytes ;
uint imgfile_start ; //分区数据所在的扇区
uint tmp_imgfile_start ;
u8 * down_buffer = source_buff + SPRITE_CARD_HEAD_BUFF ;
int partdata_format ;
int ret = - 1 ;
//*******************************************************************
//获取分区起始扇区
tmp_partstart_by_sector = partstart_by_sector = part_info - > addrlo ;
//获取分区大小,字节数
partsize_by_byte = part_info - > lenlo ;
partsize_by_byte < < = 9 ;
//打开分区镜像
imgitemhd = Img_OpenItem ( imghd , " RFSFAT16 " , ( char * ) part_info - > dl_filename ) ;
if ( ! imgitemhd )
{
printf ( " sunxi sprite error: open part %s failed \n " , part_info - > dl_filename ) ;
return - 1 ;
}
//获取分区镜像字节数
partdata_by_byte = Img_GetItemSize ( imghd , imgitemhd ) ;
if ( partdata_by_byte < = 0 )
{
printf ( " sunxi sprite error: fetch part len %s failed \n " , part_info - > dl_filename ) ;
goto __download_normal_part_err1 ;
}
printf ( " partdata hi 0x%x \n " , ( uint ) ( partdata_by_byte > > 32 ) ) ;
printf ( " partdata lo 0x%x \n " , ( uint ) partdata_by_byte ) ;
//如果分区数据超过分区大小
if ( partdata_by_byte > partsize_by_byte )
{
printf ( " sunxi sprite: data size 0x%x is larger than part %s size 0x%x \n " , ( uint ) ( partdata_by_byte / 512 ) , part_info - > dl_filename , ( uint ) ( partsize_by_byte / 512 ) ) ;
goto __download_normal_part_err1 ;
}
//准备读取分区镜像数据
tmp_partdata_by_bytes = partdata_by_byte ;
if ( tmp_partdata_by_bytes > = SPRITE_CARD_ONCE_DATA_DEAL )
{
onetime_read_sectors = SPRITE_CARD_ONCE_SECTOR_DEAL ;
first_write_bytes = SPRITE_CARD_ONCE_DATA_DEAL ;
}
else
{
onetime_read_sectors = ( tmp_partdata_by_bytes + 511 ) > > 9 ;
first_write_bytes = ( uint ) tmp_partdata_by_bytes ;
}
//开始获取分区数据
imgfile_start = Img_GetItemStart ( imghd , imgitemhd ) ;
if ( ! imgfile_start )
{
printf ( " sunxi sprite err : cant get part data imgfile_start %s \n " , part_info - > dl_filename ) ;
goto __download_normal_part_err1 ;
}
tmp_imgfile_start = imgfile_start ;
//读出第一笔固件中的分区数据, 大小为buffer字节数
if ( sunxi_flash_read ( tmp_imgfile_start , onetime_read_sectors , down_buffer ) ! = onetime_read_sectors )
{
printf ( " sunxi sprite error : read sdcard block %d, total %d failed \n " , tmp_imgfile_start , onetime_read_sectors ) ;
goto __download_normal_part_err1 ;
}
//下一个要读出的数据
tmp_imgfile_start + = onetime_read_sectors ;
//尝试查看是否sparse格式
partdata_format = unsparse_probe ( ( char * ) down_buffer , first_write_bytes , partstart_by_sector ) ; //判断数据格式
if ( partdata_format ! = ANDROID_FORMAT_DETECT )
{
//写入第一笔数据
if ( sunxi_sprite_write ( tmp_partstart_by_sector , onetime_read_sectors , down_buffer ) ! = onetime_read_sectors )
{
printf ( " sunxi sprite error: download rawdata error %s \n " , part_info - > dl_filename ) ;
goto __download_normal_part_err1 ;
}
tmp_partdata_by_bytes - = first_write_bytes ;
tmp_partstart_by_sector + = onetime_read_sectors ;
while ( tmp_partdata_by_bytes > = SPRITE_CARD_ONCE_DATA_DEAL )
{
//继续读出固件中的分区数据, 大小为buffer字节数
if ( sunxi_flash_read ( tmp_imgfile_start , SPRITE_CARD_ONCE_SECTOR_DEAL , down_buffer ) ! = SPRITE_CARD_ONCE_SECTOR_DEAL )
{
printf ( " sunxi sprite error : read sdcard block %d, total %d failed \n " , tmp_imgfile_start , SPRITE_CARD_ONCE_SECTOR_DEAL ) ;
goto __download_normal_part_err1 ;
}
//写入flash
if ( sunxi_sprite_write ( tmp_partstart_by_sector , SPRITE_CARD_ONCE_SECTOR_DEAL , down_buffer ) ! = SPRITE_CARD_ONCE_SECTOR_DEAL )
{
printf ( " sunxi sprite error: download rawdata error %s, start 0x%x, sectors 0x%x \n " , part_info - > dl_filename , tmp_partstart_by_sector , SPRITE_CARD_ONCE_SECTOR_DEAL ) ;
goto __download_normal_part_err1 ;
}
tmp_imgfile_start + = SPRITE_CARD_ONCE_SECTOR_DEAL ;
tmp_partdata_by_bytes - = SPRITE_CARD_ONCE_DATA_DEAL ;
tmp_partstart_by_sector + = SPRITE_CARD_ONCE_SECTOR_DEAL ;
}
if ( tmp_partdata_by_bytes > 0 )
{
uint rest_sectors = ( tmp_partdata_by_bytes + 511 ) > > 9 ;
//继续读出固件中的分区数据, 大小为buffer字节数
if ( sunxi_flash_read ( tmp_imgfile_start , rest_sectors , down_buffer ) ! = rest_sectors )
{
printf ( " sunxi sprite error : read sdcard block %d, total %d failed \n " , tmp_imgfile_start , rest_sectors ) ;
goto __download_normal_part_err1 ;
}
//写入flash
if ( sunxi_sprite_write ( tmp_partstart_by_sector , rest_sectors , down_buffer ) ! = rest_sectors )
{
printf ( " sunxi sprite error: download rawdata error %s, start 0x%x, sectors 0x%x \n " , part_info - > dl_filename , tmp_partstart_by_sector , rest_sectors ) ;
goto __download_normal_part_err1 ;
}
}
}
else
{
if ( unsparse_direct_write ( down_buffer , first_write_bytes ) )
{
printf ( " sunxi sprite error: download sparse error %s \n " , part_info - > dl_filename ) ;
goto __download_normal_part_err1 ;
}
tmp_partdata_by_bytes - = first_write_bytes ;
while ( tmp_partdata_by_bytes > = SPRITE_CARD_ONCE_DATA_DEAL )
{
//继续读出固件中的分区数据, 大小为buffer字节数
if ( sunxi_flash_read ( tmp_imgfile_start , SPRITE_CARD_ONCE_SECTOR_DEAL , down_buffer ) ! = SPRITE_CARD_ONCE_SECTOR_DEAL )
{
printf ( " sunxi sprite error : read sdcard block 0x%x, total 0x%x failed \n " , tmp_imgfile_start , SPRITE_CARD_ONCE_SECTOR_DEAL ) ;
goto __download_normal_part_err1 ;
}
//写入flash
if ( unsparse_direct_write ( down_buffer , SPRITE_CARD_ONCE_DATA_DEAL ) )
{
printf ( " sunxi sprite error: download sparse error %s \n " , part_info - > dl_filename ) ;
goto __download_normal_part_err1 ;
}
tmp_imgfile_start + = SPRITE_CARD_ONCE_SECTOR_DEAL ;
tmp_partdata_by_bytes - = SPRITE_CARD_ONCE_DATA_DEAL ;
}
if ( tmp_partdata_by_bytes > 0 )
{
uint rest_sectors = ( tmp_partdata_by_bytes + 511 ) > > 9 ;
//继续读出固件中的分区数据, 大小为buffer字节数
if ( sunxi_flash_read ( tmp_imgfile_start , rest_sectors , down_buffer ) ! = rest_sectors )
{
printf ( " sunxi sprite error : read sdcard block 0x%x, total 0x%x failed \n " , tmp_imgfile_start , rest_sectors ) ;
goto __download_normal_part_err1 ;
}
//写入flash
if ( unsparse_direct_write ( down_buffer , tmp_partdata_by_bytes ) )
{
printf ( " sunxi sprite error: download sparse error %s \n " , part_info - > dl_filename ) ;
goto __download_normal_part_err1 ;
}
}
}
tick_printf ( " successed in writting part %s \n " , part_info - > name ) ;
ret = 0 ;
if ( imgitemhd )
{
Img_CloseItem ( imghd , imgitemhd ) ;
imgitemhd = NULL ;
}
//判断是否需要进行校验
if ( part_info - > verify )
{
uint active_verify ;
uint origin_verify ;
uchar verify_data [ 1024 ] ;
ret = - 1 ;
if ( part_info - > vf_filename [ 0 ] )
{
imgitemhd = Img_OpenItem ( imghd , " RFSFAT16 " , ( char * ) part_info - > vf_filename ) ;
if ( ! imgitemhd )
{
printf ( " sprite update warning: open part %s failed \n " , part_info - > vf_filename ) ;
goto __download_normal_part_err1 ;
}
if ( ! Img_ReadItem ( imghd , imgitemhd , ( void * ) verify_data , 1024 ) ) //读出数据
{
printf ( " sprite update warning: fail to read data from %s \n " , part_info - > vf_filename ) ;
goto __download_normal_part_err1 ;
}
if ( partdata_format = = ANDROID_FORMAT_DETECT )
{
active_verify = sunxi_sprite_part_sparsedata_verify ( ) ;
}
else
{
active_verify = sunxi_sprite_part_rawdata_verify ( partstart_by_sector , partdata_by_byte ) ;
}
{
uint * tmp = ( uint * ) verify_data ;
origin_verify = * tmp ;
}
printf ( " origin_verify value = %x, active_verify value = %x \n " , origin_verify , active_verify ) ;
if ( origin_verify ! = active_verify )
{
printf ( " origin checksum=%x, active checksum=%x \n " , origin_verify , active_verify ) ;
printf ( " sunxi sprite: part %s verify error \n " , part_info - > dl_filename ) ;
goto __download_normal_part_err1 ;
}
ret = 0 ;
}
else
{
printf ( " sunxi sprite err: part %s unablt to find verify file \n " , part_info - > dl_filename ) ;
}
tick_printf ( " successed in verify part %s \n " , part_info - > name ) ;
}
else
{
printf ( " sunxi sprite err: part %s not need to verify \n " , part_info - > dl_filename ) ;
}
__download_normal_part_err1 :
if ( imgitemhd )
{
Img_CloseItem ( imghd , imgitemhd ) ;
imgitemhd = NULL ;
}
return ret ;
}
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* function
*
* name :
*
* parmeters :
*
* return :
*
* note :
*
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
static int __download_sysrecover_part ( dl_one_part_info * part_info , uchar * source_buff )
{
uint partstart_by_sector ; //分区起始扇区
uint tmp_partstart_by_sector ;
s64 partsize_by_byte ; //分区大小(字节单位)
s64 partdata_by_byte ; //需要下载的分区数据(字节单位)
s64 tmp_partdata_by_bytes ;
uint onetime_read_sectors ; //一次读写的扇区数
uint imgfile_start ; //分区数据所在的扇区
uint tmp_imgfile_start ;
u8 * down_buffer = source_buff + SPRITE_CARD_HEAD_BUFF ;
int ret = - 1 ;
//*******************************************************************
//获取分区起始扇区
tmp_partstart_by_sector = partstart_by_sector = part_info - > addrlo ;
//获取分区大小,字节数
partsize_by_byte = part_info - > lenlo ;
partsize_by_byte < < = 9 ;
//打开分区镜像
//获取分区镜像字节数
partdata_by_byte = Img_GetSize ( imghd ) ;
if ( partdata_by_byte < = 0 )
{
printf ( " sunxi sprite error: fetch part len %s failed \n " , part_info - > dl_filename ) ;
goto __download_sysrecover_part_err1 ;
}
//如果分区数据超过分区大小
if ( partdata_by_byte > partsize_by_byte )
{
printf ( " sunxi sprite: data size 0x%x is larger than part %s size 0x%x \n " , ( uint ) ( partdata_by_byte / 512 ) , part_info - > dl_filename , ( uint ) ( partsize_by_byte / 512 ) ) ;
goto __download_sysrecover_part_err1 ;
}
//准备读取分区镜像数据
tmp_partdata_by_bytes = partdata_by_byte ;
if ( tmp_partdata_by_bytes > = SPRITE_CARD_ONCE_DATA_DEAL )
{
onetime_read_sectors = SPRITE_CARD_ONCE_SECTOR_DEAL ;
}
else
{
onetime_read_sectors = ( tmp_partdata_by_bytes + 511 ) > > 9 ;
}
//开始获取分区数据
imgfile_start = sprite_card_firmware_start ( ) ;
if ( ! imgfile_start )
{
printf ( " sunxi sprite err : cant get part data imgfile_start %s \n " , part_info - > dl_filename ) ;
goto __download_sysrecover_part_err1 ;
}
tmp_imgfile_start = imgfile_start ;
while ( tmp_partdata_by_bytes > = SPRITE_CARD_ONCE_DATA_DEAL )
{
//继续读出固件中的分区数据, 大小为buffer字节数
if ( sunxi_flash_read ( tmp_imgfile_start , onetime_read_sectors , down_buffer ) ! = onetime_read_sectors )
{
printf ( " sunxi sprite error : read sdcard block %d, total %d failed \n " , tmp_imgfile_start , onetime_read_sectors ) ;
goto __download_sysrecover_part_err1 ;
}
//写入flash
if ( sunxi_sprite_write ( tmp_partstart_by_sector , onetime_read_sectors , down_buffer ) ! = onetime_read_sectors )
{
printf ( " sunxi sprite error: download rawdata error %s, start 0x%x, sectors 0x%x \n " , part_info - > dl_filename , tmp_partstart_by_sector , onetime_read_sectors ) ;
goto __download_sysrecover_part_err1 ;
}
tmp_imgfile_start + = onetime_read_sectors ;
tmp_partdata_by_bytes - = onetime_read_sectors * 512 ;
tmp_partstart_by_sector + = onetime_read_sectors ;
}
if ( tmp_partdata_by_bytes > 0 )
{
uint rest_sectors = ( tmp_partdata_by_bytes + 511 ) / 512 ;
//继续读出固件中的分区数据, 大小为buffer字节数
if ( sunxi_flash_read ( tmp_imgfile_start , rest_sectors , down_buffer ) ! = rest_sectors )
{
printf ( " sunxi sprite error : read sdcard block %d, total %d failed \n " , tmp_imgfile_start , rest_sectors ) ;
goto __download_sysrecover_part_err1 ;
}
//写入flash
if ( sunxi_sprite_write ( tmp_partstart_by_sector , rest_sectors , down_buffer ) ! = rest_sectors )
{
printf ( " sunxi sprite error: download rawdata error %s, start 0x%x, sectors 0x%x \n " , part_info - > dl_filename , tmp_partstart_by_sector , rest_sectors ) ;
goto __download_sysrecover_part_err1 ;
}
}
ret = 0 ;
__download_sysrecover_part_err1 :
if ( imgitemhd )
{
Img_CloseItem ( imghd , imgitemhd ) ;
imgitemhd = NULL ;
}
return ret ;
}
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* function
*
* name :
*
* parmeters :
*
* return :
*
* note :
*
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
int sunxi_sprite_deal_part ( sunxi_download_info * dl_map )
{
dl_one_part_info * part_info ;
int ret = - 1 ;
int ret1 ;
int i = 0 ;
uchar * down_buff = NULL ;
int rate ;
if ( ! dl_map - > download_count )
{
printf ( " sunxi sprite: no part need to write \n " ) ;
return 0 ;
}
rate = ( 70 - 10 ) / dl_map - > download_count ;
//初始化flash, nand或者mmc
if ( sunxi_sprite_init ( 1 ) )
{
printf ( " sunxi sprite err: init flash err \n " ) ;
return - 1 ;
}
//申请内存
down_buff = ( uchar * ) malloc ( SPRITE_CARD_ONCE_DATA_DEAL + SPRITE_CARD_HEAD_BUFF ) ;
if ( ! down_buff )
{
printf ( " sunxi sprite err: unable to malloc memory for sunxi_sprite_deal_part \n " ) ;
goto __sunxi_sprite_deal_part_err1 ;
}
for ( part_info = dl_map - > one_part_info , i = 0 ; i < dl_map - > download_count ; i + + , part_info + + )
{
tick_printf ( " begin to download part %s \n " , part_info - > name ) ;
if ( ! strncmp ( " UDISK " , ( char * ) part_info - > name , strlen ( " UDISK " ) ) )
{
ret1 = __download_udisk ( part_info , down_buff ) ;
if ( ret1 < 0 )
{
printf ( " sunxi sprite err: sunxi_sprite_deal_part, download_udisk failed \n " ) ;
goto __sunxi_sprite_deal_part_err2 ;
}
else if ( ret1 > 0 )
{
printf ( " do NOT need download UDISK \n " ) ;
}
} //如果是sysrecovery分区, 烧录完整分区镜像
else if ( ! strncmp ( " sysrecovery " , ( char * ) part_info - > name , strlen ( " sysrecovery " ) ) )
{
ret1 = __download_sysrecover_part ( part_info , down_buff ) ;
if ( ret1 ! = 0 )
{
printf ( " sunxi sprite err: sunxi_sprite_deal_part, download sysrecovery failed \n " ) ;
goto __sunxi_sprite_deal_part_err2 ;
}
} //如果是private分区, 检查是否需要烧录
else if ( ! strncmp ( " private " , ( char * ) part_info - > name , strlen ( " private " ) ) )
{
if ( 1 )
{
//需要烧录此分区
printf ( " NEED down private part \n " ) ;
ret1 = __download_normal_part ( part_info , down_buff ) ;
if ( ret1 ! = 0 )
{
printf ( " sunxi sprite err: sunxi_sprite_deal_part, download private failed \n " ) ;
goto __sunxi_sprite_deal_part_err2 ;
}
}
else
{
printf ( " IGNORE private part \n " ) ;
}
}
else
{
ret1 = __download_normal_part ( part_info , down_buff ) ;
if ( ret1 ! = 0 )
{
printf ( " sunxi sprite err: sunxi_sprite_deal_part, download normal failed \n " ) ;
goto __sunxi_sprite_deal_part_err2 ;
}
}
sprite_cartoon_upgrade ( 10 + rate * ( i + 1 ) ) ;
tick_printf ( " successed in download part %s \n " , part_info - > name ) ;
}
ret = 0 ;
__sunxi_sprite_deal_part_err1 :
sunxi_sprite_exit ( 1 ) ;
__sunxi_sprite_deal_part_err2 :
if ( down_buff )
{
free ( down_buff ) ;
}
return ret ;
}
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* function
*
* name :
*
* parmeters :
*
* return :
*
* note :
*
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
int sunxi_sprite_deal_uboot ( int production_media )
{
char buffer [ 4 * 1024 * 1024 ] ;
uint item_original_size ;
if ( gd - > bootfile_mode = = SUNXI_BOOT_FILE_NORMAL )
{
imgitemhd = Img_OpenItem ( imghd , " 12345678 " , " UBOOT_0000000000 " ) ;
}
else if ( gd - > bootfile_mode = = SUNXI_BOOT_FILE_PKG )
{
if ( get_boot_storage_type ( ) ! = STORAGE_NOR )
{
imgitemhd = Img_OpenItem ( imghd , " 12345678 " , " BOOTPKG-00000000 " ) ;
}
else
{
imgitemhd = Img_OpenItem ( imghd , " 12345678 " , " BOOTPKG-NOR00000 " ) ;
}
}
else
{
imgitemhd = Img_OpenItem ( imghd , " 12345678 " , " TOC1_00000000000 " ) ;
}
if ( ! imgitemhd )
{
printf ( " sprite update error: fail to open uboot item \n " ) ;
return - 1 ;
}
//uboot长度
item_original_size = Img_GetItemSize ( imghd , imgitemhd ) ;
if ( ! item_original_size )
{
printf ( " sprite update error: fail to get uboot item size \n " ) ;
return - 1 ;
}
/*获取uboot的数据*/
if ( ! Img_ReadItem ( imghd , imgitemhd , ( void * ) buffer , 4 * 1024 * 1024 ) )
{
printf ( " update error: fail to read data from for uboot \n " ) ;
return - 1 ;
}
Img_CloseItem ( imghd , imgitemhd ) ;
imgitemhd = NULL ;
if ( sunxi_sprite_download_uboot ( buffer , production_media , 0 ) )
{
printf ( " update error: fail to write uboot \n " ) ;
return - 1 ;
}
printf ( " sunxi_sprite_deal_uboot ok \n " ) ;
return 0 ;
}
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* function
*
* name :
*
* parmeters :
*
* return :
*
* note :
*
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
int sunxi_sprite_deal_boot0 ( int production_media )
{
char buffer [ 1 * 1024 * 1024 ] ;
uint item_original_size ;
if ( gd - > bootfile_mode = = SUNXI_BOOT_FILE_NORMAL | | gd - > bootfile_mode = = SUNXI_BOOT_FILE_PKG )
{
if ( production_media = = STORAGE_NAND )
{
imgitemhd = Img_OpenItem ( imghd , " BOOT " , " BOOT0_0000000000 " ) ;
}
else if ( production_media = = STORAGE_NOR )
{
imgitemhd = Img_OpenItem ( imghd , " 12345678 " , " 1234567890BNOR_0 " ) ;
}
else
{
imgitemhd = Img_OpenItem ( imghd , " 12345678 " , " 1234567890BOOT_0 " ) ;
}
}
else
{
imgitemhd = Img_OpenItem ( imghd , " 12345678 " , " TOC0_00000000000 " ) ;
}
if ( ! imgitemhd )
{
printf ( " sprite update error: fail to open boot0 item \n " ) ;
return - 1 ;
}
//boot0长度
item_original_size = Img_GetItemSize ( imghd , imgitemhd ) ;
if ( ! item_original_size )
{
printf ( " sprite update error: fail to get boot0 item size \n " ) ;
return - 1 ;
}
/*获取boot0的数据*/
if ( ! Img_ReadItem ( imghd , imgitemhd , ( void * ) buffer , 1 * 1024 * 1024 ) )
{
printf ( " update error: fail to read data from for boot0 \n " ) ;
return - 1 ;
}
Img_CloseItem ( imghd , imgitemhd ) ;
imgitemhd = NULL ;
if ( sunxi_sprite_download_boot0 ( buffer , production_media ) )
{
printf ( " update error: fail to write boot0 \n " ) ;
return - 1 ;
}
return 0 ;
}
int sunxi_sprite_deal_recorvery_boot ( int production_media )
{
char buffer_uboot [ 4 * 1024 * 1024 ] ;
char buffer_boot0 [ 1 * 1024 * 1024 ] ;
uint item_size_uboot ;
uint item_size_boot0 ;
if ( gd - > bootfile_mode = = SUNXI_BOOT_FILE_NORMAL )
{
imgitemhd = Img_OpenItem ( imghd , " 12345678 " , " UBOOT_0000000000 " ) ;
}
else if ( gd - > bootfile_mode = = SUNXI_BOOT_FILE_PKG )
{
imgitemhd = Img_OpenItem ( imghd , " 12345678 " , " BOOTPKG-00000000 " ) ;
}
else
{
imgitemhd = Img_OpenItem ( imghd , " 12345678 " , " TOC1_00000000000 " ) ;
}
if ( ! imgitemhd )
{
printf ( " sprite update error: fail to open uboot item \n " ) ;
return - 1 ;
}
item_size_uboot = Img_GetItemSize ( imghd , imgitemhd ) ;
if ( ! item_size_uboot )
{
printf ( " sprite update error: fail to get uboot item size \n " ) ;
return - 1 ;
}
if ( ! Img_ReadItem ( imghd , imgitemhd , ( void * ) buffer_uboot , 4 * 1024 * 1024 ) )
{
printf ( " update error: fail to read data from for uboot \n " ) ;
return - 1 ;
}
Img_CloseItem ( imghd , imgitemhd ) ;
imgitemhd = NULL ;
if ( gd - > bootfile_mode = = SUNXI_BOOT_FILE_NORMAL | | gd - > bootfile_mode = = SUNXI_BOOT_FILE_PKG )
{
if ( production_media = = 0 )
{
imgitemhd = Img_OpenItem ( imghd , " BOOT " , " BOOT0_0000000000 " ) ;
}
else
{
imgitemhd = Img_OpenItem ( imghd , " 12345678 " , " 1234567890BOOT_0 " ) ;
}
}
else
{
imgitemhd = Img_OpenItem ( imghd , " 12345678 " , " TOC0_00000000000 " ) ;
}
if ( ! imgitemhd )
{
printf ( " sprite update error: fail to open boot0 item \n " ) ;
return - 1 ;
}
item_size_boot0 = Img_GetItemSize ( imghd , imgitemhd ) ;
if ( ! item_size_boot0 )
{
printf ( " sprite update error: fail to get boot0 item size \n " ) ;
return - 1 ;
}
if ( ! Img_ReadItem ( imghd , imgitemhd , ( void * ) buffer_boot0 , 1 * 1024 * 1024 ) )
{
printf ( " update error: fail to read data from for boot0 \n " ) ;
return - 1 ;
}
Img_CloseItem ( imghd , imgitemhd ) ;
imgitemhd = NULL ;
/*write boot data*/
if ( sunxi_sprite_download_uboot ( buffer_uboot , production_media , 0 ) )
{
printf ( " update error: fail to write uboot \n " ) ;
return - 1 ;
}
tick_printf ( " successed in downloading uboot \n " ) ;
if ( sunxi_sprite_download_boot0 ( buffer_boot0 , production_media ) )
{
printf ( " update error: fail to write boot0 \n " ) ;
return - 1 ;
}
tick_printf ( " successed in downloading boot0 \n " ) ;
printf ( " sunxi_sprite_deal_recorvery_boot ok \n " ) ;
return 0 ;
}
2018-12-13 10:48:25 +00:00
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* function
*
* name :
*
* parmeters :
*
* return :
*
* note :
*
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
int card_verify_uboot ( uint start_block , uint length )
{
int ret = 0 ;
char * buffer = NULL ;
buffer = ( char * ) malloc ( length ) ;
if ( ! buffer ) {
printf ( " %s: malloc %d byte memory fail \n " , __func__ , length ) ;
return - 1 ;
}
memset ( buffer , 0 , length ) ;
ret = sunxi_sprite_phyread ( start_block , length / 512 , buffer ) ;
if ( ! ret ) {
printf ( " %s: write boot0 from %d fail \n " , __func__ , start_block ) ;
goto ERR_OUT ;
}
if ( gd - > bootfile_mode = = SUNXI_BOOT_FILE_NORMAL ) {
struct spare_boot_head_t * uboot = ( struct spare_boot_head_t * ) buffer ;
printf ( " uboot magic %.*s \n " , MAGIC_SIZE , uboot - > boot_head . magic ) ;
if ( strncmp ( ( const char * ) uboot - > boot_head . magic , UBOOT_MAGIC , MAGIC_SIZE ) ) {
printf ( " sunxi sprite: uboot magic is error \n " ) ;
return - 1 ;
}
length = uboot - > boot_head . length ;
if ( sunxi_sprite_verify_checksum ( buffer , uboot - > boot_head . length , uboot - > boot_head . check_sum ) ) {
printf ( " sunxi sprite: boot0 checksum is error flash_sum=0x%x \n " , uboot - > boot_head . check_sum ) ;
goto ERR_OUT ;
}
ret = 1 ;
} else {
sbrom_toc1_head_info_t * toc1 = ( sbrom_toc1_head_info_t * ) buffer ;
if ( gd - > bootfile_mode = = SUNXI_BOOT_FILE_PKG ) {
printf ( " uboot_pkg magic 0x%x \n " , toc1 - > magic ) ;
} else {
printf ( " toc magic 0x%x \n " , toc1 - > magic ) ;
}
if ( toc1 - > magic ! = TOC_MAIN_INFO_MAGIC ) {
printf ( " sunxi sprite: toc magic is error \n " ) ;
return - 1 ;
}
length = toc1 - > valid_len ;
if ( sunxi_sprite_verify_checksum ( buffer , toc1 - > valid_len , toc1 - > add_sum ) ) {
printf ( " sunxi sprite: toc1 checksum is error flash_sum=0x%x \n " , toc1 - > add_sum ) ;
goto ERR_OUT ;
}
ret = 1 ;
}
ERR_OUT :
if ( buffer ! = NULL )
free ( buffer ) ;
if ( ! ret )
return - 1 ;
else
return 0 ;
}
2018-07-13 01:31:50 +00:00
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* function
*
* name :
*
* parmeters :
*
* return :
*
* note :
*
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
int card_download_uboot ( uint length , void * buffer )
{
int ret ;
ret = sunxi_sprite_phywrite ( UBOOT_START_SECTOR_IN_SDMMC , length / 512 , buffer ) ;
if ( ! ret )
{
2018-12-13 10:48:25 +00:00
printf ( " %s: write uboot from %d fail \n " , __func__ , UBOOT_START_SECTOR_IN_SDMMC ) ;
return - 1 ;
}
ret = card_verify_uboot ( UBOOT_START_SECTOR_IN_SDMMC , length ) ;
if ( ret < 0 ) {
printf ( " %s: verify uboot checksum from %d fail \n " , __func__ , UBOOT_START_SECTOR_IN_SDMMC ) ;
2018-07-13 01:31:50 +00:00
return - 1 ;
}
ret = sunxi_sprite_phywrite ( UBOOT_BACKUP_START_SECTOR_IN_SDMMC , length / 512 , buffer ) ;
if ( ! ret )
{
2018-12-13 10:48:25 +00:00
printf ( " %s: write uboot from %d fail \n " , __func__ , UBOOT_BACKUP_START_SECTOR_IN_SDMMC ) ;
2018-07-13 01:31:50 +00:00
return - 1 ;
}
return 0 ;
}
2018-12-13 10:48:25 +00:00
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* function
*
* name :
*
* parmeters :
*
* return :
*
* note :
*
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
int card_verify_boot0 ( uint start_block , uint length )
{
int ret = 0 ;
char * buffer = NULL ;
buffer = ( char * ) malloc ( length ) ;
if ( ! buffer ) {
printf ( " %s: malloc %d byte memory fail \n " , __func__ , length ) ;
return - 1 ;
}
memset ( buffer , 0 , length ) ;
ret = sunxi_sprite_phyread ( start_block , length / 512 , buffer ) ;
if ( ! ret ) {
printf ( " %s: write boot0 from %d fail \n " , __func__ , start_block ) ;
goto ERR_OUT ;
}
if ( gd - > bootfile_mode = = SUNXI_BOOT_FILE_NORMAL | | gd - > bootfile_mode = = SUNXI_BOOT_FILE_PKG ) {
boot0_file_head_t * boot0 = ( boot0_file_head_t * ) buffer ;
debug ( " %.*s \n " , MAGIC_SIZE , boot0 - > boot_head . magic ) ;
if ( strncmp ( ( const char * ) boot0 - > boot_head . magic , BOOT0_MAGIC , MAGIC_SIZE ) ) {
printf ( " sunxi sprite: boot0 magic is error \n " ) ;
goto ERR_OUT ;
}
if ( sunxi_sprite_verify_checksum ( buffer , boot0 - > boot_head . length , boot0 - > boot_head . check_sum ) ) {
printf ( " sunxi sprite: boot0 checksum is error flash_check_sum=0x%x \n " , boot0 - > boot_head . check_sum ) ;
goto ERR_OUT ;
}
ret = 1 ;
} else {
toc0_private_head_t * toc0 = ( toc0_private_head_t * ) buffer ;
debug ( " %s \n " , ( char * ) toc0 - > name ) ;
if ( strncmp ( ( const char * ) toc0 - > name , TOC0_MAGIC , MAGIC_SIZE ) ) {
printf ( " sunxi sprite: toc0 magic is error \n " ) ;
goto ERR_OUT ;
}
if ( sunxi_sprite_verify_checksum ( buffer , toc0 - > length , toc0 - > check_sum ) ) {
printf ( " sunxi sprite: toc0 checksum is error flash_check_sum=0x%x \n " , toc0 - > check_sum ) ;
goto ERR_OUT ;
}
ret = 1 ;
}
ERR_OUT :
if ( buffer ! = NULL )
free ( buffer ) ;
if ( ! ret )
return - 1 ;
else
return 0 ;
}
2018-07-13 01:31:50 +00:00
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* function
*
* name :
*
* parmeters :
*
* return :
*
* note :
*
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
int card_download_boot0 ( uint length , void * buffer , uint storage_type )
{
int ret = 0 ;
char * erase_buffer = NULL ;
erase_buffer = ( char * ) malloc ( length ) ;
if ( ! erase_buffer )
{
printf ( " %s: malloc %d byte memory fail \n " , __func__ , length ) ;
return - 1 ;
}
memset ( erase_buffer , 0 , length ) ;
//for card2
if ( storage_type = = STORAGE_EMMC )
{
2018-12-13 10:48:25 +00:00
printf ( " card2 download boot0 \n " ) ;
2018-07-13 01:31:50 +00:00
//write boot0 bankup copy firstly
ret = sunxi_sprite_phywrite ( BOOT0_SDMMC_BACKUP_START_ADDR , length / 512 , buffer ) ;
if ( ! ret )
{
printf ( " %s: write boot0 from %d fail \n " , __func__ , BOOT0_SDMMC_BACKUP_START_ADDR ) ;
goto ERR_OUT ;
}
ret = sunxi_sprite_phywrite ( BOOT0_SDMMC_START_ADDR , length / 512 , buffer ) ;
if ( ! ret )
{
printf ( " %s: write boot0 from %d fail \n " , __func__ , BOOT0_SDMMC_START_ADDR ) ;
goto ERR_OUT ;
}
2018-12-13 10:48:25 +00:00
if ( card_verify_boot0 ( BOOT0_SDMMC_START_ADDR , length ) < 0 ) {
printf ( " %s: verify boot0 checksum from %d fail \n " , __func__ , BOOT0_SDMMC_START_ADDR ) ;
goto ERR_OUT ;
}
2018-07-13 01:31:50 +00:00
# ifdef PLATFORM_SUPPORT_EMMC3
ret = sunxi_sprite_phywrite ( BOOT0_EMMC3_START_ADDR , length / 512 , erase_buffer ) ;
if ( ! ret )
{
printf ( " %s: write boot0 from %d fail \n " , __func__ , BOOT0_EMMC3_START_ADDR ) ;
goto ERR_OUT ;
}
ret = sunxi_sprite_phywrite ( BOOT0_EMMC3_BACKUP_START_ADDR , length / 512 , erase_buffer ) ;
if ( ! ret )
{
printf ( " %s: write boot0 from %d fail \n " , __func__ , BOOT0_EMMC3_BACKUP_START_ADDR ) ;
goto ERR_OUT ;
}
# endif
}
else if ( storage_type = = STORAGE_SD1 )
{
2018-12-13 10:48:25 +00:00
printf ( " card1 download boot0 \n " ) ;
2018-07-13 01:31:50 +00:00
//write boot0 bankup copy firstly
ret = sunxi_sprite_phywrite ( BOOT0_SDMMC_BACKUP_START_ADDR , length / 512 , buffer ) ;
if ( ! ret )
{
printf ( " %s: write boot0 from %d fail \n " , __func__ , BOOT0_SDMMC_BACKUP_START_ADDR ) ;
goto ERR_OUT ;
}
ret = sunxi_sprite_phywrite ( BOOT0_SDMMC_START_ADDR , length / 512 , buffer ) ;
if ( ! ret )
{
printf ( " %s: write boot0 from %d fail \n " , __func__ , BOOT0_SDMMC_START_ADDR ) ;
goto ERR_OUT ;
}
# ifdef PLATFORM_SUPPORT_EMMC3
ret = sunxi_sprite_phywrite ( BOOT0_EMMC3_START_ADDR , length / 512 , erase_buffer ) ;
if ( ! ret )
{
printf ( " %s: write boot0 from %d fail \n " , __func__ , BOOT0_EMMC3_START_ADDR ) ;
goto ERR_OUT ;
}
ret = sunxi_sprite_phywrite ( BOOT0_EMMC3_BACKUP_START_ADDR , length / 512 , erase_buffer ) ;
if ( ! ret )
{
printf ( " %s: write boot0 from %d fail \n " , __func__ , BOOT0_EMMC3_BACKUP_START_ADDR ) ;
goto ERR_OUT ;
}
# endif
}
else //for card3
{
# ifdef PLATFORM_SUPPORT_EMMC3
2018-12-13 10:48:25 +00:00
printf ( " card3 download boot0 \n " ) ;
2018-07-13 01:31:50 +00:00
//write boot0 bankup copy firstly
ret = sunxi_sprite_phywrite ( BOOT0_EMMC3_BACKUP_START_ADDR , length / 512 , buffer ) ;
if ( ! ret )
{
printf ( " %s: write boot0 from %d fail \n " , __func__ , BOOT0_EMMC3_BACKUP_START_ADDR ) ;
goto ERR_OUT ;
}
ret = sunxi_sprite_phywrite ( BOOT0_EMMC3_START_ADDR , length / 512 , buffer ) ;
if ( ! ret )
{
printf ( " %s: write boot0 from %d fail \n " , __func__ , BOOT0_EMMC3_START_ADDR ) ;
goto ERR_OUT ;
}
ret = sunxi_sprite_phywrite ( BOOT0_SDMMC_START_ADDR , length / 512 , erase_buffer ) ;
if ( ! ret )
{
printf ( " %s: write boot0 from %d fail \n " , __func__ , BOOT0_SDMMC_START_ADDR ) ;
goto ERR_OUT ;
}
ret = sunxi_sprite_phywrite ( BOOT0_SDMMC_BACKUP_START_ADDR , length / 512 , erase_buffer ) ;
if ( ! ret )
{
printf ( " %s: write boot0 from %d fail \n " , __func__ , BOOT0_SDMMC_BACKUP_START_ADDR ) ;
goto ERR_OUT ;
}
# endif
}
ERR_OUT :
if ( erase_buffer ! = NULL )
free ( erase_buffer ) ;
if ( ! ret )
return - 1 ;
else
return 0 ;
}
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* function
*
* name :
*
* parmeters :
*
* return :
*
* note :
*
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
//static void buffer_dump(void *buffer, int len)
//{
// int i;
// char *data = (char *)buffer;
//
// for(i=0;i<len;i++)
// {
// printf("%02x", data[i]);
// if((i & 0x07) == 7)
// {
// printf("\n");
// }
// else
// {
// puts(" ");
// }
// }
//}
int card_download_standard_mbr ( void * buffer )
{
mbr_stand * mbrst ;
sunxi_mbr_t * mbr = ( sunxi_mbr_t * ) buffer ;
char mbr_bufst [ 512 ] ;
int i ;
int sectors ;
int unusd_sectors ;
sectors = 0 ;
for ( i = 1 ; i < mbr - > PartCount - 1 ; i + + )
{
memset ( mbr_bufst , 0 , 512 ) ;
mbrst = ( mbr_stand * ) mbr_bufst ;
sectors + = mbr - > array [ i ] . lenlo ;
mbrst - > part_info [ 0 ] . part_type = 0x83 ;
mbrst - > part_info [ 0 ] . start_sectorl = ( ( mbr - > array [ i ] . addrlo - i + 20 * 1024 * 1024 / 512 ) & 0x0000ffff ) > > 0 ;
mbrst - > part_info [ 0 ] . start_sectorh = ( ( mbr - > array [ i ] . addrlo - i + 20 * 1024 * 1024 / 512 ) & 0xffff0000 ) > > 16 ;
mbrst - > part_info [ 0 ] . total_sectorsl = ( mbr - > array [ i ] . lenlo & 0x0000ffff ) > > 0 ;
mbrst - > part_info [ 0 ] . total_sectorsh = ( mbr - > array [ i ] . lenlo & 0xffff0000 ) > > 16 ;
if ( i ! = mbr - > PartCount - 2 )
{
mbrst - > part_info [ 1 ] . part_type = 0x05 ;
mbrst - > part_info [ 1 ] . start_sectorl = i ;
mbrst - > part_info [ 1 ] . start_sectorh = 0 ;
mbrst - > part_info [ 1 ] . total_sectorsl = ( mbr - > array [ i ] . lenlo & 0x0000ffff ) > > 0 ;
mbrst - > part_info [ 1 ] . total_sectorsh = ( mbr - > array [ i ] . lenlo & 0xffff0000 ) > > 16 ;
}
mbrst - > end_flag = 0xAA55 ;
if ( ! sunxi_sprite_phywrite ( i , 1 , mbr_bufst ) )
{
printf ( " write standard mbr %d failed \n " , i ) ;
return - 1 ;
}
}
memset ( mbr_bufst , 0 , 512 ) ;
mbrst = ( mbr_stand * ) mbr_bufst ;
unusd_sectors = sunxi_sprite_size ( ) - 20 * 1024 * 1024 / 512 - sectors ;
mbrst - > part_info [ 0 ] . indicator = 0x80 ;
mbrst - > part_info [ 0 ] . part_type = 0x0B ;
mbrst - > part_info [ 0 ] . start_sectorl = ( ( mbr - > array [ mbr - > PartCount - 1 ] . addrlo + 20 * 1024 * 1024 / 512 ) & 0x0000ffff ) > > 0 ;
mbrst - > part_info [ 0 ] . start_sectorh = ( ( mbr - > array [ mbr - > PartCount - 1 ] . addrlo + 20 * 1024 * 1024 / 512 ) & 0xffff0000 ) > > 16 ;
mbrst - > part_info [ 0 ] . total_sectorsl = ( unusd_sectors & 0x0000ffff ) > > 0 ;
mbrst - > part_info [ 0 ] . total_sectorsh = ( unusd_sectors & 0xffff0000 ) > > 16 ;
mbrst - > part_info [ 1 ] . part_type = 0x06 ;
mbrst - > part_info [ 1 ] . start_sectorl = ( ( mbr - > array [ 0 ] . addrlo + 20 * 1024 * 1024 / 512 ) & 0x0000ffff ) > > 0 ;
mbrst - > part_info [ 1 ] . start_sectorh = ( ( mbr - > array [ 0 ] . addrlo + 20 * 1024 * 1024 / 512 ) & 0xffff0000 ) > > 16 ;
mbrst - > part_info [ 1 ] . total_sectorsl = ( mbr - > array [ 0 ] . lenlo & 0x0000ffff ) > > 0 ;
mbrst - > part_info [ 1 ] . total_sectorsh = ( mbr - > array [ 0 ] . lenlo & 0xffff0000 ) > > 16 ;
mbrst - > part_info [ 2 ] . part_type = 0x05 ;
mbrst - > part_info [ 2 ] . start_sectorl = 1 ;
mbrst - > part_info [ 2 ] . start_sectorh = 0 ;
mbrst - > part_info [ 2 ] . total_sectorsl = ( sectors & 0x0000ffff ) > > 0 ;
mbrst - > part_info [ 2 ] . total_sectorsh = ( sectors & 0xffff0000 ) > > 16 ;
mbrst - > end_flag = 0xAA55 ;
if ( ! sunxi_sprite_phywrite ( 0 , 1 , mbr_bufst ) )
{
printf ( " write standard mbr 0 failed \n " ) ;
return - 1 ;
}
return 0 ;
}
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* function
*
* name :
*
* parmeters :
*
* return :
*
* note :
*
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
# define CARD_ERASE_BLOCK_BYTES (8 * 1024 * 1024)
# define CARD_ERASE_BLOCK_SECTORS (CARD_ERASE_BLOCK_BYTES / 512)
int card_erase ( int erase , void * mbr_buffer )
{
char * erase_buffer ;
sunxi_mbr_t * mbr = ( sunxi_mbr_t * ) mbr_buffer ;
unsigned int erase_head_sectors ;
unsigned int erase_head_addr ;
unsigned int erase_tail_sectors ;
unsigned int erase_tail_addr ;
unsigned int skip_space [ 1 + 2 * 2 ] = { 0 } ;
unsigned int from , nr ;
int k , ret = 0 ;
int i ;
//tick_printf("erase all part start\n");
if ( ! erase )
{
return 0 ;
}
erase_buffer = ( char * ) malloc ( CARD_ERASE_BLOCK_BYTES ) ;
if ( ! erase_buffer )
{
printf ( " card erase fail: unable to malloc memory for card erase \n " ) ;
return - 1 ;
}
memset ( erase_buffer , 0 , CARD_ERASE_BLOCK_BYTES ) ;
//erase boot0,write 0x00
card_download_boot0 ( 32 * 1024 , erase_buffer , get_boot_storage_type ( ) ) ;
printf ( " erase boot0, size:32k, write 0x00 \n " ) ;
for ( i = 1 ; i < mbr - > PartCount ; i + + )
{
printf ( " erase %s part \n " , mbr - > array [ i ] . name ) ;
if ( mbr - > array [ i ] . lenlo > CARD_ERASE_BLOCK_SECTORS * 2 ) // part > 16M
{
erase_head_sectors = CARD_ERASE_BLOCK_SECTORS ;
erase_head_addr = mbr - > array [ i ] . addrlo ;
//erase_tail_sectors = CARD_ERASE_BLOCK_SECTORS;
erase_tail_sectors = 2 * 1024 * 1024 / 512 ;
erase_tail_addr = mbr - > array [ i ] . addrlo + mbr - > array [ i ] . lenlo - CARD_ERASE_BLOCK_SECTORS ;
}
else if ( mbr - > array [ i ] . lenlo > CARD_ERASE_BLOCK_SECTORS ) // 8M < part <= 16M
{
erase_head_sectors = CARD_ERASE_BLOCK_SECTORS ;
erase_head_addr = mbr - > array [ i ] . addrlo ;
//erase_tail_sectors = mbr->array[i].lenlo - CARD_ERASE_BLOCK_SECTORS;
erase_tail_sectors = 2 * 1024 * 1024 / 512 ;
erase_tail_addr = mbr - > array [ i ] . addrlo + mbr - > array [ i ] . lenlo - erase_tail_sectors ;
}
else if ( mbr - > array [ i ] . lenlo > 0 ) // 0 < part <= 8M
{
erase_head_sectors = mbr - > array [ i ] . lenlo ;
erase_head_addr = mbr - > array [ i ] . addrlo ;
erase_tail_sectors = 0 ;
erase_tail_addr = mbr - > array [ i ] . addrlo ;
}
else {
2018-12-13 10:48:25 +00:00
//printf("don't deal prat's length is 0 (%s)\n", mbr->array[i].name);
2018-07-13 01:31:50 +00:00
//break;
erase_head_sectors = CARD_ERASE_BLOCK_SECTORS ;
erase_head_addr = mbr - > array [ i ] . addrlo ;
erase_tail_sectors = 0 ;
erase_tail_addr = mbr - > array [ i ] . addrlo ;
}
from = mbr - > array [ i ] . addrlo + CONFIG_MMC_LOGICAL_OFFSET ;
nr = mbr - > array [ i ] . lenlo ;
ret = sunxi_sprite_mmc_phyerase ( from , nr , skip_space ) ;
if ( ret = = 0 )
{
//printf("erase part from sector 0x%x to 0x%x ok\n", from, (from+nr-1));
}
else if ( ret = = 1 )
{
for ( k = 0 ; k < 2 ; k + + )
{
if ( skip_space [ 0 ] & ( 1 < < k ) ) {
printf ( " write zeros-%d: from 0x%x to 0x%x \n " , k , skip_space [ 2 * k + 1 ] ,
( skip_space [ 2 * k + 1 ] + skip_space [ 2 * k + 2 ] - 1 ) ) ;
from = skip_space [ 2 * k + 1 ] ;
nr = skip_space [ 2 * k + 2 ] ;
if ( ! sunxi_sprite_mmc_phywrite ( from , nr , erase_buffer ) )
{
printf ( " card erase fail in erasing part %s \n " , mbr - > array [ i ] . name ) ;
free ( erase_buffer ) ;
return - 1 ;
}
}
}
}
else if ( ret = = - 1 )
{
// erase head for partition
if ( ! sunxi_sprite_write ( erase_head_addr , erase_head_sectors , erase_buffer ) )
{
printf ( " card erase fail in erasing part %s \n " , mbr - > array [ i ] . name ) ;
free ( erase_buffer ) ;
return - 1 ;
}
printf ( " erase prat's head from sector 0x%x to 0x%x \n " , erase_head_addr , erase_head_addr + erase_head_sectors ) ;
// erase tail for partition
if ( erase_tail_sectors )
{
if ( ! sunxi_sprite_write ( erase_tail_addr , erase_tail_sectors , erase_buffer ) )
{
printf ( " card erase fail in erasing part %s \n " , mbr - > array [ i ] . name ) ;
free ( erase_buffer ) ;
return - 1 ;
}
printf ( " erase part's tail from sector 0x%x to 0x%x \n " , erase_tail_addr , erase_tail_addr + erase_tail_sectors ) ;
}
}
}
printf ( " card erase all \n " ) ;
free ( erase_buffer ) ;
//while((*(volatile unsigned int *)0) != 1);
//tick_printf("erase all part end\n");
return 0 ;
}
# define BOOT0_MAX_SIZE (32 * 1024)
int sunxi_card_fill_boot0_magic ( void )
{
uchar buffer [ BOOT0_MAX_SIZE ] ;
boot0_file_head_t * boot0_head ;
uint src_sum , cal_sum ;
struct mmc * mmc0 ;
char debug_info [ 1024 ] ;
int ret = - 1 ;
puts ( " probe mmc0 if exist \n " ) ;
memset ( debug_info , 0 , 1024 ) ;
board_mmc_pre_init ( 0 ) ;
mmc0 = find_mmc_device ( 0 ) ;
if ( ! mmc0 )
{
strcpy ( debug_info , " fail to find mmc0 " ) ;
goto __sunxi_card_fill_boot0_magic_exit ;
}
printf ( " try to init mmc0 \n " ) ;
if ( mmc_init ( mmc0 ) )
{
strcpy ( debug_info , " MMC0 init failed " ) ;
goto __sunxi_card_fill_boot0_magic_exit ;
}
memset ( buffer , 0 , BOOT0_MAX_SIZE ) ;
if ( mmc0 - > block_dev . block_read_mass_pro ( mmc0 - > block_dev . dev , 16 , BOOT0_MAX_SIZE / 512 , buffer ) ! = BOOT0_MAX_SIZE / 512 )
{
strcpy ( debug_info , " read mmc boot0 failed " ) ;
goto __sunxi_card_fill_boot0_magic_exit ;
}
//compare data
boot0_head = ( boot0_file_head_t * ) buffer ;
//fill boot0 magic
memcpy ( ( char * ) boot0_head - > boot_head . magic , BOOT0_MAGIC , 8 ) ;
2018-12-13 10:48:25 +00:00
printf ( " boot0_head->boot_head.magic == %.*s \n " , MAGIC_SIZE , ( char * ) boot0_head - > boot_head . magic ) ;
2018-07-13 01:31:50 +00:00
src_sum = boot0_head - > boot_head . check_sum ;
2018-12-13 10:48:25 +00:00
printf ( " src_sum = %x \n " , src_sum ) ;
2018-07-13 01:31:50 +00:00
//boot0_head->boot_head.check_sum = STAMP_VALUE;
2018-12-13 10:48:25 +00:00
printf ( " boot0_head->boot_head.length = %d \n " , boot0_head - > boot_head . length ) ;
2018-07-13 01:31:50 +00:00
boot0_head - > boot_head . check_sum = STAMP_VALUE ;
cal_sum = add_sum ( buffer , boot0_head - > boot_head . length ) ;
if ( src_sum ! = cal_sum )
{
puts ( " boot0 addsum error \n " ) ;
return ret ;
}
boot0_head - > boot_head . check_sum = src_sum ;
flush_cache ( ( ulong ) buffer , BOOT0_MAX_SIZE ) ;
if ( mmc0 - > block_dev . block_write_mass_pro ( mmc0 - > block_dev . dev , 16 , BOOT0_MAX_SIZE / 512 , buffer ) ! = BOOT0_MAX_SIZE / 512 )
{
strcpy ( debug_info , " write mmc boot0 failed " ) ;
goto __sunxi_card_fill_boot0_magic_exit ;
}
ret = 0 ;
return ret ;
__sunxi_card_fill_boot0_magic_exit :
printf ( " %s \n " , debug_info ) ;
return ret ;
}
int sunxi_sprite_deal_part_from_sysrevoery ( sunxi_download_info * dl_map )
{
dl_one_part_info * part_info ;
int ret = - 1 ;
int ret1 ;
int i = 0 ;
uchar * down_buff = NULL ;
int rate ;
if ( ! dl_map - > download_count )
{
printf ( " sunxi sprite: no part need to write \n " ) ;
return 0 ;
}
rate = ( 80 ) / ( dl_map - > download_count + 1 ) ;
down_buff = ( uchar * ) malloc ( SPRITE_CARD_ONCE_DATA_DEAL + SPRITE_CARD_HEAD_BUFF ) ;
if ( ! down_buff )
{
printf ( " sunxi sprite err: unable to malloc memory for sunxi_sprite_deal_part \n " ) ;
goto __sunxi_sprite_deal_part_err1 ;
}
for ( part_info = dl_map - > one_part_info , i = 0 ; i < dl_map - > download_count ; i + + , part_info + + )
{
tick_printf ( " begin to download part %s \n " , part_info - > name ) ;
if ( ! strcmp ( " env " , ( const char * ) part_info - > name ) )
{
printf ( " env part do not need to rewrite \n " ) ;
sprite_cartoon_upgrade ( 20 + rate * ( i + 1 ) ) ;
continue ;
}
else if ( ! strcmp ( " sysrecovery " , ( const char * ) part_info - > name ) )
{
printf ( " THIS_IMG_SELF_00 do not need to rewrite \n " ) ;
sprite_cartoon_upgrade ( 20 + rate * ( i + 1 ) ) ;
continue ;
}
else if ( ! strcmp ( " UDISK " , ( const char * ) part_info - > name ) )
{
printf ( " UDISK do not need to rewrite \n " ) ;
sprite_cartoon_upgrade ( 20 + rate * ( i + 1 ) ) ;
continue ;
}
else if ( ! strcmp ( " private " , ( const char * ) part_info - > name ) )
{
printf ( " private do not need to rewrite \n " ) ;
sprite_cartoon_upgrade ( 20 + rate * ( i + 1 ) ) ;
continue ;
}
else
{
ret1 = __download_normal_part ( part_info , down_buff ) ;
if ( ret1 ! = 0 )
{
printf ( " sunxi sprite err: sunxi_sprite_deal_part, download normal failed \n " ) ;
goto __sunxi_sprite_deal_part_err2 ;
}
}
sprite_cartoon_upgrade ( 20 + rate * ( i + 1 ) ) ;
tick_printf ( " successed in download part %s \n " , part_info - > name ) ;
}
ret = 0 ;
__sunxi_sprite_deal_part_err1 :
sunxi_sprite_exit ( 1 ) ;
__sunxi_sprite_deal_part_err2 :
if ( down_buff )
{
free ( down_buff ) ;
}
return ret ;
}
int __imagehd ( HIMAGE tmp_himage )
{
imghd = tmp_himage ;
if ( imghd )
{
return 0 ;
}
return - 1 ;
}
# ifdef CONFIG_SUNXI_SPINOR
extern int sunxi_sprite_setdata_finish ( void ) ;
static int __download_fullimg_part ( uchar * source_buff )
{
uint tmp_partstart_by_sector ;
s64 partdata_by_byte ;
s64 tmp_partdata_by_bytes ;
uint onetime_read_sectors ;
uint first_write_bytes ;
uint imgfile_start ;
uint tmp_imgfile_start ;
u8 * down_buffer = source_buff + SPRITE_CARD_HEAD_BUFF ;
int ret = - 1 ;
tmp_partstart_by_sector = 0 ;
imgitemhd = Img_OpenItem ( imghd , " 12345678 " , " FULLIMG_00000000 " ) ;
if ( ! imgitemhd )
{
printf ( " sunxi sprite error: open part FULLIMG failed \n " ) ;
return - 1 ;
}
partdata_by_byte = Img_GetItemSize ( imghd , imgitemhd ) ;
if ( partdata_by_byte < = 0 )
{
printf ( " sunxi sprite error: fetch part len FULLIMG failed \n " ) ;
goto __download_fullimg_part_err1 ;
}
printf ( " partdata hi 0x%x \n " , ( uint ) ( partdata_by_byte > > 32 ) ) ;
printf ( " partdata lo 0x%x \n " , ( uint ) partdata_by_byte ) ;
tmp_partdata_by_bytes = partdata_by_byte ;
if ( tmp_partdata_by_bytes > = SPRITE_CARD_ONCE_DATA_DEAL )
{
onetime_read_sectors = SPRITE_CARD_ONCE_SECTOR_DEAL ;
first_write_bytes = SPRITE_CARD_ONCE_DATA_DEAL ;
}
else
{
onetime_read_sectors = ( tmp_partdata_by_bytes + 511 ) > > 9 ;
first_write_bytes = ( uint ) tmp_partdata_by_bytes ;
}
imgfile_start = Img_GetItemStart ( imghd , imgitemhd ) ;
if ( ! imgfile_start )
{
printf ( " sunxi sprite err : cant get part data imgfile_start FULLIMG \n " ) ;
goto __download_fullimg_part_err1 ;
}
tmp_imgfile_start = imgfile_start ;
if ( sunxi_flash_read ( tmp_imgfile_start , onetime_read_sectors , down_buffer ) ! = onetime_read_sectors )
{
printf ( " sunxi sprite error : read sdcard block %d, total %d failed \n " , tmp_imgfile_start , onetime_read_sectors ) ;
goto __download_fullimg_part_err1 ;
}
tmp_imgfile_start + = onetime_read_sectors ;
if ( sunxi_sprite_write ( tmp_partstart_by_sector , onetime_read_sectors , down_buffer ) ! = onetime_read_sectors )
{
printf ( " sunxi sprite error: download rawdata error FULLIMG \n " ) ;
goto __download_fullimg_part_err1 ;
}
tmp_partdata_by_bytes - = first_write_bytes ;
tmp_partstart_by_sector + = onetime_read_sectors ;
while ( tmp_partdata_by_bytes > = SPRITE_CARD_ONCE_DATA_DEAL )
{
if ( sunxi_flash_read ( tmp_imgfile_start , SPRITE_CARD_ONCE_SECTOR_DEAL , down_buffer ) ! = SPRITE_CARD_ONCE_SECTOR_DEAL )
{
printf ( " sunxi sprite error : read sdcard block %d, total %d failed \n " , tmp_imgfile_start , SPRITE_CARD_ONCE_SECTOR_DEAL ) ;
goto __download_fullimg_part_err1 ;
}
//D′ è?flash
if ( sunxi_sprite_write ( tmp_partstart_by_sector , SPRITE_CARD_ONCE_SECTOR_DEAL , down_buffer ) ! = SPRITE_CARD_ONCE_SECTOR_DEAL )
{
printf ( " sunxi sprite error: download rawdata error FULLIMG, start 0x%x, sectors 0x%x \n " , tmp_partstart_by_sector , SPRITE_CARD_ONCE_SECTOR_DEAL ) ;
goto __download_fullimg_part_err1 ;
}
tmp_imgfile_start + = SPRITE_CARD_ONCE_SECTOR_DEAL ;
tmp_partdata_by_bytes - = SPRITE_CARD_ONCE_DATA_DEAL ;
tmp_partstart_by_sector + = SPRITE_CARD_ONCE_SECTOR_DEAL ;
}
if ( tmp_partdata_by_bytes > 0 )
{
uint rest_sectors = ( tmp_partdata_by_bytes + 511 ) > > 9 ;
if ( sunxi_flash_read ( tmp_imgfile_start , rest_sectors , down_buffer ) ! = rest_sectors )
{
printf ( " sunxi sprite error : read sdcard block %d, total %d failed \n " , tmp_imgfile_start , rest_sectors ) ;
goto __download_fullimg_part_err1 ;
}
if ( sunxi_sprite_write ( tmp_partstart_by_sector , rest_sectors , down_buffer ) ! = rest_sectors )
{
printf ( " sunxi sprite error: download rawdata error FULLIMG, start 0x%x, sectors 0x%x \n " , tmp_partstart_by_sector , rest_sectors ) ;
goto __download_fullimg_part_err1 ;
}
}
printf ( " successed in writting part FULLIMG \n " ) ;
ret = 0 ;
__download_fullimg_part_err1 :
if ( imgitemhd )
{
Img_CloseItem ( imghd , imgitemhd ) ;
imgitemhd = NULL ;
}
return ret ;
}
int sunxi_sprite_deal_fullimg ( void )
{
int ret = - 1 ;
int ret1 ;
uchar * down_buff = NULL ;
if ( sunxi_sprite_init ( 1 ) )
{
printf ( " sunxi sprite err: init flash err \n " ) ;
return - 1 ;
}
down_buff = ( uchar * ) malloc ( SPRITE_CARD_ONCE_DATA_DEAL + SPRITE_CARD_HEAD_BUFF ) ;
if ( ! down_buff )
{
printf ( " sunxi sprite err: unable to malloc memory for sunxi_sprite_deal_part \n " ) ;
goto __sunxi_sprite_deal_fullimg_err1 ;
}
ret1 = __download_fullimg_part ( down_buff ) ;
if ( ret1 ! = 0 )
{
printf ( " sunxi sprite err: sunxi_sprite_deal_part, download normal failed \n " ) ;
goto __sunxi_sprite_deal_fullimg_err2 ;
}
//while(*(volatile uint *)0 != 0x12);
sunxi_sprite_setdata_finish ( ) ;
printf ( " sunxi card sprite trans finish \n " ) ;
ret = 0 ;
__sunxi_sprite_deal_fullimg_err1 :
sunxi_sprite_exit ( 1 ) ;
__sunxi_sprite_deal_fullimg_err2 :
if ( down_buff )
{
free ( down_buff ) ;
}
return ret ;
}
# endif