327 lines
7.8 KiB
C
327 lines
7.8 KiB
C
|
/*
|
||
|
* (C) Copyright 2007-2013
|
||
|
* Allwinner Technology Co., Ltd. <www.allwinnertech.com>
|
||
|
* Char <yanjianbo@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.
|
||
|
*/
|
||
|
#include <config.h>
|
||
|
#include <common.h>
|
||
|
#include <malloc.h>
|
||
|
#include <sunxi_board.h>
|
||
|
#include "sprite_card.h"
|
||
|
#include "sprite_download.h"
|
||
|
#include "./firmware/imgdecode.h"
|
||
|
#include "./firmware/imagefile_new.h"
|
||
|
#include <sys_config.h>
|
||
|
#include <fdt_support.h>
|
||
|
#include "./cartoon/sprite_cartoon.h"
|
||
|
#include <sys_partition.h>
|
||
|
|
||
|
extern uint img_file_start;
|
||
|
extern int sunxi_sprite_deal_part_from_sysrevoery(sunxi_download_info *dl_map);
|
||
|
extern int __imagehd(HIMAGE tmp_himage);
|
||
|
extern int char8_char16_compare(const char *char8, const efi_char16_t *char16,
|
||
|
size_t char16_len);
|
||
|
|
||
|
typedef struct tag_IMAGE_HANDLE {
|
||
|
ImageHead_t ImageHead;
|
||
|
ImageItem_t *ItemTable;
|
||
|
} IMAGE_HANDLE;
|
||
|
|
||
|
static HIMAGE Img_Open_from_sysrecovery(__u32 start)
|
||
|
{
|
||
|
IMAGE_HANDLE *pImage = NULL;
|
||
|
uint ItemTableSize;
|
||
|
|
||
|
img_file_start = start;
|
||
|
if (!img_file_start) {
|
||
|
pr_err("sunxi sprite error: unable to get firmware start position\n");
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
debug("img start = 0x%x\n", img_file_start);
|
||
|
pImage = (IMAGE_HANDLE *)malloc(sizeof(IMAGE_HANDLE));
|
||
|
if (NULL == pImage) {
|
||
|
pr_err("sunxi sprite error: fail to malloc memory for img head\n");
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
memset(pImage, 0, sizeof(IMAGE_HANDLE));
|
||
|
|
||
|
//debug("try to read mmc start %d\n", img_file_start);
|
||
|
if (!sunxi_flash_read(img_file_start, IMAGE_HEAD_SIZE / 512,
|
||
|
&pImage->ImageHead)) {
|
||
|
pr_err("sunxi sprite error: read iamge head fail\n");
|
||
|
|
||
|
goto _img_open_fail_;
|
||
|
}
|
||
|
debug("read mmc ok\n");
|
||
|
|
||
|
if (memcmp(pImage->ImageHead.magic, IMAGE_MAGIC, 8) != 0) {
|
||
|
pr_err("sunxi sprite error: iamge magic is bad\n");
|
||
|
|
||
|
goto _img_open_fail_;
|
||
|
}
|
||
|
|
||
|
ItemTableSize = pImage->ImageHead.itemcount * sizeof(ImageItem_t);
|
||
|
pImage->ItemTable = (ImageItem_t *)malloc(ItemTableSize);
|
||
|
if (NULL == pImage->ItemTable) {
|
||
|
pr_err("sunxi sprite error: fail to malloc memory for item table\n");
|
||
|
|
||
|
goto _img_open_fail_;
|
||
|
}
|
||
|
|
||
|
if (!sunxi_flash_read(img_file_start + (IMAGE_HEAD_SIZE / 512),
|
||
|
ItemTableSize / 512, pImage->ItemTable)) {
|
||
|
pr_err("sunxi sprite error: read iamge item table fail\n");
|
||
|
|
||
|
goto _img_open_fail_;
|
||
|
}
|
||
|
|
||
|
return pImage;
|
||
|
|
||
|
_img_open_fail_:
|
||
|
if (pImage->ItemTable) {
|
||
|
free(pImage->ItemTable);
|
||
|
}
|
||
|
if (pImage) {
|
||
|
free(pImage);
|
||
|
}
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
static int sprite_erase_partition_by_name(char *part_name)
|
||
|
{
|
||
|
int ret = -1;
|
||
|
__u32 img_start;
|
||
|
__u32 part_size;
|
||
|
|
||
|
ret = sunxi_partition_get_info_byname(part_name, &img_start,
|
||
|
&part_size);
|
||
|
if (ret) {
|
||
|
pr_msg("sprite update error: no %s found\n", part_name);
|
||
|
if (!strcmp(part_name, "data")) {
|
||
|
ret = sunxi_partition_get_info_byname(
|
||
|
"UDISK", &img_start, &part_size);
|
||
|
if (ret) {
|
||
|
pr_err("sprite update error: no udisk partition\n");
|
||
|
}
|
||
|
ret = sunxi_partition_get_info_byname(
|
||
|
"userdata", &img_start, &part_size);
|
||
|
if (ret) {
|
||
|
pr_err("sprite update error: no userdata partition\n");
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!ret) {
|
||
|
__u32 tmp_size;
|
||
|
__u32 tmp_start;
|
||
|
char *src_buf = NULL;
|
||
|
|
||
|
src_buf = (char *)malloc(1024 * 1024);
|
||
|
if (!src_buf) {
|
||
|
pr_err("sprite erase error: fail to get memory for tmpdata\n");
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
tmp_start = img_start;
|
||
|
tmp_size = part_size;
|
||
|
pr_msg("data part size=%d\n", tmp_size);
|
||
|
tick_printf("begin erase part %s\n", part_name);
|
||
|
memset(src_buf, 0xff, 1024 * 1024);
|
||
|
|
||
|
sunxi_flash_write(tmp_start, 1024 * 1024 / 512, src_buf);
|
||
|
|
||
|
if (src_buf) {
|
||
|
free(src_buf);
|
||
|
}
|
||
|
|
||
|
tick_printf("finish erase part\n");
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* pms id:79675
|
||
|
* DragonSN tool usage
|
||
|
* 1. Destroy the data of metadata partition and UserData partition.
|
||
|
* When Android starts, it recognizes that the partition is damaged,
|
||
|
* which will trigger Android erasure
|
||
|
* 2. Speed up the production line
|
||
|
*/
|
||
|
int sprite_erase_for_androidrecovery(void)
|
||
|
{
|
||
|
int ret;
|
||
|
ret = sprite_erase_partition_by_name("data");
|
||
|
if (ret) {
|
||
|
pr_err("sprite update error: fail to erase data\n");
|
||
|
return -1;
|
||
|
}
|
||
|
ret = sprite_erase_partition_by_name("meta");
|
||
|
if (ret) {
|
||
|
pr_err("sprite update error: fail to erase data\n");
|
||
|
return -1;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int sprite_erase_in_sysrecovery(void)
|
||
|
{
|
||
|
int ret;
|
||
|
ret = sprite_erase_partition_by_name("data");
|
||
|
if (ret) {
|
||
|
pr_err("sprite update error: fail to erase data\n");
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
ret = sprite_erase_partition_by_name("cache");
|
||
|
if (ret) {
|
||
|
pr_err("sprite update error: fail to erase cache\n");
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
ret = sprite_erase_partition_by_name("Reserve0");
|
||
|
if (ret) {
|
||
|
pr_err("sprite update error: fail to erase cache\n");
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
ret = sprite_erase_partition_by_name("Reserve1");
|
||
|
if (ret) {
|
||
|
pr_err("sprite update error: fail to erase cache\n");
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
ret = sprite_erase_partition_by_name("Reserve2");
|
||
|
if (ret) {
|
||
|
pr_err("sprite update error: fail to erase cache\n");
|
||
|
return -1;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int sprite_form_sysrecovery(void)
|
||
|
{
|
||
|
HIMAGEITEM imghd = 0;
|
||
|
__u32 part_size;
|
||
|
__u32 img_start;
|
||
|
sunxi_download_info *dl_info = NULL;
|
||
|
char *src_buf = NULL;
|
||
|
int ret = -1;
|
||
|
int production_media = get_boot_storage_type();
|
||
|
|
||
|
#ifdef CONFIG_SUNXI_SPRITE_CARTOON
|
||
|
int nodeoffset;
|
||
|
int processbar_direct = 0;
|
||
|
;
|
||
|
nodeoffset = fdt_path_offset(working_fdt, FDT_PATH_CARD_BOOT);
|
||
|
if (nodeoffset >= 0) {
|
||
|
if (fdt_getprop_u32(working_fdt, nodeoffset,
|
||
|
"processbar_direct",
|
||
|
(uint32_t *)&processbar_direct) < 0)
|
||
|
processbar_direct = 0;
|
||
|
}
|
||
|
|
||
|
sprite_cartoon_create(processbar_direct);
|
||
|
#endif
|
||
|
tick_printf("sunxi sprite begin\n");
|
||
|
|
||
|
src_buf = (char *)malloc(1024 * 1024);
|
||
|
if (!src_buf) {
|
||
|
pr_err("sprite update error: fail to get memory for tmpdata\n");
|
||
|
goto _update_error_;
|
||
|
}
|
||
|
|
||
|
ret = sunxi_partition_get_info_byname("sysrecovery", &img_start, &part_size);
|
||
|
if (ret) {
|
||
|
pr_err("sprite update error: read image start error\n");
|
||
|
goto _update_error_;
|
||
|
}
|
||
|
tick_printf("part start = %d\n", img_start);
|
||
|
imghd = Img_Open_from_sysrecovery(img_start);
|
||
|
if (!imghd) {
|
||
|
pr_err("sprite update error: fail to open img\n");
|
||
|
goto _update_error_;
|
||
|
}
|
||
|
__imagehd(imghd);
|
||
|
|
||
|
#ifdef CONFIG_SUNXI_SPRITE_CARTOON
|
||
|
sprite_cartoon_upgrade(10);
|
||
|
#endif
|
||
|
|
||
|
//erase the data partition.
|
||
|
ret = sprite_erase_in_sysrecovery();
|
||
|
if (ret) {
|
||
|
goto _update_error_;
|
||
|
}
|
||
|
|
||
|
dl_info = (sunxi_download_info *)malloc(sizeof(sunxi_download_info));
|
||
|
if (!dl_info) {
|
||
|
pr_err("sprite update error: fail to get memory for download map\n");
|
||
|
goto _update_error_;
|
||
|
}
|
||
|
memset(dl_info, 0, sizeof(sunxi_download_info));
|
||
|
|
||
|
ret = sprite_card_fetch_download_map(dl_info);
|
||
|
if (ret) {
|
||
|
pr_err("sunxi sprite error: donn't download dl_map\n");
|
||
|
goto _update_error_;
|
||
|
}
|
||
|
#ifdef CONFIG_SUNXI_SPRITE_CARTOON
|
||
|
sprite_cartoon_upgrade(20);
|
||
|
#endif
|
||
|
|
||
|
if (sunxi_sprite_deal_part_from_sysrevoery(dl_info)) {
|
||
|
pr_err("sunxi sprite error : download part error\n");
|
||
|
goto _update_error_;
|
||
|
}
|
||
|
|
||
|
if (sunxi_sprite_deal_recorvery_boot(production_media)) {
|
||
|
pr_err("recovery error : download uboot or boot0 error!\n");
|
||
|
goto _update_error_;
|
||
|
}
|
||
|
tick_printf("successed in downloading uboot and boot0\n");
|
||
|
#ifdef CONFIG_SUNXI_SPRITE_CARTOON
|
||
|
sprite_cartoon_upgrade(100);
|
||
|
#endif
|
||
|
mdelay(3000);
|
||
|
|
||
|
Img_Close(imghd);
|
||
|
if (dl_info) {
|
||
|
free(dl_info);
|
||
|
}
|
||
|
if (src_buf) {
|
||
|
free(src_buf);
|
||
|
}
|
||
|
|
||
|
sunxi_board_restart(0);
|
||
|
return 0;
|
||
|
|
||
|
_update_error_:
|
||
|
if (dl_info) {
|
||
|
free(dl_info);
|
||
|
}
|
||
|
if (src_buf) {
|
||
|
free(src_buf);
|
||
|
}
|
||
|
pr_err("sprite update error: current card sprite failed\n");
|
||
|
pr_err("now hold the machine\n");
|
||
|
return -1;
|
||
|
}
|