⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 intel-p3c3.cpp

📁 Ep93XX TionProV2 BSP
💻 CPP
📖 第 1 页 / 共 3 页
字号:
            physicalSectorAddr = g_FMDInfo.BaseAddress + (i*SECTOR_SIZE);
		
        ulBlockAddress = (ULONG)(physicalSectorAddr - (physicalSectorAddr % g_FMDInfo.BlockSize));

		if(GetEraseFlashSectorIndex(ulBlockAddress-g_FMDInfo.ChipBaseAddress)==FALSE)
		{
			  RETAILMSG(ZONE_TEST, (TEXT("ERASE Block error,not aligned\r\n")));
			return FALSE;
		}
	
		RETAILMSG(ZONE_TEST, (TEXT("blockID=%x,physicalSectorAddr=%x,g_bXIPMode=%x,ulBlockAddress=%x,g_FMDInfo.gdwCurEraseRegion=%x,gdwCurEraseBlock=%x.\r\n"),
						blockID,physicalSectorAddr,g_bXIPMode,ulBlockAddress,g_FMDInfo.gdwCurEraseRegion,g_FMDInfo.gdwCurEraseBlock));

		if(g_FlashRegion[g_FMDInfo.gdwCurEraseRegion].block_size==g_FMDInfo.BlockSize)
		{  
			WRITE_COMMAND(ulBlockAddress, READ_ARRAY_CMD);

	        //----- Read the necessary sector data -----
	        if(pSectorBuff)
	        {
	            memcpy(pSectorBuff, (CONST PVOID)physicalSectorAddr, SECTOR_SIZE);
	            pSectorBuff += SECTOR_SIZE;
	        }
		
	        //----- Read the necessary SectorInfo data (metadata) -----
	        if(!g_bXIPMode && pSectorInfoBuff)
	        {
	            // The metadata bytes are read directly into the SectorInfo structure...
	            memcpy(pSectorInfoBuff, (CONST PVOID)(physicalSectorAddr+SECTOR_SIZE), sizeof(SectorInfo));
	            pSectorInfoBuff += sizeof(SectorInfo);
	        }
		RETAILMSG(ZONE_TEST, (TEXT("read sector %x\r\n"),physicalSectorAddr,ulBlockAddress));
		}
		else
		{
			for(j = g_FMDInfo.gdwCurEraseBlock; j< g_FlashRegion[g_FMDInfo.gdwCurEraseRegion].blocks; j++) 
			{
				WRITE_COMMAND(ulBlockAddress, READ_ARRAY_CMD);
				ulBlockAddress = ulBlockAddress +g_FlashRegion[g_FMDInfo.gdwCurEraseRegion].block_size;
			}
			//----- Read the necessary sector data -----
	        if(pSectorBuff)
	        {
	            memcpy(pSectorBuff, (CONST PVOID)physicalSectorAddr, SECTOR_SIZE);
	            pSectorBuff += SECTOR_SIZE;
	        }
	        //----- Read the necessary SectorInfo data (metadata) -----
	        if(!g_bXIPMode && pSectorInfoBuff)
	        {
	            // The metadata bytes are read directly into the SectorInfo structure...
	            memcpy(pSectorInfoBuff, (CONST PVOID)(physicalSectorAddr+SECTOR_SIZE), sizeof(SectorInfo));
	            pSectorInfoBuff += sizeof(SectorInfo);
	        }
		}
	}
    SetWriteProtect(TRUE);
    SetKMode(bLastMode);

	RETAILMSG(ZONE_TEST, (TEXT("FMD_ReadSector: over.\r\n") ));
    return(TRUE);
}


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:       FMD_WriteSector()

Description:    Writes the requested sector data and/or sector metadata to the
                Flash media.

Notes:          Notice that although each byte of a NOR Flash block is individually
                addressable, the media is still logically broken up into sectors.
                Thus, for each sector request, we must determine where to put the
                data in each respective Flash block (see note above).

                By default, the NOR Flash is configured in READ ARRAY MODE we need
                to set some control lines to prepare for the WRITE operation.

Returns:        Boolean indicating success.
------------------------------------------------------------------------------*/
BOOL  FMD_WriteSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors)
{
    volatile SECTOR_ADDR physicalSectorAddr = 0;
    BLOCK_ID blockID = 0;
    DWORD i = 0;
    DWORD j = 0;
    DWORD k = 0;
    volatile ULONG ulBlockAddress = 0;
    BOOL bLastMode;
    DWORD dwBusWidth = g_bPairedFlash ? sizeof(ULONG) : sizeof(USHORT);
    LPBYTE pBuffer = pSectorBuff;
    USHORT usBufferSize = g_bPairedFlash ? (1 << g_FMDInfo.Geometry.WriteBuffSize) * 2 : (1 << g_FMDInfo.Geometry.WriteBuffSize);
    BOOL fRet = FALSE;
	
    DWORD uResult = 0;

	RETAILMSG(ZONE_TEST, (TEXT("FMD_WriteSector: startAdd =%x num=%x)  sector_add=%x sectorinfo_add=%x.\r\n"),startSectorAddr,dwNumSectors,
						pSectorBuff,pSectorInfoBuff));


#ifdef READ_FROM_REGISTRY
    BYTE cTempBuffer[SECTOR_SIZE];
#endif

    //----- 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);
    
    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(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.
            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;
            }

			uResult =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)&&(uResult))
        {
            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 -----
    WRITE_COMMAND(ulBlockAddress, READ_ARRAY_CMD);
    SetWriteProtect(TRUE);
    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;

	volatile PUSHORT    pusDest16;

	pusDest16= (PUSHORT)physicalSectorAddr;


	SetBlockLock((ulBlockAddress-g_FMDInfo.BaseAddress)/g_FMDInfo.BlockSize, 1, FALSE);

    WRITE_COMMAND(ulBlockAddress, CLEAR_STATUS_CMD);


    for(k = 0 ; k < dwWordCount ; k += 1)
    {
        if (g_bPairedFlash)
        {
			*((ULONG *)physicalSectorAddr+(ulCount1>>2)) = 0x00400040;
			*((ULONG *)physicalSectorAddr+(ulCount1>>2)) = *(pLongBuffer+(ulCount1>>2));
		}
        else
        {
			pusDest16[ulCount1>>1] = 0x0040;
			pusDest16[ulCount1>>1] = pShortBuffer[ulCount1>>1];
        }
   		ulCount = 0;
		WRITE_COMMAND(ulBlockAddress, READ_STATUS_CMD);
		while (!CHECK_STATUS(ulBlockAddress, STATUS_READY_MASK))
		{
    		DelayInuSec(1);
    		if ( ulCount++ == 1000 )
    		{
        			RETAILMSG(ZONE_TEST, (TEXT("DoBufferedWrite: Timed out writing buffered data 1\r\n")));
        			return 0;
    		}
		}
		WRITE_COMMAND(ulBlockAddress, CLEAR_STATUS_CMD);

  		if (g_bPairedFlash)
		{
			ulCount1 += sizeof(ULONG);
  		}
		else
		{
			ulCount1 += sizeof(USHORT);
		}
	}
	WRITE_COMMAND(ulBlockAddress, READ_ARRAY_CMD);
	ulCount1 =0;

    for(k = 0 ; k < dwWordCount ; k += 1)
	{
        if (g_bPairedFlash)
        {
			if( *((ULONG *)physicalSectorAddr + k)!=*(pLongBuffer+k) )
			{
				RETAILMSG(ZONE_TEST, (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(ZONE_TEST, (TEXT("DoWordWrite: mismath add=%x value=%x shoud-value %x\r\n"),
					physicalSectorAddr + k,
					pusDest16[ulCount1>>1] , 
					pShortBuffer[ulCount1>>1]   ));
			}
			ulCount1 += sizeof(USHORT);
		}
	}
    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);
	UINT  j;

	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);

	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(SetBlockLock(blockID, 1, FALSE)==FALSE)
		{
			RETAILMSG(ZONE_TEST, (TEXT("IntelFlashClearLockBits: id =%x ).\r\n"), blockID));
			return FALSE;
		}
		
	    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));
	    WRITE_COMMAND(ulBlockAddress, CLEAR_STATUS_CMD);	
	        
	    // Set the block back to read array mode...
	    WRITE_COMMAND(ulBlockAddress, READ_ARRAY_CMD);
	    SetWriteProtect(TRUE);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -