176af099aSliuyi /* 276af099aSliuyi * (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd 376af099aSliuyi * Seth Liu 2017.03.01 476af099aSliuyi * 576af099aSliuyi * SPDX-License-Identifier: GPL-2.0+ 676af099aSliuyi */ 776af099aSliuyi 876af099aSliuyi #include "RKDevice.h" 976af099aSliuyi 1076af099aSliuyi const char* szManufName[] = 1176af099aSliuyi { 1276af099aSliuyi "SAMSUNG", 1376af099aSliuyi "TOSHIBA", 1476af099aSliuyi "HYNIX", 1576af099aSliuyi "INFINEON", 1676af099aSliuyi "MICRON", 1776af099aSliuyi "RENESAS", 1876af099aSliuyi "ST", 1976af099aSliuyi "INTEL" 2076af099aSliuyi }; 2176af099aSliuyi 2276af099aSliuyi void CRKDevice::SetVendorID(USHORT value) 2376af099aSliuyi { 2476af099aSliuyi m_vid = value; 2576af099aSliuyi } 2676af099aSliuyi void CRKDevice::SetProductID(USHORT value) 2776af099aSliuyi { 2876af099aSliuyi m_pid = value; 2976af099aSliuyi } 3076af099aSliuyi void CRKDevice::SetDeviceType(ENUM_RKDEVICE_TYPE value) 3176af099aSliuyi { 3276af099aSliuyi m_device = value; 3376af099aSliuyi } 3476af099aSliuyi void CRKDevice::SetOsType(ENUM_OS_TYPE value) 3576af099aSliuyi { 3676af099aSliuyi m_os = value; 3776af099aSliuyi } 3876af099aSliuyi 3976af099aSliuyi void CRKDevice::SetUsbType(ENUM_RKUSB_TYPE value) 4076af099aSliuyi { 4176af099aSliuyi m_usb = value; 4276af099aSliuyi } 4376af099aSliuyi void CRKDevice::SetBcdUsb(USHORT value) 4476af099aSliuyi { 4576af099aSliuyi m_bcdUsb = value; 4676af099aSliuyi } 4776af099aSliuyi void CRKDevice::SetLayerName(char *value) 4876af099aSliuyi { 4976af099aSliuyi strcpy(m_layerName,value); 5076af099aSliuyi } 5176af099aSliuyi void CRKDevice::SetLocationID(DWORD value) 5276af099aSliuyi { 5376af099aSliuyi m_locationID = value; 5476af099aSliuyi } 5576af099aSliuyi 5676af099aSliuyi void CRKDevice::SetCallBackPointer(ProgressPromptCB value) 5776af099aSliuyi { 5876af099aSliuyi if (value) 5976af099aSliuyi { 6076af099aSliuyi m_callBackProc = value; 6176af099aSliuyi } 6276af099aSliuyi } 6376af099aSliuyi CRKLog* CRKDevice::GetLogObjectPointer() 6476af099aSliuyi { 6576af099aSliuyi return m_pLog; 6676af099aSliuyi } 6776af099aSliuyi 6876af099aSliuyi CRKComm* CRKDevice::GetCommObjectPointer() 6976af099aSliuyi { 7076af099aSliuyi return m_pComm; 7176af099aSliuyi } 7276af099aSliuyi 7376af099aSliuyi USHORT CRKDevice::GetVendorID() 7476af099aSliuyi { 7576af099aSliuyi return m_vid; 7676af099aSliuyi } 7776af099aSliuyi USHORT CRKDevice::GetProductID() 7876af099aSliuyi { 7976af099aSliuyi return m_pid; 8076af099aSliuyi } 8176af099aSliuyi ENUM_RKDEVICE_TYPE CRKDevice::GetDeviceType() 8276af099aSliuyi { 8376af099aSliuyi return m_device; 8476af099aSliuyi } 8576af099aSliuyi ENUM_OS_TYPE CRKDevice::GetOsType() 8676af099aSliuyi { 8776af099aSliuyi return m_os; 8876af099aSliuyi } 8976af099aSliuyi 9076af099aSliuyi ENUM_RKUSB_TYPE CRKDevice::GetUsbType() 9176af099aSliuyi { 9276af099aSliuyi return m_usb; 9376af099aSliuyi } 9476af099aSliuyi 9576af099aSliuyi USHORT CRKDevice::GetBcdUsb() 9676af099aSliuyi { 9776af099aSliuyi return m_bcdUsb; 9876af099aSliuyi } 9976af099aSliuyi DWORD CRKDevice::GetLocationID() 10076af099aSliuyi { 10176af099aSliuyi return m_locationID; 10276af099aSliuyi } 10376af099aSliuyi char* CRKDevice::GetLayerName() 10476af099aSliuyi { 10576af099aSliuyi return m_layerName; 10676af099aSliuyi } 10776af099aSliuyi 10876af099aSliuyi string CRKDevice::GetLayerString(DWORD dwLocationID) 10976af099aSliuyi { 11076af099aSliuyi char szLocation[32] = "\0"; 11176af099aSliuyi sprintf(szLocation, "%d-%d", dwLocationID >> 8, dwLocationID & 0xff); 11276af099aSliuyi return szLocation; 11376af099aSliuyi } 11476af099aSliuyi 11576af099aSliuyi CRKDevice::CRKDevice(STRUCT_RKDEVICE_DESC &device) 11676af099aSliuyi { 11776af099aSliuyi VendorID.setContainer(this); 11876af099aSliuyi VendorID.getter(&CRKDevice::GetVendorID); 11976af099aSliuyi VendorID.setter(&CRKDevice::SetVendorID); 12076af099aSliuyi 12176af099aSliuyi ProductID.setContainer(this); 12276af099aSliuyi ProductID.getter(&CRKDevice::GetProductID); 12376af099aSliuyi ProductID.setter(&CRKDevice::SetProductID); 12476af099aSliuyi 12576af099aSliuyi DeviceType.setContainer(this); 12676af099aSliuyi DeviceType.getter(&CRKDevice::GetDeviceType); 12776af099aSliuyi DeviceType.setter(&CRKDevice::SetDeviceType); 12876af099aSliuyi 12976af099aSliuyi UsbType.setContainer(this); 13076af099aSliuyi UsbType.getter(&CRKDevice::GetUsbType); 13176af099aSliuyi UsbType.setter(&CRKDevice::SetUsbType); 13276af099aSliuyi 13376af099aSliuyi LayerName.setContainer(this); 13476af099aSliuyi LayerName.getter(&CRKDevice::GetLayerName); 13576af099aSliuyi LayerName.setter(&CRKDevice::SetLayerName); 13676af099aSliuyi 13776af099aSliuyi BcdUsb.setContainer(this); 13876af099aSliuyi BcdUsb.getter(&CRKDevice::GetBcdUsb); 13976af099aSliuyi BcdUsb.setter(&CRKDevice::SetBcdUsb); 14076af099aSliuyi 14176af099aSliuyi LocationID.setContainer(this); 14276af099aSliuyi LocationID.getter(&CRKDevice::GetLocationID); 14376af099aSliuyi LocationID.setter(&CRKDevice::SetLocationID); 14476af099aSliuyi 14576af099aSliuyi OsType.setContainer(this); 14676af099aSliuyi OsType.getter(&CRKDevice::GetOsType); 14776af099aSliuyi OsType.setter(&CRKDevice::SetOsType); 14876af099aSliuyi 14976af099aSliuyi LogObjectPointer.setContainer(this); 15076af099aSliuyi LogObjectPointer.getter(&CRKDevice::GetLogObjectPointer); 15176af099aSliuyi 15276af099aSliuyi CommObjectPointer.setContainer(this); 15376af099aSliuyi CommObjectPointer.getter(&CRKDevice::GetCommObjectPointer); 15476af099aSliuyi 15576af099aSliuyi CallBackPointer.setContainer(this); 15676af099aSliuyi CallBackPointer.setter(&CRKDevice::SetCallBackPointer); 15776af099aSliuyi 15876af099aSliuyi m_vid = device.usVid; 15976af099aSliuyi m_pid = device.usPid; 16076af099aSliuyi m_usb = device.emUsbType; 16176af099aSliuyi m_device = device.emDeviceType; 16276af099aSliuyi m_bcdUsb = device.usbcdUsb; 16376af099aSliuyi m_locationID = device.uiLocationID; 16476af099aSliuyi strcpy(m_layerName, GetLayerString(m_locationID).c_str()); 16576af099aSliuyi 16676af099aSliuyi memset(m_flashInfo.blockState, 0, IDBLOCK_TOP); 16776af099aSliuyi m_flashInfo.usPhyBlokcPerIDB = 1; 16876af099aSliuyi m_flashInfo.uiSecNumPerIDB = 0; 16976af099aSliuyi m_callBackProc = NULL; 17076af099aSliuyi m_chipData = NULL; 17176af099aSliuyi m_pImage = NULL; 17276af099aSliuyi m_pLog = NULL; 17376af099aSliuyi m_pComm = NULL; 17476af099aSliuyi m_pFlashInfoData = NULL; 17576af099aSliuyi m_usFlashInfoDataLen = 0; 17676af099aSliuyi m_usFlashInfoDataOffset = 0; 17776af099aSliuyi m_bEmmc = false; 178*081d237aSliuyi m_bDirectLba = false; 179*081d237aSliuyi m_bFirst4mAccess = false; 18076af099aSliuyi } 18176af099aSliuyi CRKDevice::~CRKDevice() 18276af099aSliuyi { 18376af099aSliuyi if (m_pComm) { 18476af099aSliuyi delete m_pComm; 18576af099aSliuyi m_pComm = NULL; 18676af099aSliuyi } 18776af099aSliuyi if (m_chipData) { 18876af099aSliuyi delete []m_chipData; 18976af099aSliuyi m_chipData = NULL; 19076af099aSliuyi } 19176af099aSliuyi 19276af099aSliuyi if (m_pFlashInfoData) { 19376af099aSliuyi delete []m_pFlashInfoData; 19476af099aSliuyi m_pFlashInfoData = NULL; 19576af099aSliuyi } 19676af099aSliuyi } 19776af099aSliuyi bool CRKDevice::SetObject(CRKImage *pImage, CRKComm *pComm, CRKLog *pLog) 19876af099aSliuyi { 19976af099aSliuyi if (!pComm) { 20076af099aSliuyi return false; 20176af099aSliuyi } 20276af099aSliuyi m_pImage = pImage; 20376af099aSliuyi m_pComm = pComm; 20476af099aSliuyi m_pLog = pLog; 20576af099aSliuyi if (m_pImage) { 20676af099aSliuyi m_os = m_pImage->OsType; 20776af099aSliuyi } else 20876af099aSliuyi m_os = RK_OS; 20976af099aSliuyi return true; 21076af099aSliuyi } 21176af099aSliuyi int CRKDevice::EraseEmmcBlock(UCHAR ucFlashCS, DWORD dwPos, DWORD dwCount) 21276af099aSliuyi { 21376af099aSliuyi int sectorOffset,nWrittenBlcok,iRet; 21476af099aSliuyi BYTE emptyData[4 * (SECTOR_SIZE+SPARE_SIZE)]; 21576af099aSliuyi memset(emptyData, 0xff, 4 * (SECTOR_SIZE + SPARE_SIZE)); 21676af099aSliuyi nWrittenBlcok = 0; 21776af099aSliuyi while (dwCount > 0) { 21876af099aSliuyi sectorOffset = (ucFlashCS * m_flashInfo.uiBlockNum + dwPos + nWrittenBlcok) * m_flashInfo.uiSectorPerBlock; 21976af099aSliuyi iRet = m_pComm->RKU_WriteSector(sectorOffset, 4, emptyData); 22076af099aSliuyi if ((iRet != ERR_SUCCESS) && (iRet != ERR_FOUND_BAD_BLOCK)) { 22176af099aSliuyi if (m_pLog) { 22276af099aSliuyi m_pLog->Record("<LAYER %s> ERROR:EraseEmmcBlock-->RKU_WriteSector failed, RetCode(%d)", m_layerName, iRet); 22376af099aSliuyi } 22476af099aSliuyi return iRet; 22576af099aSliuyi } 22676af099aSliuyi dwCount--; 22776af099aSliuyi nWrittenBlcok++; 22876af099aSliuyi } 22976af099aSliuyi return ERR_SUCCESS; 23076af099aSliuyi } 23176af099aSliuyi int CRKDevice::EraseEmmcByWriteLBA(DWORD dwSectorPos, DWORD dwCount) 23276af099aSliuyi { 23376af099aSliuyi int nWritten,iRet; 23476af099aSliuyi BYTE emptyData[32 * SECTOR_SIZE]; 23576af099aSliuyi memset(emptyData, 0xff, 32 * SECTOR_SIZE); 23676af099aSliuyi 23776af099aSliuyi while (dwCount > 0) { 23876af099aSliuyi nWritten = (dwCount < 32) ? dwCount : 32; 23976af099aSliuyi iRet = m_pComm->RKU_WriteLBA(dwSectorPos, nWritten, emptyData); 24076af099aSliuyi if (iRet != ERR_SUCCESS) { 24176af099aSliuyi if (m_pLog) { 24276af099aSliuyi m_pLog->Record("<LAYER %s> ERROR:EraseEmmcByWriteLBA-->RKU_WriteLBA failed, RetCode(%d)", m_layerName, iRet); 24376af099aSliuyi } 24476af099aSliuyi return iRet; 24576af099aSliuyi } 24676af099aSliuyi dwCount -= nWritten; 24776af099aSliuyi dwSectorPos += nWritten; 24876af099aSliuyi } 24976af099aSliuyi return ERR_SUCCESS; 25076af099aSliuyi } 25176af099aSliuyi bool CRKDevice::EraseEmmc() 25276af099aSliuyi { 253*081d237aSliuyi UINT uiCount,uiEraseCount,uiSectorOffset,uiTotalCount; 254*081d237aSliuyi UINT uiErase=1024*32; 25576af099aSliuyi int iRet=ERR_SUCCESS,iLoopTimes=0; 256*081d237aSliuyi uiTotalCount = uiCount = m_flashInfo.uiFlashSize*2*1024; 257*081d237aSliuyi uiSectorOffset = 0; 25876af099aSliuyi DWORD dwLayerID; 25976af099aSliuyi dwLayerID = m_locationID; 26076af099aSliuyi ENUM_CALL_STEP emCallStep = CALL_FIRST; 261*081d237aSliuyi 262*081d237aSliuyi while (uiCount) 263*081d237aSliuyi { 264*081d237aSliuyi if (uiCount >= uiErase) 265*081d237aSliuyi { 266*081d237aSliuyi uiEraseCount = uiErase; 267*081d237aSliuyi } 268*081d237aSliuyi else 269*081d237aSliuyi uiEraseCount = uiCount; 270*081d237aSliuyi iRet = m_pComm->RKU_EraseLBA(uiSectorOffset, uiEraseCount); 271*081d237aSliuyi 27276af099aSliuyi if (iRet != ERR_SUCCESS) { 27376af099aSliuyi if (m_pLog) { 274*081d237aSliuyi m_pLog->Record("ERROR:EraseEmmc-->RKU_EraseLBA failed,RetCode(%d),offset=0x%x,count=0x%x",iRet, uiSectorOffset, uiEraseCount); 27576af099aSliuyi } 27676af099aSliuyi return false; 27776af099aSliuyi } 278*081d237aSliuyi uiCount -= uiEraseCount; 279*081d237aSliuyi uiSectorOffset += uiEraseCount; 28076af099aSliuyi iLoopTimes++; 28176af099aSliuyi if (iLoopTimes % 8 == 0) { 28276af099aSliuyi if (m_callBackProc) { 283*081d237aSliuyi m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, uiTotalCount, uiSectorOffset, emCallStep); 28476af099aSliuyi emCallStep = CALL_MIDDLE; 28576af099aSliuyi } 28676af099aSliuyi } 28776af099aSliuyi } 28876af099aSliuyi if (m_callBackProc) { 28976af099aSliuyi emCallStep = CALL_LAST; 290*081d237aSliuyi m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, uiTotalCount, uiTotalCount, emCallStep); 29176af099aSliuyi } 29276af099aSliuyi return true; 29376af099aSliuyi } 29476af099aSliuyi bool CRKDevice::GetFlashInfo() 29576af099aSliuyi { 29676af099aSliuyi STRUCT_FLASHINFO_CMD info; 29776af099aSliuyi BYTE flashID[5]; 29876af099aSliuyi int iRet; 29976af099aSliuyi UINT uiRead; 30076af099aSliuyi iRet = m_pComm->RKU_ReadFlashInfo((PBYTE)&info, &uiRead); 30176af099aSliuyi if( ERR_SUCCESS == iRet ) { 30276af099aSliuyi if ((info.usBlockSize == 0) || (info.bPageSize == 0)) { 30376af099aSliuyi if (m_pLog) { 30476af099aSliuyi m_pLog->Record("<LAYER %s> ERROR:GetFlashInfo-->RKU_ReadFlashInfo failed,pagesize or blocksize is zero", m_layerName); 30576af099aSliuyi } 30676af099aSliuyi return false; 30776af099aSliuyi } 30876af099aSliuyi if (info.bManufCode <= 7) { 30976af099aSliuyi strcpy(m_flashInfo.szManufacturerName, szManufName[info.bManufCode]); 31076af099aSliuyi } else { 31176af099aSliuyi strcpy(m_flashInfo.szManufacturerName, "UNKNOWN"); 31276af099aSliuyi } 31376af099aSliuyi m_flashInfo.uiFlashSize = info.uiFlashSize / 2 / 1024; 31476af099aSliuyi m_flashInfo.uiPageSize = info.bPageSize / 2; 31576af099aSliuyi m_flashInfo.usBlockSize = info.usBlockSize / 2; 31676af099aSliuyi m_flashInfo.bECCBits = info.bECCBits; 31776af099aSliuyi m_flashInfo.bAccessTime = info.bAccessTime; 31876af099aSliuyi m_flashInfo.uiBlockNum = m_flashInfo.uiFlashSize * 1024 / m_flashInfo.usBlockSize; 31976af099aSliuyi m_flashInfo.uiSectorPerBlock = info.usBlockSize; 32076af099aSliuyi m_flashInfo.bFlashCS = info.bFlashCS; 32176af099aSliuyi m_flashInfo.usValidSecPerBlock = (info.usBlockSize / info.bPageSize) * 4; 32276af099aSliuyi if (m_pFlashInfoData) { 32376af099aSliuyi delete []m_pFlashInfoData; 32476af099aSliuyi m_pFlashInfoData = NULL; 32576af099aSliuyi } 32676af099aSliuyi m_usFlashInfoDataLen = BYTE2SECTOR(uiRead); 32776af099aSliuyi m_pFlashInfoData = new BYTE[SECTOR_SIZE * m_usFlashInfoDataLen]; 32876af099aSliuyi memset(m_pFlashInfoData, 0, SECTOR_SIZE * m_usFlashInfoDataLen); 32976af099aSliuyi memcpy(m_pFlashInfoData, (PBYTE)&info, uiRead); 33076af099aSliuyi if (m_pLog) { 33176af099aSliuyi string strFlashInfo; 33276af099aSliuyi m_pLog->PrintBuffer(strFlashInfo, m_pFlashInfoData, 11); 33376af099aSliuyi m_pLog->Record("<LAYER %s> INFO:FlashInfo:%s", m_layerName, strFlashInfo.c_str()); 33476af099aSliuyi } 33576af099aSliuyi } else { 33676af099aSliuyi if (m_pLog) { 33776af099aSliuyi m_pLog->Record("<LAYER %s> ERROR:GetFlashInfo-->RKU_ReadFlashInfo failed, RetCode(%d)", m_layerName, iRet); 33876af099aSliuyi } 33976af099aSliuyi return false; 34076af099aSliuyi } 34176af099aSliuyi iRet = m_pComm->RKU_ReadFlashID(flashID); 34276af099aSliuyi if( ERR_SUCCESS == iRet ) { 34376af099aSliuyi DWORD *pID = (DWORD *)flashID; 34476af099aSliuyi if (*pID==0x434d4d45)/*emmc*/ { 34576af099aSliuyi m_bEmmc = true; 34676af099aSliuyi } else 34776af099aSliuyi m_bEmmc = false; 34876af099aSliuyi } else { 34976af099aSliuyi if (m_pLog) { 35076af099aSliuyi m_pLog->Record("<LAYER %s> ERROR:GetFlashInfo-->RKU_ReadFlashID failed, RetCode(%d)", m_layerName, iRet); 35176af099aSliuyi } 35276af099aSliuyi return false; 35376af099aSliuyi } 35476af099aSliuyi return true; 35576af099aSliuyi } 35676af099aSliuyi bool CRKDevice::TestDevice() 35776af099aSliuyi { 35876af099aSliuyi int iResult, iTryCount; 35976af099aSliuyi DWORD dwTotal, dwCurrent, dwLayerID; 36076af099aSliuyi dwLayerID = m_locationID; 36176af099aSliuyi ENUM_CALL_STEP emCallStep = CALL_FIRST; 36276af099aSliuyi do { 36376af099aSliuyi iTryCount = 3; 36476af099aSliuyi while (iTryCount > 0) { 36576af099aSliuyi iResult = m_pComm->RKU_TestDeviceReady(&dwTotal, &dwCurrent); 36676af099aSliuyi if ((iResult == ERR_SUCCESS) || (iResult == ERR_DEVICE_UNREADY)) { 36776af099aSliuyi break; 36876af099aSliuyi } 36976af099aSliuyi if (m_pLog) { 37076af099aSliuyi m_pLog->Record("<LAYER %s> ERROR:TestDevice-->RKU_TestDeviceReady failed, RetCode(%d)", m_layerName, iResult); 37176af099aSliuyi } 37276af099aSliuyi iTryCount--; 37376af099aSliuyi sleep(1); 37476af099aSliuyi } 37576af099aSliuyi if (iTryCount <= 0) { 37676af099aSliuyi return false; 37776af099aSliuyi } 37876af099aSliuyi 37976af099aSliuyi if (iResult == ERR_SUCCESS) { 38076af099aSliuyi if (emCallStep == CALL_MIDDLE) { 38176af099aSliuyi if (m_callBackProc) { 38276af099aSliuyi dwCurrent = dwTotal; 38376af099aSliuyi emCallStep = CALL_LAST; 38476af099aSliuyi m_callBackProc(dwLayerID, TESTDEVICE_PROGRESS, dwTotal, dwCurrent, emCallStep); 38576af099aSliuyi } 38676af099aSliuyi } 38776af099aSliuyi break; 38876af099aSliuyi } 38976af099aSliuyi if (dwCurrent>dwTotal) { 39076af099aSliuyi if (m_pLog) { 39176af099aSliuyi m_pLog->Record("<LAYER %s> ERROR:TestDevice-->RKU_TestDeviceReady failed,Total=%d, Current=%d", m_layerName, dwTotal, dwCurrent); 39276af099aSliuyi } 39376af099aSliuyi return false; 39476af099aSliuyi } 39576af099aSliuyi if (UsbType == RKUSB_LOADER) { 39676af099aSliuyi if (dwTotal == 0) { 39776af099aSliuyi if (m_pLog) 39876af099aSliuyi { 39976af099aSliuyi m_pLog->Record("<LAYER %s> ERROR:TestDevice-->RKU_TestDeviceReady failed, Total is zero", m_layerName); 40076af099aSliuyi } 40176af099aSliuyi return false; 40276af099aSliuyi } 40376af099aSliuyi } 40476af099aSliuyi if (m_callBackProc) 40576af099aSliuyi { 40676af099aSliuyi m_callBackProc(dwLayerID, TESTDEVICE_PROGRESS, dwTotal, dwCurrent, emCallStep); 40776af099aSliuyi emCallStep = CALL_MIDDLE; 40876af099aSliuyi } 40976af099aSliuyi sleep(1); 41076af099aSliuyi }while(iResult == ERR_DEVICE_UNREADY); 41176af099aSliuyi return true; 41276af099aSliuyi } 41376af099aSliuyi bool CRKDevice::ResetDevice() 41476af099aSliuyi { 41576af099aSliuyi int iRet; 41676af099aSliuyi iRet = m_pComm->RKU_ResetDevice(); 41776af099aSliuyi if (iRet == ERR_SUCCESS) { 41876af099aSliuyi return true; 41976af099aSliuyi } else { 42076af099aSliuyi bool bRet = false; 42176af099aSliuyi if ((iRet == -2) || (iRet == -4)) { 42276af099aSliuyi bRet = true; 42376af099aSliuyi } 42476af099aSliuyi if (m_pLog) { 42576af099aSliuyi m_pLog->Record("<LAYER %s> ERROR:ResetDevice-->RKU_ResetDevice failed, RetCode(%d)", m_layerName, iRet); 42676af099aSliuyi } 42776af099aSliuyi return bRet; 42876af099aSliuyi } 42976af099aSliuyi } 43076af099aSliuyi 43176af099aSliuyi bool CRKDevice::PowerOffDevice() 43276af099aSliuyi { 43376af099aSliuyi int iRet; 43476af099aSliuyi iRet = m_pComm->RKU_ResetDevice(RST_POWEROFF_SUBCODE); 43576af099aSliuyi if (iRet == ERR_SUCCESS) { 43676af099aSliuyi return true; 43776af099aSliuyi } else { 43876af099aSliuyi if (m_pLog) { 43976af099aSliuyi m_pLog->Record("<LAYER %s> ERROR:PowerOffDevice-->RKU_ResetDevice failed, RetCode(%d)", m_layerName, iRet); 44076af099aSliuyi } 44176af099aSliuyi return false; 44276af099aSliuyi } 44376af099aSliuyi } 44476af099aSliuyi bool CRKDevice::CheckChip() 44576af099aSliuyi { 44676af099aSliuyi int iRet; 44776af099aSliuyi BYTE bChipInfo[CHIPINFO_LEN]; 44876af099aSliuyi ENUM_RKDEVICE_TYPE curDeviceType = RKNONE_DEVICE; 44976af099aSliuyi memset(bChipInfo, 0, CHIPINFO_LEN); 45076af099aSliuyi iRet = m_pComm->RKU_ReadChipInfo(bChipInfo); 45176af099aSliuyi if (iRet == ERR_SUCCESS) { 45276af099aSliuyi if (!m_chipData) { 45376af099aSliuyi m_chipData = new BYTE[CHIPINFO_LEN]; 45476af099aSliuyi } 45576af099aSliuyi memset(m_chipData, 0, CHIPINFO_LEN); 45676af099aSliuyi memcpy(m_chipData, bChipInfo, CHIPINFO_LEN); 45776af099aSliuyi DWORD *pValue; 45876af099aSliuyi pValue = (DWORD *)(&bChipInfo[0]); 45976af099aSliuyi 46076af099aSliuyi if ((ENUM_RKDEVICE_TYPE)(*pValue) == m_device) { 46176af099aSliuyi return true; 46276af099aSliuyi } 46376af099aSliuyi if (*pValue == 0x524B3237) { 46476af099aSliuyi curDeviceType = RK27_DEVICE; 46576af099aSliuyi } else if (*pValue == 0x32373341) { 46676af099aSliuyi curDeviceType = RKCAYMAN_DEVICE; 46776af099aSliuyi } else if (*pValue == 0x524B3238) { 46876af099aSliuyi curDeviceType = RK28_DEVICE; 46976af099aSliuyi } else if (*pValue == 0x32383158) { 47076af099aSliuyi curDeviceType = RK281X_DEVICE; 47176af099aSliuyi } else if (*pValue == 0x32383242) { 47276af099aSliuyi curDeviceType = RKPANDA_DEVICE; 47376af099aSliuyi } else if (*pValue == 0x32393058) { 47476af099aSliuyi curDeviceType = RK29_DEVICE; 47576af099aSliuyi } else if (*pValue == 0x32393258) { 47676af099aSliuyi curDeviceType = RK292X_DEVICE; 47776af099aSliuyi } else if (*pValue == 0x33303041) { 47876af099aSliuyi curDeviceType = RK30_DEVICE; 47976af099aSliuyi } else if (*pValue == 0x33313041) { 48076af099aSliuyi curDeviceType = RK30B_DEVICE; 48176af099aSliuyi } else if (*pValue == 0x33313042) { 48276af099aSliuyi curDeviceType = RK31_DEVICE; 48376af099aSliuyi } else if (*pValue == 0x33323041) { 48476af099aSliuyi curDeviceType = RK32_DEVICE; 48576af099aSliuyi } else if (*pValue == 0x32363243) { 48676af099aSliuyi curDeviceType = RKSMART_DEVICE; 48776af099aSliuyi } else if (*pValue == 0x6E616E6F) { 48876af099aSliuyi curDeviceType = RKNANO_DEVICE; 48976af099aSliuyi } else if (*pValue == 0x4E4F5243) { 49076af099aSliuyi curDeviceType = RKCROWN_DEVICE; 49176af099aSliuyi } 49276af099aSliuyi 49376af099aSliuyi if (curDeviceType == m_device){ 49476af099aSliuyi return true; 49576af099aSliuyi } else { 49676af099aSliuyi if (m_pLog) { 49776af099aSliuyi m_pLog->Record("<LAYER %s> ERROR:CheckChip-->Chip is not match, firmware(0x%x), device(0x%x)", m_layerName, m_device, *pValue); 49876af099aSliuyi } 49976af099aSliuyi return false; 50076af099aSliuyi } 50176af099aSliuyi } 50276af099aSliuyi else { 50376af099aSliuyi if (m_pLog) { 50476af099aSliuyi m_pLog->Record("<LAYER %s> ERROR:CheckChip-->RKU_ReadChipInfo failed,RetCode(%d)", m_layerName, iRet); 50576af099aSliuyi } 50676af099aSliuyi return false; 50776af099aSliuyi } 50876af099aSliuyi } 50976af099aSliuyi 51076af099aSliuyi int CRKDevice::DownloadBoot() 51176af099aSliuyi { 51276af099aSliuyi UCHAR i; 51376af099aSliuyi DWORD dwSize, dwDelay; 51476af099aSliuyi PBYTE pBuffer = NULL; 51576af099aSliuyi for ( i = 0; i < m_pImage->m_bootObject->Entry471Count; i++ ) { 51676af099aSliuyi if ( !m_pImage->m_bootObject->GetEntryProperty(ENTRY471, i, dwSize, dwDelay) ) { 51776af099aSliuyi if (m_pLog) { 51876af099aSliuyi m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->GetEntry471Property failed,index(%d)", m_layerName, i); 51976af099aSliuyi } 52076af099aSliuyi return -2; 52176af099aSliuyi } 52276af099aSliuyi if (dwSize>0) { 52376af099aSliuyi pBuffer = new BYTE[dwSize]; 52476af099aSliuyi if ( !m_pImage->m_bootObject->GetEntryData(ENTRY471, i, pBuffer) ) { 52576af099aSliuyi if (m_pLog) { 52676af099aSliuyi m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->GetEntry471Data failed,index(%d)", m_layerName, i); 52776af099aSliuyi } 52876af099aSliuyi delete []pBuffer; 52976af099aSliuyi return -3; 53076af099aSliuyi } 53176af099aSliuyi if ( !Boot_VendorRequest(0x0471,pBuffer,dwSize) ) { 53276af099aSliuyi if (m_pLog) { 53376af099aSliuyi m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->Boot_VendorRequest471 failed,index(%d)", m_layerName, i); 53476af099aSliuyi } 53576af099aSliuyi delete []pBuffer; 53676af099aSliuyi return -4; 53776af099aSliuyi } 53876af099aSliuyi delete []pBuffer; 53976af099aSliuyi pBuffer = NULL; 54076af099aSliuyi if (dwDelay>0) { 54176af099aSliuyi usleep(dwDelay * 1000); 54276af099aSliuyi } 54376af099aSliuyi 54476af099aSliuyi } 54576af099aSliuyi } 54676af099aSliuyi 54776af099aSliuyi for ( i=0; i < m_pImage->m_bootObject->Entry472Count; i++ ) { 54876af099aSliuyi if ( !m_pImage->m_bootObject->GetEntryProperty(ENTRY472, i, dwSize, dwDelay) ) { 54976af099aSliuyi if (m_pLog) { 55076af099aSliuyi m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->GetEntry472Property failed,index(%d)", m_layerName, i); 55176af099aSliuyi } 55276af099aSliuyi return -2; 55376af099aSliuyi } 55476af099aSliuyi if (dwSize > 0) { 55576af099aSliuyi pBuffer = new BYTE[dwSize]; 55676af099aSliuyi if ( !m_pImage->m_bootObject->GetEntryData(ENTRY472, i, pBuffer) ) { 55776af099aSliuyi if (m_pLog) { 55876af099aSliuyi m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->GetEntry472Data failed,index(%d)", m_layerName, i); 55976af099aSliuyi } 56076af099aSliuyi delete []pBuffer; 56176af099aSliuyi return -3; 56276af099aSliuyi } 56376af099aSliuyi if ( !Boot_VendorRequest(0x0472, pBuffer, dwSize) ) { 56476af099aSliuyi if (m_pLog) { 56576af099aSliuyi m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->Boot_VendorRequest472 failed,index(%d)", m_layerName, i); 56676af099aSliuyi } 56776af099aSliuyi delete []pBuffer; 56876af099aSliuyi return -4; 56976af099aSliuyi } 57076af099aSliuyi delete []pBuffer; 57176af099aSliuyi pBuffer = NULL; 57276af099aSliuyi if (dwDelay > 0) { 57376af099aSliuyi usleep(dwDelay * 1000); 57476af099aSliuyi } 57576af099aSliuyi } 57676af099aSliuyi } 57776af099aSliuyi sleep(1); 57876af099aSliuyi return 0; 57976af099aSliuyi 58076af099aSliuyi } 58176af099aSliuyi bool CRKDevice::Boot_VendorRequest( DWORD requestCode, PBYTE pBuffer, DWORD dwDataSize) 58276af099aSliuyi { 58376af099aSliuyi int iRet; 58476af099aSliuyi iRet = m_pComm->RKU_DeviceRequest(requestCode, pBuffer, dwDataSize); 58576af099aSliuyi return (iRet == ERR_SUCCESS) ? true : false; 58676af099aSliuyi } 58776af099aSliuyi int CRKDevice::EraseAllBlocks() 58876af099aSliuyi { 58976af099aSliuyi int i; 59076af099aSliuyi UINT uiBlockCount; 59176af099aSliuyi int iRet = ERR_SUCCESS, iErasePos = 0, iEraseBlockNum = 0, iEraseTimes = 0, iCSIndex = 0; 59276af099aSliuyi BYTE bCSCount = 0; 59376af099aSliuyi for (i = 0; i < 8; i++) { 59476af099aSliuyi if ( m_flashInfo.bFlashCS & (1 << i) ) { 59576af099aSliuyi bCSCount++; 59676af099aSliuyi } 59776af099aSliuyi } 598*081d237aSliuyi ReadCapability(); 59976af099aSliuyi DWORD dwLayerID; 60076af099aSliuyi dwLayerID = LocationID; 60176af099aSliuyi ENUM_CALL_STEP emCallStep = CALL_FIRST; 602*081d237aSliuyi if ((m_bEmmc)||(m_bDirectLba)) { 60376af099aSliuyi if (!EraseEmmc()) { 60476af099aSliuyi if (m_pLog) { 60576af099aSliuyi m_pLog->Record("<LAYER %s> ERROR:EraseAllBlocks-->EraseEmmc failed", m_layerName); 60676af099aSliuyi } 60776af099aSliuyi return -1; 60876af099aSliuyi } 60976af099aSliuyi return 0; 61076af099aSliuyi } 61176af099aSliuyi for (i = 0; i < 8; i++) { 61276af099aSliuyi if ( m_flashInfo.bFlashCS & (1 << i) ) { 61376af099aSliuyi uiBlockCount = m_flashInfo.uiBlockNum; 61476af099aSliuyi iErasePos = 0; 61576af099aSliuyi iEraseTimes = 0; 61676af099aSliuyi while (uiBlockCount > 0) { 61776af099aSliuyi iEraseBlockNum = (uiBlockCount < MAX_ERASE_BLOCKS) ? uiBlockCount : MAX_ERASE_BLOCKS; 61876af099aSliuyi iRet = m_pComm->RKU_EraseBlock(i, iErasePos, iEraseBlockNum, ERASE_FORCE); 61976af099aSliuyi if ((iRet != ERR_SUCCESS) && (iRet != ERR_FOUND_BAD_BLOCK)) { 62076af099aSliuyi if (m_pLog) { 62176af099aSliuyi m_pLog->Record("<LAYER %s> ERROR:EraseAllBlocks-->RKU_EraseBlock failed,RetCode(%d)", m_layerName, iRet); 62276af099aSliuyi } 62376af099aSliuyi return -1; 62476af099aSliuyi } 62576af099aSliuyi iErasePos += iEraseBlockNum; 62676af099aSliuyi uiBlockCount -= iEraseBlockNum; 62776af099aSliuyi iEraseTimes++; 62876af099aSliuyi if (iEraseTimes % 8 == 0) { 62976af099aSliuyi if (m_callBackProc) { 63076af099aSliuyi m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, m_flashInfo.uiBlockNum * bCSCount, iCSIndex * m_flashInfo.uiBlockNum + iErasePos, emCallStep); 63176af099aSliuyi emCallStep = CALL_MIDDLE; 63276af099aSliuyi } 63376af099aSliuyi } 63476af099aSliuyi } 63576af099aSliuyi iCSIndex++; 63676af099aSliuyi } 63776af099aSliuyi } 63876af099aSliuyi 63976af099aSliuyi if (m_callBackProc) { 64076af099aSliuyi emCallStep = CALL_LAST; 64176af099aSliuyi m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, m_flashInfo.uiBlockNum * bCSCount, iCSIndex * m_flashInfo.uiBlockNum, emCallStep); 64276af099aSliuyi } 64376af099aSliuyi return 0; 64476af099aSliuyi } 645*081d237aSliuyi bool CRKDevice::ReadCapability() 646*081d237aSliuyi { 647*081d237aSliuyi int ret; 648*081d237aSliuyi BYTE data[8]; 649*081d237aSliuyi ret = m_pComm->RKU_ReadCapability(data); 650*081d237aSliuyi if (ret != ERR_SUCCESS) 651*081d237aSliuyi { 652*081d237aSliuyi if (m_pLog) 653*081d237aSliuyi { 654*081d237aSliuyi m_pLog->Record("ERROR:ReadCapability-->RKU_ReadCapability failed,err(%d)", ret); 655*081d237aSliuyi } 656*081d237aSliuyi return false; 657*081d237aSliuyi } 658*081d237aSliuyi if (data[0] & 0x1) 659*081d237aSliuyi { 660*081d237aSliuyi m_bDirectLba = true; 661*081d237aSliuyi } 662*081d237aSliuyi else 663*081d237aSliuyi m_bDirectLba = false; 664*081d237aSliuyi if (data[0] & 0x4) 665*081d237aSliuyi { 666*081d237aSliuyi m_bFirst4mAccess = true; 667*081d237aSliuyi } 668*081d237aSliuyi else 669*081d237aSliuyi m_bFirst4mAccess = false; 670*081d237aSliuyi return true; 671*081d237aSliuyi } 672*081d237aSliuyi 67376af099aSliuyi 674