//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;
}
Exemple #2
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 (_check_if_secureboot_enabled()) {
        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;
}
Exemple #3
0
int optimus_keysburn_onekey(const char* keyName, u8* keyVal, unsigned keyValLen)
{
        int rc = 0;
        unsigned wrLen = 0;

        DWN_MSG("keyName[%s], keyValAddr=%p,len=%d\n", keyName, keyVal, keyValLen);
        wrLen = v2_key_burn(keyName, keyVal, keyValLen, _errInfo);
        DWN_MSG("writeLen=====%d\n", wrLen);
        rc = wrLen != keyValLen;
        _AML_KEY_ERR("%s in burn key[%s]\n", rc ? "failed" : "success", keyName);

        return rc;
}
Exemple #4
0
int optimus_burn_package_in_sdmmc(const char* sdc_cfg_file)
{
    int rcode = 0;

#if defined(CONFIG_AML_MESON_8)
        AML_WATCH_DOG_DISABLE(); //disable watchdog
#endif//#ifdef CONFIG_AML_MESON_8

    DWN_MSG("mmcinfo\n");
    rcode = run_command("mmcinfo", 0);
    if(rcode){
        DWN_ERR("Fail in init mmc, Does sdcard not plugged in?\n");
        return __LINE__;
    }

#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_burn_with_cfg_file(sdc_cfg_file);

    return rcode;
}
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;
}
//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 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;
}
//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;
}
Exemple #9
0
static int do_aml_key_burn(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
        int rc = 0;
	cmd_tbl_t *c;

        sprintf(_errInfo, "success");
	c = find_cmd_tbl(argv[1], cmd_opt_key_burn, ARRAY_SIZE(cmd_opt_key_burn));

        if(!c){
                DWN_ERR("Can't find subcmd[%s]\n", argv[1]);
		return 1;
        }

        rc = c->cmd(cmdtp, flag, argc, argv);
        DWN_MSG("[key]%s\n", _errInfo);
        if(rc < 0){
                DWN_ERR("Fail in cmd[%s %s].ret=%d\n", argv[1], argv[2], rc);
                return -__LINE__;
        }
        rc = strncmp("success", _errInfo, 7);

        return rc;
}
Exemple #10
0
int dwc_pcd_irq(void)
{
	gintsts_data_t  gintr_status;
	gintsts_data_t  gintr_msk;

	gintr_msk.d32 = dwc_read_reg32(DWC_REG_GINTMSK);
	gintr_status.d32 = dwc_read_reg32(DWC_REG_GINTSTS);

	if ((gintr_status.d32 & gintr_msk.d32)== 0)
		return 0;

	DBG("irq gintmsk:  0x%08x\n",gintr_msk.d32);
	DBG("irq gintrsts: 0x%08x\n",gintr_status.d32);

	gintr_status.d32 = gintr_status.d32 & gintr_msk.d32;
	DBG("irq gintmsk & gintrsts = 0x%08x\n",gintr_status.d32);

    if (gintr_status.b.sofintr)
	{
        if (_sofintr_not_occur) {
			DWN_MSG("sof\n");
			_sofintr_not_occur = 0;
		}
	}

	if (gintr_status.b.rxstsqlvl) {
		dwc_otg_pcd_handle_rx_status_q_level_intr();
		pcd_out_completed(&this_pcd[0]);
	}
	if (gintr_status.b.nptxfempty) {
		dwc_otg_pcd_handle_np_tx_fifo_empty_intr( );
	}

	if (gintr_status.b.usbreset) {
	   dwc_otg_pcd_handle_usb_reset_intr( );
	}
	if (gintr_status.b.enumdone) {
	    dwc_otg_pcd_handle_enum_done_intr();
	}
	if (gintr_status.b.epmismatch) {
	    //dwc_otg_pcd_handle_ep_mismatch_intr( core_if );
	}
	if (gintr_status.b.inepint) {
	    dwc_otg_pcd_handle_in_ep_intr();
	}
	if (gintr_status.b.outepintr) {
	    dwc_otg_pcd_handle_out_ep_intr( );
	}

#if 0
    if (gintr_status.b.otgintr)
    {
        gotgint_data_t gotgint;

        gotgint.d32 = dwc_read_reg32(DWC_REG_GOTGINT);
        if (gotgint.b.sesenddet)
        {
            printf("dis-connect-intr\n");
            cb_4_dis_connect_intr();
        }
    }
#endif//#if 0

    dwc_write_reg32(DWC_REG_GINTSTS,gintr_status.d32);
    flush_cpu_cache();
	return 0;
}
int optimus_storage_exit(void)
{
    _disk_intialed_ok = 0;
    DWN_MSG("store_exit yet!!\n");
    return store_exit();
}
int optimus_storage_init(int toErase)
{
    int ret = 0;
    char* cmd = NULL;

    if(_disk_intialed_ok){//To assert only actual disk intialed once
        DWN_MSG("Disk inited 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_exit();
    }

    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 fbbt; 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;

        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();
        }
    }

    return ret;
}
//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)
{
    u64 partCap = 0;
    int ret = 0;

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

    //TODO: check format is normal/bootloader if upload!!
    
    if(!strcmp("sparse", imgType))
    {
        pDownInfo->imgType = IMG_TYPE_SPARSE;
    }
    else if(!strcmp("bootloader", partName))
    {
        pDownInfo->imgType = IMG_TYPE_BOOTLOADER;
    }
    else if(!strcmp("normal", imgType))
    {
        pDownInfo->imgType = IMG_TYPE_NORMAL;
    }
    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))//get size if not bootloader
        {
            ret = store_get_partititon_size((u8*)partName, &partCap);
            if(ret){
                DWN_ERR("Fail to get size for part %s\n", partName);
                return __LINE__;
            }
            partCap <<= 9;//trans sector to byte
            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;
} 
//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;
    unsigned char* partName = (unsigned char*)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(buff, addrOrOffsetInBy, (u64)readSzInBy);
                }
                else
                {
                    ret = store_read_ops(partName, buff, addrOrOffsetInBy, (u64)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*)(unsigned)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 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:
                        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;

                    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*)(unsigned)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!
            {
                int rc = 0;
                char* dtbLoadAddr = (char*)CONFIG_DTB_LOAD_ADDR;
                const int DtbMaxSz = (2U<<20);
                unsigned fdtSz = 0;
                unsigned char* destDtb = (unsigned char*)data;

                //Make sure flash already inited before 'run aml_dt'
                //old tool will download dtb before 'disk_initial', but new tool will 'disk_initial' first
                if(is_optimus_storage_inited() || 
                                (OPTIMUS_WORK_MODE_USB_PRODUCE != optimus_work_mode_get()))
                {
                        destDtb = (unsigned char*)get_multi_dt_entry((unsigned int)data);
                }
                rc = fdt_check_header(destDtb);
                if(rc){
                    sprintf(errInfo, "failed at fdt_check_header\n");
                    DWN_ERR(errInfo);
                    return 0;
                }
                fdtSz = fdt_totalsize(destDtb);
                if(DtbMaxSz <= fdtSz){
                    sprintf(errInfo, "failed: fdt header ok but sz 0%x > max 0x%x\n", fdtSz, DtbMaxSz);
                    DWN_ERR(errInfo);
                    return 0;
                }

                DWN_MSG("load dtb to 0x%p\n", dtbLoadAddr);
                memcpy(dtbLoadAddr, destDtb, fdtSz);
            }

            burnSz = dataSz;
        }
        break;

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

    return burnSz;
}
Exemple #16
0
static int _check_if_secureboot_enabled(void)
{
    const unsigned long cfg10 = readl(AO_SEC_SD_CFG10);
    DWN_MSG("cfg10=0x%lX\n", cfg10);
    return ( cfg10 & (0x1<< 4) );
}
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;
    }
    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 = aml_nftl_get_dev(partName);*/
                    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 _check_partition_table_consistency(const unsigned uboot_bin)
{
    int rc = 0;
    unsigned partitionTableSz = 0;
    const int acsOffsetInSpl   = START_ADDR - AHB_SRAM_BASE;
    const int addrMapFromAhb2Bin = AHB_SRAM_BASE - uboot_bin;

    const struct acs_setting* acsSettingInBin   = NULL;
    unsigned partTabAddrInBin             = 0;
    const struct partitions*  partsTabInBin     = NULL;

    const struct acs_setting* acsSettingInSram  = NULL;
    const struct partitions*  partsTabInSram    = NULL;

    DWN_DBG("uboot_bin 0x%p, acsOffsetInSpl 0x%x, addrMapFromAhb2Bin 0x%x\n", uboot_bin, acsOffsetInSpl, addrMapFromAhb2Bin);
    acsSettingInBin   = (struct acs_setting*)(*(unsigned*)(uboot_bin + acsOffsetInSpl) - addrMapFromAhb2Bin);
    partitionTableSz = acsSettingInBin->partition_table_length;
    DWN_MSG("acsSettingInBin=0x%x, partTabSz=0x%x\n", (unsigned int)acsSettingInBin, partitionTableSz);
    
    if( (unsigned)acsSettingInBin >= uboot_bin + 64*1024 || (unsigned)acsSettingInBin <= uboot_bin){//acs not in the spl
        DWN_MSG("Acs not in the spl of uboot_bin\n");
        return 0;
    }
    if(memcmp(MAGIC_ACS, acsSettingInBin->acs_magic, strlen(MAGIC_ACS))
        || memcmp(TABLE_MAGIC_NAME, acsSettingInBin->partition_table_magic, strlen(TABLE_MAGIC_NAME)))
    {
        DWN_MSG("acs magic OR part magic in ubootin not match\n");
        return 0;//Not to check partTable as acs magic or part magic not match in u-boot.bin, maybe encrypted by AMLETOOL
    }
    partTabAddrInBin  = acsSettingInBin->partition_table_addr - addrMapFromAhb2Bin;
    partsTabInBin     = (const struct partitions*)partTabAddrInBin;

#ifndef CONFIG_MESON_TRUSTZONE
    acsSettingInSram  = (struct acs_setting*)(*(unsigned*)START_ADDR);
#else
    //twice eget value at sram address and copy 1K to memory
    acsSettingInSram  = (struct acs_setting*)meson_trustzone_acs_addr(START_ADDR);
    DWN_MSG("[Trust]acsSettingInSram=0x%p\n", acsSettingInSram);
#endif// #ifndef CONFIG_MESON_TRUSTZONE
    partsTabInSram    = (const struct partitions*)acsSettingInSram->partition_table_addr;
    DWN_MSG("partsTabInSram=0x%p\n", partsTabInSram);

    if(memcmp(MAGIC_ACS, acsSettingInSram->acs_magic, strlen(MAGIC_ACS))
       || memcmp(TABLE_MAGIC_NAME, acsSettingInSram->partition_table_magic, strlen(TABLE_MAGIC_NAME)))
    {
        DWN_MSG("acs magic OR part magic in SPL not match\n");
        return __LINE__;//Not to check partTable as acs magic or part magic not match in SRAM, assert this!!
    }

#ifdef CONFIG_MESON_TRUSTZONE
    partsTabInSram    = (const struct partitions*)meson_trustzone_acs_addr((unsigned)&acsSettingInSram->partition_table_addr);
#endif// #ifndef CONFIG_MESON_TRUSTZONE

    rc = memcmp(partsTabInSram, partsTabInBin, partitionTableSz);
    DWN_MSG("Check parts table %s\n", !rc ? "OK." : "FAILED!");
#if 0//I comment print as str-prefix function (strcmp, strcmp, and .etc) are all not reliable in uboot
    if(rc)
    {
        DWN_MSG("acs_setting    0x%p, 0x%p\n", acsSettingInBin, acsSettingInSram);
        DWN_MSG("partitions     0x%08x, 0x%p\n", partTabAddrInBin, partsTabInSram);
        DWN_MSG("partition_table_addr 0x%x, 0x%x\n", acsSettingInSram->partition_table_addr, acsSettingInBin->partition_table_addr);

        DWN_MSG("part in ubootbin:\n");
        _show_partition_table(partsTabInBin);

        DWN_MSG("part in spl:\n");
        _show_partition_table(partsTabInSram);
        return __LINE__;
    }
#endif//#if 0

    return rc;
}
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_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;)
Exemple #20
0
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;
}
Exemple #21
0
//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;
}
Exemple #22
0
//.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;

    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);
    leftItemSz        -= itemSizeNotAligned;
    rcode = sdc_burn_buf_manager_init(partName, imgItemSz, fileFmt, itemSizeNotAligned);
    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)
        {
            DWN_MSG("itemSizeNotAligned 0x%x\n", itemSizeNotAligned);
            rcode = image_item_read(hImg, hImgItem, downTransBuf - itemSizeNotAligned, itemSizeNotAligned);
            if (rcode) {
                DWN_ERR("fail in read data from item,rcode %d, len 0x%x, sequenceNo %d\n", rcode, itemSizeNotAligned, sequenceNo);
                goto _finish;
            }
        }

        rcode = image_item_read(hImg, hImgItem, downTransBuf, thisReadLen);
        if (rcode) {
            DWN_ERR("fail in read data from item,rcode %d\n", rcode);
            goto _finish;
        }

        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;
}
//1, Read the whole file content to buffer
//2, parse file content to lines
//3, parse each valid line 
static int parse_ini_file(const char* filePath, u8* iniBuf, const unsigned bufSz)
{
    const int MaxLines = 1024;//
    const int MaxWordsALine = 32;

    char* lines[MaxLines];
    char* wordsALine[MaxWordsALine];
    int ret = 0;
    unsigned fileSz = 0;
    unsigned lineNum = 0; 
    int nwords = 0;
    int currentSetIndex = -1;
    int hFile = -1;
    unsigned readLen = 0;
    unsigned i = 0;
    unsigned lineIndex = 0; 

    fileSz = (unsigned)do_fat_get_fileSz(filePath);
    if(!fileSz){
        err("File %s not exist in sdcard??\n", filePath);
        return __LINE__;
    }
    if(fileSz >= bufSz){
        err("file size 0x%x illegal, buf size is 0x%x\n", fileSz, bufSz);
        return __LINE__;
    }
    DWN_MSG("ini sz 0x%xB\n", fileSz);

    hFile = do_fat_fopen(filePath);
    if(hFile < 0){
        err("Fail to open file %s\n", filePath);
        return __LINE__;
    }

    readLen = do_fat_fread(hFile, iniBuf, fileSz);
    if(readLen != fileSz){
        err("failed to load cfg file, want size 0x%x, but 0x%x\n", fileSz, readLen);
        do_fat_fclose(hFile);
        return __LINE__;
    }
    iniBuf[fileSz] = 0;

    do_fat_fclose(hFile);

    dbg("\\r is 0x%x\t, \\n is 0x%x\n", '\r', '\n');
    char* curLine = (char*)iniBuf;
    char* pTemp = curLine;

    //step1:first loop to seprate buffer to lines
    for (i = 0; i < fileSz ; i++, ++pTemp)
    {
        char c = *pTemp;
        int isFileEnd = i + 1 >= fileSz;

        if(MaxLines <= lineNum){
            err("total line number %d too many, at most %d lines!\n", lineNum, MaxLines);
            break;
        }

        if(isFileEnd)
        {
            lines[lineNum++] = curLine;
            break;//End to read file if file ended
        }

        if('\r' != c && '\n' != c) {
            continue;
        }
        *pTemp = 0;///

        dbg("%3d: %s\n", lineNum, curLine);
        if('\r' == c)//for DOS \r\n mode
        {
            if('\n' == pTemp[1])
            {
                lines[lineNum++] = curLine;

                ++pTemp;
                curLine = pTemp + 1;
                ++i;//skip '\n' which follows '\r'
            }
            else
            {
                err("Syntax error at line %d, DOS end \\r\\n, but \\r%x\n", lineNum + 1, pTemp[1]);
                return __LINE__;
            }
        }
        else if('\n' == c)//for UNIX '\n' mode
        {
            lines[lineNum++] = curLine;
            curLine = pTemp + 1;
        }
    }
    
    //step 2: abandon comment or space lines
    for (lineIndex = 0; lineIndex < lineNum ; lineIndex++)
    {
        int isSpaceLine = 1;
        char c = 0;
        curLine = lines[lineIndex];

        while(c = *curLine++, c)
        {
            //escape space and tab
            if (is_space_char(c))
            {
                continue;
            }
            
            isSpaceLine = 0;//no space line
            //test if frist char is comment delimeter
            if(';' == c)
            {
                lines[lineIndex] = NULL;//invalid comment lines
            }
        }

        //if all character is space or tab, also invlalid it 
        if (isSpaceLine)
        {
            lines[lineIndex] = NULL;
        }
    }

    dbg("\nvalid lines:\n");
    for (lineIndex = 0; lineIndex < lineNum ; lineIndex++)
    {
        int lineType = INI_LINE_TYPE_ERR;
        const char* iniKey = NULL;
        const char* iniVal = NULL;
        const char* iniSet = NULL;

        curLine = lines[lineIndex];

        if(!curLine)continue;

        if(!line_is_valid(curLine)) //only comment lines can contain non-ASCII letters
        {
            err("line %d contain invalid chars\n", lineIndex + 1);
            ret = __LINE__;
            break;
        }
        dbg("%3d: %s\n",lineIndex, curLine);

        nwords = line_2_words(curLine, wordsALine, MaxWordsALine);
        if(nwords <= 0){
            ret = __LINE__;
            break;
        }
        if(nwords > 3){
            err("line %d error: ini support at most 3 words, but %d\n", lineIndex + 1, nwords);
            ret = __LINE__;
            break;
        }

        switch (nwords)
        {
        case 3:
            {
                if (!strcmp("=", wordsALine[1]))//k/v pair
                {
                    lineType = INI_LINE_TYPE_KE_VALUE;
                    iniKey = wordsALine[0]; iniVal = wordsALine[2];
                    break;
                }
                else if(!strcmp("[" , wordsALine[0]) && !strcmp("]" , wordsALine[2]))//set line
                {
                    lineType = INI_LINE_TYPE_SET;
                    iniSet = wordsALine[1];
                    break;
                }
                else
                {
                    lineType = INI_LINE_TYPE_ERR;
                    err("Ini syntax error when parse line %d\n", lineIndex + 1);
                    ret = __LINE__; break;
                }
            }
        	break;

        case 2:
            {
                if('[' == wordsALine[0][0])//set like "[set ]" or "[ set]"
                {
                    if(!strcmp("]", wordsALine[1]))
                    {
                        lineType = INI_LINE_TYPE_SET;
                        iniSet = wordsALine[0] + 1;
                        break;
                    }
                    else if (']' == wordsALine[1][strlen(wordsALine[1]) - 1] && !strcmp("[", wordsALine[0]))
                    {
                        lineType = INI_LINE_TYPE_SET;
                        iniSet = wordsALine[1];
                        wordsALine[1][strlen(wordsALine[1]) - 1] = 0;
                        break;
                    }
                }
                else if(!strcmp("=", wordsALine[1]))//k/v pair like "key = " 
                {
                    lineType = INI_LINE_TYPE_KE_VALUE;
                    iniKey = wordsALine[0];
                    break;
                }
                else if('=' == wordsALine[1][0])//k/v pair like "key =v" or "key= v"
                {
                    lineType = INI_LINE_TYPE_KE_VALUE;
                    iniKey = wordsALine[0];
                    iniVal = wordsALine[1] + 1;
                    break;
                }
                else if ('=' == wordsALine[0][strlen(wordsALine[0]) - 1])//k/v pair like "key= v"
                {
                    wordsALine[0][strlen(wordsALine[0]) - 1] = 0;
                    lineType = INI_LINE_TYPE_KE_VALUE;
                    iniKey = wordsALine[0];
                    iniVal = wordsALine[1];
                }
            }
            break;

        case 1:
            {
                char* word = wordsALine[0];
                char firstChar = word[0];
                char lastChar  = word[strlen(word) - 1];

                if('[' == firstChar && ']' == lastChar)
                {
                    lineType = INI_LINE_TYPE_SET;
                    iniSet = word + 1;
                    word[strlen(word) - 1] = 0;
                    break;
                }
                else 
                {
                    char c = 0;

                    iniKey = word;
                    while(c = *word++, c)
                    {
                        if ('=' == c)//TODO: not assert only delimeter in a line yet
                        {
                            lineType = INI_LINE_TYPE_KE_VALUE;
                            *--word = 0;
                            iniVal = ++word;
                            iniVal = *iniVal ? iniVal : NULL;
                            break;
                        }
                    }
                }
            }
            break;

        default:
            break;
        }

        if (INI_LINE_TYPE_SET == lineType)
        {
            const char* setname = NULL;
            dbg("set line, set is %s\n", iniSet);
            
            currentSetIndex = -1;//set index to invalid

            for (i = 0; i < TOTAL_SET_NUM; i++)
            {
                setname = _iniSets[i];
                if (!strcmp(setname, iniSet))break;//set is useful for sdc burn
            }

            //set is useful
            if(i < TOTAL_SET_NUM)
            {
                if(!strcmp(setname, SET_BURN_PARTS))
                {
                    if(g_sdcBurnPara.setsBitMap.burnParts){
                        ret = __LINE__; goto _set_duplicated;
                    }
                    g_sdcBurnPara.setsBitMap.burnParts = 1;
                }

                if(!strcmp(setname, SET_BURN_PARA_EX))
                {
                    if(g_sdcBurnPara.setsBitMap.burnEx){
                        ret = __LINE__; goto _set_duplicated;
                    }
                    g_sdcBurnPara.setsBitMap.burnEx = 1;
                }

                if(!strcmp(setname, SET_CUSTOM_PARA))
                {
                    if(g_sdcBurnPara.setsBitMap.custom){
                        ret = __LINE__; goto _set_duplicated;
                    }
                    g_sdcBurnPara.setsBitMap.custom = 1;
                }

                currentSetIndex = i;//set set index to valid
            }

        }

        if(INI_LINE_TYPE_KE_VALUE == lineType)
        {
            dbg("k/v line, key (%s), val (%s)\n", iniKey, iniVal);

            if (currentSetIndex >= 0 && currentSetIndex < TOTAL_SET_NUM)//set is valid
            {
                const char* setName = _iniSets[currentSetIndex];

                if (!strcmp(setName, SET_BURN_PARTS))
                {
                    ret = parse_burn_parts(iniKey, iniVal);
                    if(ret){
                        ret = __LINE__; goto _line_err;
                    }
                }

                if (!strcmp(setName, SET_BURN_PARA_EX))
                {
                    ret = parse_set_burnEx(iniKey, iniVal);
                    if(ret){
                        ret = __LINE__; goto _line_err;
                    }
                }

                if (!strcmp(setName, SET_CUSTOM_PARA))
                {
                    ret = parse_set_custom_para(iniKey, iniVal);
                    if(ret){
                        ret = __LINE__; goto _line_err;
                    }
                }
            }
        }
    }


	return ret;

_line_err:
    err("Fail to parse line %d\n", lineIndex + 1);
    return ret;

_set_duplicated:
    err("line %d err:set is duplicated!!\n", lineIndex + 1);
    return ret;
}
Exemple #24
0
/**
 * This interrupt indicates that an IN EP has a pending Interrupt.
 * The sequence for handling the IN EP interrupt is shown below:
 * -#	Read the Device All Endpoint Interrupt register
 * -#	Repeat the following for each IN EP interrupt bit set (from
 *   	LSB to MSB).
 * -#	Read the Device Endpoint Interrupt (DIEPINTn) register
 * -#	If "Transfer Complete" call the request complete function
 * -#	If "Endpoint Disabled" complete the EP disable procedure.
 * -#	If "AHB Error Interrupt" log error
 * -#	If "Time-out Handshake" log error
 * -#	If "IN Token Received when TxFIFO Empty" write packet to Tx
 *   	FIFO.
 * -#	If "IN Token EP Mismatch" (disable, this is handled by EP
 *   	Mismatch Interrupt)
 */
