sdk-hwV1.3/lichee/brandy-2.0/u-boot-2018/sprite/sprite_card.c

1868 lines
53 KiB
C
Raw Normal View History

2024-05-07 10:09:20 +00:00
/*
* * Copyright 2000-2009
* * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
* *
* * SPDX-License-Identifier: GPL-2.0+
* */
#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>
#include <private_toc.h>
#include <sunxi_flashmap.h>
//#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 "private_uboot.h"
#include <sunxi_flash.h>
#include <mmc.h>
#include <sys_config.h>
#include <private_boot0.h>
#include <sunxi_board.h>
#include "sprite.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;
static void *imgitemhd;
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 :
*
*
************************************************************************************************************
*/
lbaint_t sprite_card_firmware_start(void)
{
return sunxi_partition_get_offset(1);
}
/*
************************************************************************************************************
*
* function
*
* name :
*
* parmeters :
*
* return :
*
* note :
*
*
************************************************************************************************************
*/
int sprite_card_firmware_probe(char *name)
{
printf("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 <= CONFIG_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;
}
sunxi_flash_write_end();
sunxi_flash_flush();
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;
debug("line:%d tmp_partstart_by_sector=0x%x\n", __LINE__,
tmp_partstart_by_sector);
//获取分区大小,字节数
partsize_by_byte = part_info->lenlo;
partsize_by_byte <<= 9;
debug("line:%d partsize_by_byte=0x%llx\n", __LINE__, partsize_by_byte);
//打开分区镜像
debug("line:%d part_info->dl_filename=%s\n", __LINE__,
part_info->dl_filename);
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;
debug("line:%d onetime_read_sectors=0x%x\n", __LINE__,
onetime_read_sectors);
debug("line:%d first_write_bytes=0x%x\n", __LINE__,
first_write_bytes);
} else {
onetime_read_sectors = (tmp_partdata_by_bytes + 511) >> 9;
first_write_bytes = (uint)tmp_partdata_by_bytes;
debug("line:%d onetime_read_sectors=0x%x\n", __LINE__,
onetime_read_sectors);
debug("line:%d first_write_bytes=0x%x\n", __LINE__,
first_write_bytes);
}
//开始获取分区数据
imgfile_start = Img_GetItemStart(imghd, imgitemhd);
debug("line:%d imgfile_start=tmp_imgfile_start=0x%x\n", __LINE__,
imgfile_start);
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;
verify_data = (uchar *)memalign(CONFIG_SYS_CACHELINE_SIZE, ALIGN(1024, CONFIG_SYS_CACHELINE_SIZE));
memset(verify_data, 0, ALIGN(1024, CONFIG_SYS_CACHELINE_SIZE));
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);
free(verify_data);
} 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;
if (!dl_map->download_count) {
printf("sunxi sprite: no part need to write\n");
return 0;
}
//初始化flashnand或者mmc
// if(sunxi_sprite_init(1))
// {
// printf("sunxi sprite err: init flash err\n");
// return -1;
// }
//申请内存
down_buff = (uchar *)memalign(CONFIG_SYS_CACHELINE_SIZE, ALIGN(SPRITE_CARD_ONCE_DATA_DEAL +
SPRITE_CARD_HEAD_BUFF, CONFIG_SYS_CACHELINE_SIZE));
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("line:%d sunxi sprite err: sunxi_sprite_deal_part, download private failed\n",
__LINE__);
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("line:%d sunxi sprite err: sunxi_sprite_deal_part, download private failed\n",
__LINE__);
goto __sunxi_sprite_deal_part_err2;
}
}
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;
buffer = (char *)memalign(CONFIG_SYS_CACHELINE_SIZE, ALIGN(4 * 1024 * 1024, CONFIG_SYS_CACHELINE_SIZE));
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");
free(buffer);
return 0;
}
/*
************************************************************************************************************
*
* function
*
* name :
*
* parmeters :
*
* return :
*
* note :
*
*
************************************************************************************************************
*/
int sunxi_sprite_deal_boot0(int production_media)
{
char *buffer = NULL;
uint item_original_size;
buffer = (char *)memalign(CONFIG_SYS_CACHELINE_SIZE, ALIGN(1*1024*1024, CONFIG_SYS_CACHELINE_SIZE));
if (!buffer) {
printf("err: unable to malloc memory\n");
return -1;
}
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");
goto sprite_boot0_fail;
}
//boot0长度
item_original_size = Img_GetItemSize(imghd, imgitemhd);
if (!item_original_size) {
printf("sprite update error: fail to get boot0 item size\n");
goto sprite_boot0_fail;
}
/*获取boot0的数据*/
if (!Img_ReadItem(imghd, imgitemhd, (void *)buffer, 1 * 1024 * 1024)) {
printf("update error: fail to read data from for boot0\n");
goto sprite_boot0_fail;
}
Img_CloseItem(imghd, imgitemhd);
imgitemhd = NULL;
if (sunxi_sprite_download_boot0(buffer, production_media)) {
printf("update error: fail to write boot0\n");
goto sprite_boot0_fail;
}
return 0;
sprite_boot0_fail:
free(buffer);
return -1;
}
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;
}
/*
************************************************************************************************************
*
* function
*
* name :
*
* parmeters :
*
* return :
*
* note :
*
*
************************************************************************************************************
*/
int card_verify_uboot(uint start_block, uint length)
{
int ret = 0;
char *buffer = NULL;
buffer = (char *)memalign(CONFIG_SYS_CACHELINE_SIZE, ALIGN(length, CONFIG_SYS_CACHELINE_SIZE));
if (!buffer) {
printf("%s: malloc %d byte memory fail\n", __func__, length);
return -1;
}
memset(buffer, 0, ALIGN(length, CONFIG_SYS_CACHELINE_SIZE));
ret = sunxi_flash_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", 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;
}
/*
************************************************************************************************************
*
* function
*
* name :
*
* parmeters :
*
* return :
*
* note :
*
*
************************************************************************************************************
*/
int card_download_uboot(uint length, void *buffer)
{
int ret;
ret = sunxi_flash_phywrite(sunxi_flashmap_offset(FLASHMAP_SDMMC, TOC1), length / 512,
buffer);
if (!ret) {
printf("%s: write uboot from %d fail\n", __func__,
sunxi_flashmap_offset(FLASHMAP_SDMMC, TOC1));
return -1;
}
ret = card_verify_uboot(sunxi_flashmap_offset(FLASHMAP_SDMMC, TOC1), length);
if (ret < 0) {
printf("%s: verify uboot checksum from %d fail\n", __func__,
sunxi_flashmap_offset(FLASHMAP_SDMMC, TOC1));
return -1;
}
ret = sunxi_flash_phywrite(sunxi_flashmap_offset(FLASHMAP_SDMMC, TOC1_BAK),
length / 512, buffer);
if (!ret) {
printf("%s: write uboot from %d fail\n", __func__,
sunxi_flashmap_offset(FLASHMAP_SDMMC, TOC1_BAK));
return -1;
}
return 0;
}
/*
************************************************************************************************************
*
* function
*
* name :
*
* parmeters :
*
* return :
*
* note :
*
*
************************************************************************************************************
*/
int card_verify_boot0(uint start_block, uint length)
{
int ret = 0;
char *buffer = NULL;
buffer = (char *)memalign(CONFIG_SYS_CACHELINE_SIZE, ALIGN(length, CONFIG_SYS_CACHELINE_SIZE));
if (!buffer) {
printf("%s: malloc %d byte memory fail\n", __func__, length);
return -1;
}
memset(buffer, 0, ALIGN(length, CONFIG_SYS_CACHELINE_SIZE));
ret = sunxi_flash_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", 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;
}
/*
************************************************************************************************************
*
* function
*
* name :
*
* parmeters :
*
* return :
*
* note :
*
*
************************************************************************************************************
*/
int card_erase_boot0(uint length, void *buffer, uint storage_type)
{
int ret = 0;
char *erase_buffer = NULL;
erase_buffer = (char *)memalign(CONFIG_SYS_CACHELINE_SIZE, ALIGN(length, CONFIG_SYS_CACHELINE_SIZE));
if (!erase_buffer) {
debug("%s: malloc %d byte memory fail\n", __func__, length);
return -1;
}
memset(erase_buffer, 0, length);
//for card2
if ((storage_type == STORAGE_EMMC) || (storage_type == STORAGE_EMMC0)) {
printf("card2 erase boot0 \n");
//write boot0 bankup copy firstly
ret = sunxi_sprite_phywrite(CONFIG_SUNXI_BOOT0_SDMMC_BACKUP_START_ADDR,
length / 512, buffer);
if (!ret) {
debug("%s: write boot0 from %d fail\n", __func__,
CONFIG_SUNXI_BOOT0_SDMMC_BACKUP_START_ADDR);
goto ERR_OUT;
}
ret = sunxi_sprite_phywrite(BOOT0_SDMMC_START_ADDR, length / 512,
buffer);
if (!ret) {
debug("%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) {
debug("%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) {
debug("%s: write boot0 from %d fail\n", __func__,
BOOT0_EMMC3_BACKUP_START_ADDR);
goto ERR_OUT;
}
#endif
} else {
//for card3
#ifdef PLATFORM_SUPPORT_EMMC3
printf("card3 erase boot0 \n");
//write boot0 bankup copy firstly
ret = sunxi_sprite_phywrite(BOOT0_EMMC3_BACKUP_START_ADDR,
length / 512, buffer);
if (!ret) {
debug("%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) {
debug("%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) {
debug("%s: write boot0 from %d fail\n", __func__,
BOOT0_SDMMC_START_ADDR);
goto ERR_OUT;
}
ret = sunxi_sprite_phywrite(CONFIG_SUNXI_BOOT0_SDMMC_BACKUP_START_ADDR,
length / 512, erase_buffer);
if (!ret) {
debug("%s: write boot0 from %d fail\n", __func__,
CONFIG_SUNXI_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_flash_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_flash_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_flash_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 *)memalign(CONFIG_SYS_CACHELINE_SIZE, ALIGN(CARD_ERASE_BLOCK_BYTES, CONFIG_SYS_CACHELINE_SIZE));
if (!erase_buffer) {
debug("card erase fail: unable to malloc memory for card erase\n");
return -1;
}
memset(erase_buffer, 0, ALIGN(CARD_ERASE_BLOCK_BYTES, CONFIG_SYS_CACHELINE_SIZE));
//erase boot0,write 0x00
if (card_erase_boot0(32 * 1024, erase_buffer, get_boot_storage_type())) {
return -1;
}
for (i = 1; i < mbr->PartCount; i++) {
printf("erase %s part\n", mbr->array[i].name);
// part > 16M
if (mbr->array[i].lenlo > CARD_ERASE_BLOCK_SECTORS * 2) {
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;
// 8M < part <= 16M
} else if (mbr->array[i].lenlo > CARD_ERASE_BLOCK_SECTORS) {
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;
// 0 < part <= 8M
} else if (mbr->array[i].lenlo > 0) {
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 {
//printf("don't deal prat's length is 0 (%s) \n", mbr->array[i].name);
//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 + sunxi_flashmap_logical_offset(FLASHMAP_SDMMC, LINUX_LOGIC_OFFSET);
nr = mbr->array[i].lenlo;
ret = sunxi_sprite_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)) {
debug("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_phywrite(
from, nr, erase_buffer)) {
debug("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)) {
debug("card erase fail in erasing part %s\n",
mbr->array[i].name);
free(erase_buffer);
return -1;
}
debug("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)) {
debug("card erase fail in erasing part %s\n",
mbr->array[i].name);
free(erase_buffer);
return -1;
}
debug("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;
char debug_info[1024];
int ret = -1;
puts("probe mmc0 if exist\n");
memset(debug_info, 0, 1024);
memset(buffer, 0, BOOT0_MAX_SIZE);
if (sunxi_sprite_read(16, BOOT0_MAX_SIZE / 512, (void *)buffer))
// if(sunxi_sprite_mmc_phyread(16, BOOT0_MAX_SIZE/512, (void *)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);
printf("boot0_head->boot_head.magic == %s \n",
(char *)boot0_head->boot_head.magic);
src_sum = boot0_head->boot_head.check_sum;
printf("src_sum = %x \n", src_sum);
//boot0_head->boot_head.check_sum = STAMP_VALUE;
printf("boot0_head->boot_head.length = %d \n",
boot0_head->boot_head.length);
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.devnum, 16, BOOT0_MAX_SIZE/512, (void *)buffer) != BOOT0_MAX_SIZE/512)
if (sunxi_sprite_write(16, BOOT0_MAX_SIZE / 512, (void *)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;
__maybe_unused 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 *)memalign(CONFIG_SYS_CACHELINE_SIZE, ALIGN(SPRITE_CARD_ONCE_DATA_DEAL +
SPRITE_CARD_HEAD_BUFF, CONFIG_SYS_CACHELINE_SIZE));
if (!down_buff) {
printf("sunxi sprite err: unable to malloc memory for sunxi_sprite_deal_part\n");
goto __sunxi_sprite_deal_part_err;
}
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_err;
}
}
// sprite_cartoon_upgrade(20 + rate * (i+1));
tick_printf("successed in download part %s\n", part_info->name);
}
ret = 0;
__sunxi_sprite_deal_part_err:
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_flash_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_flash_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_flash_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 (get_boot_storage_type() == STORAGE_NAND ? sunxi_sprite_init(1) : 0) {
printf("sunxi sprite err: init flash err\n");
return -1;
}
down_buff = (uchar *)memalign(CONFIG_SYS_CACHELINE_SIZE, ALIGN(SPRITE_CARD_ONCE_DATA_DEAL +
SPRITE_CARD_HEAD_BUFF, CONFIG_SYS_CACHELINE_SIZE));
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("line:%d sunxi sprite err: sunxi_sprite_deal_part, download private failed\n",
__LINE__);
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:
get_boot_storage_type() == STORAGE_NAND ? sunxi_sprite_exit(1) : 0;
__sunxi_sprite_deal_fullimg_err2:
if (down_buff) {
free(down_buff);
}
return ret;
}
#endif