📄 fmd.cpp
字号:
// Returns:
// TRUE/FALSE for success
//
//-----------------------------------------------------------------------------
BOOL FMD_Deinit(PVOID hFMD)
{
BOOL bLastMode;
DEBUGMSG(ZONE_FUNCTION, (TEXT("FMD_Deinit+\r\n")));
bLastMode = SetKMode(TRUE);
if(g_pNORFlashBase)
MmUnmapIoSpace(g_pNORFlashBase, 0);
if(g_pAlignBuf)
LocalFree(g_pAlignBuf);
SetKMode(bLastMode);
DEBUGMSG(ZONE_FUNCTION, (TEXT("FMD_Deinit-\r\n")));
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: FMD_GetInfo
//
// Function Determines the characteristics for the flash device.
//
// Parameters:
// pFlashInfo
// [out] structure to contain characteristics for the flash device.
//
// Returns:
// TRUE/FALSE for success
//
//-----------------------------------------------------------------------------
BOOL FMD_GetInfo(PFlashInfo pFlashInfo)
{
DEBUGMSG(ZONE_FUNCTION, (TEXT("FMD_GetInfo+\r\n")));
if(pFlashInfo)
{
pFlashInfo->flashType = NOR;
pFlashInfo->dwNumBlocks = g_FMDInfo.NumBlocks;
pFlashInfo->wSectorsPerBlock = g_FMDInfo.SectorsPerBlock;
pFlashInfo->wDataBytesPerSector = g_FMDInfo.BytesPerSector;
pFlashInfo->dwBytesPerBlock = g_FMDInfo.BytesPerSector * g_FMDInfo.SectorsPerBlock;
DEBUGMSG(ZONE_INFO, (TEXT("type %s: dwNumBlock %d wSectorsPerBlock %d wDataBytesPerSector %d dwBytesPerBlock %d\r\n"),
(pFlashInfo->flashType == NOR? L"NOR" : L"UNKNOWN"),
pFlashInfo->dwNumBlocks,
pFlashInfo->wSectorsPerBlock,
pFlashInfo->wDataBytesPerSector,
pFlashInfo->dwBytesPerBlock));
return TRUE;
}
else
ERRORMSG(ZONE_ERROR, (TEXT("Invalid flash info pointer!\r\n")));
DEBUGMSG(ZONE_FUNCTION, (TEXT("FMD_GetInfo-\r\n")));
return FALSE;
}
//-----------------------------------------------------------------------------
//
// Function: FMD_ReadSector
//
// Function Reads the requested sector data and metadata from the flash media.
//
// Parameters:
// startSectorAddr
// [in] starting sector address.
//
// pSectorBuff
// [in] Ptr to buffer that contains sector data read from flash.
// Set to NULL if data is not needed.
//
// pSectorInfoBuff
// [in] Buffer for an array of sector information structures.
// One sector information entry for every sector to be read.
// Set to NULL if not needed.
//
// dwNumSectors
// [in] Number of sectors to read.
//
// Returns:
// TRUE/FALSE for success
//
//-----------------------------------------------------------------------------
BOOL FMD_ReadSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff,
PSectorInfo pSectorInfoBuff, DWORD dwNumSectors)
{
volatile SECTOR_ADDR MappedSectorAddr = 0;
volatile SECTOR_ADDR MappedSectorInfoAddr = 0;
BLOCK_ID blockID = 0;
DWORD i = 0;
BOOL bLastMode;
DEBUGMSG(ZONE_FUNCTION, (TEXT("FMD_ReadSector+ 0x%08X 0x%08x 0x%08X 0x%08x\r\n"),
startSectorAddr, dwNumSectors, pSectorBuff, pSectorInfoBuff));
// Check the input parameters
if(dwNumSectors == 0 || (pSectorBuff == NULL && pSectorInfoBuff == NULL))
{
DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: FMD_ReadSector invalid parameters!\r\n")));
return FALSE;
}
bLastMode = SetKMode(TRUE);
for(i = startSectorAddr; i < (startSectorAddr + dwNumSectors); i++)
{
// Get mapped address for the requested sector
GetMappedSectorAddress(i, (SECTOR_ADDR *)&MappedSectorAddr,
(SECTOR_ADDR *)&MappedSectorInfoAddr);
DEBUGMSG(ZONE_FUNCTION, (TEXT("FMD_ReadSector: MappedSectorAddr 0x%08X MappedSectorInfoAddr 0x%08X!\r\n"),
MappedSectorAddr, MappedSectorInfoAddr));
// Read sector data
if(pSectorBuff)
{
memcpy(pSectorBuff, (void *)MappedSectorAddr, g_FMDInfo.BytesPerSector);
pSectorBuff += g_FMDInfo.BytesPerSector;
}
// Read sector metadata
if(pSectorInfoBuff)
{
if(g_bXIPMode)
{
// For XIP, fill the SectorInfo with 1:1 log/phys mapping and read-only status
memset(pSectorInfoBuff, 0xFF, sizeof(SectorInfo));
pSectorInfoBuff->dwReserved1 = startSectorAddr;
}
else
{
// For non-XIP, The metadata bytes are read from flash
memcpy(pSectorInfoBuff, (void *)MappedSectorInfoAddr, sizeof(SectorInfo));
}
pSectorInfoBuff++;
}
}
SetKMode(bLastMode);
DEBUGMSG(ZONE_FUNCTION, (TEXT("FMD_ReadSector-\r\n")));
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: FMD_WriteSector
//
// Function Writes the requested sector data and metadata to the flash media.
//
// Parameters:
// startSectorAddr
// [in] starting physical sector address.
//
// pSectorBuff
// [in] Ptr to buffer that contains sector data to write.
// Set to NULL if data is not needed.
//
// pSectorInfoBuff
// [in] Buffer for an array of sector information structures.
// One sector information entry for every sector to be written.
// Set to NULL if not needed.
//
// dwNumSectors
// [in] Number of sectors to write.
//
// Returns:
// TRUE/FALSE for success
//
//-----------------------------------------------------------------------------
BOOL FMD_WriteSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff,
PSectorInfo pSectorInfoBuff, DWORD dwNumSectors)
{
volatile SECTOR_ADDR MappedSectorAddr = 0;
volatile SECTOR_ADDR MappedSectorInfoAddr = 0;
BLOCK_ID blockID = 0;
DWORD i = 0;
BOOL bSuccess;
BOOL bLastMode;
DWORD dwBusWidth;
BYTE *pAlignBufr;
DEBUGMSG(ZONE_FUNCTION, (TEXT("FMD_WriteSector+ 0x%08X 0x%08x 0x%08X 0x%08x\r\n"),
startSectorAddr, dwNumSectors, pSectorBuff, pSectorInfoBuff));
// Check the input parameters
if(dwNumSectors == 0 || (pSectorBuff == NULL && pSectorInfoBuff == NULL))
{
ERRORMSG(ZONE_ERROR, (TEXT("ERROR: FMD_WriteSector invalid parameters!\r\n")));
return FALSE;
}
bLastMode = SetKMode(TRUE);
bSuccess = TRUE;
dwBusWidth = g_FMDInfo.bIsPairedFlash? (g_FMDInfo.ulDeviceWidth >> 2) : (g_FMDInfo.ulDeviceWidth >> 3);
for(i = startSectorAddr; i < (startSectorAddr + dwNumSectors); i++)
{
// Get mapped address for the requested sector
GetMappedSectorAddress(i, (SECTOR_ADDR *)&MappedSectorAddr,
(SECTOR_ADDR *)&MappedSectorInfoAddr);
DEBUGMSG(ZONE_FUNCTION, (TEXT("FMD_WriteSector: MappedSectorAddr 0x%08X MappedSectorInfoAddr 0x%08X!\r\n"),
MappedSectorAddr, MappedSectorInfoAddr));
// Write sector data
if(pSectorBuff)
{
if((DWORD)pSectorBuff & (dwBusWidth - 1))
{
memcpy(g_pAlignBuf, pSectorBuff, g_FMDInfo.BytesPerSector);
pAlignBufr = g_pAlignBuf;
}
else
pAlignBufr = pSectorBuff;
if(!NORProgram((ULONG)MappedSectorAddr, (UCHAR *)pAlignBufr, g_FMDInfo.BytesPerSector, FALSE))
{
ERRORMSG(ZONE_ERROR, (TEXT("ERROR: Write sector %d failed!\r\n"), i));
bSuccess = FALSE;
goto _exit;
}
pSectorBuff += g_FMDInfo.BytesPerSector;
}
// Write sector metadata
if(pSectorInfoBuff)
{
if(!g_bXIPMode)
{
// For non-XIP, the metadata bytes are written to flash.
if(!NORProgram((ULONG)MappedSectorInfoAddr, (UCHAR *)pSectorInfoBuff, sizeof(SectorInfo), TRUE))
{
ERRORMSG(ZONE_ERROR, (TEXT("ERROR: Write sector %d meta info failed!\r\n"), i));
bSuccess = FALSE;
goto _exit;
}
}
pSectorInfoBuff++;
}
}
_exit:
SetKMode(bLastMode);
DEBUGMSG(ZONE_FUNCTION, (TEXT("FMD_WriteSector-\r\n")));
return bSuccess;
}
//-----------------------------------------------------------------------------
//
// Function: FMD_GetBlockStatus
//
// Function Returns the status of a block.
//
// Parameters:
// blockID
// [in] block number used to check status.
//
// Returns:
// block status bitmap
//
//-----------------------------------------------------------------------------
DWORD FMD_GetBlockStatus(BLOCK_ID blockID)
{
SECTOR_ADDR Sector = blockID * g_FMDInfo.SectorsPerBlock;
SectorInfo SI;
DWORD dwResult = 0;
DEBUGMSG(ZONE_FUNCTION, (TEXT("FMD_GetBlockStatus+: blockID=0x%X\r\n"), blockID));
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;
DEBUGMSG(ZONE_FUNCTION, (TEXT("FMD_GetBlockStatus- dwResult 0x%X\r\n"), dwResult));
return dwResult;
}
//-----------------------------------------------------------------------------
//
// Function: FMD_SetBlockStatus
//
// Function Sets the status of a block.
//
// Parameters:
// blockID
// [in] block number to set status.
//
// dwStatus
// [in] status value to set.
//
// Returns:
// TRUE/FALSE for success
//
//-----------------------------------------------------------------------------
BOOL FMD_SetBlockStatus(BLOCK_ID blockID, DWORD dwStatus)
{
DEBUGMSG(ZONE_FUNCTION, (TEXT("FMD_SetBlockStatus+: blockID=0x%X\r\n"), blockID));
if(dwStatus & (BLOCK_STATUS_READONLY | BLOCK_STATUS_RESERVED))
{
SECTOR_ADDR Sector = blockID * g_FMDInfo.SectorsPerBlock;
SectorInfo SI;
if(!FMD_ReadSector(Sector, NULL, &SI, 1))
{
ERRORMSG(ZONE_ERROR, (TEXT("read block %d sector failed.\r\n"), blockID));
return FALSE;
}
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -