📄 amd.cpp
字号:
ULONG nResult = 0 ;
#ifdef READ_FROM_REGISTRY
BYTE cTempBuffer[SECTOR_SIZE];
#endif
RETAILMSG(ZONE_TEST, (TEXT("FMD_WriteSector: startAdd =%x num=%x) sector_add=%x sectorinfo_add=%x.\r\n"),startSectorAddr,dwNumSectors,
pSectorBuff,pSectorInfoBuff));
//----- 1. Check the input parameters -----
// NOTE: The FAL insures that the starting sector address is in the allowable range.
if((dwNumSectors == 0) || ((pSectorBuff == NULL) && (pSectorInfoBuff == NULL)))
{
return(FALSE);
}
//----- 2. Process the write request(s)... -----
bLastMode = SetKMode(TRUE);
for(i = startSectorAddr; i < (startSectorAddr + dwNumSectors); i++)
{
//----- Determine the block this physical sector resides in -----
blockID = (i / g_FMDInfo.SectorsPerBlock);
//----- Compute the physical address for the requested sector -----
// Note we do this differently based on whether the caller wants us to write the sector information structure as well. Since we're
// dealing with a NOR flash which is XIP-able, one might want to use this function to write an XIP region (i.e., no sector information
// structures in flash).
//
if (!g_bXIPMode)
physicalSectorAddr = g_FMDInfo.BaseAddress + i*(SECTOR_SIZE + sizeof(SectorInfo))
+ (blockID * g_FMDInfo.UnusedBytesPerBlock);
else
physicalSectorAddr = g_FMDInfo.BaseAddress + (i*SECTOR_SIZE);
// Compute the block address for this sector write.
//
ulBlockAddress = (ULONG)(physicalSectorAddr - (physicalSectorAddr % g_FMDInfo.BlockSize));
//----- Write the necessary sector data -----
if(pSectorBuff)
{
#ifdef READ_FROM_REGISTRY
// Check for unaligned pointer. Only need to do this if the FMD is being used as
// a block driver (and therefore READ_FROM_REGISTRY is set)
if ((DWORD)pSectorBuff & (dwBusWidth - 1))
{
RETAILMSG(ZONE_TEST, (TEXT("FMD_WriteSector: Unaligned pointer - using internal buffer\r\n")));
memcpy(cTempBuffer, pSectorBuff, SECTOR_SIZE);
pBuffer = cTempBuffer;
}
else
#endif
{
pBuffer = pSectorBuff;
}
// from Intel: if the sector is not aligned modulo write buffer size -
// performance can be enhanced my doing a partial write to align the buffer
// for the rest of the writes to complete the sector. If you are doing
// partial writes to align the buffer address, and a single word
// (or DWORD of x32) is being written, it is faster to use the flash's WORD
// write command instead of the buffered write.
k = DoBufferedWrite(ulBlockAddress, physicalSectorAddr , pBuffer, SECTOR_SIZE);
if (!k)
goto exit;
nResult=1;
pSectorBuff += SECTOR_SIZE;
}
//----- Write the necessary sector info data (metadata) -----
// NOTE: Notice that the 6 metadata bytes are just stored after the sector data...
if((!g_bXIPMode && pSectorInfoBuff)&&(nResult))
{
RETAILMSG(ZONE_TEST, (TEXT("FMD_WriteSector: write info\r\n")));
if (!DoBufferedWrite(ulBlockAddress, physicalSectorAddr+SECTOR_SIZE, (PUCHAR)pSectorInfoBuff, sizeof(SectorInfo)))
goto exit;
pSectorInfoBuff += sizeof(SectorInfo);
}
}
fRet = TRUE;
exit:
//----- 3. Put the Flash back into READ ARRAY mode -----
SetKMode(bLastMode);
RETAILMSG(ZONE_TEST, (TEXT("FMD_WriteSector: over %x \r\n"),fRet ));
return fRet;
}
DWORD DoBufferedWrite(volatile ULONG ulBlockAddress,
volatile SECTOR_ADDR physicalSectorAddr,
PUCHAR pBuffer,
USHORT NumWriteBytes)
{
DWORD k = 0;
ULONG ulCount,ulCount1=0;
DWORD dwBusWidth = g_bPairedFlash ? sizeof(ULONG) : sizeof(USHORT);
DWORD dwWordCount = (NumWriteBytes / dwBusWidth);
PULONG pLongBuffer = (PULONG)pBuffer;
PUSHORT pShortBuffer = (PUSHORT)pBuffer;
int iResult = FLASH_ERR_OK;
volatile USHORT * pusDest16;
volatile ULONG * pusDest32;
DWORD m_offset=0;
//RETAILMSG(1, (TEXT("WRITE: ).\r\n")));
if (g_bPairedFlash)
{
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,0x0020);
}
else
{
pusDest16= (volatile USHORT*)g_FMDInfo.ChipBaseAddress;
WRITE_COMMAND(pusDest16+ AMD_SETUP_ADDR1,AMD_SETUP_CODE1);
WRITE_COMMAND(pusDest16+ AMD_SETUP_ADDR2,AMD_SETUP_CODE2);
WRITE_COMMAND(pusDest16+ AMD_SETUP_ADDR1,0x0020);
}
m_offset=physicalSectorAddr-g_FMDInfo.ChipBaseAddress;
for(k = 0 ; k < dwWordCount ; k ++)
{
if (g_bPairedFlash)
{
pusDest32= (volatile ULONG *)g_FMDInfo.ChipBaseAddress;
WRITE_COMMAND(pusDest32+ 0x00000,0x00a0);
*(pusDest32+(m_offset>>2)+k)=*(pLongBuffer+k) ;
DelayInuSec(100);
ulCount = 0;
while ( *(pusDest32+(m_offset>>2)+k) != *(pLongBuffer+k) )
{
DelayInuSec(1);
if ( ulCount++== 1000)
{
RETAILMSG(ZONE_TEST, (TEXT("DoWordWrite: %x %x\r\n"),*(pusDest32+(m_offset>>2)+k),*(pLongBuffer+k) ));
iResult = FLASH_ERR_DRV_TIMEOUT;
//return 0;
break;
}
}
}
else
{
pusDest16= (PUSHORT)g_FMDInfo.ChipBaseAddress;
WRITE_COMMAND(pusDest16+ 0x00000,0x00a0);
*(pusDest16+(m_offset>>1)+k)=*(pShortBuffer+k) ;
DelayInuSec(1);
ulCount = 0;
while ( *(pusDest16+(m_offset>>1)+k) != *(pShortBuffer+k) )
{
DelayInuSec(1);
if ( ulCount++== 1000 )
{
RETAILMSG(ZONE_TEST, (TEXT("DoWordWrite: Timed out writing buffered data 1\r\n")));
iResult = FLASH_ERR_DRV_TIMEOUT;
break;
}
}
}
DelayInuSec(1);
ulCount = 0;
}
if (g_bPairedFlash)
{
pusDest32= (volatile ULONG *)g_FMDInfo.ChipBaseAddress;
WRITE_COMMAND(pusDest32+ AMD_SETUP_ADDR1,0x0090);
WRITE_COMMAND(pusDest32+ AMD_SETUP_ADDR2,0x0000);
}
else
{
pusDest16= (volatile USHORT *)g_FMDInfo.ChipBaseAddress;
WRITE_COMMAND(pusDest16+ AMD_SETUP_ADDR1,0x0090);
WRITE_COMMAND(pusDest16+ AMD_SETUP_ADDR2,0x0000);
}
//RETAILMSG(1, (TEXT("--WRITE: ).\r\n")));
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);
unsigned int j;
ULONG ulCount=0;
volatile USHORT * pusDest16;
volatile ULONG * pusDest32;
DWORD m_offset=0;
RETAILMSG(ZONE_TEST, (TEXT("FMD_EraseBlock: id =%x ).\r\n"), blockID));
// Determine the address for the specified block.
ulBlockAddress = g_FMDInfo.BaseAddress + (blockID * g_FMDInfo.BlockSize);
pusDest16= (PUSHORT)ulBlockAddress;
pusDest32= (PULONG)ulBlockAddress;
if(GetEraseFlashSectorIndex(ulBlockAddress-g_FMDInfo.ChipBaseAddress)==FALSE)
{
RETAILMSG(ZONE_TEST, (TEXT("ERASE Block error,not aligned\r\n")));
return FALSE;
}
if(g_FlashRegion[g_FMDInfo.gdwCurEraseRegion].block_size==g_FMDInfo.BlockSize)
{
if (g_bPairedFlash)
{
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 )
//Sleep(1);
//if ( ulCount++ == 10 )
{
RETAILMSG(ZONE_TEST, (TEXT("erase: Timed out writing buffered data 1\r\n")));
return 0;
}
}
}
else
{
// m_offset=ulBlockAddress-g_FMDInfo.ChipBaseAddress;
pusDest16=(volatile USHORT *)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;
// *(pusDest16+(m_offset>>1))= AMD_BLOCK_ERASE;
Sleep(5);
// DelayInuSec(5000);
pusDest16=(PUSHORT)ulBlockAddress;
*pusDest16 = AMD_BLOCK_ERASE;
Sleep(10);
// DelayInuSec(10000);
ulCount = 0;
while (!CHECK_STATUS(ulBlockAddress, AMD_SECTOR_ERASE_TIMER))
{
//DelayInuSec(1);
//if ( ulCount++ == 10000 )
Sleep(1);
if ( ulCount++ == 10 )
{
RETAILMSG(1, (TEXT("erase: Timed out writing buffered data 1\r\n")));
return 0;
}
}
}
DelayInuSec(100);
} //g_FlashRegion[g_FMDInfo.gdwCurEraseRegion].block_size==g_FMDInfo.BlockSize
else
{
for(j = g_FMDInfo.gdwCurEraseBlock;
j< g_FlashRegion[g_FMDInfo.gdwCurEraseRegion].blocks; j++)
{
if (g_bPairedFlash)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -