/*
 * \file        optimu_download.c
 * \brief
 *
 * \version     1.0.0
 * \date        2013/4/25
 * \author      Sam.Wu <yihui.wu@amlogic.com>
 *
 * Copyright (c) 2013 Amlogic Inc. All Rights Reserved.
 *
 */
#include "../v2_burning_i.h"
#include <linux/libfdt.h>
#include <partition_table.h>
#include <asm/arch/secure_apb.h>
#include <asm/arch/bl31_apis.h>
#include <asm/io.h>
#include <asm/arch/mailbox.h>

#define ROM_BOOT_SKIP_BOOT_ENABLED_4_USB      1//skip boot to usb supported by romboot
#ifdef SCPI_CMD_SDCARD_BOOT
#define ROM_BOOT_SKIP_BOOT_ENABLED_4_SDC      1//skip boot sdcard supported by romboot
#else
#define ROM_BOOT_SKIP_BOOT_ENABLED_4_SDC      0
#endif//#ifdef SCPI_CMD_SDCARD_BOOT

extern unsigned int get_multi_dt_entry(unsigned long fdt_addr);
int is_optimus_storage_inited(void);

#if !defined(CONFIG_UNIFY_KEY_MANAGE)
int v2_key_read(const char* keyName, u8* keyVal, const unsigned keyValLen, char* errInfo, unsigned* fmtLen)
{
    DWN_ERR("burn key not supported as CONFIG_UNIFY_KEY_MANAGE undef!!");
    return OPT_DOWN_FAIL;
}

unsigned v2_key_burn(const char* keyName, const u8* keyVal, const unsigned keyValLen, char* errInfo)
{
    DWN_ERR("burn key not supported as CONFIG_UNIFY_KEY_MANAGE undef!!");
    return OPT_DOWN_FAIL;
}

int v2_key_command(const int argc, char * const argv[], char *info)
{

    DWN_ERR("burn key not supported as CONFIG_UNIFY_KEY_MANAGE undef!!");
    return OPT_DOWN_FAIL;
}
#endif//#ifndef CONFIG_UNIFY_KEY_MANAGE

static unsigned long _dtb_is_loaded = 0;


#define IMG_VERIFY_ALG_NONE     0 //not need to veryfy
#define IMG_VERIFY_ALG_SHA1SUM  1
#define IMG_VERIFY_ALG_CRC32    2
#define IMG_VERIFY_ALG_ADDSUM   3

#define OPTIMUS_IMG_STA_EMPTY           0
#define OPTIMUS_IMG_STA_PRE_BURN        1 //has get tplcmd load
#define OPTIMUS_IMG_STA_BURN_ING        2
#define OPTIMUS_IMG_STA_BURN_COMPLETE   3
#define OPTIMUS_IMG_STA_BURN_FAILED     4
#define OPTIMUS_IMG_STA_VERIFY_ING      5
#define OPTIMUS_IMG_STA_VERIFY_END      6

enum {
    IMG_TYPE_SPARSE     = 0xae  ,
    IMG_TYPE_NORMAL             ,
    IMG_TYPE_BOOTLOADER         ,
    IMG_TYPE_DTB                ,
    IMG_TYPE_UBIFS		,
};

//Image info for burnning and verify
//FIXME: how to assert that image not larger than the partition
#define IMG_BURN_INFO_SZ    96
struct ImgBurnInfo{
    u8  imgType;    //0 normal, 1 sparse
    u8  verifyAlgorithm;//0--sha1sum, 1--crc32, 2--addsum
    u8  imgBurnSta;//
    u8  storageMediaType;//NAND default,
    u8  isDumpMode; //if dump mode
    u8  resrv4Align[3];

    u64 nextMediaOffset;//image size already  received
    u64 imgPktSz;//total size of the file image
    u64 imgSzDisposed;//total size alreay disposed
    u64 partBaseOffset;//start offset of this part

    void* devHdle;
    char partName[32];//

    u8  burnInfoPrivate[IMG_BURN_INFO_SZ - 32 - sizeof(void*) - sizeof(u64) * 5];//needed private info when verify, for example when we read ext4 to sparse file
};

static struct ImgBurnInfo OptimusImgBurnInfo = {0};
static const char*   _usbDownPartImgType = "";

struct imgBurnInfo_sparse{

};

struct imgBurnInfo_normal{
};

struct imgBurnInfo_bootloader{
    u32     transferBufAddr;
    u32     transferBufSzTotal;

};

COMPILE_TIME_ASSERT(IMG_BURN_INFO_SZ == sizeof(struct ImgBurnInfo));

#if CONFIG_AML_STORAGE
//asset logical partition size >= CFG size in storage.c
//nand often make mistake this size, emmc should always ok
static int _assert_logic_partition_cap(const char* thePartName, const uint64_t nandPartCap)
{
    extern struct partitions * part_table;

    int partIndex                   = 0;
    struct partitions * thePart     = NULL;
    if (NULL == part_table)
        return 0;
    for (thePart = part_table; partIndex < 36; ++thePart, ++partIndex)
    {
        if (memcmp(thePartName, thePart->name, strnlen(thePartName, MAX_PART_NAME_LEN))) continue;

        const uint64_t dtsPartSz = thePart->size;
        DWN_DBG("cfg dtsPartSz %llx for part(%s)\n", dtsPartSz, thePartName);
        if (NAND_PART_SIZE_FULL == dtsPartSz) {return 0;}
        if (dtsPartSz > nandPartCap) {
            DWN_ERR("partSz of logic part(%s): sz dts %llx > Sz flash %llx\n",
                    thePartName, dtsPartSz, nandPartCap);
            return __LINE__;
        }

        return 0;
    }

    DWN_ERR("Can't find your download part(%s)\n", thePartName);
    return __LINE__;
}
#else
#define _assert_logic_partition_cap(thePartName, nandPartCap) 0
#endif// #if CONFIG_AML_STORAGE

//return value is the actual size it write
static int optimus_download_dtb_image(struct ImgBurnInfo* pDownInfo, u32 dataSzReceived, const u8* data)
{
    int ret = 0;
    DWN_MSG("%s:dataSzReceived=0x%x\n", __func__, dataSzReceived);
    store_erase("dtb", 0, store_rsv_size("dtb"), 0);
    ret = store_rsv_write("dtb", dataSzReceived, (u8*)data);

    return ret ? 0 : dataSzReceived;
}

static int optimus_verify_dtb(struct ImgBurnInfo* pDownInfo, u8* genSum)
{
    int ret = OPT_DOWN_OK;
    unsigned char* pBuf = (unsigned char*)OPTIMUS_DOWNLOAD_TRANSFER_BUF_ADDR;
    uint64_t size = 0;

    size=pDownInfo->imgPktSz;
    ret = store_rsv_read("dtb", size, pBuf);
    if (ret) {
        DWN_ERR("Fail to read dtb\n");
        return __LINE__;
    }

    sha1_csum(pBuf, (u32)pDownInfo->imgPktSz, genSum);

    return ret;
}