static int32_t dwc_otg_pcd_handle_in_ep_intr(void)
{
#define CLEAR_IN_EP_INTR(__epnum,__intr) \
do { \
        diepint_data_t diepint = { 0 }; \
	diepint.b.__intr = 1; \
	dwc_write_reg32(DWC_REG_IN_EP_INTR(__epnum), \
			diepint.d32); \
} while (0)

        diepint_data_t diepint = { 0 };
//        depctl_data_t diepctl = { 0 };
        uint32_t ep_intr;
        uint32_t epnum = 0;
        gintmsk_data_t intr_mask = {0};
        gintsts_data_t gintsts;

	 DBG( "dwc_otg_pcd_handle_in_ep_intr()\n" );

	/* Read in the device interrupt bits */
        ep_intr = (dwc_read_reg32(DWC_REG_DAINT) &
                dwc_read_reg32( DWC_REG_DAINTMSK));
        ep_intr =( (ep_intr & 0xffff) );


	/* Clear the INEPINT in GINTSTS */
	/* Clear all the interrupt bits for all IN endpoints in DAINT */
	gintsts.d32 = 0;
	gintsts.b.inepint = 1;
	dwc_write_reg32 (DWC_REG_GINTSTS, gintsts.d32);
	dwc_write_reg32(DWC_REG_DAINT, 0xFFFF );
	flush_cpu_cache();

	/* Service the Device IN interrupts for each endpoint */
        while ( ep_intr ) {
                if (ep_intr&0x1) {

                        diepint.d32 = (dwc_read_reg32( DWC_REG_IN_EP_INTR(epnum)) &
									dwc_read_reg32(DWC_REG_DAINTMSK));
                        /* Transfer complete */
                        if ( diepint.b.xfercompl ) {


                                /* Disable the NP Tx FIFO Empty
                                 * Interrrupt */
                                intr_mask.b.nptxfempty = 1;
                                dwc_modify_reg32( DWC_REG_GINTMSK, intr_mask.d32, 0);

                                /* Clear the bit in DIEPINTn for this interrupt */
                                CLEAR_IN_EP_INTR(epnum,xfercompl);

                                /* Complete the transfer */
					if (epnum == 0) {
						handle_ep0( 0 );
					} else {
						complete_ep( epnum,1 );
					}
                        }
                        /* Endpoint disable  */
                        if ( diepint.b.epdisabled ) {
                                handle_in_ep_disable_intr( epnum );

                                /* Clear the bit in DIEPINTn for this interrupt */
                                CLEAR_IN_EP_INTR(epnum,epdisabled);
                        }
                        /* AHB Error */
                        if ( diepint.b.ahberr ) {
				/* Clear the bit in DIEPINTn for this interrupt */
				CLEAR_IN_EP_INTR(epnum,ahberr);
                        }
                        /* TimeOUT Handshake (non-ISOC IN EPs) */
                        if ( diepint.b.timeout ) {
                                handle_in_ep_timeout_intr( epnum );

				CLEAR_IN_EP_INTR(epnum,timeout);
                        }
                        /** IN Token received with TxF Empty */
                        if (diepint.b.intktxfemp) {
                                DWN_MSG("diepint.b.intktxfemp\n");
#if 0
                                if (!ep->stopped && epnum != 0) {
                                        diepmsk_data_t diepmsk = { 0};
                                        diepmsk.b.intktxfemp = 1;
                                        dwc_modify_reg32( &dev_if->dev_global_regs->diepmsk, diepmsk.d32, 0 );
                                        start_next_request(ep);
                                }
#endif
				CLEAR_IN_EP_INTR(epnum,intktxfemp);
                        }
                        /** IN Token Received with EP mismatch */
                        if (diepint.b.intknepmis) {
                                DWN_MSG("intknepmis ep%d\n", epnum);
                                CLEAR_IN_EP_INTR(epnum,intknepmis);
                        }
                        /** IN Endpoint NAK Effective */
                        if (diepint.b.inepnakeff) {
				CLEAR_IN_EP_INTR(epnum,inepnakeff);
                        }
                }
                epnum++;
                ep_intr >>=1;
        }

        return 1;

#undef CLEAR_IN_EP_INTR
}