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

327 lines
7.8 KiB
C
Raw Normal View History

2024-05-07 10:09:20 +00:00
/*
* (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;
}