//32k, Now nand not need align any more, but I remember spi nor flash need 32k aligh
#define BOOTLOADER_ALIGN_BITS   0//15

//return value is the actual size it write
static int optimus_download_bootloader_image(struct ImgBurnInfo* pDownInfo, u32 dataSzReceived, const u8* data)
{
    int ret = OPT_DOWN_OK;
    int size = dataSzReceived;
    int iCopy = 0;

    if (dataSzReceived < pDownInfo->imgPktSz) {
        DWN_ERR("please write back bootloader after all data rx end.0x(%x, %x)\n", dataSzReceived, (u32)pDownInfo->imgPktSz);
        return 0;
    }

    if (size > (2U<<20)) {
        DWN_ERR("uboot.bin size 0x%x > 2M unsupported\n", size);
        return 0;
    }

    const char* bootName = "bootloader";
    const int bootCpyNum = store_boot_copy_num(bootName);
    const int bootCpySz  = (int)store_boot_copy_size(bootName);
    DWN_MSG("bootCpyNum %d, bootCpySz 0x%x\n", bootCpyNum, bootCpySz);
    if (size > bootCpySz) {
        DWN_MSG("bootloader img sz 0x%x > bootCpySz 0x%x\n", size, bootCpySz);
        return 0;
    }
#if BOOTLOADER_ALIGN_BITS
    size += (1U<<BOOTLOADER_ALIGN_BITS) -1;
    size >>= BOOTLOADER_ALIGN_BITS;
    size <<= BOOTLOADER_ALIGN_BITS;
    if (dataSzReceived != size)DWN_MSG("align bootloader sz from 0x%x to 0x%lx\n", dataSzReceived, size) ;
#endif// #if BOOTLOADER_ALIGN_BITS
    for (; iCopy < bootCpyNum; ++iCopy) {
        ret = store_boot_write(bootName, iCopy, size, (u8*)data);
        if (ret) {
            DWN_ERR("FAil in program[%s] at copy[%d]\n", bootName, iCopy);
            return 0;
        }
    }

    return ret ? 0 : dataSzReceived;
}

extern unsigned device_boot_flag;
static int optimus_verify_bootloader(struct ImgBurnInfo* pDownInfo, u8* genSum)
{
    int ret = OPT_DOWN_OK;
    unsigned char* pBuf = (unsigned char*)OPTIMUS_DOWNLOAD_TRANSFER_BUF_ADDR;
    int size = 0;
    int iCopy = 0;
    int bootRealSz = pDownInfo->imgPktSz;

#if defined(CONFIG_AML_MTD) && defined(CONFIG_DISCRETE_BOOTLOADER)
    uint64_t off  = 0;
    if ( NAND_BOOT_FLAG == device_boot_flag )
        off  = (1ULL << 62) - 1; //verify mode for verify discrete bootloader
#endif//#if defined(CONFIG_AML_MTD)

    size=bootRealSz;
    const char* bootName = "bootloader";
    const int bootCpyNum = store_boot_copy_num(bootName);
    const int bootCpySz  = (int)store_boot_copy_size(bootName);
    DWN_MSG("bootCpyNum %d, bootCpySz 0x%x\n", bootCpyNum, bootCpySz);
    if (size > bootCpySz) {
        DWN_MSG("bootloader img sz 0x%x > bootCpySz 0x%x\n", size, bootCpySz);
        return 0;
    }
#if BOOTLOADER_ALIGN_BITS
    size += (1U<<BOOTLOADER_ALIGN_BITS) -1;
    size >>= BOOTLOADER_ALIGN_BITS;
    size <<= BOOTLOADER_ALIGN_BITS;
#endif// #if BOOTLOADER_ALIGN_BITS
    for (iCopy = 0; iCopy < bootCpyNum; ++iCopy) {
        void* dataBuf = iCopy ? pBuf + size : pBuf;
        ret = store_boot_read(bootName, iCopy, size, dataBuf);
        if (ret) {
            DWN_ERR("Fail to read boot[%s] at copy[%d]\n", bootName, iCopy);
            return __LINE__;
        }
        if (iCopy) {
            if (memcmp(pBuf, dataBuf, bootRealSz)) {
                DWN_ERR("copy[%d] content not the same as copy[0]\n", iCopy);
                return __LINE__;
            }
        }
    }

    sha1_csum(pBuf, bootRealSz, genSum);
    return ret;
}


u32 optimus_cb_simg_write_media(const unsigned destAddrInSec, const unsigned dataSzInBy, const char* data)
{
    int ret = OPT_DOWN_OK;
    const char* partName = OptimusImgBurnInfo.partName;

    if (OPTIMUS_MEDIA_TYPE_STORE < OptimusImgBurnInfo.storageMediaType) {
        DWN_ERR("storage type %d not supported yet!\n", OptimusImgBurnInfo.storageMediaType);
        return OPT_DOWN_FAIL;
    }

    DWN_DBG("1addrOffset=0x%llx, dataSz=0x%x, data = 0x%p\t", (((u64)destAddrInSec)<<9), dataSzInBy, (void*)data);
    ret = store_write(partName, (((u64)destAddrInSec)<<9), dataSzInBy, (void*)data);
    if (ret) {
        DWN_ERR("Fail to write to media, ret = %d\n", ret);
        return 0;
    }
    platform_busy_increase_un_reported_size(dataSzInBy);

    return dataSzInBy;
}

//return value: the data size disposed
static u32 optimus_download_sparse_image(struct ImgBurnInfo* pDownInfo, u32 dataSz, const u8* data)
{
    u32 unParsedDataLen = 0;
    int flashOffset = 0;
    const u64 addrOffset = pDownInfo->nextMediaOffset;

    flashOffset = optimus_simg_to_media((char*)data, dataSz, &unParsedDataLen, ((u32)(addrOffset>>9)));
    if (flashOffset < 0) {
        DWN_ERR("Fail in parse simg. src 0x%p, size 0x%x, unParsedDataLen 0x%x, ret %d\n", data, dataSz, unParsedDataLen, flashOffset);
        return 0;
    }
    pDownInfo->nextMediaOffset += ((u64)flashOffset)<<9;

    return dataSz - unParsedDataLen;
}

//Normal image can write directly to NAND, best aligned to 16K when write
//FIXME: check it aligned to 16K when called
//1, write to media     2 -- save the verify info
static u32 optimus_download_normal_image(struct ImgBurnInfo* pDownInfo, u32 dataSz, const u8* data)
{
    int ret = 0;
    u64 addrOrOffsetInBy = pDownInfo->nextMediaOffset;

    DWN_DBG("addrOffset=0x%llx, dataSz=0x%x, data = 0x%p\n", addrOrOffsetInBy, dataSz, data);

    ret = store_write(pDownInfo->partName, addrOrOffsetInBy, dataSz, (void*)data);
    if (ret) {
        DWN_ERR("Fail to write to media\n");
        return 0;
    }
    platform_busy_increase_un_reported_size(dataSz);

    pDownInfo->nextMediaOffset += dataSz;

    return dataSz;
}

static int optimus_storage_open(struct ImgBurnInfo* pDownInfo, const u8* data, const u32 dataSz)
{
    int ret = OPT_DOWN_OK;
    const char* partName = (const char*)pDownInfo->partName;
    const int imgType = pDownInfo->imgType;
    const int MediaType = pDownInfo->storageMediaType;

    if (!pDownInfo->imgSzDisposed && OPTIMUS_IMG_STA_PRE_BURN == pDownInfo->imgBurnSta)
    {
        DWN_MSG("Burn Start...\n");
        pDownInfo->imgBurnSta = OPTIMUS_IMG_STA_BURN_ING;
#if defined(CONFIG_AML_MTD)
        //Need erasing if 'Have not erasing the WHOLE chip' and 'NOT bootloader'
        if ( (NAND_BOOT_FLAG == device_boot_flag || SPI_NAND_FLAG == device_boot_flag) && MediaType < OPTIMUS_MEDIA_TYPE_MEM )
        #if  defined(CONFIG_DISCRETE_BOOTLOADER)
            if ( strcmp(CONFIG_TPL_PART_NAME, partName) )
        #endif//#if  defined(CONFIG_DISCRETE_BOOTLOADER)
            if (!pDownInfo->isDumpMode && !(is_optimus_storage_inited()>>16) && strcmp("bootloader", partName)) {
                char cmd[96];
                sprintf(cmd, "store erase partition %s", partName);
                DWN_MSG("cmd[%s]\n", cmd);
                run_command(cmd, 0);
            }
    #if defined(OPTIMUS_BURN_TARGET_SUPPORT_UBIFS)
        if (IMG_TYPE_UBIFS == pDownInfo->imgType) //get size if not bootloader
        {
            char cmd[64];
            static int _ubiDeviceIndex = 0;
            sprintf(cmd, "ubi part %s", partName);
            ret = run_command(cmd, 0);
            if (ret) {
                DWN_ERR("Fail in run cmd[%s]\n", cmd); return __LINE__;
            }
            sprintf(cmd, "ubi device %d", _ubiDeviceIndex++);
            ret = run_command(cmd, 0);
            sprintf(cmd, "ubi create %s", partName);
            ret = run_command(cmd, 0);
            if (ret) {
                DWN_ERR("Fail in run cmd[%s]\n", cmd); return __LINE__;
            }
        }
    #endif// #if defined(OPTIMUS_BURN_TARGET_SUPPORT_UBIFS)
#endif//#if defined(CONFIG_AML_MTD)
    }
    else if(pDownInfo->imgSzDisposed == pDownInfo->imgPktSz && OPTIMUS_IMG_STA_BURN_COMPLETE == pDownInfo->imgBurnSta)
    {
        DWN_MSG("Verify Start...\n");
        pDownInfo->imgBurnSta = OPTIMUS_IMG_STA_VERIFY_ING;
    }

    switch (MediaType)
    {
        case OPTIMUS_MEDIA_TYPE_NAND:
        case OPTIMUS_MEDIA_TYPE_SDMMC:
        case OPTIMUS_MEDIA_TYPE_STORE:
            {
                if (IMG_TYPE_BOOTLOADER != pDownInfo->imgType && !pDownInfo->devHdle) //if not bootloader and device not open
                {
                    pDownInfo->devHdle = (void*)1;
                    if (!pDownInfo->devHdle) {
                        DWN_ERR("Fail to open nand part %s\n", partName);
                        return OPT_DOWN_FAIL;
                    }

                    if (IMG_TYPE_SPARSE == imgType)
                    {
                        ret = optimus_simg_probe(data, dataSz);
                        if (!ret) {
                            DWN_ERR("Fail in sparse format probe,ret=%d\n", ret);
                            return OPT_DOWN_FAIL;
                        }
                        return optimus_simg_parser_init(data);
                    }
                }
                else//is bootloader, than do nothing
                {
                    return OPT_DOWN_OK;
                }
            }
            break;

        case OPTIMUS_MEDIA_TYPE_KEY_UNIFY:
            break;

        case OPTIMUS_MEDIA_TYPE_MEM:
            break;

        default:
            DWN_MSG("Error MediaType %d\n", MediaType);
            return OPT_DOWN_FAIL;
    }

    return ret;
}

static int optimus_storage_close(struct ImgBurnInfo* pDownInfo)
{
    if (pDownInfo->imgSzDisposed == pDownInfo->imgPktSz && OPTIMUS_IMG_STA_BURN_ING == pDownInfo->imgBurnSta)
    {
        pDownInfo->imgBurnSta = OPTIMUS_IMG_STA_BURN_COMPLETE;
        DWN_MSG("Burn complete\n");

        return OPT_DOWN_OK;
    }

    if (!pDownInfo->imgSzDisposed && OPTIMUS_IMG_STA_VERIFY_ING == pDownInfo->imgBurnSta)
    {
        pDownInfo->imgBurnSta = OPTIMUS_IMG_STA_VERIFY_END;
        DWN_MSG("Verify End\n");
        return OPT_DOWN_OK;
    }

    return OPT_DOWN_OK;
}


