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

📄 amd.cpp

📁 Ep93XX TionProV2 BSP
💻 CPP
📖 第 1 页 / 共 3 页
字号:
				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 + -