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

📄 intel-p3c3.cpp

📁 Ep93XX TionProV2 BSP
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	}
	else
	{
	    SetWriteProtect(FALSE);

   		for(j = g_FMDInfo.gdwCurEraseBlock; 
			j< g_FlashRegion[g_FMDInfo.gdwCurEraseRegion].blocks; j++) 
		{
			if(SetBlockLock(j, 1, FALSE)==FALSE)
			{
				RETAILMSG(ZONE_TEST, (TEXT("IntelFlashClearLockBits: id =%x ).\r\n"), blockID));
				return 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);

			ulBlockAddress = ulBlockAddress +g_FlashRegion[g_FMDInfo.gdwCurEraseRegion].block_size;
   		}
	    SetWriteProtect(TRUE);
	}
	SetKMode(bLastMode);

	RETAILMSG(ZONE_TEST, (TEXT("FMD_EraseBlock over: id =%x ).\r\n"), blockID));
	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.
        {
            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.
        {
            g_FMDInfo.UnusedBytesPerBlock = (USHORT)(g_FMDInfo.BlockSize % SECTOR_SIZE);
            g_FMDInfo.SectorsPerBlock     = (USHORT)(g_FMDInfo.BlockSize / SECTOR_SIZE);
        }
        break;
    case IOCTL_FMD_LOCK_BLOCKS:
        // Lock one of more blocks in a specified range.
        if (!pInBuf || nInBufSize < sizeof(BlockLockInfo))
        {
            RETAILMSG(ZONE_TEST, (TEXT("FMD_OEMIoControl: IOCTL_FMD_LOCK_BLOCKS bad parameter(s).\r\n")));
            return(FALSE);
        }
        if (!SetBlockLock(((PBlockLockInfo)pInBuf)->StartBlock, ((PBlockLockInfo)pInBuf)->NumBlocks, TRUE))
        {
            RETAILMSG(ZONE_TEST, (TEXT("FMD_OEMIoControl: IOCTL_FMD_LOCK_BLOCKS failed to lock blocks (start=0x%x, number=0x%x).\r\n"), ((PBlockLockInfo)pInBuf)->StartBlock, ((PBlockLockInfo)pInBuf)->NumBlocks));
            return(FALSE);
        }
        break;
    case IOCTL_FMD_UNLOCK_BLOCKS:
        // Unlock one of more blocks in a specified range.
        if (!pInBuf || nInBufSize < sizeof(BlockLockInfo))
        {
            RETAILMSG(ZONE_TEST, (TEXT("FMD_OEMIoControl: IOCTL_FMD_UNLOCK_BLOCKS bad parameter(s).\r\n")));
            return(FALSE);
        }
        if (!SetBlockLock(((PBlockLockInfo)pInBuf)->StartBlock, ((PBlockLockInfo)pInBuf)->NumBlocks, FALSE))
        {
            RETAILMSG(ZONE_TEST, (TEXT("FMD_OEMIoControl: IOCTL_FMD_UNLOCK_BLOCKS failed to unlock blocks (start=0x%x, number=0x%x).\r\n"), ((PBlockLockInfo)pInBuf)->StartBlock, ((PBlockLockInfo)pInBuf)->NumBlocks));
            return(FALSE);
        }
        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:%x.\r\n"),ChipFlashLength));

//	liBasePhyAddr.HighPart	= 0 ;
//	liBasePhyAddr.LowPart	= (DWORD)pChipPhyBaseAddress;

//	pChipBaseAddress=(volatile ULONG *)MmMapIoSpace(liBasePhyAddr,ChipFlashLength,FALSE);
//	pBaseAddress = pChipBaseAddress+(pPhyBaseAddress-pChipPhyBaseAddress);
	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));

    //
    // Assume the flash part is an Intel Strataflash - first check the manufacturer code.
    //

	#if( EP93XX_FLASH_WIDTH ==32 )
		g_bPairedFlash = TRUE;
	#else
		g_bPairedFlash = FALSE;

    #endif

#if 0
    g_bPairedFlash = TRUE;    // Assume flash is paired.
    
    WRITE_COMMAND(pChipBaseAddress, READ_IDENT_CMD);

    nShort[0] = READ_USHORT((volatile USHORT *)pChipBaseAddress + QS_MFGCODE_OFFSET + 0) ;
    nShort[1] = READ_USHORT((volatile USHORT *)pChipBaseAddress + QS_MFGCODE_OFFSET + 1) ;
    nShort[2] = READ_USHORT((volatile USHORT *)pChipBaseAddress + QS_MFGCODE_OFFSET + 2) ;
    nShort[3] = READ_USHORT((volatile USHORT *)pChipBaseAddress + QS_MFGCODE_OFFSET + 3) ;

	RETAILMSG(ZONE_TEST, (TEXT("INFO: Flash id %x %x %x %x.\r\n"),nShort[0],nShort[1],nShort[2],nShort[3]));

    //
    //verify the flash is 16 or 32bit
    //
    if( (nShort[0]& MFGCODE_INTEL) == MFGCODE_INTEL )
    {
        if( (nShort[1]& MFGCODE_INTEL) == MFGCODE_INTEL )
        {
            RETAILMSG(ZONE_TEST, (TEXT("INFO: Found paired Intel flash.\r\n")));
            g_bPairedFlash = TRUE;
        }
		else
        {
            RETAILMSG(ZONE_TEST, (TEXT("INFO: Found single Intel flash.\r\n")));
            g_bPairedFlash = FALSE;
        }
    }
    else if( (nShort[0]& MFGCODE_MICRON) == MFGCODE_MICRON )
    {
        if( (nShort[1]& MFGCODE_INTEL) == MFGCODE_INTEL )
        {
            RETAILMSG(ZONE_TEST, (TEXT("INFO: Found paired Micron flash.\r\n")));
            g_bPairedFlash = TRUE;
        }
		else
        {
            RETAILMSG(ZONE_TEST, (TEXT("INFO: Found single Micron flash.\r\n")));
            g_bPairedFlash = FALSE;
        }
    }
    else
    {
        RETAILMSG(1, (TEXT("ERROR: InitializeFlash: invalid manufacturing code. %08x %04x\r\n"),nShort[0],nShort[1]));
        return(FALSE);
    }
#endif
    //
    // Look for a Common Flash Interface (CFI).
    //
    WRITE_COMMAND(pChipBaseAddress, READ_QUERY_CMD);
    if (!CHECK_STATUS_INDEXED(pChipBaseAddress, QS_IDSTRING_OFFSET,  IDSTRING_Q) ||
        !CHECK_STATUS_INDEXED(pChipBaseAddress, QS_IDSTRING_OFFSET + 1, IDSTRING_R) ||
        !CHECK_STATUS_INDEXED(pChipBaseAddress, QS_IDSTRING_OFFSET + 2, IDSTRING_Y))
    {
        RETAILMSG(ZONE_TEST, (TEXT("INFO: Do not support CFI. Maybe it is Micron Flash.\r\n")));
        g_FMDInfo.Geometry.NumEraseBlocks = 1;
        g_FMDInfo.Geometry.FlashRegionInfo[0].block_size = 0x200;
        g_FMDInfo.Geometry.WriteBuffSize = 5;
    }
    else
    {
        // 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;

	nLong=1<<g_FMDInfo.Geometry.DevSize;
	
//    nLong = (ULONG)pow(2,g_FMDInfo.Geometry.DevSize);
    if (g_bPairedFlash) 
    {
       //nLong*= 2;
		nLong<<=1;
    }
    if(ChipFlashLength!=nLong)
    {
		RETAILMSG(ZONE_TEST, (TEXT("INFO: CFI query error:Device size= %x,register chipfile=%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.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).
    //
    WRITE_COMMAND(pChipBaseAddress, READ_ARRAY_CMD);

	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 + -