📄 fmd.cpp
字号:
SetWriteProtect(FALSE);
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(1, (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.
#if 0
USHORT BytesNeededToAlign = usBufferSize - (USHORT)(physicalSectorAddr % (ULONG)usBufferSize);
if (!DoBufferedWrite(ulBlockAddress, physicalSectorAddr, pBuffer, BytesNeededToAlign))
{
goto exit;
}
for (j = BytesNeededToAlign, k = 0 ; (j < SECTOR_SIZE) ; j += k)
{
// Since we're using the StrataFlash write buffer to accelerate the write operation, we need to determine how many words should be written
// to the part(s). The value will be the minimum of either the sector bytes remaining or the write buffer size itself (including the number
// of flash parts/banks in the design). Since we write the data in longword form, we assume 2 banks in our design.
//
USHORT NumWriteBytes = MIN((USHORT)(SECTOR_SIZE - j), usBufferSize);
k = DoBufferedWrite(ulBlockAddress, physicalSectorAddr + j, pBuffer + j, NumWriteBytes);
if (!k)
goto exit;
}
#endif
k = DoBufferedWrite(ulBlockAddress, physicalSectorAddr , pBuffer, SECTOR_SIZE);
if (!k)
goto exit;
nResult=1;
pSectorBuff += SECTOR_SIZE;
#if 0
for (j = 0, k = 0 ; (j < SECTOR_SIZE) ; j += k)
{
// Since we're using the StrataFlash write buffer to accelerate the write operation, we need to determine how many words should be written
// to the part(s). The value will be the minimum of either the sector bytes remaining or the write buffer size itself (including the number
// of flash parts/banks in the design). Since we write the data in longword form, we assume 2 banks in our design.
//
USHORT NumWriteBytes = MIN((USHORT)(SECTOR_SIZE - j), (USHORT)((1 << g_FMDInfo.Geometry.WriteBuffSize) * 2));
// Select write buffer mode and wait for the buffer to become available.
//
WRITE_COMMAND(ulBlockAddress, BUFFER_WRITE_CMD);
while (!CHECK_STATUS(ulBlockAddress, STATUS_READY_MASK))
{
// Do nothing - read status command not required...
}
// TODO - write data in this section for non-paired design.
// Let the flash know the size of the buffer we plan to send (note that this is a 0-based word count and we simulatenously
// write it to both flash parts (upper and lower).
//
WRITE_FLASH(ulBlockAddress, ((((NumWriteBytes / sizeof(USHORT)) / 2) - 1) << 16 | (((NumWriteBytes / sizeof(USHORT)) / 2) - 1)));
for(k = 0 ; k < NumWriteBytes ; k += sizeof(ULONG))
{
WRITE_FLASH((physicalSectorAddr + j + k), *((PDWORD)(pSectorBuff + j + k)));
}
// Now program the buffer into flash...
//
WRITE_COMMAND(ulBlockAddress, BLOCK_PROCEED_CMD);
do
{
WRITE_COMMAND(ulBlockAddress, READ_STATUS_CMD);
}
while (!CHECK_STATUS(ulBlockAddress, STATUS_READY_MASK));
}
pSectorBuff += SECTOR_SIZE;
#endif
}
//----- 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))
{
#if flash_debug
RETAILMSG(1, (TEXT("FMD_WriteSector: write info\r\n")));
#endif
if (!DoBufferedWrite(ulBlockAddress, physicalSectorAddr+SECTOR_SIZE, (PUCHAR)pSectorInfoBuff, sizeof(SectorInfo)))
goto exit;
//RETAILMSG(1, (TEXT("sectorInfo: %x %x %x %x\r\n"),
// pSectorInfoBuff.bBadBlock,pSectorInfoBuff.bOEMReserved,
// pSectorInfoBuff.dwReserved1,pSectorInfoBuff.wReserved2));
pSectorInfoBuff += sizeof(SectorInfo);
#if 0
//----- Write the first reserved field -----
WRITE_COMMAND(physicalSectorAddr+SECTOR_SIZE, BYTEWORD_PROGRAM_CMD);
WRITE_FLASH(physicalSectorAddr+SECTOR_SIZE, pSectorInfoBuff->dwReserved1);
do
{
WRITE_COMMAND(physicalSectorAddr+SECTOR_SIZE, READ_STATUS_CMD);
}
while (!CHECK_STATUS(physicalSectorAddr+SECTOR_SIZE, STATUS_READY_MASK));
//----- Write the OEM reserved byte, bad block byte, and second reserved field -----
WRITE_COMMAND(physicalSectorAddr+SECTOR_SIZE, BYTEWORD_PROGRAM_CMD);
WRITE_FLASH(physicalSectorAddr+SECTOR_SIZE+sizeof(ULONG), (DWORD)((pSectorInfoBuff->wReserved2 << 16) |
(pSectorInfoBuff->bBadBlock << 8) |
(pSectorInfoBuff->bOEMReserved)));
do
{
WRITE_COMMAND(physicalSectorAddr+SECTOR_SIZE, READ_STATUS_CMD);
}
while (!CHECK_STATUS(physicalSectorAddr+SECTOR_SIZE, STATUS_READY_MASK));
pSectorInfoBuff += sizeof(SectorInfo);
#endif
}
}
fRet = TRUE;
exit:
//----- 3. Put the Flash back into READ ARRAY mode -----
#if 0
WRITE_COMMAND(ulBlockAddress, READ_ARRAY_CMD);
#endif
SetWriteProtect(TRUE);
SetKMode(bLastMode);
#if flash_debug
RETAILMSG(1, (TEXT("FMD_WriteSector: over %x \r\n"),fRet ));
#endif
return fRet;
}
//****************************************************************************
// DelayuS
//****************************************************************************
// Delays a certian number of microseconds.
//
//
static void DelayInuSec(ULONG ulMicroSec)
{
LARGE_INTEGER liStart, liCurrent;
BOOL b;
b = QueryPerformanceCounter(&liStart);
ASSERT(b);
do
{
Sleep(0);
b = QueryPerformanceCounter(&liCurrent);
ASSERT(b);
} while((liStart.QuadPart + (LONGLONG)ulMicroSec) >=liCurrent.QuadPart);
}
#if have_buffer_write
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 PUSHORT pusDest16;
volatile PULONG pusDest32;
//pusDest16= (PUSHORT)physicalSectorAddr;
//pusDest32= (PULONG)physicalSectorAddr;
DWORD m_offset=0;
#if 0
SetBlockLock((ulBlockAddress-g_FMDInfo.BaseAddress)/g_FMDInfo.BlockSize, 1, FALSE);
WRITE_COMMAND(ulBlockAddress, CLEAR_STATUS_CMD);
for(k = 0 ; k < dwWordCount ; k += 1)
{
//RETAILMSG(1, (TEXT("DoWordWrite: write over 0 \r\n")));
if (g_bPairedFlash)
{
//WRITE_ULONG (physicalSectorAddr + k, 0x400040);
//WRITE_ULONG (physicalSectorAddr + k, *pLongBuffer++);
//DelayInuSec(10);
//WRITE_ULONG (physicalSectorAddr + k, *(physicalSectorAddr+k));
//DelayInuSec(1);
*((ULONG *)physicalSectorAddr+(ulCount1>>2)) = 0x00400040;
//DelayInuSec(100);
//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 0\r\n")));
// return 0;
// }
//}
//WRITE_COMMAND(ulBlockAddress, CLEAR_STATUS_CMD);
*((ULONG *)physicalSectorAddr+(ulCount1>>2)) = *(pLongBuffer+(ulCount1>>2));
/*
ulCount = 0;
while((*pLongBuffer)!=(*((PULONG)physicalSectorAddr + k) ) )
{
DelayInuSec(1);
if ( ulCount++ == 1000000 )
{
RETAILMSG(1, (TEXT("DoWordWrite: Timed out writing buffered data 1\r\n")));
return 0;
}
}
*/
}
else
{
//*((USHORT *)physicalSectorAddr+(ulCount1>>1)) = 0x0040;
//*((USHORT *)physicalSectorAddr+(ulCount1>>1)) = *(pShortBuffer+(ulCount1>>1));
pusDest16[ulCount1>>1] = 0x0040;
pusDest16[ulCount1>>1] = pShortBuffer[ulCount1>>1];
}
//DelayInuSec(100);
//RETAILMSG(1, (TEXT("DoWordWrite: write over 1 \r\n")));
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 1\r\n")));
return 0;
}
}
WRITE_COMMAND(ulBlockAddress, CLEAR_STATUS_CMD);
//RETAILMSG(1, (TEXT("DoWordWrite: write over 2 \r\n")));
if (g_bPairedFlash)
{
ulCount1 += sizeof(ULONG);
}
else
{
ulCount1 += sizeof(USHORT);
}
}
//RETAILMSG(1, (TEXT("DoWordWrite: write over\r\n")));
//DelayInuSec(10);
//
//
//
WRITE_COMMAND(ulBlockAddress, READ_ARRAY_CMD);
ulCount1 =0;
for(k = 0 ; k < dwWordCount ; k += 1)
{
if (g_bPairedFlash)
{
/*
if(*((ULONG *)physicalSectorAddr+(ulCount1>>2)) != *(pLongBuffer+(ulCount1>>2)))
{
RETAILMSG(1, (TEXT("DoWordWrite: mismath add=%x value=%x shoud-value %x\r\n"),
physicalSectorAddr + k,
((ULONG *)physicalSectorAddr + k),
*pLongBuffer));
}
ulCount1 += sizeof(ULONG);
*/
//DelayInuSec(100);
if( *((ULONG *)physicalSectorAddr + k)!=*(pLongBuffer+k) )
{
RETAILMSG(1, (TEXT("DoWordWrite: mismath add=%x value= %x should value=%x\r\n"), physicalSectorAddr + k,*((ULONG *)physicalSectorAddr + k), *(pLongBuffer+k) ));
}
}
else
{
if( pusDest16[ulCount1>>1] !=pShortBuffer[ulCount1>>1])
{
RETAILMSG(1, (TEXT("DoWordWrite: mismath add=%x value=%x shoud-value %x\r\n"),
physicalSectorAddr + k,
pusDest16[ulCount1>>1] ,
pShortBuffer[ulCount1>>1] ));
}
ulCount1 += sizeof(USHORT);
}
}
#endif
#ifdef flash_amd
if (g_bPairedFlash)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -