fmd_tyax.cpp
来自「该BSP是基于PXA270+WINCE的BSP」· C++ 代码 · 共 1,678 行 · 第 1/5 页
CPP
1,678 行
if (pBytesReturned)
*pBytesReturned = 0;
return(FALSE);
} else
{
if (pBytesReturned)
*pBytesReturned = dwTableSize;
if (g_pReservedTable)
memcpy (pOutBuf, g_pReservedTable, dwTableSize);
return(TRUE);
}
}
break;
case IOCTL_FMD_SET_SECTORSIZE:
if (!pInBuf || nInBufSize < sizeof(DWORD))
{
LOGMSG(1, (TEXT("FMD_OEMIoControl: IOCTL_FMD_SET_SECTORSIZE bad parameter(s).\r\n")));
return(FALSE);
}
g_FMDInfo.SectorSize = *(LPDWORD)pInBuf;
break;
case IOCTL_FMD_RAW_WRITE_BLOCKS:
if (!pInBuf || nInBufSize < sizeof(RawWriteBlocksReq))
{
LOGMSG(1, (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))
{
LOGMSG(1, (TEXT("FMD_OEMIoControl: IOCTL_FMD_GET_RAW_BLOCK_SIZE bad parameter(s).\r\n")));
return(FALSE);
}
*((PDWORD)pOutBuf) = g_FMDInfo.BlockSize;
return(TRUE);
case IOCTL_FMDHAL_FLASH_CMD:
if (FMDHAL_IOControl( *pInBuf,pOutBuf, pInBuf ) )
{
DBGMSG(1, (TEXT("FMD_OEMIoControl: IOCTL_FMDHAL_FLASH_CMD OK\r\n")));
return(TRUE);
} else
{
LOGMSG(1, (TEXT("FMD_OEMIoControl: IOCTL_FMDHAL_FLASH_CMD failed\r\n")));
return(FALSE);
}
default:
LOGMSG(1, (TEXT("FMD_OEMIoControl: unrecognized IOCTL (0x%x)\r\n"), dwIoControlCode));
return(FALSE);
}
return(TRUE);
}
/*
@func BOOLEAN | UnlockBlock | Unlocks the specified flash block.
@rdesc TRUE returned on success, FALSE on failure.
@comm
@xref
*/
BOOLEAN SetBlockLock(BLOCK_ID blockID, ULONG NumBlocks, BOOL bLock)
{
volatile ULONG ulBlockAddress = 0;
#ifndef UNDER_BOOTLOADER
BOOL bLastMode = SetKMode(TRUE);
#endif
struct FMDHAL_CmdStruct CurrCmd;
if (bLock) {
DBGMSG(1, (TEXT("FMD:SetBlockLock: lock 0x%x-0x%x\r\n"), blockID, blockID+(NumBlocks-1)));
}
else {
DBGMSG(1, (TEXT("FMD:SetBlockLock: unlock 0x%x-0x%x\r\n"), blockID, blockID+(NumBlocks-1)));
}
ulBlockAddress = g_FMDInfo.BaseAddress + (blockID * g_FMDInfo.BlockSize);
CurrCmd.pTargetAddress = (ULONG *)ulBlockAddress;
CurrCmd.ulNumBlocks = NumBlocks;
CurrCmd.uCmd = bLock?FMDHAL_CMD_LOCK_BLOCK:FMDHAL_CMD_UNLOCK_BLOCK;
// Grab the flash mutex
WAIT_FMD_FLASH_MUTEX(ghFlashMutex);
if (!FMD_OEMIoControl(IOCTL_FMDHAL_FLASH_CMD, (PBYTE) &CurrCmd, sizeof(struct FMDHAL_CmdStruct),
NULL, NULL, NULL))
{
#ifndef UNDER_BOOTLOADER
SetKMode(bLastMode);
#endif
// If failed, release Mutex
RELEASE_FMD_FLASH_MUTEX(ghFlashMutex);
return(FALSE);
}
#ifndef UNDER_BOOTLOADER
SetKMode(bLastMode);
#endif
// Release Mutex after SetBlockLock completes
RELEASE_FMD_FLASH_MUTEX(ghFlashMutex);
return(TRUE);
}
BOOL ReadWriteReserved (PReservedReq pReq, BOOL fRead)
{
PCSTR szName = pReq->szName;
LPBYTE pBuffer = pReq->pBuffer;
#ifndef UNDER_BOOTLOADER
BOOL bLastMode = SetKMode(TRUE);
#endif
#ifndef UNDER_BOOTLOADER
if ((pBuffer = (LPBYTE)MapCallerPtr((LPVOID)(pReq->pBuffer), pReq->dwLen)) == NULL)
{
LOGMSG(1, (TEXT("ReadWriteReserved() - MapCallerPtr() failed, couldn't obtain pointer to buffer.\r\n")));
goto Error;
}
#endif
for (DWORD i = 0; i < g_dwNumReserved; i++)
{
#ifndef UNDER_BOOTLOADER
if (_strnicmp(szName, g_pReservedTable[i].szName, RESERVED_NAME_LEN) == 0)
#else
if (0)
#endif
{
//
// Found a region name match
//
// Verify the request is in the valid range
DWORD dwRegionSize = g_pReservedTable[i].dwNumBlocks * g_FMDInfo.BlockSize;
if ((pReq->dwStart >= dwRegionSize) || (pReq->dwStart + pReq->dwLen > dwRegionSize))
{
LOGMSG(1, (TEXT("ReadWriteReserved: Invalid request. Start: 0x%x. Len: 0x%x\r\n"), pReq->dwStart, pReq->dwLen));
goto Error;
}
if (fRead)
{
PVOID pStartAddress = (PVOID)(g_FMDInfo.BaseAddress + g_pReservedTable[i].dwStartBlock * g_FMDInfo.BlockSize + pReq->dwStart);
memcpy (pBuffer, pStartAddress, pReq->dwLen);
} else
{
//
// Write flash case
//
DWORD dwBusWidth = g_bPairedFlash ? sizeof(ULONG) : sizeof(USHORT);
if (pReq->dwStart % g_FMDInfo.SectorSize)
{
LOGMSG(1, (TEXT("ReadWriteReserved: Invalid write request. Start: 0x%x is not sector aligned.\r\n"), pReq->dwStart));
goto Error;
}
if ((DWORD)pBuffer & (dwBusWidth - 1))
{
LOGMSG(1, (TEXT("ReadWriteReserved: Unaligned pointer 0x%x.\r\n"), pBuffer));
goto Error;
}
DWORD dwStartBlock = pReq->dwStart / g_FMDInfo.BlockSize + g_pReservedTable[i].dwStartBlock;
DWORD dwEndBlock = (pReq->dwStart + pReq->dwLen - 1) / g_FMDInfo.BlockSize + g_pReservedTable[i].dwStartBlock;
DWORD iBlock;
DWORD dwWriteRemain = pReq->dwLen;
for (iBlock = dwStartBlock; iBlock <= dwEndBlock; iBlock++)
{
DWORD dwBlockWriteLen = MIN (g_FMDInfo.BlockSize, dwWriteRemain);
DWORD dwBlockOffset = 0;
// If this is the first block, then start at the appropriate offset within the block
if (iBlock == dwStartBlock)
{
dwBlockOffset = pReq->dwStart % g_FMDInfo.BlockSize;
dwBlockWriteLen = MIN (dwBlockWriteLen, g_FMDInfo.BlockSize - dwBlockOffset);
}
if (!WriteBlock (iBlock, pBuffer, dwBlockOffset, dwBlockWriteLen))
{
LOGMSG(1, (TEXT("ReadWriteReserved: WriteBlock failed (0x%x).\r\n"), iBlock));
goto Error;
}
pBuffer += dwBlockWriteLen;
dwWriteRemain -= dwBlockWriteLen;
}
}
#ifndef UNDER_BOOTLOADER
SetKMode(bLastMode);
#endif
return(TRUE);
}
}
Error:
#ifndef UNDER_BOOTLOADER
SetKMode(bLastMode);
#endif
return(FALSE);
}
BOOL RawWriteBlocks (PRawWriteBlocksReq pReq)
{
DWORD dwEndBlock = pReq->dwStartBlock + pReq->dwNumBlocks - 1;
LPBYTE pBuffer = pReq->pBuffer;
#ifndef UNDER_BOOTLOADER
BOOL bLastMode = SetKMode(TRUE);
#endif
BOOL fRet = FALSE;
if (pReq->dwStartBlock >= g_FMDInfo.TotalFlashBlocks ||
dwEndBlock >= g_FMDInfo.TotalFlashBlocks ||
dwEndBlock < pReq->dwStartBlock)
{
LOGMSG(1, (TEXT("FMD:RawWriteBlocks: Invalid request: (0x%x, 0x%x)\r\n"), pReq->dwStartBlock, pReq->dwNumBlocks));
goto Error;
}
if (pReq->cbBuffer < (pReq->dwNumBlocks * g_FMDInfo.BlockSize))
{
LOGMSG(1, (TEXT("FMD:RawWriteBlocks: Insufficient buffer: (0x%x)\r\n"), pReq->cbBuffer));
goto Error;
}
DBGMSG(1, (TEXT("FMD:RawWriteBlocks: (0x%x,0x%x)\r\n"), pReq->dwStartBlock, pReq->dwNumBlocks));
for (DWORD dwBlock = pReq->dwStartBlock; dwBlock <= dwEndBlock; dwBlock++)
{
if (!WriteBlock (dwBlock, pBuffer, 0, g_FMDInfo.BlockSize))
{
LOGMSG(1, (TEXT("FMD:RawWriteBlocks: WriteBlock failed (0x%x)\r\n"), dwBlock));
goto Error;
}
pBuffer += g_FMDInfo.BlockSize;
}
fRet = TRUE;
Error:
#ifndef UNDER_BOOTLOADER
SetKMode(bLastMode);
#endif
return(fRet);
}
BOOL IsReservedTableBlock (BLOCK_ID dwBlock)
{
for (DWORD i = 0; i < g_dwNumReserved; i++)
{
if (dwBlock >= g_pReservedTable[i].dwStartBlock &&
dwBlock <= (g_pReservedTable[i].dwStartBlock + g_pReservedTable[i].dwNumBlocks - 1))
{
return(TRUE);
}
}
return(FALSE);
}
/////////////
/* ******* */
/////////////
DWORD GetRegion (DWORD dwBlock)
{
for (DWORD i = 0; i < g_dwNumRegions; i++)
{
if (dwBlock >= g_pRegionTable[i].dwStartPhysBlock &&
dwBlock < (g_pRegionTable[i].dwStartPhysBlock + g_pRegionTable[i].dwNumPhysBlocks))
{
//DBGMSG(1, (TEXT("GetRegion: BlockID[%d] is in Region[%d]\r\n"), dwBlock, i));
return(i);
}
}
LOGMSG(1, (TEXT("GetRegion: Could not find region for block 0x%x.\r\n"), dwBlock));
ASSERT(0);
return(INVALID_BLOCK_ID);
}
SECTOR_ADDR GetStartSectorInBlock (DWORD dwBlock)
{
DWORD i = GetRegion(dwBlock);
if (i == INVALID_BLOCK_ID)
return(INVALID_SECTOR_ADDR);
// The starting sector in the block is the starting physical sector
// of the region plus the block offset into the region times
// the sectors per block
//DBGMSG(1, (TEXT("GetStartSectorInBlock: The start sector for block[%d] = %d.\r\n"), dwBlock, (g_pStartSectorTable[i] + (dwBlock - g_pRegionTable[i].dwStartPhysBlock) * g_pRegionTable[i].dwSectorsPerBlock)));
return(g_pStartSectorTable[i] + (dwBlock - g_pRegionTable[i].dwStartPhysBlock) * g_pRegionTable[i].dwSectorsPerBlock);
}
// bman: this routine seems ok
//
VOID GetPhysicalSectorAddress (DWORD dwSector, PSECTOR_ADDR pStartSectorAddr, PSECTOR_ADDR pStartSectorInfoAddr, BLOCK_ID *pBlockID)
{
for (DWORD i = 0; i < g_dwNumRegions; i++)
{
// Determine the region this physical sector resides in
if (dwSector >= g_pStartSectorTable[i] &&
((i == g_dwNumRegions - 1) || (dwSector < g_pStartSectorTable[i+1])))
{
DWORD dwSectorOffsetInRegion = dwSector - g_pStartSectorTable[i];
DWORD dwBlockID = dwSectorOffsetInRegion / g_pRegionTable[i].dwSectorsPerBlock + g_pRegionTable[i].dwStartPhysBlock;
DWORD dwSectorOffsetInBlock = dwSectorOffsetInRegion % g_pRegionTable[i].dwSectorsPerBlock;
// Determine physical address of the block
SECTOR_ADDR BlockAddr = g_FMDInfo.BaseAddress + (dwBlockID * g_FMDInfo.BlockSize);
// Determine the physical address of the sector
*pStartSectorAddr = BlockAddr + (dwSectorOffsetInBlock * g_FMDInfo.SectorSize);
//DBGMSG(1, (TEXT("GetPhysicalSector
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?