?? amd.cpp
字號:
m_offset=ulBlockAddress-g_FMDInfo.ChipBaseAddress;
// Issue erase and confirm command.
// Note: eventually this should be changed to issue mass block erases, then loop to
// verify each completes.
pusDest32= (volatile ULONG *)g_FMDInfo.ChipBaseAddress;
WRITE_COMMAND(pusDest32+AMD_SETUP_ADDR1, AMD_SETUP_CODE1);
WRITE_COMMAND(pusDest32+AMD_SETUP_ADDR2, AMD_SETUP_CODE2);
WRITE_COMMAND(pusDest32+AMD_SETUP_ADDR1, AMD_SETUP_ERASE);
WRITE_COMMAND(pusDest32+AMD_SETUP_ADDR1, AMD_SETUP_CODE1);
WRITE_COMMAND(pusDest32+AMD_SETUP_ADDR2, AMD_SETUP_CODE2);
*(pusDest32+(m_offset>>2))= (AMD_BLOCK_ERASE<<16)|AMD_BLOCK_ERASE;
ulCount = 0;
while ((*(pusDest32+(m_offset>>2)) &AMD_SECTOR_ERASE_TIMER)!=AMD_SECTOR_ERASE_TIMER)
{
DelayInuSec(1);
if ( ulCount++ == 10000 )
{
RETAILMSG(ZONE_TEST, (TEXT("erase: Timed out writing buffered data 1\r\n")));
return 0;
}
}
}
else
{
pusDest16=(PUSHORT)g_FMDInfo.ChipBaseAddress;
// Issue erase and confirm command.
// Note: eventually this should be changed to issue mass block erases, then loop to
// verify each completes.
*(pusDest16+ AMD_SETUP_ADDR1)= AMD_SETUP_CODE1;
*(pusDest16+ AMD_SETUP_ADDR2)= AMD_SETUP_CODE2;
*(pusDest16+ AMD_SETUP_ADDR1)= AMD_SETUP_ERASE;
*(pusDest16+ AMD_SETUP_ADDR1)= AMD_SETUP_CODE1;
*(pusDest16+ AMD_SETUP_ADDR2)=AMD_SETUP_CODE2;
DelayInuSec(100);
pusDest16=(PUSHORT)ulBlockAddress;
*pusDest16 = AMD_BLOCK_ERASE;
ulCount = 0;
DelayInuSec(100);
while (!CHECK_STATUS(ulBlockAddress, AMD_SECTOR_ERASE_TIMER))
{
DelayInuSec(1);
if ( ulCount++ == 1000 )
{
RETAILMSG(ZONE_TEST, (TEXT("erase: Timed out writing buffered data 1\r\n")));
return 0;
}
}
}
DelayInuSec(100);
ulBlockAddress = ulBlockAddress +g_FlashRegion[g_FMDInfo.gdwCurEraseRegion].block_size;
}
}
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(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.
{
RETAILMSG(ZONE_TEST, (TEXT("FMD_OEMIoControl: IOCTL_FMD_SET_XIPMODE NON XIP.\r\n")));
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.
{
RETAILMSG(ZONE_TEST, (TEXT("FMD_OEMIoControl: IOCTL_FMD_SET_XIPMODE XIP.\r\n")));
g_FMDInfo.UnusedBytesPerBlock = (USHORT)(g_FMDInfo.BlockSize % SECTOR_SIZE);
g_FMDInfo.SectorsPerBlock = (USHORT)(g_FMDInfo.BlockSize / SECTOR_SIZE);
}
break;
case IOCTL_FMD_LOCK_BLOCKS:
//break;
case IOCTL_FMD_UNLOCK_BLOCKS:
//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:phy length=%x, file system length=%x.\r\n"),ChipFlashLength,FlashLength));
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));
#if( EP93XX_FLASH_WIDTH ==32 )
g_bPairedFlash = TRUE;
#else
g_bPairedFlash = FALSE;
#endif
RETAILMSG(1, (TEXT("INFO: InitializeFlash. AMD like Flash defined\r\n")));
//
#if 0
g_bPairedFlash = TRUE; // Assume flash is paired.
WRITE_COMMAND(pChipBaseAddress+AMD_SETUP_ADDR1, AMD_SETUP_CODE1);
WRITE_COMMAND(pChipBaseAddress+AMD_SETUP_ADDR2, AMD_SETUP_CODE2);
WRITE_COMMAND(pChipBaseAddress+AMD_SETUP_ADDR1, AMD_READ_ID);
nShort[0] = READ_USHORT((volatile USHORT *)pChipBaseAddress + AMD_VENDORID_ADDR);
nShort[1] = READ_USHORT((volatile USHORT *)pChipBaseAddress + AMD_VENDORID_ADDR+1);
RETAILMSG(1, (TEXT("INFO: Flash id %x %x 1111\r\n"),nShort[0],nShort[1]));
g_bPairedFlash = TRUE;
if( nShort[0] != MFGCODE_AMD ){
g_bPairedFlash = FALSE;
//this is for 16 bits only braden?????????????????
*((volatile USHORT *)pChipBaseAddress+AMD_SETUP_ADDR1) =AMD_SETUP_CODE1;
*((volatile USHORT *)pChipBaseAddress+AMD_SETUP_ADDR2) =AMD_SETUP_CODE2;
*((volatile USHORT *)pChipBaseAddress+AMD_SETUP_ADDR1) =AMD_READ_ID;
nShort[0] = READ_USHORT((volatile USHORT *)pChipBaseAddress + AMD_VENDORID_ADDR) ;
nShort[1] = READ_USHORT((volatile USHORT *)pChipBaseAddress + AMD_VENDORID_ADDR+1) ;
RETAILMSG(1, (TEXT("INFO: Flash id %x %x \r\n"),nShort[0],nShort[1]));
if( nShort[0] != MFGCODE_AMD ){
RETAILMSG(1, (TEXT("ERROR: InitializeFlash: invalid manufacturing code. %08x %04x\r\n"),nShort[0],nShort[1]));
return(FALSE);
}
RETAILMSG(1, (TEXT("INFO: Found single AMD flash.\r\n")));
}else{
RETAILMSG(1, (TEXT("INFO: Found paired AMD flash.\r\n")));
}
#endif
//
//
// Look for a Common Flash Interface (CFI).
//
//this is for 16 bits only braden?????????????????
if( !g_bPairedFlash ) {
WRITE_COMMAND(pChipBaseAddress+AMD_SETUP_ADDR1, AMD_SETUP_CODE1);
WRITE_COMMAND(pChipBaseAddress+AMD_SETUP_ADDR2, AMD_SETUP_CODE2);
}
WRITE_COMMAND(pChipBaseAddress+AMD_QUERY_ADDR, AMD_READ_QUERY );
// 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;
RETAILMSG(ZONE_TEST, (TEXT("INFO: CFI query write buffer %x\r\n"), g_FMDInfo.Geometry.WriteBuffSize));
// nLong = (ULONG)pow(2,g_FMDInfo.Geometry.DevSize);
nLong=1<<g_FMDInfo.Geometry.DevSize;
if (g_bPairedFlash)
{
nLong<<=1;
// nLong*= 2;
}
if(ChipFlashLength!=nLong)
{
RETAILMSG(1,(TEXT("INFO: CFI query error:Device size= %x,file=%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.EraseRegionSize * REGION_SIZE_MULT);
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).
//
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 + -