//return value is the data size that actual dealed
static u32 optimus_storage_write(struct ImgBurnInfo* pDownInfo, u64 addrOrOffsetInBy, unsigned dataSz, const u8* data, char* errInfo)
{
    u32 burnSz = 0;
    const u32 imgType = pDownInfo->imgType;
    const int MediaType = pDownInfo->storageMediaType;

    addrOrOffsetInBy += pDownInfo->partBaseOffset;
    DWN_DBG("[0x]Data %p, addrOrOffsetInBy %llx, dataSzInBy %x\n", data, addrOrOffsetInBy, dataSz);

    if (OPTIMUS_IMG_STA_BURN_ING != pDownInfo->imgBurnSta) {
        sprintf(errInfo, "Error burn sta %d\n", pDownInfo->imgBurnSta);
        DWN_ERR(errInfo);
        return 0;
    }

    switch (MediaType)
    {
        case OPTIMUS_MEDIA_TYPE_NAND:
        case OPTIMUS_MEDIA_TYPE_SDMMC:
        case OPTIMUS_MEDIA_TYPE_STORE:
            {
                switch (imgType)
                {
                    case IMG_TYPE_NORMAL:
#if defined(UBIFS_IMG) || defined(CONFIG_CMD_UBIFS)
                    case IMG_TYPE_UBIFS:
#endif// #if defined(UBIFS_IMG) || defined(CONFIG_CMD_UBIFS)
                        burnSz = optimus_download_normal_image(pDownInfo, dataSz, data);
                        break;

                    case IMG_TYPE_BOOTLOADER:
                        burnSz = optimus_download_bootloader_image(pDownInfo, dataSz, data);
                        break;

                    case IMG_TYPE_SPARSE:
                        burnSz = optimus_download_sparse_image(pDownInfo, dataSz, data);
                        break;

                    case IMG_TYPE_DTB:
                        burnSz = optimus_download_dtb_image(pDownInfo, dataSz, data);
                        break;

                    default:
                        DWN_ERR("error image type %d\n", imgType);
                }
            }
            break;

        case OPTIMUS_MEDIA_TYPE_KEY_UNIFY:
            {
                burnSz = v2_key_burn(pDownInfo->partName, data, dataSz, errInfo);
                if (burnSz != dataSz) {//return value is write size
                    DWN_ERR("burn key failed\n");
                    return 0;
                }
            }
            break;

        case OPTIMUS_MEDIA_TYPE_MEM:
        {
            u8* buf = (u8*)addrOrOffsetInBy;
            if (buf != data) {
                DWN_ERR("buf(%llx) != data(%p)\n", addrOrOffsetInBy, data);
                return 0;
            }
            if (!strcmp("dtb", pDownInfo->partName)) //as memory write back size = min[fileSz, 2G], so reach here if downloaded ok!
            {
                unsigned char* dtbLoadAddr = (unsigned char*)OPTIMUS_DTB_LOAD_ADDR;
                unsigned char* srcDownDtb = (unsigned char*)data;

                memcpy(dtbLoadAddr, srcDownDtb, dataSz);
                DWN_MSG("load dt.img to 0x%p, sz=0x%x\n", dtbLoadAddr, dataSz);
                _dtb_is_loaded = dataSz;
            }

            burnSz = dataSz;
        }
        break;

        default:
            sprintf(errInfo, "Error MediaType %d\n", MediaType);
            DWN_ERR(errInfo);
    }

    return burnSz;
}

//TODO: to consist with optimus_storage_write, return value should be readSzInBy
static int optimus_storage_read(struct ImgBurnInfo* pDownInfo, u64 addrOrOffsetInBy,
                            unsigned readSzInBy, unsigned char* buff, char* errInfo)
{
    int ret = 0;
    const int MediaType = pDownInfo->storageMediaType;
    const char* partName = pDownInfo->partName;

    addrOrOffsetInBy += pDownInfo->partBaseOffset;

    switch (MediaType)
    {
        case OPTIMUS_MEDIA_TYPE_NAND:
        case OPTIMUS_MEDIA_TYPE_SDMMC:
        case OPTIMUS_MEDIA_TYPE_STORE:
            {
                if (IMG_TYPE_BOOTLOADER == pDownInfo->imgType)
                {
                    ret = store_boot_read("bootloader", 0, readSzInBy, (char*)buff);
                }
                else if (IMG_TYPE_DTB == pDownInfo->imgType) {
                    ret = store_rsv_read("dtb", readSzInBy, buff);
                }
                else
                {
                    ret = store_read(partName, addrOrOffsetInBy, readSzInBy, buff);
                    platform_busy_increase_un_reported_size(readSzInBy);
                }
                if (ret) {
                    if (errInfo) sprintf(errInfo, "Read failed\n") ;
                    DWN_ERR("Read failed\n");
                    return OPT_DOWN_FAIL;
                }

            }
            break;

        case OPTIMUS_MEDIA_TYPE_KEY_UNIFY:
            {
                unsigned fmtLen = 0;
                if (addrOrOffsetInBy) {
                    DWN_ERR("OH NO, IS key len > 64K!!? addrOrOffsetInBy is 0x%llx not 0\n", addrOrOffsetInBy);
                    return OPT_DOWN_FAIL;
                }
                ret = v2_key_read(pDownInfo->partName, buff, readSzInBy, errInfo, &fmtLen);
            }
            break;

        case OPTIMUS_MEDIA_TYPE_MEM:
        {
            u8* buf = (u8*)addrOrOffsetInBy;
            if (addrOrOffsetInBy >> 32) {
                DWN_ERR("mem addr 0x%llx too large\n", addrOrOffsetInBy);
            }
            if (buf != buff) {
                DWN_ERR("buf(%llx) != buff(%p)\n", addrOrOffsetInBy, buff);
            }
        }
        break;

        default:
            DWN_MSG("Error MediaType %d\n", MediaType);
            return OPT_DOWN_FAIL;
    }

    return ret;
}

//return value is the size actual write to media
//Paras: const char* partName, const char* imgType, const char* verifyAlgorithm
static u32 optimus_func_download_image(struct ImgBurnInfo* pDownInfo, u32 dataSz, const u8* data, char* errInfo)
{
    int burnSz = 0;
    int ret = 0;
    u64 nextMediaOffset = pDownInfo->nextMediaOffset;

    DWN_DBG("data=0x%p, sz=0x%x, offset=%llx\n", data, dataSz, nextMediaOffset);

    ret = optimus_storage_open(pDownInfo, data, dataSz);
    if (OPT_DOWN_OK != ret) {
        sprintf(errInfo, "Fail to open stoarge\n");
        DWN_ERR(errInfo);
        return 0;
    }

    burnSz = optimus_storage_write(pDownInfo, nextMediaOffset, dataSz, data, errInfo);
    if (!burnSz) {
        DWN_ERR("Fail in optimus_storage_write, data 0x%p, wantSz 0x%x\n", data, dataSz);
        goto _err;
    }
    pDownInfo->imgSzDisposed += burnSz;

    ret = optimus_storage_close(pDownInfo);
    if (ret) {
        DWN_ERR("Fail to close media\n");
        return 0;
    }

    return burnSz;

_err:
    optimus_storage_close(pDownInfo);
    pDownInfo->imgBurnSta = OPTIMUS_IMG_STA_BURN_FAILED;////
    return 0;
}

//TODO: add _errInfo as argument to pass more info
static int _parse_img_download_info(struct ImgBurnInfo* pDownInfo, const char* partName,
                                     const u64 imgSz, const char* imgType, const char* mediaType, const u64 partBaseOffset)
{
    int ret = 0;

    memset(pDownInfo, 0, sizeof(struct ImgBurnInfo));//clear burnning info

    //TODO: check format is normal/bootloader if upload!!

    _usbDownPartImgType = "";

    if (!strcmp("sparse", imgType))
    {
        pDownInfo->imgType = IMG_TYPE_SPARSE;
    }
    else if(!strcmp("bootloader", partName))
    {
        pDownInfo->imgType = (u8)IMG_TYPE_BOOTLOADER;
    }
    else if ( !strcmp("_aml_dtb", partName) ) {
        pDownInfo->imgType = (u8)IMG_TYPE_DTB;
    }
    else if(!strcmp("normal", imgType))
    {
        pDownInfo->imgType = (u8)IMG_TYPE_NORMAL;
    }
    else if(!strcmp("ubifs", imgType))
    {
        pDownInfo->imgType = IMG_TYPE_UBIFS;
        _usbDownPartImgType = "ubifs";
    }
    else{
        DWN_ERR("err image type %s\n", imgType);
        return __LINE__;
    }

    if (!strcmp("store", mediaType))
    {
        pDownInfo->storageMediaType = OPTIMUS_MEDIA_TYPE_STORE;
    }
    else if(!strcmp("nand", mediaType))
    {
        pDownInfo->storageMediaType = OPTIMUS_MEDIA_TYPE_NAND;
    }
    else if(!strcmp("sdmmc", mediaType))
    {
        pDownInfo->storageMediaType = OPTIMUS_MEDIA_TYPE_SDMMC;
    }
    else if(!strcmp("spiflash", mediaType))
    {
        pDownInfo->storageMediaType = OPTIMUS_MEDIA_TYPE_SPIFLASH;
    }
    else if(!strcmp("key", mediaType))
    {
        pDownInfo->storageMediaType = OPTIMUS_MEDIA_TYPE_KEY_UNIFY;

        if (OPTIMUS_DOWNLOAD_SLOT_SZ <= imgSz) {
            DWN_ERR("size (0x%llx) for key %s invalid!!\n", imgSz, partName);
            return __LINE__;
        }
    }
    else if(!strcmp("mem", mediaType))
    {
        pDownInfo->storageMediaType = OPTIMUS_MEDIA_TYPE_MEM;
    }
    else{
        DWN_ERR("error mediaType %s\n", mediaType);
        return __LINE__;
    }

    pDownInfo->partBaseOffset   = partBaseOffset;
    memcpy(pDownInfo->partName, partName, strlen(partName));

    if (OPTIMUS_MEDIA_TYPE_MEM > pDownInfo->storageMediaType) //if command for burning partition
    {
        if (strcmp("bootloader", partName) && strcmp("_aml_dtb", partName)) //get size if not bootloader
        {
            u64 partCap = store_part_size(partName);
            if (!partCap) {
                DWN_ERR("Fail to get size for part %s\n", partName);
                return __LINE__;
            }
            DWN_MSG("flash LOGIC partCap 0x%llxB\n", partCap);
            if (imgSz > partCap) {
                DWN_ERR("imgSz 0x%llx out of cap 0x%llx\n", imgSz, partCap);
                return __LINE__;
            }
            ret = _assert_logic_partition_cap(partName, partCap);
            if (ret) {
                    DWN_ERR("Fail in _assert_logic_partition_cap\n");
                    return __LINE__;
            }
        }
    }

    pDownInfo->nextMediaOffset  = pDownInfo->imgSzDisposed = 0;
    pDownInfo->imgPktSz         = imgSz;
    pDownInfo->imgBurnSta       = OPTIMUS_IMG_STA_PRE_BURN;

    DWN_MSG("Down(%s) part(%s) sz(0x%llx) fmt(%s)\n", mediaType, partName, pDownInfo->imgPktSz, imgType);

    return 0;
}

int optimus_download_init(void)
{
    memset(&OptimusImgBurnInfo, 0, sizeof(struct ImgBurnInfo));
    return 0;
}

int optimus_download_exit(void)
{
    return 0;
}

int optimus_parse_img_download_info(const char* partName, const u64 imgSz, const char* imgType, const char* mediaType, const u64 partBaseOffset)
{
    return _parse_img_download_info(&OptimusImgBurnInfo, partName, imgSz, imgType, mediaType, partBaseOffset);
}

static int _disk_intialed_ok = 0;

int is_optimus_storage_inited(void)
{
    return _disk_intialed_ok;
}

int optimus_save_loaded_dtb_to_flash(void)
{
    unsigned char* dtbLoadedAddr = (unsigned char*)OPTIMUS_DTB_LOAD_ADDR;

    if (!_dtb_is_loaded) return 0;

    //dtb erasing before write, or some NAND chip maybe cannot write real
    store_rsv_erase("dtb");
    return store_rsv_write("dtb", _dtb_is_loaded, dtbLoadedAddr);
}

int optimus_storage_init(int toErase)
{
    int ret = 0;
    char* cmd = NULL;
    unsigned char* dtbLoadedAddr = (unsigned char*)OPTIMUS_DTB_LOAD_ADDR;

    if (_disk_intialed_ok) {//To assert only actual disk intialed once
        DWN_MSG("Disk inited but init again!!!\n");
        /*return 0;*/
    }

    if (OPTIMUS_WORK_MODE_USB_PRODUCE != optimus_work_mode_get()) //Already inited in other work mode
    {
        /*DWN_MSG("Exit before re-init\n");*/
        /*store_exit1();*/
    }

    if (!_dtb_is_loaded) {
        DWN_WRN("dtb is not loaded yet\n");
    }
    else{
#ifdef CONFIG_AML_MTD
        if ( NAND_BOOT_FLAG == device_boot_flag ) {
            extern int check_valid_dts(unsigned char *buffer);
            ret =  check_valid_dts(dtbLoadedAddr);
        } else
#endif // #ifdef CONFIG_AML_MTD
        ret = get_partition_from_dts(dtbLoadedAddr);

        if (ret) {
            DWN_ERR("Failed at check dts\n");
            return __LINE__;
        }
    }

    switch (toErase)
    {
        case 0://NO erase
            ret = store_init(1);
            break;

        case 3://erase all(with key)
            {
                cmd = "store disprotect key";
                DWN_MSG("run cmd [%s]\n", cmd);
                ret = run_command(cmd, 0);
                if (ret) {
                    DWN_ERR("Fail when run cmd[%s], ret %d\n", cmd, ret);
                    break;
                }
            }
        case 1://normal erase, store init 3
            ret = store_init(3);
            break;

        case 4://force erase all
            {
                cmd = "store disprotect key; store disprotect hynix";
                DWN_MSG("run cmd [%s]\n", cmd);
                ret = run_command(cmd, 0);
                if (ret) {
                    DWN_ERR("Fail when run cmd[%s], ret %d\n", cmd, ret);
                    break;
                }
            }
        case 2:
            ret = store_init(4);
            break;

        default:
            DWN_ERR("Unsupported erase flag %d\n", toErase); ret = -__LINE__;
            break;
    }

    if (!ret)
    {
        _disk_intialed_ok  = 1;
        _disk_intialed_ok += toErase <<16;

#if 0
        ret = optimus_save_loaded_dtb_to_flash();
        if (ret) {
                DWN_ERR("FAiled in dtb wr\n");
                return __LINE__;
        }
#endif

        if (OPTIMUS_WORK_MODE_USB_PRODUCE == optimus_work_mode_get()) //env not relocated in this case
        {
            DWN_MSG("usb producing env_relocate\n");
            env_relocate();
        }

        if (_dtb_is_loaded)//for key init, or fail when get /unifykey
        {
                unsigned long fdtAddr = (unsigned long)dtbLoadedAddr;
#ifdef CONFIG_MULTI_DTB
                fdtAddr = get_multi_dt_entry(fdtAddr);
#endif// #ifdef CONFIG_MULTI_DTB
                ret = fdt_check_header((char*)fdtAddr);
                unsigned fdtsz    = fdt_totalsize((char*)fdtAddr);
                if (ret || !fdtsz ) {
                        DWN_ERR("Fail in fdt check header\n");
                        return __LINE__;
                }
               // if (fdtsz < _dtb_is_loaded)
                        memmove((char*)dtbLoadedAddr, (char*)fdtAddr, fdtsz);
        }
    }

    return ret;
}

int is_optimus_on_burn(void)//is now transfering image
{
    return (OPTIMUS_IMG_STA_BURN_ING == OptimusImgBurnInfo.imgBurnSta);
}

int is_optimus_pre_burn(void)    //is now has get "download command"
{
    return (OPTIMUS_IMG_STA_PRE_BURN == OptimusImgBurnInfo.imgBurnSta);
}

int is_optimus_to_burn_ready(void)
{
    return (OPTIMUS_IMG_STA_PRE_BURN == OptimusImgBurnInfo.imgBurnSta);
}

int is_optimus_burn_complete(void)
{
    int is_burn_completed = 0;

    is_burn_completed = (OPTIMUS_IMG_STA_BURN_COMPLETE == OptimusImgBurnInfo.imgBurnSta);
    if (!is_burn_completed) {
        DWN_MSG("imgSzDisposed 0x%llx != imgPktSz 0x%llx\n", OptimusImgBurnInfo.imgSzDisposed, OptimusImgBurnInfo.imgPktSz);
    }

    return is_burn_completed;
}

u32 optimus_download_img_data(const u8* data, const u32 size, char* errInfo)
{
    return optimus_func_download_image(&OptimusImgBurnInfo, size, data, errInfo);
}

static int optimus_sha1sum_verify_partition(const char* partName, const u64 verifyLen, const u8 imgType, u8* genSum)
{
    int ret = 0;
    u8* buff = (u8*) OPTIMUS_SHA1SUM_BUFFER_ADDR;
    const u32 buffSz = OPTIMUS_SHA1SUM_BUFFER_LEN;
    sha1_context ctx;
    u64 leftLen = verifyLen;

    if (strcmp(partName, OptimusImgBurnInfo.partName)) {
        DWN_ERR("partName %s err, must %s\n", partName, OptimusImgBurnInfo.partName);
        return OPT_DOWN_FAIL;
    }

    if (!is_optimus_burn_complete()) {
        return OPT_DOWN_FAIL;
    }

    memset(buff, 0xde, 1024);//clear 1kb data before verfiy, in case read buffer not overlapped
    if (IMG_TYPE_BOOTLOADER == imgType)
    {
        return optimus_verify_bootloader(&OptimusImgBurnInfo, genSum);
    }
    else if (IMG_TYPE_DTB == imgType) {
        return optimus_verify_dtb(&OptimusImgBurnInfo, genSum);
    }
    else if(IMG_TYPE_SPARSE == imgType)//sparse image
    {
        ret = optimus_sparse_back_info_probe();
        if (OPT_DOWN_TRUE != ret) {
            DWN_ERR("Fail to probe back sparse info\n");
            return OPT_DOWN_FAIL;
        }
    }

    ret = optimus_storage_open(&OptimusImgBurnInfo, NULL, 0);
    if (ret) {
        DWN_ERR("Fail to open storage for read\n");
        return OPT_DOWN_FAIL;
    }

    sha1_starts(&ctx);

    DWN_MSG("To verify part %s in fmt %s\n", partName, (IMG_TYPE_SPARSE == imgType) ? "sparse": "normal");
    if (IMG_TYPE_SPARSE == imgType) //sparse image
    {
        for (; leftLen;)
        {
            u32 spHeadSz   = 0;
            u32 chunkDataLen    = 0;
            u64 chunkDataOffset = 0;
            u8* head = NULL;

            ret = optimus_sparse_get_chunk_data(&head, &spHeadSz, &chunkDataLen, &chunkDataOffset);
            if (ret) {
                DWN_ERR("Fail to get chunk data\n");
                goto _finish;
            }

            sha1_update(&ctx, head, spHeadSz);

            leftLen -= spHeadSz + chunkDataLen;//update image read info

            for (;chunkDataLen;)
            {
                const int thisReadLen = (chunkDataLen > buffSz) ? buffSz : chunkDataLen;

                ret = optimus_storage_read(&OptimusImgBurnInfo, chunkDataOffset, thisReadLen, buff, NULL);
                if (ret) {
                    DWN_ERR("Fail to read at offset 0x[%x, %8x], len=0x%8x\n", ((u32)(chunkDataOffset>>32)), (u32)chunkDataOffset, thisReadLen);
                    goto _finish;
                }

                sha1_update(&ctx, buff, thisReadLen);

                chunkDataLen    -= thisReadLen;
                chunkDataOffset += thisReadLen;
            }

            if (leftLen && !spHeadSz) {
                DWN_ERR("Fail to read when pkt len left 0x%x\n", (u32)leftLen);
                break;
            }
        }
    }
    else//normal image
    {
        for (; leftLen;)
        {
            int thisReadLen = 0;
#if defined(UBIFS_IMG) || defined(CONFIG_CMD_UBIFS)
            if (!strcmp(_usbDownPartImgType, "ubifs")) {
                thisReadLen = leftLen;
            } else
#endif// #if defined(UBIFS_IMG) || defined(CONFIG_CMD_UBIFS)
            thisReadLen = (leftLen > buffSz) ? buffSz : ((u32)leftLen);

            u64 addrOffset = verifyLen - leftLen;

            ret = optimus_storage_read(&OptimusImgBurnInfo, addrOffset, thisReadLen, buff, NULL);
            if (ret) {
                DWN_ERR("Fail to read at offset 0x[%x, %8x], len=0x%8x\n", ((u32)(addrOffset>>32)), (u32)addrOffset, thisReadLen);
                goto _finish;
            }

            sha1_update(&ctx, buff, thisReadLen);

            leftLen -= thisReadLen;
        }

    }

_finish:
    OptimusImgBurnInfo.imgSzDisposed = leftLen;
    sha1_finish(&ctx, genSum);
    optimus_storage_close(&OptimusImgBurnInfo);

    return ret;
}

//usage: verify sha1sum nand srcSum part_name size imgType
int optimus_media_download_verify(const int argc, char * const argv[], char *info)
{
    const char* verifyType      = argv[1];
    const char* srcSum          = argv[2];
    static u8  verifyResult[20];
    static char sha1Result[42];
    const u8 srcImgType = OptimusImgBurnInfo.imgType;
    const char* partName = OptimusImgBurnInfo.partName;
    u64 verifyLen = OptimusImgBurnInfo.imgPktSz;
    int ret = 0;

    if (argc != 3) {
        strcpy(info, "failed:need 3 args\n");
        printf(info);
        return -1;
    }

    if (strcmp(verifyType, "sha1sum")) {
        ret = __LINE__;
        sprintf(info, "verifyType [%s] err, ret %d!\n", verifyType, ret);
        DWN_ERR(info);
        return ret;
    }

    ret = optimus_sha1sum_verify_partition(partName, verifyLen, srcImgType, verifyResult);
    if (ret) {
        DWN_ERR("Fail to gen check sum\n");
        return __LINE__;
    }

    ret = optimus_hex_data_2_ascii_str(verifyResult, 20, sha1Result, 42);
    if (ret) {
        DWN_ERR("Failed when format sha1 to string\n");
        return __LINE__;
    }

    /*DWN_MSG("%s %s\n", verifyType, sha1Result);*/
    ret = strcmp(sha1Result, srcSum);
    if (ret) {
        sprintf(info, "failed:Verify Failed with %s, origin sum \"%s\" != gen sum \"%s\"\n", verifyType, srcSum, sha1Result);
        DWN_ERR(info);
        return __LINE__;
    }

    DWN_MSG("VERIFY OK \n");
    return ret;
}

int optimus_key_burn_init(const char* keyType)
{
    int ret = 0;

    if (!strcmp("efuse", keyType))
    {
        return ret;
    }

    if (!strcmp("secure", keyType))
    {
        return ret;
    }

    DWN_ERR("unsported key type %s\n", keyType);
    return OPT_DOWN_FAIL;
}

//update tplcmd dev0 "download nand part_name imageType imgSz"
//update tplcmd dev0 "download get_status"
int optimus_parse_download_cmd(int argc, char* argv[])
{
    const int isUpload = !strcmp("upload", argv[0]);
    const char* mediaType   = argv[1];
    const char* part_name   = argv[2];
    const char* imgType     = argv[3];
    const char* imgSzStr    = argv[4];
    u64   imgSzInBy   = 0;
    u64   partBaseOffset = 0;
    int ret = 0;

    if (!strcmp("get_status", mediaType))
    {
        return !is_optimus_burn_complete();
    }

    if (!strcmp("is_ready", mediaType))
    {
        return !is_optimus_to_burn_ready();
    }

    if (5 > argc) {
        printf("argc[%d] too few, use \"download nand part_name imageType imgSz\"\n", argc);
        return  __LINE__;
    }

    imgSzInBy = simple_strtoull(imgSzStr, NULL, 0);

    if (!strcmp("mem", mediaType))
    {
        char* endp = NULL;
        partBaseOffset = simple_strtoull(part_name, &endp, 0);
        if (0 != *endp) //not a valid 0-terminated c string
        {
            if (!strcmp("dtb", part_name))
            {
                partBaseOffset = OPTIMUS_DOWNLOAD_TRANSFER_BUF_ADDR;
                DWN_DBG("dtb down to %llx\n", partBaseOffset);
            }
        }
    }

    ret = optimus_parse_img_download_info(part_name, imgSzInBy, imgType, mediaType, partBaseOffset);
    if (ret) {
        DWN_ERR("Fail in init download info\n");
        return __LINE__;
    }

    ret = optimus_buf_manager_tplcmd_init(mediaType, part_name, partBaseOffset, imgType, imgSzInBy, isUpload, 0);
    if (ret) {
        DWN_ERR("Fail in init download info\n");
        return __LINE__;
    }

    return OPT_DOWN_OK;
}

u32 optimus_dump_storage_data(u8* pBuf, const u32 wantSz, char* errInfo)
{
    struct ImgBurnInfo* pDownInfo = &OptimusImgBurnInfo;
    u64 nextMediaOffset = pDownInfo->nextMediaOffset;
    int ret = 0;

    DWN_DBG("pBuf=0x%p, wantSz=0x%x, nextMediaOffset=%x\n", pBuf, wantSz, (u32)nextMediaOffset);

    pDownInfo->isDumpMode = 1; //do not do any erase in dump mode
    ret = optimus_storage_open(pDownInfo, pBuf, wantSz);
    if (OPT_DOWN_OK != ret) {
        sprintf(errInfo, "Fail to open stoarge\n");
        DWN_ERR(errInfo);
        return 0;
    }

    ret = optimus_storage_read(pDownInfo, nextMediaOffset, wantSz, pBuf, errInfo);
    if (ret) {
        DWN_ERR("Failed \n");
        goto _err;
    }
    pDownInfo->imgSzDisposed    += wantSz;
    pDownInfo->nextMediaOffset  += wantSz;

    ret = optimus_storage_close(pDownInfo);
    if (ret) {
        DWN_ERR("Fail to close media\n");
        return 0;
    }

    return wantSz;

_err:
    optimus_storage_close(pDownInfo);
    pDownInfo->imgBurnSta = OPTIMUS_IMG_STA_BURN_FAILED;////
    return 0;
}

static int _optimusWorkMode = OPTIMUS_WORK_MODE_NONE;

int optimus_work_mode_get(void)
{
    return _optimusWorkMode;
}

int optimus_work_mode_set(int workmode)
{
    _optimusWorkMode = workmode;
    return 0;
}

int is_the_flash_first_burned(void)
{
    const char* s = getenv("upgrade_step");

    DWN_MSG("====>upgrade_step=%s<=====\n", s ? s : "<UNDEFINED>");

    return !strcmp(s, "0");//"0" indicate first boot
}

//FIXME: check whether 'saveenv' failed and exception when usb prodcing mode from code boot mode if without env_relocate
int optimus_set_burn_complete_flag(void)
{
    int rc = 0;
#if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE)
    const int IsTplLoadedFromBurningPackage = aml_burn_check_uboot_loaded_for_burn(0);
    char upgrade_step[8];

    if (IsTplLoadedFromBurningPackage)
    {
        /*rc = run_command("defenv", 0);//use new env directly if uboot is new !!!*/
        set_default_env("## save_setting ##\n");//use new env directly if uboot is new !!!
#if 0
        const char* def_env_initargs = getenv("initargs");
        const char* def_env_bootargs = getenv("bootargs");
        if (!strstr(getenv("initargs"), "storage") && getenv("initargs") && 0) {
                rc = run_command("setenv initargs ${initargs} storage=${store}", 0);
                DWN_MSG("[initargs=%s]\n", getenv("initargs"));
        }
        else if(!strstr(getenv("bootargs"), "storage") && getenv("bootargs") && 0){//user not configure storage in 'bootargs' of default env
                rc = run_command("setenv bootargs ${bootargs} storage=${store}", 0);
                DWN_MSG("[bootargs=%s]\n", getenv("bootargs"));
        }
#endif
    }

    //Enable firstboot when flash empty to wipe_data/wipe_cache
    setenv("firstboot", "1");
    upgrade_step[0] = '1' + IsTplLoadedFromBurningPackage;
    upgrade_step[1] = '\0';
    DWN_MSG("Set upgrade_step to %s\n", upgrade_step);
    rc = setenv("upgrade_step", upgrade_step);
    if (rc) {
        DWN_ERR("Fail to set upgraded_step to 1\n");
    }
    rc = run_command("saveenv", 0);
    if (rc) {
        DWN_ERR("Fail to saveenv to flash\n");
    }
    udelay(200);
#endif//#if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE)

    return rc;
}

static int _optimus_set_reboot_mode(const int cfgFlag)
{
    char cmdbuf[96];
    const char* reboot_mode = NULL;
    switch (cfgFlag)
    {
        case OPTIMUS_BURN_COMPLETE__REBOOT_UPDATE:
            reboot_mode = "update";
            break;

        case OPTIMUS_BURN_COMPLETE__REBOOT_SDC_BURN:
            /*reboot_mode = MESON_SDC_BURNER_REBOOT;  */
            break;

        case OPTIMUS_BURN_COMPLETE__REBOOT_NORMAL:
        default:
            reboot_mode = "normal";
            break;
    }

    sprintf(cmdbuf, "reboot %s", reboot_mode);

    return run_command(cmdbuf, 0);
}

void optimus_reset(const int cfgFlag)
{
    unsigned i = 0x100;

    //set reboot mode
    _optimus_set_reboot_mode(cfgFlag);
    printf("Burn Reboot...\n");//Add printf to delay to save env
    while (--i > 0) {;}

    /*disable_interrupts();*/
	reset_cpu(0);

    while (i++)
    {
        unsigned ret = i;
        unsigned mask = 1U<<20;

        mask -= 1;
        ret &= mask;
        if (!ret) {
            printf("To reseting...\n");
        }
    }
}

void optimus_poweroff(void)
{
#ifndef CONFIG_POWER_KEY_SUPPORTED_FOR_BURN //default not support power key
    DWN_MSG("stop here as poweroff and powerkey not supported in platform!\n");
    DWN_MSG("You can <Ctrl-c> to reboot\n");
    while (!ctrlc()) continue;
    optimus_reset(OPTIMUS_BURN_COMPLETE__REBOOT_NORMAL);
#else
    printf("To poweroff\n");
    run_command("poweroff", 0);
    printf("!!!After run command poweroff!!\n");
#endif// #if CONFIG_POWER_KEY_SUPPORTED_FOR_BURN

    return;
}

//use choice = 0xfu to query is_burn_completed
int optimus_burn_complete(const int choice)
{
    static unsigned _isBurnComplete = 0;
    int rc = 0;

    switch (choice)
    {
        case OPTIMUS_BURN_COMPLETE__POWEROFF_AFTER_POWERKEY://wait power key to power off, for sdc_burn
            {
#ifndef CONFIG_POWER_KEY_SUPPORTED_FOR_BURN
                    optimus_poweroff();
#endif// #if CONFIG_POWER_KEY_SUPPORTED_FOR_BURN
                    DWN_MSG("PLS short-press power key to shut down\n");
                    do
                    {
                            rc = run_command("getkey", 0);
                    }while(rc);
            }
        case OPTIMUS_BURN_COMPLETE__POWEROFF_DIRECT:
            optimus_poweroff();
            break;

        case OPTIMUS_BURN_COMPLETE__POWEROFF_AFTER_DISCONNECT:
            DWN_MSG("Pls un-plug USB line to poweroff\n");
            _isBurnComplete = 0xefe;
            break;
        case OPTIMUS_BURN_COMPLETE__QUERY:
            return (0xefe == _isBurnComplete);

        case OPTIMUS_BURN_COMPLETE__REBOOT_UPDATE:
        case OPTIMUS_BURN_COMPLETE__REBOOT_NORMAL:
            {
                optimus_reset(choice);
            }
            break;


        default:
            rc = 1;
            DWN_ERR("Error burn_complete flag %d\n", choice);
    }

    return rc;
}

static int optimus_enable_romboot_skip_boot(const char* extBootDev)
{
    if (!strcmp("usb", extBootDev))
    {
#if ROM_BOOT_SKIP_BOOT_ENABLED_4_USB
#if SCPI_CMD_USB_UNBOOT
        set_boot_first_timeout(SCPI_CMD_USB_UNBOOT);
#else
        set_usb_boot_function(FORCE_USB_BOOT);
#endif// #if SCPI_CMD_USB_UNBOOT
#endif// #if ROM_BOOT_SKIP_BOOT_ENABLED_4_USB
    }

    if (!strcmp("sdc", extBootDev))
    {
#if ROM_BOOT_SKIP_BOOT_ENABLED_4_SDC
        set_boot_first_timeout(SCPI_CMD_SDCARD_BOOT);
#endif// #if ROM_BOOT_SKIP_BOOT_ENABLED_4_SDC
    }

    return 0;
}

//I assume that store_inited yet when "bootloader_is_old"!!!!
int optimus_erase_bootloader(const char* extBootDev)
{
    if (!strcmp("usb", extBootDev))
    {
#if ROM_BOOT_SKIP_BOOT_ENABLED_4_USB
    return optimus_enable_romboot_skip_boot("usb");
#endif// #if ROM_BOOT_SKIP_BOOT_ENABLED_4_USB
    }

    if (!strcmp("sdc", extBootDev))
    {
#if ROM_BOOT_SKIP_BOOT_ENABLED_4_SDC
    return optimus_enable_romboot_skip_boot("sdc");
#endif// #if ROM_BOOT_SKIP_BOOT_ENABLED_4_SDC
    }

    const char* bootName = "bootloader";
    const int bootCpyNum = store_boot_copy_num(bootName);
    int iCopy = 0;
    for (; iCopy < bootCpyNum; ++iCopy) {
        store_boot_erase(bootName, iCopy);
    }
    return 0;
}

