fmd_tyax.cpp
来自「该BSP是基于PXA270+WINCE的BSP」· C++ 代码 · 共 1,678 行 · 第 1/5 页
CPP
1,678 行
SECTOR_ADDR Sector = GetStartSectorInBlock(blockID); // virtual block.
if (Sector == INVALID_SECTOR_ADDR)
{
LOGMSG(1, (TEXT("FMD_GetBlockStatus: INVALID_SECTOR_ADDR. GetStartSectorInBlock() returns 0x%x\r\n"), Sector));
return(BLOCK_STATUS_UNKNOWN);
}
SectorInfo SI;
DWORD dwResult = 0;
if (!FMD_ReadSector(Sector, NULL, &SI, 1))
{
LOGMSG(1, (TEXT("FMD_GetBlockStatus: BLOCK_STATUS_UNKNOWN. FMD_ReadSector returned FALSE\r\n")));
return(BLOCK_STATUS_UNKNOWN);
}
//if (!(SI.bOEMReserved & OEM_BLOCK_READONLY))
//dwResult |= BLOCK_STATUS_READONLY;
if (!(SI.bOEMReserved & OEM_BLOCK_RESERVED))
dwResult |= BLOCK_STATUS_RESERVED;
//DBGMSG(1, (TEXT("FMD_GetBlockStatus: dwResult = 0x%x\r\n"), dwResult));
return(dwResult);
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: FMD_SetBlockStatus()
Description: Sets the status of a block.
Returns: TRUE if no errors in setting.
------------------------------------------------------------------------------*/
BOOL FMD_SetBlockStatus(BLOCK_ID blockID, DWORD dwStatus)
{
DBGMSG(1, (TEXT("FMD_SetBlockStatus(0x%x,0x%x):\r\n"), blockID, dwStatus));
// Don't allow setting block status for reserved or XIP blocks.
if (IsReservedTableBlock(blockID))
{
LOGMSG(1, (TEXT("FMD_SetBlockStatus(0x%x,0x%x): Reserved block\r\n"), blockID, dwStatus));
return(FALSE);
}
DWORD dwRegion = GetRegion(blockID);
if (dwRegion == INVALID_BLOCK_ID)
{
LOGMSG(1, (TEXT("FMD_SetBlockStatus(0x%x,0x%x): Invalid block\r\n"), blockID, dwStatus));
return(FALSE);
}
if (g_pRegionTable[dwRegion].regionType == XIP)
{
LOGMSG(1, (TEXT("FMD_SetBlockStatus(0x%x,0x%x): XIP block\r\n"), blockID, dwStatus));
return(FALSE);
}
if (dwStatus & (BLOCK_STATUS_READONLY | BLOCK_STATUS_RESERVED))
{
SECTOR_ADDR Sector = GetStartSectorInBlock(blockID);
if (Sector == INVALID_SECTOR_ADDR)
{
LOGMSG(1, (TEXT("FMD_SetBlockStatus(0x%x,0x%x): Invalid sector\r\n"), blockID, dwStatus));
return(FALSE);
}
SectorInfo SI;
if (!FMD_ReadSector(Sector, NULL, &SI, 1))
{
LOGMSG(1, (TEXT("FMD_SetBlockStatus(0x%x,0x%x): FMD_ReadSector failed\r\n"), blockID, dwStatus));
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))
{
LOGMSG(1, (TEXT("FMD_SetBlockStatus(0x%x,0x%x): FMD_WriteSector failed\r\n"), blockID, dwStatus));
return(FALSE);
}
}
return(TRUE);
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: FMD_EraseBlock()
Description: Erases the specified Flash block.
Returns: Boolean indicating success.
------------------------------------------------------------------------------*/
BOOL FMD_EraseBlock(BLOCK_ID blockID)
{
//USHORT loopCnt, x;
//ULONG BlockAdx;
volatile ULONG ulBlockAddress = 0;
BOOL bRetVal = TRUE;
#ifndef UNDER_BOOTLOADER
BOOL bLastMode;
#endif
BYTE cNullSignature[BLOCK_SIG_BYTES] = {0};
struct FMDHAL_CmdStruct CurrCmd;
DWORD dwRegion = GetRegion(blockID);
if (dwRegion == INVALID_BLOCK_ID)
{
LOGMSG(1, (TEXT("FMD:FMD_EraseBlock: ERROR! INVALID_BLOCK_ID 0x%x\r\n"), blockID));
return(FALSE);
}
DWORD region_type = g_pRegionTable[dwRegion].regionType;
BOOL bXIPBlock = (region_type == XIP);
BOOL bReservedBlock = (FMD_GetBlockStatus(blockID) & BLOCK_STATUS_RESERVED);
#ifndef UNDER_BOOTLOADER
bLastMode = SetKMode(TRUE);
#endif
// Determine the address for the specified virtual block.
ulBlockAddress = g_FMDInfo.BaseAddress + (blockID * g_FMDInfo.BlockSize);
DBGMSG(1, (TEXT("FMD:FMD_EraseBlock(0x%x): ba=0x%x\r\n"), blockID, ulBlockAddress));
CurrCmd.pTargetAddress = (ULONG *)ulBlockAddress;
CurrCmd.uCmd = FMDHAL_CMD_ERASE;
// Grab the Flash block mutex
WAIT_FMD_FLASH_MUTEX(ghFlashMutex);
if (!FMD_OEMIoControl(IOCTL_FMDHAL_FLASH_CMD,(PBYTE) &CurrCmd, sizeof(struct FMDHAL_CmdStruct),
NULL, NULL, NULL))
{
bRetVal = FALSE;
// Release Mutex if erase failed
RELEASE_FMD_FLASH_MUTEX(ghFlashMutex);
goto Error;
}
// Release Mutex when EraseBlock completes
RELEASE_FMD_FLASH_MUTEX(ghFlashMutex);
// Sign the block/ This will only work because the block has already been ERASED.
//
if (bXIPBlock || bReservedBlock)
{
DBGMSG(1, (TEXT("FMD:FMD_EraseBlock(x%08x): Skipping SignBlock (bXIPBlock=%u, bReservedBlock=%u)\r\n"),
blockID, bXIPBlock, bReservedBlock));
}
else if (!SignBlock(ulBlockAddress, (PUCHAR) gc_dwBlockSig))
{
LOGMSG(1, (TEXT("FMD:FMD_EraseBlock(x%08x): SignBlock failed (status=x%08x)\r\n"), blockID, last_status));
bRetVal = FALSE;
goto Error;
}
Error:
#ifndef UNDER_BOOTLOADER
SetKMode(bLastMode);
#endif
return(bRetVal);
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: FMD_PowerUp()
Description: Restores power to the Flash memory device (if applicable).
Returns: None.
------------------------------------------------------------------------------*/
VOID FMD_PowerUp(VOID)
{
ULONG unlock_ret;
unlock_ret = UnlockFILESYSRegions();
DBGMSG(1, (TEXT("FMD_PowerUp: %u blocks in %u regions unlocked\r\n"), unlock_ret & 0xffff, unlock_ret >> 16));
return;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: FMD_PowerDown()
Description: Suspends power to the Flash memory device (if applicable).
Returns: None.
------------------------------------------------------------------------------*/
VOID FMD_PowerDown(VOID)
{
return;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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)
{
switch (dwIoControlCode)
{
case IOCTL_FMD_GET_INTERFACE:
{
if (!pOutBuf || nOutBufSize < sizeof(FMDInterface))
{
LOGMSG(1, (TEXT("FMD:FMD_OEMIoControl: IOCTL_FMD_GET_INTERFACE bad parameter(s).\r\n")));
return(FALSE);
}
DBGMSG(1, (TEXT("FMD_OEMIoControl: IOCTL_FMD_GET_INTERFACE\r\n")));
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;
}
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))
{
LOGMSG(1, (TEXT("FMD_OEMIoControl: IOCTL_FMD_SET_XIPMODE bad parameter(s).\r\n")));
return(FALSE);
}
g_bXIPEntire = *(PBOOLEAN)pInBuf;
break;
case IOCTL_FMD_GET_XIPMODE:
if (!pOutBuf || nOutBufSize < sizeof(BOOLEAN))
{
LOGMSG(1, (TEXT("FMD_OEMIoControl: IOCTL_FMD_GET_XIPMODE bad parameter(s).\r\n")));
return(FALSE);
}
*(PBOOLEAN)pOutBuf = g_bXIPEntire;
break;
case IOCTL_FMD_LOCK_BLOCKS:
// Lock one of more blocks in a specified range.
if (!pInBuf || nInBufSize < sizeof(BlockLockInfo))
{
LOGMSG(1, (TEXT("FMD_OEMIoControl: IOCTL_FMD_LOCK_BLOCKS bad parameter(s).\r\n")));
return(FALSE);
}
if (!SetBlockLock(((PBlockLockInfo)pInBuf)->StartBlock, ((PBlockLockInfo)pInBuf)->NumBlocks, TRUE))
{
LOGMSG(1, (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);
}
else
{
DBGMSG(1, (TEXT("FMD_OEMIoControl: IOCTL_FMD_LOCK_BLOCKS OK (start=0x%x, number=0x%x).\r\n"),
((PBlockLockInfo)pInBuf)->StartBlock, ((PBlockLockInfo)pInBuf)->NumBlocks));
}
break;
case IOCTL_FMD_UNLOCK_BLOCKS:
// Unlock one of more blocks in a specified range.
if (!pInBuf || nInBufSize < sizeof(BlockLockInfo))
{
LOGMSG(1, (TEXT("FMD_OEMIoControl: IOCTL_FMD_UNLOCK_BLOCKS bad parameter(s).\r\n")));
return(FALSE);
}
if (!SetBlockLock(((PBlockLockInfo)pInBuf)->StartBlock, ((PBlockLockInfo)pInBuf)->NumBlocks, FALSE))
{
LOGMSG(1, (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);
}
else
{
DBGMSG(1, (TEXT("FMD_OEMIoControl: IOCTL_FMD_UNLOCK_BLOCKS OK (start=0x%x, number=0x%x).\r\n"),
((PBlockLockInfo)pInBuf)->StartBlock, ((PBlockLockInfo)pInBuf)->NumBlocks));
}
break;
case IOCTL_FMD_READ_RESERVED:
// Read from a specified reserved region.
if (!pInBuf || nInBufSize < sizeof(ReservedReq))
{
LOGMSG(1, (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))
{
LOGMSG(1, (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 = g_dwNumReserved * sizeof(ReservedEntry);
return(TRUE);
} else
{
DWORD dwTableSize = g_dwNumReserved * sizeof(ReservedEntry);
if (nOutBufSize < dwTableSize)
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?