📄 fmd.cpp
字号:
{
RETAILMSG(1, (TEXT("FMD:FMD_EraseBlock:This error block=%d!!\r\n"),blockID));
}
// RETAILMSG(1, (TEXT("FMD:FMD_EraseBlock:This block=%d!!\r\n"),blockID));
/*added 20080414 end*/
if(g_pNandFlashChip)
{
Return_Status = g_pNandFlashChip->pEraseBlock(blockID);
return Return_Status;
}
return FALSE;
}
/*
@func BOOL | FMD_WriteSector | Writes the specified data to the specified NAND flash sector/page.
@rdesc TRUE = Success, FALSE = Failure.
@comm
@xref
*/
BOOL FMD_WriteSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors)
{
/*added by yangrui 20080414*/
BOOL Return_Status=FALSE;
startSectorAddr = startSectorAddr + (NandPartitionInfo.PartitionStartSector);
//Added by Sky Xu to Control Shut down WinCE on Jan 15.2009 - Start
#if 1
PELITE_GLOBALS peliteGlobal=NULL;
peliteGlobal = (PELITE_GLOBALS)(DRIVER_GLOBALS_PHYSICAL_MEMORY_START+ (DWORD)(&((PDRIVER_GLOBALS)0)->elite));
if(FALSE == peliteGlobal->Control_ShutDown_WinCE)
{
RETAILMSG(1, (TEXT("<<<Sky Xu>>>FMD_WriteSector:::Control_ShutDown_WinCE was setted as FALSE!!!\r\n")));
return FALSE;
}
#endif
//Added by Sky Xu to Control Shut down WinCE on Jan 15.2009 - Start
if(startSectorAddr/64 > 2047)
{
RETAILMSG(1, (TEXT("FMD:FMD_WriteSector:This error block=%d!!\r\n"),startSectorAddr/64));
RETAILMSG(1, (TEXT("FMD:FMD_WriteSector:This error SectorAddr=%d!!\r\n"),startSectorAddr));
}
//RETAILMSG(1, (TEXT("FMD:FMD_WriteSector:This SectorAddr=%d!!\r\n"),startSectorAddr));
/*added 20080414 end*/
if(g_pNandFlashChip)
{
Return_Status = g_pNandFlashChip->pWriteSector(startSectorAddr,pSectorBuff,pSectorInfoBuff,dwNumSectors);
return Return_Status;
}
return FALSE;
}
VOID FMD_PowerUp(VOID)
{
}
VOID FMD_PowerDown(VOID)
{
}
BOOL FMD_OEMIoControl(DWORD dwIoControlCode, PBYTE pInBuf, DWORD nInBufSize, PBYTE pOutBuf, DWORD nOutBufSize, PDWORD pBytesReturned)
{
return(TRUE);
}
BOOL FMD_Deinit(PVOID hFMD)
{
// destroy the mutex
if (g_hMutex)
{
CloseHandle(g_hMutex);
}
return(TRUE);
}
/*
@func BOOL | FMD_GetInfo | Provides information on the NAND flash.
@rdesc TRUE = Success, FALSE = Failure.
@comm
@xref
*/
BOOL FMD_GetInfo(PFlashInfo pFlashInfo)
{
RETAILMSG(0, (TEXT("FMD_GetInfo\r\n")));
if (!pFlashInfo)
{
return(FALSE);
}
pFlashInfo->flashType = NAND;
pFlashInfo->wDataBytesPerSector = (WORD)NandPartitionInfo.wDataBytesPerSector;
pFlashInfo->dwNumBlocks = NandPartitionInfo.TotalPartitionBlocks * 1;
pFlashInfo->wSectorsPerBlock = (WORD)NandPartitionInfo.SectorsPerBlock;
pFlashInfo->dwBytesPerBlock = (pFlashInfo->wSectorsPerBlock * pFlashInfo->wDataBytesPerSector);
RETAILMSG(0,(TEXT("FMD_GetInfo:pFlashInfo->dwNumBlocks = %d!!\r\n"),pFlashInfo->dwNumBlocks));
RETAILMSG(0,(TEXT("FMD_GetInfo:pFlashInfo->wSectorsPerBlock = %d!!\r\n"),pFlashInfo->wSectorsPerBlock));
RETAILMSG(0,(TEXT("FMD_GetInfo:the whole sector = %d!!\r\n"),(pFlashInfo->wSectorsPerBlock)*(pFlashInfo->dwNumBlocks)));
return(TRUE);
}
BOOL IsBlockBad(BLOCK_ID blockID)
{
/*added by yangrui 20080414*/
BOOL Return_Status=FALSE;
blockID = blockID + (NandPartitionInfo.PartitionStartBlock);
if(blockID > 2047)
{
RETAILMSG(1, (TEXT("FMD:IsBlockBad:This error block=%d!!\r\n"),blockID));
}
/*added 20080414 end*/
if(g_pNandFlashChip)
{
Return_Status = g_pNandFlashChip->pIsBlockBad(blockID);
return Return_Status;
}
return FALSE;
}
/*
@func DWORD | FMD_GetBlockStatus | Returns the status of the specified block.
@rdesc Block status (see fmd.h).
@comm
@xref
*/
DWORD FMD_GetBlockStatus(BLOCK_ID blockID)
{
SECTOR_ADDR Sector = (blockID * NAND_PAGE_CNT);
SectorInfo SI;
DWORD dwResult = 0;
if (IsBlockBad(blockID))
//20080223 eboot test
return BLOCK_STATUS_BAD;
//dwResult |=BLOCK_STATUS_BAD;
//20080223 by yqx
if (!FMD_ReadSector(Sector, NULL, &SI, 1))
return BLOCK_STATUS_UNKNOWN;
if (!(SI.bOEMReserved & OEM_BLOCK_READONLY))
dwResult |= BLOCK_STATUS_READONLY;
if (!(SI.bOEMReserved & OEM_BLOCK_RESERVED))
dwResult |= BLOCK_STATUS_RESERVED;
return(dwResult);
}
/*
@func BOOL | MarkBlockBad | Marks the specified block as bad.
@rdesc TRUE = Success, FALSE = Failure.
@comm
@xref
*/
static BOOL MarkBlockBad(BLOCK_ID blockID)
{
/*added by yangrui 20080414*/
BOOL Return_Status=FALSE;
blockID = blockID + (NandPartitionInfo.PartitionStartBlock);
if(blockID > 2047)
{
RETAILMSG(1, (TEXT("FMD:IsBlockBad:This error block=%d!!\r\n"),blockID));
}
/*added 20080414 end*/
if(g_pNandFlashChip)
{
Return_Status = g_pNandFlashChip->pMarkBlockBad(blockID);
return Return_Status;
}
return FALSE;
}
/*
@func BOOL | FMD_SetBlockStatus | Marks the block with the specified block status.
@rdesc TRUE = Success, FALSE = Failure.
@comm
@xref
*/
BOOL FMD_SetBlockStatus(BLOCK_ID blockID, DWORD dwStatus)
{
RETAILMSG(1,(TEXT("FMD_SetBlockStatus:block:%d,status:%d \r\n"),blockID,dwStatus));
//Added by Sky Xu to Control Shut down WinCE on Jan 15.2009 - Start
PELITE_GLOBALS peliteGlobal=NULL;
peliteGlobal = (PELITE_GLOBALS)(DRIVER_GLOBALS_PHYSICAL_MEMORY_START+ (DWORD)(&((PDRIVER_GLOBALS)0)->elite));
if(FALSE == peliteGlobal->Control_ShutDown_WinCE)
{
RETAILMSG(0, (TEXT("<<<Sky Xu>>>FMD_SetBlockStatus:::Control_ShutDown_WinCE was setted as FALSE!!!\r\n")));
return FALSE;
}
//Added by Sky Xu to Control Shut down WinCE on Jan 15.2009 - Start
if (dwStatus & BLOCK_STATUS_BAD)
{
if (!MarkBlockBad(blockID))
return(FALSE);
}
if (dwStatus & (BLOCK_STATUS_READONLY | BLOCK_STATUS_RESERVED)) {
SECTOR_ADDR Sector = blockID * NAND_PAGE_CNT;
SectorInfo SI;
if (!FMD_ReadSector(Sector, NULL, &SI, 1)) {
return FALSE;
}
if (dwStatus & BLOCK_STATUS_READONLY) {
SI.bOEMReserved &= ~OEM_BLOCK_READONLY;
}
if (dwStatus & BLOCK_STATUS_RESERVED) {
SI.bOEMReserved &= ~OEM_BLOCK_RESERVED;
}
if (!FMD_WriteSector (Sector, NULL, &SI, 1)) {
return FALSE;
}
}
return(TRUE);
}
BOOL FMD_ReadSector1G08(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors)
{
ULONG SectorAddr = (ULONG)startSectorAddr;
int i;
BOOL bRet = TRUE;
//20080229 ADD ECC 2048
BYTE ECCBuf[4];
BYTE ECCBufN[4];
DWORD ECCRegVal;
BYTE temp;
DWORD ecc_state;
DWORD byteLocation;
DWORD bitLocation;
//20080229 by yqx
// RETAILMSG(1,(TEXT("FMD_ReadSector1G08,startSectorAddr=%d,pSectorBuff=0x%x,pSectorInfoBuff=0x%x,dwNumSectors=%d\r\n"),startSectorAddr,pSectorBuff,pSectorInfoBuff,dwNumSectors));
// EdbgOutputDebugString("FMD_ReadSector1G08(%d,%p,%p,%d)\n",startSectorAddr,pSectorBuff,pSectorInfoBuff,dwNumSectors);
if (!pSectorBuff && !pSectorInfoBuff || dwNumSectors > 1)
{
RETAILMSG(1, (TEXT("Invalid parameters!\n")));
return FALSE;
}
GRABMUTEX(); //we should MUTEX first
NF_nFCE_L(); // Select the flash chip.
NF_WAITRnB();
//delete at 20080919
// NF_CLEAR_RB();
// NF_CMD(CMD_RESET); // Send reset command.
// for(i=0;i<10;i++);
// NF_DETECT_RB();
//delete at 20080919
ULONG blockPage = SectorAddr;//(((SectorAddr / NAND_PAGE_CNT) * NAND_PAGE_CNT) | (SectorAddr % NAND_PAGE_CNT));
if(pSectorBuff)
{
//20080229 ADD 2048 BYTE ECC
NF_RSTECC(); // Initialize ECC.
NF_MECC_UnLock();
//20080229 by yqx
NF_CLEAR_RB();
NF_CMD(CMD_READ); // Send read command.
NF_ADDR(0); // Column (A[7:0]) = 0
NF_ADDR(0); // A[11:8]
NF_ADDR((blockPage)&0xff); // A[19:12]
NF_ADDR((blockPage>>8)&0xff); // A[27:20]
#if (K9F2G08_SUPPORT||K9F4G08_SUPPORT||K9F8G08_SUPPORT)
if((g_pNandFlashChip->FlashID!=0xECF1)&&(g_pNandFlashChip->FlashID!=0xECA1))
NF_ADDR((blockPage>>16)&0xff);
#endif
NF_CLEAR_RB();
NF_CMD(0x30); // 2'nd command
NF_DETECT_RB();
if((DWORD) pSectorBuff&0x3)
{
RdPage2048Unalign (pSectorBuff,(PULONG)&s2440NAND->rNFDATA);
}
else
{
#if (TRANS_MODE == C_LANG)
RdPage2048(pSectorBuff,(PULONG)&s2440NAND->rNFDATA); // Read page/sector data.
#elif (TRANS_MODE == DMA)
// Nand to memory dma setting
s2440INT->rSRCPND=BIT_DMA0; // Init DMA src pending.
s2440DMAregs->rDISRC0=(unsigned int)NFDATA; // Nand flash data register
s2440DMAregs->rDISRCC0=(0<<1) | (1<<0); //arc=AHB,src_addr=fix
s2440DMAregs->rDIDST0=(unsigned int)pPhyDMAbuffer;
s2440DMAregs->rDIDSTC0=(0<<1) | (0<<0); //dst=AHB,dst_addr=inc;
s2440DMAregs->rDCON0=(1<<31)|(1<<30)|(1<<29)|(1<<28)|(1<<27)|(0<<23)|(1<<22)|(2<<20)|(2048/4/4);
//Handshake,AHB,interrupt,(4-burst),whole,S/W,no_autoreload,word,count=128;
// DMA on and start.
s2440DMAregs->rDMASKTRIG0=(1<<1)|(1<<0);
while(!((s2440INT->rSRCPND) & BIT_DMA0)); // Wait until Dma transfer is done.
s2440INT->rSRCPND=BIT_DMA0;
memcpy(pSectorBuff, pVirDMAbuf, 2048);
#endif
}
//20080229 add 2048 byte ecc
NF_MECC_Lock();
ECCRegVal=NF_ECC();
//RETAILMSG(1,(TEXT("FMD_ReadSector1G08(11startSectorAddr %d) ECCNEW =0x%x\r\n"),startSectorAddr,ECCRegVal));
ECCBufN[0]= (BYTE)(ECCRegVal &0xff);
ECCBufN[1]= (BYTE)((ECCRegVal>>8) &0xff);
ECCBufN[2]= (BYTE)((ECCRegVal>>16) &0xff);
ECCBufN[3]= (BYTE)((ECCRegVal>>24) &0xff);
//20080229 BY YQx
}//end if pSectorBuff
if(pSectorInfoBuff)
{
if(!pSectorBuff)
{
NF_CLEAR_RB();
NF_CMD(0x00); // Read command
NF_ADDR((2048+0)&0xff); // 2060 = 0x080c
NF_ADDR(((2048+0)>>8)&0xff);
NF_ADDR((blockPage)&0xff); // A[19:12]
NF_ADDR((blockPage>>8)&0xff); // A[27:20]
#if (K9F2G08_SUPPORT||K9F4G08_SUPPORT||K9F8G08_SUPPORT)
if((g_pNandFlashChip->FlashID!=0xECF1)&&(g_pNandFlashChip->FlashID!=0xECA1))
NF_ADDR((blockPage>>16)&0xff);
#endif
NF_CLEAR_RB();
NF_CMD(0x30); // 2'nd command
NF_DETECT_RB();
}//end if (!pSectorBuff)
// Read the bad block mark
pSectorInfoBuff->bBadBlock = (BYTE) NF_RDDATA();
// Read the SectorInfo data (we only need to read first 8 bytes)
pSectorInfoBuff->dwReserved1 = NF_DATA_R4();
// OEM byte
pSectorInfoBuff->bOEMReserved = (BYTE) NF_RDDATA();
// Second reserved field (WORD)
pSectorInfoBuff->wReserved2 = ((BYTE) NF_RDDATA() << 8);
pSectorInfoBuff->wReserved2 |= ((BYTE) NF_RDDATA());
}//end if(pSectorInfoBuff)
//20080229 ADD 2048 BYTE ECC
else
{
for(i=0; i<sizeof(SectorInfo); i++)
{
temp = (BYTE)NF_RDDATA();
}
}//end else
if (pSectorBuff)
{
//Verify the ECC values
// Read the ECC buffer
for(i=0; i<4; i++)
{
ECCBuf[i] = (BYTE) NF_RDDATA();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -