//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; }
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; }
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; }
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; }
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; }
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; }
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;)
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; }
//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; }
//.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; }
/** * 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 }