blob: a81ac30e0cf51c8225a7e16f594db4275dc8fdf4 [file] [log] [blame]
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2019 Amlogic, Inc. All rights reserved.
*/
#include "../v2_burning_i.h"
#include "../v2_sdc_burn/optimus_sdc_burn_i.h"
#include "../v2_sdc_burn/optimus_led.h"
#ifndef CONFIG_AML_SYS_RECOVERY_CLEAR_USR_DATA
#define CONFIG_AML_SYS_RECOVERY_CLEAR_USR_DATA "data"
#endif// #ifndef CONFIG_AML_SYS_RECOVERY_CLEAR_USR_DATA
extern int sdc_burn_aml_keys(HIMAGE hImg, const int keyOverWrite, int licenseKey, int imgKey);
static int optimus_sysrec_check_whole_img_before_burn(const char* partName)
{
//TODO:
return 0;
}
#ifdef CONFIG_AML_SYS_RECOVERY_CLEAR_USR_DATA
//clear data parts then the parts will formatted when firtsboot
//As fill half parttition need so much time, I just clear 2M
static int optimus_sysrec_clear_usr_data_parts(void)
{
const char* const _usrDataParts[] = {CONFIG_AML_SYS_RECOVERY_CLEAR_USR_DATA,};
const int dataPartsNum = sizeof(_usrDataParts)/sizeof(const char*);
int partIndex = 0;
int ret = 0;
char cmdbuf[128];
for (partIndex = 0; partIndex < dataPartsNum; ++partIndex)
{
sprintf(cmdbuf, "store erase partition %s", _usrDataParts[partIndex]);
ret = run_command(cmdbuf, 0);
if (ret) { DWN_WRN("Wrn:failed in cmd:%s\n", cmdbuf); }
}
return ret;
}
#endif//#ifdef CONFIG_AML_SYS_RECOVERY_CLEAR_USR_DATA
/*
*.partName: aml_sysrecovery
*.needVerify: 1 then verify partitions that contain verify file; 0 then not to verify for faster burning
*/
static int optimus_sysrec_burn_package_from_partition(const char* partName, const unsigned needVerifyWhileBurn,
const unsigned verifyPackageBeforeBurn)
{
extern ConfigPara_t g_sdcBurnPara ;
ConfigPara_t* pSdcCfgPara = &g_sdcBurnPara;
__hdle hUiProgress = NULL;
HIMAGE hImg = NULL;
int ret = 0;
int hasBootloader = 0;
u64 datapartsSz = 0;
if (verifyPackageBeforeBurn)
{
ret = optimus_sysrec_check_whole_img_before_burn(partName);
if (ret) {
DWN_ERR("Failed in crc check the burning package.\n");
return __LINE__;
}
}
hImg = image_open("store", "0", AML_SYS_RECOVERY_PART, "");
if (!hImg) {
DWN_ERR("Fail to open image in part %s\n", AML_SYS_RECOVERY_PART);
ret = __LINE__; goto _finish;
}
if (video_res_prepare_for_upgrade(hImg)) {
DWN_ERR("Fail when prepare bm res or init video for upgrade\n");
ret = __LINE__; goto _finish;
}
show_logo_to_report_burning();
//update dtb for keyman
ret = optimus_sdc_burn_dtb_load(hImg);
if (ITEM_NOT_EXIST != ret && ret) {
DWN_ERR("Fail in load dtb for sdc_burn\n");
ret = __LINE__; goto _finish;
}
optimus_storage_init(0);
hUiProgress = optimus_progress_ui_request_for_sdc_burn();
if (!hUiProgress) {
DWN_ERR("request progress handle failed!\n");
ret = __LINE__; goto _finish;
}
optimus_progress_ui_direct_update_progress(hUiProgress, UPGRADE_STEPS_AFTER_DISK_INIT_OK);
datapartsSz = optimus_img_decoder_get_data_parts_size(hImg, &hasBootloader);
DWN_MSG("datapartsSz=[%8u]MB\n", (unsigned)(datapartsSz >> 20));
ret = optimus_progress_ui_set_smart_mode(hUiProgress, datapartsSz,
UPGRADE_STEPS_FOR_BURN_DATA_PARTS_IN_PKG(!pSdcCfgPara->burnEx.bitsMap.mediaPath));
if (ret) {
DWN_ERR("Fail to set smart mode\n");
ret = __LINE__; goto _finish;
}
pSdcCfgPara->burnParts.burn_num = 0;
ret = optimus_sdc_burn_partitions(pSdcCfgPara, hImg, hUiProgress, needVerifyWhileBurn);
if (ret) {
DWN_ERR("Fail when burn partitions\n");
ret = __LINE__; goto _finish;
}
optimus_progress_ui_direct_update_progress(hUiProgress, UPGRADE_STPES_AFTER_BURN_DATA_PARTS_OK);
#if 1
if (hasBootloader)
{//burn bootloader
ret = optimus_burn_bootlader(hImg);
if (ret) {
DWN_ERR("Fail in burn bootloader\n");
goto _finish;
}
ret = optimus_set_burn_complete_flag();
if (ret) {
DWN_ERR("Fail in set_burn_complete_flag\n");
ret = __LINE__; goto _finish;
}
}
#endif
#if CONFIG_SUPPORT_SDC_KEYBURN
ret = sdc_burn_aml_keys(hImg, 0, 0, 1);
if (ret) {
DWN_ERR("Fail in recovery keys from img\n");
ret = __LINE__; goto _finish;
}
#endif// #if CONFIG_SUPPORT_SDC_KEYBURN
#ifdef CONFIG_AML_SYS_RECOVERY_CLEAR_USR_DATA
optimus_sysrec_clear_usr_data_parts();
#endif// #ifdef CONFIG_AML_SYS_RECOVERY_CLEAR_USR_DATA
optimus_progress_ui_direct_update_progress(hUiProgress, UPGRADE_STEPS_AFTER_BURN_BOOTLOADER_OK);
_finish:
image_close(hImg);
if (hUiProgress) optimus_progress_ui_report_upgrade_stat(hUiProgress, !ret);
optimus_report_burn_complete_sta(ret, 1/*pSdcCfgPara->custom.rebootAfterBurn*/);
if (hUiProgress) optimus_progress_ui_release(hUiProgress);
//optimus_storage_exit();//temporary not exit storage driver when failed as may continue burning after burn
return ret;
}
static int do_aml_sysrecovery(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
int rcode = 0;
unsigned needVerify = (1 < argc) ? simple_strtoul(argv[1], NULL, 0) : 0;
unsigned verifyPackageBeforeBurn = (2 < argc) ? simple_strtoul(argv[2], NULL, 0) : 0;
if (argc < 2 ) {
cmd_usage(cmdtp);
return __LINE__;
}
show_logo_to_report_burning();//indicate enter flow of burning! when 'run update'
if (optimus_led_open(LED_TYPE_PWM)) {
DWN_ERR("Fail to open led for burn\n");
return __LINE__;
}
optimus_led_show_in_process_of_burning();
optimus_work_mode_set(OPTIMUS_WORK_MODE_SYS_RECOVERY);
optimus_buf_manager_init(16*1024);
rcode = optimus_sysrec_burn_package_from_partition(AML_SYS_RECOVERY_PART, needVerify, verifyPackageBeforeBurn);
return rcode;
}
U_BOOT_CMD(
aml_sysrecovery, //command name
3, //maxargs
0, //repeatable
do_aml_sysrecovery, //command function
"Burning with amlogic format package from partition sysrecovery", //description
"argv: needVerify [,checkWholeImgBeforeBurn]\n"//usage
" --@needVerify: 0 then skip to verify the partition even have verify file."
" --@checkWholeImgBeforeBurn: 1 then crc32 check the burn package in partition sysrecovery before actual burn"
" eg:'aml_sysrecovery 0': burn from partition aml_sysrecovery without verify"
);