📄 intel-j3.cpp
字号:
ulCount = 0;
WRITE_COMMAND(ulBlockAddress, READ_STATUS_CMD);
while (!CHECK_STATUS(ulBlockAddress, STATUS_READY_MASK))
{
DelayInuSec(1);
if ( ulCount++ == 1000 )
{
RETAILMSG(1, (TEXT("DoBufferedWrite: Timed out writing buffered data 3\r\n")));
return 0;
}
}
WRITE_COMMAND(ulBlockAddress, READ_ARRAY_CMD);
return NumWriteBytes;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: FMD_EraseBlock()
Description: Erases the specified Flash block.
Returns: Boolean indicating success.
------------------------------------------------------------------------------*/
BOOL FMD_EraseBlock(BLOCK_ID blockID)
{
volatile ULONG ulBlockAddress = 0;
ULONG ulStatus = 0;
BOOL bLastMode = SetKMode(TRUE);
// Determine the address for the specified block.
ulBlockAddress = g_FMDInfo.BaseAddress + (blockID * g_FMDInfo.BlockSize);
SetWriteProtect(FALSE);
// Issue erase and confirm command.
// Note: eventually this should be changed to issue mass block erases, then loop to
// verify each completes.
WRITE_COMMAND(ulBlockAddress, BLOCK_ERASE_CMD);
WRITE_COMMAND(ulBlockAddress, BLOCK_PROCEED_CMD);
do
{
WRITE_COMMAND(ulBlockAddress, READ_STATUS_CMD);
}
while (!CHECK_STATUS(ulBlockAddress, STATUS_READY_MASK));
// TODO
#if 0
if ((ulStatus & 0x00200000) || (ulStatus & 0x00000020))
{
if (ulStatus & 0x00200000)
RETAILMSG(1, (TEXT("\n\rBlock erase failure. Lock bit upper flash set!\r\n")));
if (ulStatus & 0x00000020)
RETAILMSG(1, (TEXT("\n\rBlock erase failure. Lock bit lower flash set!\r\n")));
RETAILMSG(1, (TEXT("Unrecoverable failure encountered while erasing flash.\r\n")));
return(FALSE);
}
#endif
// Set the block back to read array mode...
WRITE_COMMAND(ulBlockAddress, READ_ARRAY_CMD);
SetWriteProtect(TRUE);
SetKMode(bLastMode);
return(TRUE);
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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_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))
{
RETAILMSG(1, (TEXT("FMD_OEMIoControl: IOCTL_FMD_SET_XIPMODE bad parameter(s).\r\n")));
return(FALSE);
}
g_bXIPMode = *(PBOOLEAN)pInBuf;
if (!g_bXIPMode) // Not XIP mode.
{
g_FMDInfo.UnusedBytesPerBlock = (USHORT)(g_FMDInfo.BlockSize % (SECTOR_SIZE + sizeof(SectorInfo)));
g_FMDInfo.SectorsPerBlock = (USHORT)(g_FMDInfo.BlockSize / (SECTOR_SIZE + sizeof(SectorInfo)));
}
else // XIP mode.
{
g_FMDInfo.UnusedBytesPerBlock = (USHORT)(g_FMDInfo.BlockSize % SECTOR_SIZE);
g_FMDInfo.SectorsPerBlock = (USHORT)(g_FMDInfo.BlockSize / SECTOR_SIZE);
}
break;
case IOCTL_FMD_LOCK_BLOCKS:
// Lock one of more blocks in a specified range.
if (!pInBuf || nInBufSize < sizeof(BlockLockInfo))
{
RETAILMSG(1, (TEXT("FMD_OEMIoControl: IOCTL_FMD_LOCK_BLOCKS bad parameter(s).\r\n")));
return(FALSE);
}
if (!SetBlockLock(((PBlockLockInfo)pInBuf)->StartBlock, ((PBlockLockInfo)pInBuf)->NumBlocks, TRUE))
{
RETAILMSG(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);
}
break;
case IOCTL_FMD_UNLOCK_BLOCKS:
// Unlock one of more blocks in a specified range.
if (!pInBuf || nInBufSize < sizeof(BlockLockInfo))
{
RETAILMSG(1, (TEXT("FMD_OEMIoControl: IOCTL_FMD_UNLOCK_BLOCKS bad parameter(s).\r\n")));
return(FALSE);
}
if (!SetBlockLock(((PBlockLockInfo)pInBuf)->StartBlock, ((PBlockLockInfo)pInBuf)->NumBlocks, FALSE))
{
RETAILMSG(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);
}
break;
default:
// RETAILMSG(1, (TEXT("FMD_OEMIoControl: unrecognized IOCTL (0x%x).\r\n"), dwIoControlCode));
return(FALSE);
}
return(TRUE);
}
BOOLEAN InitializeFlash(volatile ULONG * pBaseAddressPh, ULONG FlashLength)
{
UCHAR nCount = 0;
volatile ULONG * pBaseAddress;
USHORT nShort[4];
// LARGE_INTEGER liBasePhyAddr ;
InitializeFlashSMC( );
ASSERT(pBaseAddress);
ASSERT(FlashLength);
if (!pBaseAddressPh || !FlashLength)
return(FALSE);
RETAILMSG(1, (TEXT("INFO: InitializeFlash. Intel J3 like Flash defined\r\n")));
// Assume the flash part is an Intel Strataflash - first check the manufacturer code.
//
pBaseAddress =pBaseAddressPh;
#if( EP93XX_FLASH_WIDTH ==32 )
g_bPairedFlash = TRUE;
#else
g_bPairedFlash = FALSE;
#endif
#if 0
g_bPairedFlash = TRUE; // Assume flash is paired.
WRITE_COMMAND(pBaseAddress, READ_IDENT_CMD);
nShort[0] = READ_USHORT((volatile USHORT *)pBaseAddress + QS_MFGCODE_OFFSET + 0) ;
nShort[1] = READ_USHORT((volatile USHORT *)pBaseAddress + QS_MFGCODE_OFFSET + 1) ;
nShort[2] = READ_USHORT((volatile USHORT *)pBaseAddress + QS_MFGCODE_OFFSET + 2) ;
nShort[3] = READ_USHORT((volatile USHORT *)pBaseAddress + QS_MFGCODE_OFFSET + 3) ;
if( (nShort[0]& MFGCODE_INTEL) == MFGCODE_INTEL )
{
if( (nShort[1]& MFGCODE_INTEL) == MFGCODE_INTEL )
{
RETAILMSG(1, (TEXT("INFO: Found paired Intel flash.\r\n")));
g_bPairedFlash = TRUE;
}else
{
RETAILMSG(1, (TEXT("INFO: Found single Intel flash.\r\n")));
g_bPairedFlash = FALSE;
}
}
else if( (nShort[0]& MFGCODE_MICRON) == MFGCODE_MICRON )
{
if( (nShort[1]& MFGCODE_INTEL) == MFGCODE_INTEL )
{
RETAILMSG(1, (TEXT("INFO: Found paired Micron flash.\r\n")));
g_bPairedFlash = TRUE;
}else
{
RETAILMSG(1, (TEXT("INFO: Found single Micron flash.\r\n")));
g_bPairedFlash = FALSE;
}
}
else
{
RETAILMSG(1, (TEXT("ERROR: InitializeFlash: invalid manufacturing code. %08x %04x\r\n"),nShort[0],nShort[1]));
return(FALSE);
}
#endif
// Look for a Common Flash Interface (CFI).
//
WRITE_COMMAND(pBaseAddress, READ_QUERY_CMD);
if (!CHECK_STATUS_INDEXED(pBaseAddress, QS_IDSTRING_OFFSET, IDSTRING_Q) ||
!CHECK_STATUS_INDEXED(pBaseAddress, QS_IDSTRING_OFFSET + 1, IDSTRING_R) ||
!CHECK_STATUS_INDEXED(pBaseAddress, QS_IDSTRING_OFFSET + 2, IDSTRING_Y))
{
RETAILMSG(1, (TEXT("INFO: Do not support CFI. Maybe it is Micron Flash.\r\n")));
g_FMDInfo.Geometry.NumEraseBlocks = 1;
g_FMDInfo.Geometry.EraseRegionSize = 0x200;
g_FMDInfo.Geometry.WriteBuffSize = 5;
}
else
{
// We're pretty sure this is an Intel Strataflash part at this point - use the CFI to
// collect information on it (we're still in query mode). Also, we'll assume that both
// high and low word flash parts are the same from here on out (if paired).
//
for (nCount = 0 ; nCount < sizeof(FLASH_SYSINTERFACE_INFO) ; nCount++)
{
*((PUCHAR)&g_FMDInfo.SysInt + nCount) = (UCHAR)(READ_FLASH_INDEXED(pBaseAddress, QS_SYSINTF_OFFSET + nCount) & 0xFF);
}
for (nCount = 0 ; nCount < sizeof(FLASH_GEOMETRY_INFO) ; nCount++)
{
*((PUCHAR)&g_FMDInfo.Geometry + nCount) = (UCHAR)(READ_FLASH_INDEXED(pBaseAddress, QS_DEVGEOM_OFFSET + nCount) & 0xFF);
}
}
g_FMDInfo.BaseAddress = (ULONG)pBaseAddress;
g_FMDInfo.FlashLength = (ULONG)FlashLength;
// The block erase code assumes a single block per erase region - check for that here...
//
if (g_FMDInfo.Geometry.NumEraseBlocks != 1)
{
RETAILMSG(1, (TEXT("ERROR: InitializeFlash: more than one block per erase region (%d).\r\n"),
g_FMDInfo.Geometry.NumEraseBlocks));
return(FALSE);
}
// Compute block size and the total number of blocks here. Since we know an erase region contains
// only one block, the erase region size is equal to the block size.
// Note that the flash block size is 128KB, if paired, we have two of the 16-bit parts and the block size is effectively 256KB.
g_FMDInfo.BlockSize = (g_FMDInfo.Geometry.EraseRegionSize * REGION_SIZE_MULT);
if (g_bPairedFlash)
{
g_FMDInfo.BlockSize *= 2;
}
RETAILMSG(1, (TEXT("InitializeFlash: (%d -- %d --%d).\r\n"),
g_FMDInfo.Geometry.NumEraseBlocks,
g_FMDInfo.Geometry.EraseRegionSize,
g_FMDInfo.BlockSize
));
// In order for all the math to work out later, we require that the flash base address be block-aligned and that the flash length be
// an integral number of blocks.
if (!IS_BLOCK_ALIGNED(pBaseAddressPh) || !IS_BLOCK_ALIGNED(FlashLength))
{
RETAILMSG(1, (TEXT("ERROR: InitializeFlash: base address and length must be block-aligned (Base=0x%x, Length=0x%x).\r\n"),
(ULONG)pBaseAddressPh, FlashLength));
return(FALSE);
}
// Note that we need to adjust the total available blocks if the caller specified a non-zero flash offset value.
g_FMDInfo.TotalFlashBlocks = (FlashLength / g_FMDInfo.BlockSize);
// By default, we start out in *non-XIP* mode.
g_bXIPMode = FALSE;
// Default to NAND sector layout. If the caller wants to use this FMD for XIP-able code, they'll call the FMD_OEMIoControl
// and we'll change the number of UnusedBytesPerBlock.
g_FMDInfo.UnusedBytesPerBlock = (USHORT)(g_FMDInfo.BlockSize % (SECTOR_SIZE + sizeof(SectorInfo)));
g_FMDInfo.SectorsPerBlock = (USHORT)(g_FMDInfo.BlockSize / (SECTOR_SIZE + sizeof(SectorInfo)));
// Put the Flash into a known state (READ_ARRAY mode with WRITE-ENABLE disabled).
//
WRITE_COMMAND(pBaseAddress, READ_ARRAY_CMD);
return(TRUE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -