📄 intel-p3c3.cpp
字号:
}
else
{
SetWriteProtect(FALSE);
for(j = g_FMDInfo.gdwCurEraseBlock;
j< g_FlashRegion[g_FMDInfo.gdwCurEraseRegion].blocks; j++)
{
if(SetBlockLock(j, 1, FALSE)==FALSE)
{
RETAILMSG(ZONE_TEST, (TEXT("IntelFlashClearLockBits: id =%x ).\r\n"), blockID));
return 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));
WRITE_COMMAND(ulBlockAddress, CLEAR_STATUS_CMD);
// Set the block back to read array mode...
WRITE_COMMAND(ulBlockAddress, READ_ARRAY_CMD);
ulBlockAddress = ulBlockAddress +g_FlashRegion[g_FMDInfo.gdwCurEraseRegion].block_size;
}
SetWriteProtect(TRUE);
}
SetKMode(bLastMode);
RETAILMSG(ZONE_TEST, (TEXT("FMD_EraseBlock over: id =%x ).\r\n"), blockID));
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(ZONE_TEST, (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(ZONE_TEST, (TEXT("FMD_OEMIoControl: IOCTL_FMD_LOCK_BLOCKS bad parameter(s).\r\n")));
return(FALSE);
}
if (!SetBlockLock(((PBlockLockInfo)pInBuf)->StartBlock, ((PBlockLockInfo)pInBuf)->NumBlocks, TRUE))
{
RETAILMSG(ZONE_TEST, (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(ZONE_TEST, (TEXT("FMD_OEMIoControl: IOCTL_FMD_UNLOCK_BLOCKS bad parameter(s).\r\n")));
return(FALSE);
}
if (!SetBlockLock(((PBlockLockInfo)pInBuf)->StartBlock, ((PBlockLockInfo)pInBuf)->NumBlocks, FALSE))
{
RETAILMSG(ZONE_TEST, (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(ZONE_TEST, (TEXT("FMD_OEMIoControl: unrecognized IOCTL (0x%x).\r\n"), dwIoControlCode));
return(FALSE);
}
return(TRUE);
}
BOOLEAN InitializeFlash(volatile ULONG * pChipPhyBaseAddress, ULONG ChipFlashLength,
volatile ULONG * pPhyBaseAddress, ULONG FlashLength)
{
UCHAR nCount = 0;
volatile ULONG * pChipBaseAddress;
volatile ULONG * pBaseAddress;
// LARGE_INTEGER liBasePhyAddr ;
ULONG nLong;
int iIdex;
// USHORT nShort[4];
InitializeFlashSMC( );
ASSERT(pPhyBaseAddress);
ASSERT(FlashLength);
ASSERT(pChipPhyBaseAddress);
ASSERT(ChipFlashLength);
if ( !FlashLength || !ChipFlashLength)
return(FALSE);
RETAILMSG(ZONE_TEST, (TEXT("INFO: InitializeFlash:%x.\r\n"),ChipFlashLength));
// liBasePhyAddr.HighPart = 0 ;
// liBasePhyAddr.LowPart = (DWORD)pChipPhyBaseAddress;
// pChipBaseAddress=(volatile ULONG *)MmMapIoSpace(liBasePhyAddr,ChipFlashLength,FALSE);
// pBaseAddress = pChipBaseAddress+(pPhyBaseAddress-pChipPhyBaseAddress);
pChipBaseAddress=pChipPhyBaseAddress;
pBaseAddress =pPhyBaseAddress;
RETAILMSG(ZONE_TEST, (TEXT("INFO: phy add=%x file add=%x,mmap base add=%x %x.\r\n"),pChipPhyBaseAddress,pPhyBaseAddress,pChipBaseAddress,pBaseAddress));
//
// Assume the flash part is an Intel Strataflash - first check the manufacturer code.
//
#if( EP93XX_FLASH_WIDTH ==32 )
g_bPairedFlash = TRUE;
#else
g_bPairedFlash = FALSE;
#endif
#if 0
g_bPairedFlash = TRUE; // Assume flash is paired.
WRITE_COMMAND(pChipBaseAddress, READ_IDENT_CMD);
nShort[0] = READ_USHORT((volatile USHORT *)pChipBaseAddress + QS_MFGCODE_OFFSET + 0) ;
nShort[1] = READ_USHORT((volatile USHORT *)pChipBaseAddress + QS_MFGCODE_OFFSET + 1) ;
nShort[2] = READ_USHORT((volatile USHORT *)pChipBaseAddress + QS_MFGCODE_OFFSET + 2) ;
nShort[3] = READ_USHORT((volatile USHORT *)pChipBaseAddress + QS_MFGCODE_OFFSET + 3) ;
RETAILMSG(ZONE_TEST, (TEXT("INFO: Flash id %x %x %x %x.\r\n"),nShort[0],nShort[1],nShort[2],nShort[3]));
//
//verify the flash is 16 or 32bit
//
if( (nShort[0]& MFGCODE_INTEL) == MFGCODE_INTEL )
{
if( (nShort[1]& MFGCODE_INTEL) == MFGCODE_INTEL )
{
RETAILMSG(ZONE_TEST, (TEXT("INFO: Found paired Intel flash.\r\n")));
g_bPairedFlash = TRUE;
}
else
{
RETAILMSG(ZONE_TEST, (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(ZONE_TEST, (TEXT("INFO: Found paired Micron flash.\r\n")));
g_bPairedFlash = TRUE;
}
else
{
RETAILMSG(ZONE_TEST, (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(pChipBaseAddress, READ_QUERY_CMD);
if (!CHECK_STATUS_INDEXED(pChipBaseAddress, QS_IDSTRING_OFFSET, IDSTRING_Q) ||
!CHECK_STATUS_INDEXED(pChipBaseAddress, QS_IDSTRING_OFFSET + 1, IDSTRING_R) ||
!CHECK_STATUS_INDEXED(pChipBaseAddress, QS_IDSTRING_OFFSET + 2, IDSTRING_Y))
{
RETAILMSG(ZONE_TEST, (TEXT("INFO: Do not support CFI. Maybe it is Micron Flash.\r\n")));
g_FMDInfo.Geometry.NumEraseBlocks = 1;
g_FMDInfo.Geometry.FlashRegionInfo[0].block_size = 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(pChipBaseAddress, QS_SYSINTF_OFFSET + nCount) & 0xFF);
}
for (nCount = 0 ; nCount < sizeof(FLASH_GEOMETRY_INFO) ; nCount++)
{
*((PUCHAR)&g_FMDInfo.Geometry + nCount) = (UCHAR)(READ_FLASH_INDEXED(pChipBaseAddress, QS_DEVGEOM_OFFSET + nCount) & 0xFF);
}
}
//
//for C3 no buffer write
//
if(g_FMDInfo.Geometry.WriteBuffSize==0)
g_FMDInfo.Geometry.WriteBuffSize=5;
nLong=1<<g_FMDInfo.Geometry.DevSize;
// nLong = (ULONG)pow(2,g_FMDInfo.Geometry.DevSize);
if (g_bPairedFlash)
{
//nLong*= 2;
nLong<<=1;
}
if(ChipFlashLength!=nLong)
{
RETAILMSG(ZONE_TEST, (TEXT("INFO: CFI query error:Device size= %x,register chipfile=%x,device size %x\r\n"),ChipFlashLength,FlashLength,nLong));
}
if((FlashLength>nLong)||((ULONG)(pBaseAddress+FlashLength-pChipBaseAddress)>nLong))
{
RETAILMSG(ZONE_TEST, (TEXT("INFO: file system need length is too long:Device add %x size= %x,register chipfile=add %x %x\r\n"),
pChipBaseAddress,ChipFlashLength,pBaseAddress,FlashLength));
}
g_FMDInfo.ChipBaseAddress = (ULONG)pChipBaseAddress;
g_FMDInfo.ChipFlashLength = (ULONG)ChipFlashLength;
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...
//
for(iIdex=0;iIdex<g_FMDInfo.Geometry.NumEraseBlocks;iIdex++)
{
g_FlashRegion[iIdex].blocks = g_FMDInfo.Geometry.FlashRegionInfo[iIdex].blocks +1 ;
g_FlashRegion[iIdex].block_size= g_FMDInfo.Geometry.FlashRegionInfo[iIdex].block_size*REGION_SIZE_MULT;
}
//
//find the chip is or not top or bottom
//
if(g_FMDInfo.Geometry.NumEraseBlocks != 1)
{
if(g_FlashRegion[0].block_size<g_FlashRegion[1].block_size)
g_FMDInfo.bIsTop=TRUE;
else
g_FMDInfo.bIsTop = FALSE;
}
else
{
g_FMDInfo.bIsTop = 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.
if(g_FMDInfo.bIsTop==TRUE)
{
g_FMDInfo.BlockSize = (g_FMDInfo.Geometry.FlashRegionInfo[1].block_size* REGION_SIZE_MULT);
}
else
{
g_FMDInfo.BlockSize = (g_FMDInfo.Geometry.FlashRegionInfo[0].block_size* REGION_SIZE_MULT);
}
if (g_bPairedFlash)
{
g_FMDInfo.BlockSize *= 2;
for(iIdex=0;iIdex<g_FMDInfo.Geometry.NumEraseBlocks;iIdex++)
{
g_FlashRegion[iIdex].block_size *=2;
}
}
// 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 (!GetEraseFlashSectorIndex(pBaseAddress-pChipBaseAddress) ||
!GetEraseFlashSectorIndex(pBaseAddress-pChipBaseAddress+FlashLength))
{
RETAILMSG(1, (TEXT("ERROR: InitializeFlash: base address and length must be block-aligned (Base=0x%x, Length=0x%x).\r\n"), (ULONG)pBaseAddress, FlashLength));
}
RETAILMSG(ZONE_TEST, (TEXT("current region %x,block id=%x).\r\n"), g_FMDInfo.gdwCurEraseRegion, g_FMDInfo.gdwCurEraseBlock));
// 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(pChipBaseAddress, READ_ARRAY_CMD);
RETAILMSG(ZONE_TEST, (TEXT(" BlockSize=%x,TotalFlashBlocks=%x,UnusedBytesPerBlock=%x,SectorsPerBlock=%x).\r\n"),
g_FMDInfo.BlockSize, g_FMDInfo.TotalFlashBlocks,
g_FMDInfo.UnusedBytesPerBlock,g_FMDInfo.SectorsPerBlock));
return(TRUE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -