blob: 82786aa37ceac861b45cea7cef09d11ff5d7061b [file] [log] [blame]
/*
* \file optimus_sdc_burn.c
* \brief burning itself from Pheripheral tf/sdmmc card
*
* \version 1.0.0
* \date 2013-7-11
* \author Sam.Wu <yihui.wu@amlgic.com>
*
* Copyright (c) 2013 Amlogic. All Rights Reserved.
*
*/
#include "optimus_sdc_burn_i.h"
#include "optimus_led.h"
#include <asm/arch/secure_apb.h>
#include <asm/io.h>
#include <amlogic/aml_efuse.h>
static int is_bootloader_old(void)
{
int sdc_boot = is_tpl_loaded_from_ext_sdmmc();
return !sdc_boot;
}
int get_burn_parts_from_img(HIMAGE hImg, ConfigPara_t* pcfgPara)
{
BurnParts_t* pburnPartsCfg = &pcfgPara->burnParts;
int i = 0;
int ret = 0;
int burnNum = 0;
const int totalItemNum = get_total_itemnr(hImg);
for (i = 0; i < totalItemNum; i++)
{
const char* main_type = NULL;
const char* sub_type = NULL;
ret = get_item_name(hImg, i, &main_type, &sub_type);
if (ret) {
DWN_ERR("Exception:fail to get item name!\n");
return __LINE__;
}
if (!strcmp("PARTITION", main_type))
{
char* partName = pburnPartsCfg->burnParts[burnNum];
if (!strcmp("bootloader", sub_type)) continue;
if (!strcmp(AML_SYS_RECOVERY_PART, sub_type))
{
if (OPTIMUS_WORK_MODE_SYS_RECOVERY == optimus_work_mode_get()) continue;
}
strcpy(partName, sub_type);
pburnPartsCfg->bitsMap4BurnParts |= 1U<<burnNum;
burnNum += 1;
}
}
if (burnNum)
{
pburnPartsCfg->burn_num = burnNum;
ret = check_cfg_burn_parts(pcfgPara);
if (ret) {
DWN_ERR("Fail in check burn parts\n");
return __LINE__;
}
print_burn_parts_para(pburnPartsCfg);
}
return OPT_DOWN_OK;
}
int optimus_verify_partition(const char* partName, HIMAGE hImg, char* _errInfo)
{
#define MaxSz (64 - 7) //verify file to at most 64B to corresponding to USB burn, strlen("verify ") == 7
char* argv[4];
int ret = 0;
HIMAGEITEM hImgItem = NULL;
int imgItemSz = 0;
char CmdVerify[MaxSz + 7] = {0};
hImgItem = image_item_open(hImg, "VERIFY", partName);
if (!hImgItem) {
DWN_ERR("Fail to open verify file for part (%s)\n", partName);
return ITEM_NOT_EXIST;
}
imgItemSz = (int)image_item_get_size(hImgItem);
if (imgItemSz > MaxSz || !imgItemSz) {
DWN_ERR("verify file size %d for part %s invalid, max is %d\n", imgItemSz, partName, MaxSz);
ret = __LINE__; goto _finish;
}
DWN_DBG("item sz %u\n", imgItemSz);
ret = image_item_read(hImg, hImgItem, CmdVerify, imgItemSz);
if (ret) {
DWN_ERR("Fail to read verify item for part %s\n", partName);
goto _finish;
}
CmdVerify[imgItemSz] = 0;
DWN_DBG("verify[%s]\n", CmdVerify);
argv[0] = "verify";
ret = cli_simple_parse_line(CmdVerify, argv + 1);
if (ret != 2) {
DWN_ERR("verify cmd argc must be 2, but %d\n", ret);
return __LINE__;
}
ret = optimus_media_download_verify(3, argv, _errInfo);
if (ret) {
DWN_ERR("Fail when verify\n");
return __LINE__;
}
_finish:
image_item_close(hImgItem);
return ret;
}
//.NeedVerify: Try to get verify file if .NeedVerify == 1
static int optimus_burn_one_partition(const char* partName, HIMAGE hImg, __hdle hUiProgress, int NeedVerify)
{
int rcode = 0;
s64 imgItemSz = 0;
s64 leftItemSz = 0;
u32 thisReadLen = 0;
__hdle hImgItem = NULL;
char* downTransBuf = NULL;//get buffer from optimus_buffer_manager
const unsigned ItemReadBufSz = OPTIMUS_DOWNLOAD_SLOT_SZ;//read this size from image item each time
unsigned sequenceNo = 0;
const char* fileFmt = NULL;
/*static */char _errInfo[512];
unsigned itemSizeNotAligned = 0;
unsigned itemSizePreload = 0;
printf("\n");
DWN_MSG("=====>To burn part [%s]\n", partName);
optimus_progress_ui_printf("Burning part[%s]\n", partName);
hImgItem = image_item_open(hImg, "PARTITION", partName);
if (!hImgItem) {
DWN_ERR("Fail to open item for part (%s)\n", partName);
return __LINE__;
}
imgItemSz = leftItemSz = image_item_get_size(hImgItem);
if (!imgItemSz) {
DWN_ERR("image size is 0 , image of part (%s) not exist ?\n", partName);
return __LINE__;
}
fileFmt = (IMAGE_ITEM_TYPE_SPARSE == image_item_get_type(hImgItem)) ? "sparse" : "normal";
itemSizeNotAligned = image_item_get_first_cluster_size(hImg, hImgItem);
//need let 'leftItemSz > 0' to trigger optimus_buf_manager_report_transfer_complete
if ( itemSizeNotAligned >= imgItemSz ) itemSizePreload = 0;
else itemSizePreload = itemSizeNotAligned;
leftItemSz -= itemSizePreload;
rcode = sdc_burn_buf_manager_init(partName, imgItemSz, fileFmt, itemSizePreload);
if (rcode) {
DWN_ERR("fail in sdc_burn_buf_manager_init, rcode %d\n", rcode);
return __LINE__;
}
//for each loop:
//1, get buffer from buffer_manager,
//2, read item data to buffer,
//3, report data ready to buffer_manager
for (; leftItemSz > 0; leftItemSz -= thisReadLen, sequenceNo++)
{
thisReadLen = leftItemSz > ItemReadBufSz ? ItemReadBufSz: (u32)leftItemSz;
rcode = optimus_buf_manager_get_buf_for_bulk_transfer(&downTransBuf, thisReadLen, sequenceNo, _errInfo);
if (rcode) {
DWN_ERR("fail in get buf, msg[%s]\n", _errInfo);
goto _finish;
}
//If the item head is not alinged to FAT cluster, Read it firstly to speed up mmc read
if (itemSizeNotAligned && !sequenceNo)
{
if ( itemSizeNotAligned >= imgItemSz ) {
itemSizePreload = imgItemSz;
if ( imgItemSz != thisReadLen ) {
DWN_ERR("itemSizeNotAligned 0x%x >= imgItemSz 0x%llx, but thisReadLen 0x%x\n",
itemSizeNotAligned, imgItemSz, thisReadLen);
rcode = __LINE__; goto _finish;
}
}
DWN_DBG("itemSizeNotAligned 0x%x, itemSizePreload 0x%x\n", itemSizeNotAligned, itemSizePreload);
rcode = image_item_read(hImg, hImgItem, downTransBuf - itemSizePreload, itemSizePreload);
if (rcode) {
DWN_ERR("fail in read data from item,rcode %d, len 0x%x, sequenceNo %d\n", rcode, itemSizePreload, sequenceNo);
goto _finish;
}
}
if ( itemSizePreload != imgItemSz )
{
rcode = image_item_read(hImg, hImgItem, downTransBuf, thisReadLen);
if (rcode) {
DWN_ERR("fail in read data from item,rcode %d\n", rcode);
goto _finish;
}
} else {
memmove(downTransBuf, downTransBuf - itemSizePreload, itemSizePreload);
}
rcode = optimus_buf_manager_report_transfer_complete(thisReadLen, _errInfo);
if (rcode) {
DWN_ERR("fail in report data ready, rcode %d\n", rcode);
goto _finish;
}
if (hUiProgress)optimus_progress_ui_update_by_bytes(hUiProgress, thisReadLen) ;
}
DWN_DBG("BURN part %s %s!\n", partName, leftItemSz ? "FAILED" : "SUCCESS");
_finish:
image_item_close(hImgItem);
if (rcode) {
DWN_ERR("Fail to burn part(%s) with in format (%s) before verify\n", partName, fileFmt);
optimus_progress_ui_printf("Failed at burn part[%s] befor VERIFY\n", partName);
return rcode;
}
#if 1
if (!NeedVerify) {
return rcode;
}
rcode = optimus_verify_partition(partName, hImg, _errInfo);
if (ITEM_NOT_EXIST == rcode)
{
printf("WRN:part(%s) NOT verified\n", partName);
return 0;
}
if (rcode) {
printf("Fail in verify part(%s)\n", partName);
optimus_progress_ui_printf("Failed at VERIFY part[%s]\n", partName);
return __LINE__;
}
#endif//#fi 0
return rcode;
}
int optimus_sdc_burn_partitions(ConfigPara_t* pCfgPara, HIMAGE hImg, __hdle hUiProgress, int NeedVerify)
{
BurnParts_t* cfgParts = &pCfgPara->burnParts;
int burnNum = cfgParts->burn_num;
int i = 0;
int rcode = 0;
//update burn_parts para if burnNum is 0, i.e, not configured
if (!burnNum)
{
rcode = get_burn_parts_from_img(hImg, pCfgPara);
if (rcode) {
DWN_ERR("Fail to get burn parts from image\n");
return __LINE__;
}
burnNum = cfgParts->burn_num;
DWN_DBG("Data part num %d\n", burnNum);
}
if (!burnNum) {
DWN_ERR("Data part num is 0!!\n");
return __LINE__;
}
for (i = 0; i < burnNum; i++)
{
const char* partName = cfgParts->burnParts[i];
rcode = optimus_burn_one_partition(partName, hImg, hUiProgress, NeedVerify);
if (rcode) {
DWN_ERR("Fail in burn part %s\n", partName);
return __LINE__;
}
}
return rcode;
}
//not need to verify as not config ??
int optimus_sdc_burn_media_partition(const char* mediaImgPath, const char* verifyFile)
{
//TODO:change configure to 'partName = image' and work it using cmd 'sdc_update'
return optimus_burn_partition_image("media", mediaImgPath, "normal", verifyFile, 0);
}
int optimus_burn_bootlader(HIMAGE hImg)
{
int rcode = 0;
int NeedVerify = 1;
rcode = optimus_burn_one_partition("bootloader", hImg, NULL, NeedVerify);
if (rcode) {
DWN_ERR("Fail when burn bootloader\n");
return __LINE__;
}
return rcode;
}
//flag, 0 is burn completed, else burn failed
int optimus_report_burn_complete_sta(int isFailed, int rebootAfterBurn)
{
if (isFailed)
{
DWN_MSG("=====Burn Failed!!!!!\n");
DWN_MSG("PLS long-press power key to shut down\n");
optimus_led_show_burning_failure();
while (1) {
/*if(ctrlc())run_command("reset", 0);*/
}
return __LINE__;
}
DWN_MSG("======sdc burn SUCCESS.\n");
optimus_led_show_burning_success();
optimus_burn_complete(rebootAfterBurn ? rebootAfterBurn : OPTIMUS_BURN_COMPLETE__POWEROFF_AFTER_POWERKEY);//set complete flag and poweroff if burn successful
return 0;
}
int optimus_sdc_burn_dtb_load(HIMAGE hImg)
{
s64 itemSz = 0;
HIMAGEITEM hImgItem = NULL;
int rc = 0;
const char* partName = "dtb";
u64 partBaseOffset = OPTIMUS_DOWNLOAD_TRANSFER_BUF_ADDR;
unsigned char* dtbTransferBuf = (unsigned char*)partBaseOffset;
//meson1.dtb but not meson.dtb for m8 compatible
if (IS_FEAT_BOOT_VERIFY()) {
DWN_MSG("SecureEnabled, use meson1_ENC\n");
hImgItem = image_item_open(hImg, partName, "meson1_ENC");
}
else {
hImgItem = image_item_open(hImg, partName, "meson1");
}
if (!hImgItem) {
DWN_WRN("Fail to open item [meson1,%s]\n", partName);
return ITEM_NOT_EXIST;
}
itemSz = image_item_get_size(hImgItem);
if (!itemSz) {
DWN_ERR("Item size 0\n");
image_item_close(hImgItem); return __LINE__;
}
#if 1
const unsigned itemSzNotAligned = image_item_get_first_cluster_size(hImg, hImgItem);
if (itemSzNotAligned /*& 0x7*/) {//Not Aligned 8bytes/64bits, mmc dma read will failed
DWN_MSG("align 4 mmc read...\t");//Assert Make 'DDR' buffer addr align 8
dtbTransferBuf += image_get_cluster_size(hImg) - itemSzNotAligned;
partBaseOffset += image_get_cluster_size(hImg) - itemSzNotAligned;
}
#endif
rc = image_item_read(hImg, hImgItem, dtbTransferBuf, (unsigned)itemSz);
if (rc) {
DWN_ERR("Failed at item read, rc = %d\n", rc);
image_item_close(hImgItem); return __LINE__;
}
image_item_close(hImgItem);
rc = optimus_parse_img_download_info(partName, itemSz, "normal", "mem", partBaseOffset);
if (rc) {
DWN_ERR("Failed in init down info\n"); return __LINE__;
}
{
unsigned wrLen = 0;
char errInfo[512];
wrLen = optimus_download_img_data(dtbTransferBuf, (unsigned)itemSz, errInfo);
rc = (wrLen == itemSz) ? 0 : __LINE__;
}
return rc;
}
#if CONFIG_SUPPORT_SDC_KEYBURN
//fetch the keys names which need be burned from item[conf, keys]
static int sdc_burn_get_user_key_names(HIMAGE hImg, const char* **pKeysName, unsigned* keysNum)
{
int rc = 0;
HIMAGEITEM hImgItem = NULL;
unsigned itemSz = 0;
unsigned char* thisReadBuf = (unsigned char*)OPTIMUS_SPARSE_IMG_FILL_VAL_BUF;//This buf is not used and not need reuse when burning keys
const unsigned thisReadBufSz = (OPTIMUS_SPARSE_IMG_FILL_BUF_SZ >> 1);
const char* *keysName = (const char**)(thisReadBuf + thisReadBufSz);
hImgItem = image_item_open(hImg, "conf", "keys");
if (!hImgItem) {
DWN_ERR("Fail to open keys.conf\n");
return ITEM_NOT_EXIST;
}
itemSz = (unsigned)image_item_get_size(hImgItem);
if (!itemSz) {
DWN_ERR("Item size 0\n");
image_item_close(hImgItem); return __LINE__;
}
const unsigned itemSzNotAligned = image_item_get_first_cluster_size(hImg, hImgItem);
if (itemSzNotAligned /*& 0x7*/) {//Not Aligned 8bytes/64bits, mmc dma read will failed
DWN_MSG("align 4 mmc read...\t");//Assert Make 'DDR' buffer addr align 8
thisReadBuf += image_get_cluster_size(hImg);
thisReadBuf -= itemSzNotAligned;
}
rc = image_item_read(hImg, hImgItem, thisReadBuf, itemSz);
if (rc) {
DWN_ERR("Failed at item read, rc = %d\n", rc);
image_item_close(hImgItem); return __LINE__;
}
image_item_close(hImgItem);
if (itemSz >= thisReadBufSz) {
DWN_ERR("itemSz(0x%x) of keys.conf too large, > max 0x%x.\n", itemSz, thisReadBufSz);
return __LINE__;
}
rc = _optimus_parse_buf_2_lines((char*)thisReadBuf, itemSz, keysName, keysNum, 16);
if (rc) {
DWN_ERR("Fail in parse buf_2_lines\n");
return __LINE__;
}
rc = _optimus_abandon_ini_comment_lines((char**)keysName, *keysNum);
*pKeysName = keysName;
return rc;
}
//check key is burned yet --> need keyOverWrite -->can_write
static int sdc_check_key_need_to_burn(const char* keyName, const int keyOverWrite)
{
int rc = 0;
char _cmd[96];
sprintf(_cmd, "aml_key_burn misc is_burned %s", keyName);
rc = run_command(_cmd, 0);
if (rc < 0) {
DWN_ERR("Fail in check key is_burned\n");
return -__LINE__;
}
DWN_MSG("key[%s] is %s burned\n", keyName, rc ? "NOT" : "DO");
if (rc) {//not success
return 1;//need burn as not burned yet.
}
if (!keyOverWrite) {
DWN_MSG("User choose not to overwrite the key\n");
return 0;
}
sprintf(_cmd, "aml_key_burn misc can_write %s", keyName);
rc = run_command(_cmd, 0);
if (rc) {
DWN_ERR("Fail in check key[%s] is_burned\n", keyName);
return -__LINE__;
}
DWN_MSG("key[%s] is %s can_write\n", keyName, rc ? "NOT" : "DO");
return !rc;
}
//burn the amlogic keys like USB_Burning_Tool
static int sdc_burn_aml_keys(HIMAGE hImg, const int keyOverWrite)
{
int rc = 0;
const char* *keysName = NULL;
unsigned keysNum = 0;
const char** pCurKeysName = NULL;
unsigned index = 0;
rc = run_command("aml_key_burn probe vfat sdc", 0);
if (rc) {
DWN_ERR("Fail in probe for aml_key_burn\n");
return __LINE__;
}
{
unsigned random32 = 0;
unsigned seed = 0;
char cmd[96];
random32 = seed = get_timer(0) + 12345;//FIXME:make it random
/*random32 = random_u32(seed);*/
DWN_MSG("random value is 0x%x\n", random32);
sprintf(cmd, "aml_key_burn init 0x%x", random32);
rc = run_command(cmd, 0);
if (rc) {
DWN_ERR("Fail in cmd[%s]\n", cmd);
return __LINE__;
}
}
rc = sdc_burn_get_user_key_names(hImg, &keysName, &keysNum);
if (ITEM_NOT_EXIST != rc && rc) {
DWN_ERR("Fail to parse keys.conf, rc =%d\n", rc);
return __LINE__;
}
DWN_MSG("keys.conf:\n");
for (index = 0; index < keysNum; ++index)printf("\tkey[%d]\t%s\n", index, keysName[index]) ;
rc = optimus_sdc_keysprovider_init();
if (rc) {
DWN_ERR("Fail in optimus_sdc_keysprovider_init\n");
return __LINE__;
}
pCurKeysName = keysName;
for (index = 0; index < keysNum; ++index)
{
const char* const keyName = *pCurKeysName++;
if (!keyName) continue;
DWN_MSG("\n");
DWN_MSG("Now to burn key <---- [%s] ----> %d \n", keyName, index);
rc = sdc_check_key_need_to_burn(keyName, keyOverWrite);
if (rc < 0) {
DWN_ERR("Fail when when check stauts for key(%s)\n", keyName);
/*return __LINE__;*/
}
if (!rc) continue;//not need to burn this key
//0, init the key license parser
const void* pHdle = NULL;
rc = optimus_sdc_keysprovider_open(keyName, &pHdle);
if (rc) {
DWN_ERR("Fail in init license for key[%s]\n", keyName);
return __LINE__;
}
//1,using cmd_keysprovider to read a key to memory
u8* keyValue = (u8*)OPTIMUS_DOWNLOAD_TRANSFER_BUF_ADDR;
unsigned keySz = OPTIMUS_DOWNLOAD_SLOT_SZ;//buffer size
rc = optimus_sdc_keysprovider_get_keyval(pHdle, keyValue, &keySz);
if (rc) {
DWN_ERR("Fail to get value for key[%s]\n", keyName);
return __LINE__;
}
//3, burn the key
rc = optimus_keysburn_onekey(keyName, (u8*)keyValue, keySz);
if (rc) {
DWN_ERR("Fail in burn the key[%s] at addr=%p, sz=%d\n", keyName, keyValue, keySz);
return __LINE__;
}
//3,report burn result to cmd_keysprovider
rc = optimus_sdc_keysprovider_update_license(pHdle);
if (rc) {
DWN_ERR("Fail in update license for key[%s]\n", keyName);
return __LINE__;
}
}
rc = optimus_sdc_keysprovider_exit();
if (rc) {
DWN_ERR("Fail in optimus_sdc_keysprovider_exit\n");
return __LINE__;
}
rc = run_command("aml_key_burn uninit", 0);
if (rc) {
DWN_ERR("Fail in uninit for aml_key_burn\n");
return __LINE__;
}
return 0;
}
#else
#define sdc_burn_aml_keys(fmt...) 0
#endif// #if CONFIG_SUPPORT_SDC_KEYBURN
int optimus_burn_with_cfg_file(const char* cfgFile)
{
extern ConfigPara_t g_sdcBurnPara ;
int ret = 0;
HIMAGE hImg = NULL;
ConfigPara_t* pSdcCfgPara = &g_sdcBurnPara;
const char* pkgPath = pSdcCfgPara->burnEx.pkgPath;
__hdle hUiProgress = NULL;
ret = parse_ini_cfg_file(cfgFile);
if (ret) {
DWN_ERR("Fail to parse file %s\n", cfgFile);
ret = __LINE__; goto _finish;
}
if (pSdcCfgPara->custom.eraseBootloader && strcmp("1", getenv("usb_update")))
{
if (is_bootloader_old())
{
DWN_MSG("To erase OLD bootloader !\n");
ret = optimus_erase_bootloader("sdc");
if (ret) {
DWN_ERR("Fail to erase bootloader\n");
ret = __LINE__; goto _finish;
}
#if defined(CONFIG_VIDEO_AMLLCD)
//axp to low power off LCD, no-charging
DWN_MSG("To close LCD\n");
ret = run_command("video dev disable", 0);
if (ret) {
printf("Fail to close back light\n");
/*return __LINE__;*/
}
#endif// #if defined(CONFIG_VIDEO_AMLLCD)
DWN_MSG("Reset to load NEW uboot from ext-mmc!\n");
optimus_reset(OPTIMUS_BURN_COMPLETE__REBOOT_SDC_BURN);
return __LINE__;//should never reach here!!
}
}
if (OPTIMUS_WORK_MODE_SDC_PRODUCE == optimus_work_mode_get()) //led not depend on image res, can init early
{
if (optimus_led_open(LED_TYPE_PWM)) {
DWN_ERR("Fail to open led for sdc_produce\n");
return __LINE__;
}
optimus_led_show_in_process_of_burning();
}
hImg = image_open("mmc", "0", "1", pkgPath);
if (!hImg) {
DWN_ERR("Fail to open image %s\n", pkgPath);
ret = __LINE__; goto _finish;
}
//update dtb for burning drivers
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;
}
if (video_res_prepare_for_upgrade(hImg)) {
DWN_ERR("Fail when prepare bm res or init video for upgrade\n");
image_close(hImg);
return __LINE__;
}
show_logo_to_report_burning();
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_IMAGE_OPEN_OK);
int hasBootloader = 0;
u64 datapartsSz = optimus_img_decoder_get_data_parts_size(hImg, &hasBootloader);
int eraseFlag = pSdcCfgPara->custom.eraseFlash;
if (!datapartsSz) {
eraseFlag = 0;
DWN_MSG("Disable erase as data parts size is 0\n");
}
ret = optimus_storage_init(eraseFlag);
if (ret) {
DWN_ERR("Fail to init stoarge for sdc burn\n");
return __LINE__;
}
optimus_progress_ui_direct_update_progress(hUiProgress, UPGRADE_STEPS_AFTER_DISK_INIT_OK);
if (datapartsSz)
{
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;
}
ret = optimus_sdc_burn_partitions(pSdcCfgPara, hImg, hUiProgress, 1);
if (ret) {
DWN_ERR("Fail when burn partitions\n");
ret = __LINE__; goto _finish;
}
}
if (pSdcCfgPara->burnEx.bitsMap.mediaPath) //burn media image
{
const char* mediaPath = pSdcCfgPara->burnEx.mediaPath;
ret = optimus_sdc_burn_media_partition(mediaPath, NULL);//no progress bar info if have partition image not in package
if (ret) {
DWN_ERR("Fail to burn media partition with image %s\n", mediaPath);
/*optimus_storage_exit();*/
ret = __LINE__;goto _finish;
}
}
optimus_progress_ui_direct_update_progress(hUiProgress, UPGRADE_STPES_AFTER_BURN_DATA_PARTS_OK);
//TO burn nandkey/securekey/efusekey
ret = sdc_burn_aml_keys(hImg, pSdcCfgPara->custom.keyOverwrite);
if (ret) {
DWN_ERR("Fail in sdc_burn_aml_keys\n");
ret = __LINE__;goto _finish;
}
#if 1
if (hasBootloader)
{//burn bootloader
ret = optimus_burn_bootlader(hImg);
if (ret) {
DWN_ERR("Fail in burn bootloader\n");
goto _finish;
}
else
{//update bootloader ENV only when bootloader image is burned
ret = optimus_set_burn_complete_flag();
if (ret) {
DWN_ERR("Fail in set_burn_complete_flag\n");
ret = __LINE__; goto _finish;
}
}
}
#endif
optimus_progress_ui_direct_update_progress(hUiProgress, UPGRADE_STEPS_AFTER_BURN_BOOTLOADER_OK);
_finish:
image_close(hImg);
optimus_progress_ui_report_upgrade_stat(hUiProgress, !ret);
optimus_report_burn_complete_sta(ret, pSdcCfgPara->custom.rebootAfterBurn);
optimus_progress_ui_release(hUiProgress);
//optimus_storage_exit();//temporary not exit storage driver when failed as may continue burning after burn
return ret;
}
int optimus_burn_package_in_sdmmc(const char* sdc_cfg_file)
{
int rcode = 0;
#if 0//this asserted by 'run update' and 'aml_check_is_ready_for_sdc_produce'
rcode = do_fat_get_fileSz(sdc_cfg_file);
if (!rcode) {
printf("The [%s] not exist in bootable mmc card\n", sdc_cfg_file);
return __LINE__;
}
#endif//#if 0
rcode = optimus_device_probe("mmc", "0");
if (rcode) {
DWN_ERR("Fail to detect device mmc 0\n");
return __LINE__;
}
setenv("usb_update","0");
rcode = optimus_burn_with_cfg_file(sdc_cfg_file);
return rcode;
}
int do_sdc_burn(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
int rcode = 0;
const char* sdc_cfg_file = argv[1];
if (argc < 2 ) {
return CMD_RET_USAGE;
}
if ( !aml_check_is_ready_for_sdc_produce() ) {
DWN_DBG("Not ready\n");
return __LINE__;
}
optimus_work_mode_set(OPTIMUS_WORK_MODE_SDC_UPDATE);
run_command("osd clear", 0);
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();
rcode = optimus_burn_package_in_sdmmc(sdc_cfg_file);
return rcode;
}
U_BOOT_CMD(
sdc_burn, //command name
5, //maxargs
0, //repeatable
do_sdc_burn, //command function
"Burning with amlogic format package in sdmmc ", //description
"argv: [sdc_burn_cfg_file]\n"//usage
" -aml_sdc_burn.ini is usually used configure file\n"
);