📄 fmd.cpp
字号:
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: FMD_EraseBlock()
Description: Erases the specified Flash block.
Parameters: blockID [in]
The block number to erase.
Return Values: A boolean indicating function result.
TRUE on success.
FALSE on failure.
Remarks: The upper layer passes to this routine the system block value
based on what was reported in FMD_GetInfo(); however, owing to
the implementation of the Flash array physical layout this block
may be comprised of more than one physical block. This routine
determines the nature of the underlying physical layout and
translates the erase block to multiple erase commands when
necessary.
-------------------------------------------------------------------------------*/
BOOL FMD_EraseBlock(BLOCK_ID blockID)
{
PREFAST_ASSERT(s_pFmd);
return s_pFmd->EraseBlock(blockID);
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: FMD_ReadSector()
Description: This function reads the requested sector data and/or metadata
from the Flash media.
Parameters: nSectorAddr [in]
The starting physical sector address to read.
pSectorBufr [out]
Pointer to the buffer that contains the sector data read
from Flash memory. Set to NULL if this data is not needed.
pSectorInfoBuff [out]
Buffer for an array of sector information structures. There
is one sector information entry for every sector that is to
be read. Set to NULL if this data is not needed.
dwNumSectors [in]
Number of sectors to read.
Return Values: A boolean indicating function result.
TRUE on success.
FALSE on failure.
Remarks: Notice that although each byte of a NOR Flash block is
individually addressable, the media is still logically broken
up into sectors. Thus, for each sector request, we must
determine where this data resides in the respective Flash block
(see note above).
By default, the NOR Flash is configured in READ ARRAY MODE so
there is no need to set any control lines to access the media.
The data can just be read directly from the media (like RAM).
-------------------------------------------------------------------------------*/
BOOL FMD_ReadSector (SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors)
{
PREFAST_ASSERT(s_pFmd);
return s_pFmd->ReadSector(startSectorAddr, pSectorBuff, pSectorInfoBuff, dwNumSectors);
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: FMD_WriteSector()
Description: Writes the requested sector data and/or sector metadata to the
Flash media.
Parameters: nSectorAddr [in]
The starting physical sector address to write to.
pSectorBufr [in]
Pointer to the buffer that contains the sector data to
write. Set to NULL if no data is to be written.
pSectorInfoBuff [in]
Buffer for an array of sector information structures. There
must be one sector information entry for each sector that
is to be written. Set to NULL if this data is not written.
dwNumSectors [in]
Number of sectors to write.
Notes: Notice that although each byte of a NOR Flash block is
individually addressable, the media is still logically broken up
into sectors. Thus, for each sector request, we must determine
where to put the data in each respective Flash block (see note
above).
By default, the NOR Flash is configured in READ ARRAY MODE we
need to set some control lines to prepare for the WRITE
operation.
Return Values: Returns TRUE on success.
Returns FALSE on failure.
-------------------------------------------------------------------------------*/
BOOL FMD_WriteSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors)
{
PREFAST_ASSERT(s_pFmd);
return s_pFmd->WriteSector(startSectorAddr, pSectorBuff, pSectorInfoBuff, dwNumSectors);
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: FMD_PowerUp()
Description: Restores power to the Flash memory device (if applicable).
-------------------------------------------------------------------------------*/
VOID FMD_PowerUp(VOID)
{
PREFAST_ASSERT(s_pFmd);
s_pFmd->PowerUp();
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: FMD_PowerDown()
Description: Suspends power to the Flash memory device (if applicable).
-------------------------------------------------------------------------------*/
VOID FMD_PowerDown(VOID)
{
PREFAST_ASSERT(s_pFmd);
s_pFmd->PowerDown();
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: FMD_OEMIoControl()
Description: Implements user-defined (a.k.a. application specific) commands
for the Flash memory device
Returns: None.
-------------------------------------------------------------------------------*/
BOOL FMD_OEMIoControl(DWORD dwIoControlCode, PBYTE pInBuf, DWORD nInBufSize,
PBYTE pOutBuf, DWORD nOutBufSize, PDWORD pBytesReturned)
{
PREFAST_ASSERT(s_pFmd);
return s_pFmd->OEMIoControl(dwIoControlCode, pInBuf, nInBufSize, pOutBuf, nOutBufSize, pBytesReturned);
}
BOOL CFmd::OEMIoControl(DWORD dwIoControlCode, PBYTE pInBuf, DWORD nInBufSize,
PBYTE pOutBuf, DWORD nOutBufSize, PDWORD pBytesReturned)
{
BOOL fRet = TRUE;
switch(dwIoControlCode) {
case IOCTL_FMD_GET_INTERFACE:
{
if (!pOutBuf || nOutBufSize < sizeof(FMDInterface))
{
DEBUGMSG(ZONE_ERROR, (TEXT("FMD_OEMIoControl: IOCTL_FMD_GET_INTERFACE bad parameter(s).\r\n")));
return(FALSE);
}
PFMDInterface pInterface = (PFMDInterface)pOutBuf;
pInterface->cbSize = sizeof(FMDInterface);
pInterface->pInit = FMD_Init;
pInterface->pDeInit = FMD_Deinit;
pInterface->pGetInfo = FMD_GetInfo;
pInterface->pGetInfoEx = FMD_GetInfoEx;
pInterface->pGetBlockStatus = FMD_GetBlockStatus;
pInterface->pSetBlockStatus = FMD_SetBlockStatus;
pInterface->pReadSector = FMD_ReadSector;
pInterface->pWriteSector = FMD_WriteSector;
pInterface->pEraseBlock = FMD_EraseBlock;
pInterface->pPowerUp = FMD_PowerUp;
pInterface->pPowerDown = FMD_PowerDown;
pInterface->pGetPhysSectorAddr = FMD_GetPhysSectorAddr;
break;
}
default:
fRet = FALSE;
}
return fRet;
}
BOOL CNorFmd::OEMIoControl(DWORD dwIoControlCode, PBYTE pInBuf, DWORD nInBufSize,
PBYTE pOutBuf, DWORD nOutBufSize, PDWORD pBytesReturned)
{
DEBUGMSG(ZONE_INIT, (TEXT("FMD_OEMIoControl(0x%x, 0x%x, %u, 0x%x %u, 0x%x)\r\n"), dwIoControlCode, pInBuf, nInBufSize,
pOutBuf, nOutBufSize, pBytesReturned));
switch(dwIoControlCode) {
case IOCTL_FMD_SET_XIPMODE:
// Select between XIP mode or non-XIP mode. The difference from the FMD's standpoint is whether or not
// sector information is stored along with each sector.
if (!pInBuf || nInBufSize < sizeof(BOOLEAN))
{
DEBUGMSG(ZONE_ERROR, (TEXT("FMD_OEMIoControl: IOCTL_FMD_SET_XIPMODE bad parameter(s).\r\n")));
return(FALSE);
}
m_fXIPEntire = *(PBOOL)pInBuf;
break;
case IOCTL_FMD_GET_XIPMODE:
if (!pOutBuf || nOutBufSize < sizeof(BOOLEAN))
{
DEBUGMSG(ZONE_ERROR, (TEXT("FMD_OEMIoControl: IOCTL_FMD_GET_XIPMODE bad parameter(s).\r\n")));
return(FALSE);
}
*(PBOOL)pOutBuf = m_fXIPEntire;
break;
case IOCTL_FMD_LOCK_BLOCKS:
// Lock one of more blocks in a specified range.
if (!pInBuf || nInBufSize < sizeof(BlockLockInfo))
{
DEBUGMSG(ZONE_ERROR, (TEXT("FMD_OEMIoControl: IOCTL_FMD_LOCK_BLOCKS bad parameter(s).\r\n")));
return(FALSE);
}
if (!SetBlockLock(((PBlockLockInfo)pInBuf)->StartBlock, ((PBlockLockInfo)pInBuf)->NumBlocks, TRUE))
{
DEBUGMSG(ZONE_ERROR, (TEXT("FMD_OEMIoControl: IOCTL_FMD_LOCK_BLOCKS failed to lock blocks (start=0x%x, number=0x%x).\r\n"), ((PBlockLockInfo)pInBuf)->StartBlock, ((PBlockLockInfo)pInBuf)->NumBlocks));
return(FALSE);
}
break;
case IOCTL_FMD_UNLOCK_BLOCKS:
// Unlock one of more blocks in a specified range.
if (!pInBuf || nInBufSize < sizeof(BlockLockInfo))
{
DEBUGMSG(ZONE_ERROR, (TEXT("FMD_OEMIoControl: IOCTL_FMD_UNLOCK_BLOCKS bad parameter(s).\r\n")));
return(FALSE);
}
if (!SetBlockLock(((PBlockLockInfo)pInBuf)->StartBlock, ((PBlockLockInfo)pInBuf)->NumBlocks, FALSE))
{
DEBUGMSG(ZONE_ERROR, (TEXT("FMD_OEMIoControl: IOCTL_FMD_UNLOCK_BLOCKS failed to unlock blocks (start=0x%x, number=0x%x).\r\n"), ((PBlockLockInfo)pInBuf)->StartBlock, ((PBlockLockInfo)pInBuf)->NumBlocks));
return(FALSE);
}
break;
case IOCTL_FMD_READ_RESERVED:
// Read from a specified reserved region.
if (!pInBuf || nInBufSize < sizeof(ReservedReq))
{
DEBUGMSG(ZONE_ERROR, (TEXT("FMD_OEMIoControl: IOCTL_FMD_READ_RESERVED bad parameter(s).\r\n")));
return(FALSE);
}
return ReadWriteReserved ((PReservedReq)pInBuf, TRUE);
break;
case IOCTL_FMD_WRITE_RESERVED:
// Write to a specified reserved region.
if (!pInBuf || nInBufSize < sizeof(ReservedReq))
{
DEBUGMSG(ZONE_ERROR, (TEXT("FMD_OEMIoControl: IOCTL_FMD_READ_RESERVED bad parameter(s).\r\n")));
return(FALSE);
}
return ReadWriteReserved ((PReservedReq)pInBuf, FALSE);
break;
case IOCTL_FMD_GET_RESERVED_TABLE:
// Get the reserved table.
if (!pOutBuf)
{
// If no buffer is provided, return the required size.
if (pBytesReturned)
*pBytesReturned = m_cReserved * sizeof(ReservedEntry);
return TRUE;
}
else
{
DWORD dwTableSize = m_cReserved * sizeof(ReservedEntry);
if (nOutBufSize < dwTableSize)
{
if (pBytesReturned)
*pBytesReturned = 0;
return FALSE;
}
else
{
if (pBytesReturned)
*pBytesReturned = dwTableSize;
if (m_pReservedTable)
memcpy (pOutBuf, m_pReservedTable, dwTableSize);
return TRUE;
}
}
break;
case IOCTL_FMD_SET_SECTORSIZE:
if (!pInBuf || nInBufSize < sizeof(DWORD))
{
DEBUGMSG(ZONE_ERROR, (TEXT("FMD_OEMIoControl: IOCTL_FMD_SET_SECTORSIZE bad parameter(s).\r\n")));
return(FALSE);
}
m_cbSector = *(LPDWORD)pInBuf;
break;
case IOCTL_FMD_RAW_WRITE_BLOCKS:
if (!pInBuf || nInBufSize < sizeof(RawWriteBlocksReq))
{
DEBUGMSG(ZONE_ERROR, (TEXT("FMD_OEMIoControl: IOCTL_FMD_RAW_WRITE_BLOCKS bad parameter(s).\r\n")));
return(FALSE);
}
return RawWriteBlocks ((PRawWriteBlocksReq)pInBuf);
case IOCTL_FMD_GET_RAW_BLOCK_SIZE:
if (!pOutBuf || nOutBufSize < sizeof(DWORD))
{
DEBUGMSG(ZONE_ERROR, (TEXT("FMD_OEMIoControl: IOCTL_FMD_GET_RAW_BLOCK_SIZE bad parameter(s).\r\n")));
return(FALSE);
}
*((PDWORD)pOutBuf) = m_cbBlock;
return TRUE;
case IOCTL_FMD_GET_INFO:
if (!pOutBuf || nOutBufSize < sizeof(FMDInfo))
{
DEBUGMSG(ZONE_ERROR, (TEXT("FMD_OEMIoControl: IOCTL_FMD_GET_INFO bad parameter(s).\r\n")));
return(FALSE);
}
else
{
PFMDInfo pInfo = (PFMDInfo)pOutBuf;
pInfo->flashType = NOR;
pInfo->dwBaseAddress = m_dwBaseAddr;
pInfo->dwNumRegions = m_cRegions;
pInfo->dwNumReserved = m_cReserved;
}
return TRUE;
default:
DEBUGMSG(ZONE_INIT, (TEXT("FMD_OEMIoControl: unrecognized IOCTL (0x%x).\r\n"), dwIoControlCode));
return CFmd::OEMIoControl(dwIoControlCode, pInBuf, nInBufSize, pOutBuf, nOutBufSize, pBytesReturned);
}
return(TRUE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -