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
SetVendorID(USHORT value)2276af099aSliuyi void CRKDevice::SetVendorID(USHORT value)
2376af099aSliuyi {
2476af099aSliuyi m_vid = value;
2576af099aSliuyi }
SetProductID(USHORT value)2676af099aSliuyi void CRKDevice::SetProductID(USHORT value)
2776af099aSliuyi {
2876af099aSliuyi m_pid = value;
2976af099aSliuyi }
SetDeviceType(ENUM_RKDEVICE_TYPE value)3076af099aSliuyi void CRKDevice::SetDeviceType(ENUM_RKDEVICE_TYPE value)
3176af099aSliuyi {
3276af099aSliuyi m_device = value;
3376af099aSliuyi }
SetOsType(ENUM_OS_TYPE value)3476af099aSliuyi void CRKDevice::SetOsType(ENUM_OS_TYPE value)
3576af099aSliuyi {
3676af099aSliuyi m_os = value;
3776af099aSliuyi }
3876af099aSliuyi
SetUsbType(ENUM_RKUSB_TYPE value)3976af099aSliuyi void CRKDevice::SetUsbType(ENUM_RKUSB_TYPE value)
4076af099aSliuyi {
4176af099aSliuyi m_usb = value;
4276af099aSliuyi }
SetBcdUsb(USHORT value)4376af099aSliuyi void CRKDevice::SetBcdUsb(USHORT value)
4476af099aSliuyi {
4576af099aSliuyi m_bcdUsb = value;
4676af099aSliuyi }
SetLayerName(char * value)4776af099aSliuyi void CRKDevice::SetLayerName(char *value)
4876af099aSliuyi {
4976af099aSliuyi strcpy(m_layerName,value);
5076af099aSliuyi }
SetLocationID(DWORD value)5176af099aSliuyi void CRKDevice::SetLocationID(DWORD value)
5276af099aSliuyi {
5376af099aSliuyi m_locationID = value;
5476af099aSliuyi }
5576af099aSliuyi
SetCallBackPointer(ProgressPromptCB value)5676af099aSliuyi void CRKDevice::SetCallBackPointer(ProgressPromptCB value)
5776af099aSliuyi {
5876af099aSliuyi if (value)
5976af099aSliuyi {
6076af099aSliuyi m_callBackProc = value;
6176af099aSliuyi }
6276af099aSliuyi }
GetLogObjectPointer()6376af099aSliuyi CRKLog* CRKDevice::GetLogObjectPointer()
6476af099aSliuyi {
6576af099aSliuyi return m_pLog;
6676af099aSliuyi }
6776af099aSliuyi
GetCommObjectPointer()6876af099aSliuyi CRKComm* CRKDevice::GetCommObjectPointer()
6976af099aSliuyi {
7076af099aSliuyi return m_pComm;
7176af099aSliuyi }
7276af099aSliuyi
GetVendorID()7376af099aSliuyi USHORT CRKDevice::GetVendorID()
7476af099aSliuyi {
7576af099aSliuyi return m_vid;
7676af099aSliuyi }
GetProductID()7776af099aSliuyi USHORT CRKDevice::GetProductID()
7876af099aSliuyi {
7976af099aSliuyi return m_pid;
8076af099aSliuyi }
GetDeviceType()8176af099aSliuyi ENUM_RKDEVICE_TYPE CRKDevice::GetDeviceType()
8276af099aSliuyi {
8376af099aSliuyi return m_device;
8476af099aSliuyi }
GetOsType()8576af099aSliuyi ENUM_OS_TYPE CRKDevice::GetOsType()
8676af099aSliuyi {
8776af099aSliuyi return m_os;
8876af099aSliuyi }
8976af099aSliuyi
GetUsbType()9076af099aSliuyi ENUM_RKUSB_TYPE CRKDevice::GetUsbType()
9176af099aSliuyi {
9276af099aSliuyi return m_usb;
9376af099aSliuyi }
9476af099aSliuyi
GetBcdUsb()9576af099aSliuyi USHORT CRKDevice::GetBcdUsb()
9676af099aSliuyi {
9776af099aSliuyi return m_bcdUsb;
9876af099aSliuyi }
GetLocationID()9976af099aSliuyi DWORD CRKDevice::GetLocationID()
10076af099aSliuyi {
10176af099aSliuyi return m_locationID;
10276af099aSliuyi }
GetLayerName()10376af099aSliuyi char* CRKDevice::GetLayerName()
10476af099aSliuyi {
10576af099aSliuyi return m_layerName;
10676af099aSliuyi }
10776af099aSliuyi
GetLayerString(UINT dwLocationID)10821b25fd4SDave Murphy string CRKDevice::GetLayerString(UINT dwLocationID)
10976af099aSliuyi {
11076af099aSliuyi char szLocation[32] = "\0";
111*1831c99cSQuang Dang snprintf(szLocation, sizeof(szLocation), "%d-%d", dwLocationID >> 8, dwLocationID & 0xff);
11276af099aSliuyi return szLocation;
11376af099aSliuyi }
11476af099aSliuyi
CRKDevice(STRUCT_RKDEVICE_DESC & device)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;
178081d237aSliuyi m_bDirectLba = false;
179081d237aSliuyi m_bFirst4mAccess = false;
18076af099aSliuyi }
~CRKDevice()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 }
SetObject(CRKImage * pImage,CRKComm * pComm,CRKLog * pLog)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 }
EraseEmmcBlock(UCHAR ucFlashCS,DWORD dwPos,DWORD dwCount)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 }
EraseEmmcByWriteLBA(DWORD dwSectorPos,DWORD dwCount)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 }
EraseEmmc()25176af099aSliuyi bool CRKDevice::EraseEmmc()
25276af099aSliuyi {
253081d237aSliuyi UINT uiCount,uiEraseCount,uiSectorOffset,uiTotalCount;
254081d237aSliuyi UINT uiErase=1024*32;
25576af099aSliuyi int iRet=ERR_SUCCESS,iLoopTimes=0;
256081d237aSliuyi uiTotalCount = uiCount = m_flashInfo.uiFlashSize*2*1024;
257081d237aSliuyi uiSectorOffset = 0;
25876af099aSliuyi DWORD dwLayerID;
25976af099aSliuyi dwLayerID = m_locationID;
26076af099aSliuyi ENUM_CALL_STEP emCallStep = CALL_FIRST;
261081d237aSliuyi
262081d237aSliuyi while (uiCount)
263081d237aSliuyi {
264081d237aSliuyi if (uiCount >= uiErase)
265081d237aSliuyi {
266081d237aSliuyi uiEraseCount = uiErase;
267081d237aSliuyi }
268081d237aSliuyi else
269081d237aSliuyi uiEraseCount = uiCount;
270081d237aSliuyi iRet = m_pComm->RKU_EraseLBA(uiSectorOffset, uiEraseCount);
271081d237aSliuyi
27276af099aSliuyi if (iRet != ERR_SUCCESS) {
27376af099aSliuyi if (m_pLog) {
274081d237aSliuyi m_pLog->Record("ERROR:EraseEmmc-->RKU_EraseLBA failed,RetCode(%d),offset=0x%x,count=0x%x",iRet, uiSectorOffset, uiEraseCount);
27576af099aSliuyi }
27676af099aSliuyi return false;
27776af099aSliuyi }
278081d237aSliuyi uiCount -= uiEraseCount;
279081d237aSliuyi uiSectorOffset += uiEraseCount;
28076af099aSliuyi iLoopTimes++;
28176af099aSliuyi if (iLoopTimes % 8 == 0) {
28276af099aSliuyi if (m_callBackProc) {
283081d237aSliuyi m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, uiTotalCount, uiSectorOffset, emCallStep);
28476af099aSliuyi emCallStep = CALL_MIDDLE;
28576af099aSliuyi }
28676af099aSliuyi }
28776af099aSliuyi }
28876af099aSliuyi if (m_callBackProc) {
28976af099aSliuyi emCallStep = CALL_LAST;
290081d237aSliuyi m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, uiTotalCount, uiTotalCount, emCallStep);
29176af099aSliuyi }
29276af099aSliuyi return true;
29376af099aSliuyi }
GetFlashInfo()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 }
TestDevice()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 }
ResetDevice()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
PowerOffDevice()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 }
CheckChip()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
DownloadBoot()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 }
Boot_VendorRequest(DWORD requestCode,PBYTE pBuffer,DWORD dwDataSize)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 }
EraseAllBlocks(bool force_block_erase)587e541b7bbSliuyi int CRKDevice::EraseAllBlocks(bool force_block_erase)
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 }
598081d237aSliuyi ReadCapability();
59976af099aSliuyi DWORD dwLayerID;
60076af099aSliuyi dwLayerID = LocationID;
60176af099aSliuyi ENUM_CALL_STEP emCallStep = CALL_FIRST;
602e541b7bbSliuyi if (!force_block_erase) {
603081d237aSliuyi if ((m_bEmmc)||(m_bDirectLba)) {
60476af099aSliuyi if (!EraseEmmc()) {
60576af099aSliuyi if (m_pLog) {
60676af099aSliuyi m_pLog->Record("<LAYER %s> ERROR:EraseAllBlocks-->EraseEmmc failed", m_layerName);
60776af099aSliuyi }
60876af099aSliuyi return -1;
60976af099aSliuyi }
61076af099aSliuyi return 0;
61176af099aSliuyi }
612e541b7bbSliuyi }
61376af099aSliuyi for (i = 0; i < 8; i++) {
61476af099aSliuyi if ( m_flashInfo.bFlashCS & (1 << i) ) {
61576af099aSliuyi uiBlockCount = m_flashInfo.uiBlockNum;
61676af099aSliuyi iErasePos = 0;
61776af099aSliuyi iEraseTimes = 0;
61876af099aSliuyi while (uiBlockCount > 0) {
61976af099aSliuyi iEraseBlockNum = (uiBlockCount < MAX_ERASE_BLOCKS) ? uiBlockCount : MAX_ERASE_BLOCKS;
62076af099aSliuyi iRet = m_pComm->RKU_EraseBlock(i, iErasePos, iEraseBlockNum, ERASE_FORCE);
62176af099aSliuyi if ((iRet != ERR_SUCCESS) && (iRet != ERR_FOUND_BAD_BLOCK)) {
62276af099aSliuyi if (m_pLog) {
62376af099aSliuyi m_pLog->Record("<LAYER %s> ERROR:EraseAllBlocks-->RKU_EraseBlock failed,RetCode(%d)", m_layerName, iRet);
62476af099aSliuyi }
62576af099aSliuyi return -1;
62676af099aSliuyi }
62776af099aSliuyi iErasePos += iEraseBlockNum;
62876af099aSliuyi uiBlockCount -= iEraseBlockNum;
62976af099aSliuyi iEraseTimes++;
63076af099aSliuyi if (iEraseTimes % 8 == 0) {
63176af099aSliuyi if (m_callBackProc) {
63276af099aSliuyi m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, m_flashInfo.uiBlockNum * bCSCount, iCSIndex * m_flashInfo.uiBlockNum + iErasePos, emCallStep);
63376af099aSliuyi emCallStep = CALL_MIDDLE;
63476af099aSliuyi }
63576af099aSliuyi }
63676af099aSliuyi }
63776af099aSliuyi iCSIndex++;
63876af099aSliuyi }
63976af099aSliuyi }
64076af099aSliuyi
64176af099aSliuyi if (m_callBackProc) {
64276af099aSliuyi emCallStep = CALL_LAST;
64376af099aSliuyi m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, m_flashInfo.uiBlockNum * bCSCount, iCSIndex * m_flashInfo.uiBlockNum, emCallStep);
64476af099aSliuyi }
64576af099aSliuyi return 0;
64676af099aSliuyi }
ReadCapability()647081d237aSliuyi bool CRKDevice::ReadCapability()
648081d237aSliuyi {
649081d237aSliuyi int ret;
650081d237aSliuyi BYTE data[8];
651081d237aSliuyi ret = m_pComm->RKU_ReadCapability(data);
652081d237aSliuyi if (ret != ERR_SUCCESS)
653081d237aSliuyi {
654081d237aSliuyi if (m_pLog)
655081d237aSliuyi {
656081d237aSliuyi m_pLog->Record("ERROR:ReadCapability-->RKU_ReadCapability failed,err(%d)", ret);
657081d237aSliuyi }
658081d237aSliuyi return false;
659081d237aSliuyi }
660081d237aSliuyi if (data[0] & 0x1)
661081d237aSliuyi {
662081d237aSliuyi m_bDirectLba = true;
663081d237aSliuyi }
664081d237aSliuyi else
665081d237aSliuyi m_bDirectLba = false;
666081d237aSliuyi if (data[0] & 0x4)
667081d237aSliuyi {
668081d237aSliuyi m_bFirst4mAccess = true;
669081d237aSliuyi }
670081d237aSliuyi else
671081d237aSliuyi m_bFirst4mAccess = false;
672081d237aSliuyi return true;
673081d237aSliuyi }
674081d237aSliuyi
67576af099aSliuyi
676