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

📄 intel-j3.cpp

📁 Ep93XX TionProV2 BSP
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    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 3\r\n")));
            return 0;
        }
    }
    WRITE_COMMAND(ulBlockAddress, READ_ARRAY_CMD);
    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);
    
    // Determine the address for the specified block.
    ulBlockAddress  =  g_FMDInfo.BaseAddress + (blockID * g_FMDInfo.BlockSize);

    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));
        
    // TODO
#if 0
    if ((ulStatus & 0x00200000) || (ulStatus & 0x00000020))
    {
        if (ulStatus & 0x00200000)
            RETAILMSG(1, (TEXT("\n\rBlock erase failure.  Lock bit upper flash set!\r\n")));

        if (ulStatus & 0x00000020)
            RETAILMSG(1, (TEXT("\n\rBlock erase failure.  Lock bit lower flash set!\r\n")));

         RETAILMSG(1, (TEXT("Unrecoverable failure encountered while erasing flash.\r\n")));
        return(FALSE);
    }
#endif

    // Set the block back to read array mode...
    WRITE_COMMAND(ulBlockAddress, READ_ARRAY_CMD);
    SetWriteProtect(TRUE);

    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(1, (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(1, (TEXT("FMD_OEMIoControl: IOCTL_FMD_LOCK_BLOCKS bad parameter(s).\r\n")));
            return(FALSE);
        }
        if (!SetBlockLock(((PBlockLockInfo)pInBuf)->StartBlock, ((PBlockLockInfo)pInBuf)->NumBlocks, TRUE))
        {
            RETAILMSG(1, (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(1, (TEXT("FMD_OEMIoControl: IOCTL_FMD_UNLOCK_BLOCKS bad parameter(s).\r\n")));
            return(FALSE);
        }
        if (!SetBlockLock(((PBlockLockInfo)pInBuf)->StartBlock, ((PBlockLockInfo)pInBuf)->NumBlocks, FALSE))
        {
            RETAILMSG(1, (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(1, (TEXT("FMD_OEMIoControl: unrecognized IOCTL (0x%x).\r\n"), dwIoControlCode));
        return(FALSE);
    }

    return(TRUE);
}


BOOLEAN InitializeFlash(volatile ULONG * pBaseAddressPh, ULONG FlashLength)
{
    UCHAR nCount = 0;
	volatile ULONG * pBaseAddress;
    USHORT nShort[4];
//    LARGE_INTEGER    liBasePhyAddr ;

	InitializeFlashSMC( );

    ASSERT(pBaseAddress);
    ASSERT(FlashLength);

    if (!pBaseAddressPh || !FlashLength)
        return(FALSE);

    RETAILMSG(1, (TEXT("INFO: InitializeFlash. Intel J3 like Flash defined\r\n")));

    // Assume the flash part is an Intel Strataflash - first check the manufacturer code.
    //
	pBaseAddress	=pBaseAddressPh;

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

#if 0
    g_bPairedFlash = TRUE;    // Assume flash is paired.
    WRITE_COMMAND(pBaseAddress, READ_IDENT_CMD);
    nShort[0] = READ_USHORT((volatile USHORT *)pBaseAddress + QS_MFGCODE_OFFSET + 0) ;
    nShort[1] = READ_USHORT((volatile USHORT *)pBaseAddress + QS_MFGCODE_OFFSET + 1) ;
    nShort[2] = READ_USHORT((volatile USHORT *)pBaseAddress + QS_MFGCODE_OFFSET + 2) ;
    nShort[3] = READ_USHORT((volatile USHORT *)pBaseAddress + QS_MFGCODE_OFFSET + 3) ;
    if( (nShort[0]& MFGCODE_INTEL) == MFGCODE_INTEL )
    {
        if( (nShort[1]& MFGCODE_INTEL) == MFGCODE_INTEL )
        {
            RETAILMSG(1, (TEXT("INFO: Found paired Intel flash.\r\n")));
            g_bPairedFlash = TRUE;
        }else
        {
            RETAILMSG(1, (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(1, (TEXT("INFO: Found paired Micron flash.\r\n")));
            g_bPairedFlash = TRUE;
        }else
        {
            RETAILMSG(1, (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(pBaseAddress, READ_QUERY_CMD);
    if (!CHECK_STATUS_INDEXED(pBaseAddress, QS_IDSTRING_OFFSET,  IDSTRING_Q) ||
        !CHECK_STATUS_INDEXED(pBaseAddress, QS_IDSTRING_OFFSET + 1, IDSTRING_R) ||
        !CHECK_STATUS_INDEXED(pBaseAddress, QS_IDSTRING_OFFSET + 2, IDSTRING_Y))
    {
        RETAILMSG(1, (TEXT("INFO: Do not support CFI. Maybe it is Micron Flash.\r\n")));
        g_FMDInfo.Geometry.NumEraseBlocks = 1;
        g_FMDInfo.Geometry.EraseRegionSize = 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(pBaseAddress, QS_SYSINTF_OFFSET + nCount) & 0xFF);
        }
        for (nCount = 0 ; nCount < sizeof(FLASH_GEOMETRY_INFO) ; nCount++)
        {
            *((PUCHAR)&g_FMDInfo.Geometry + nCount) = (UCHAR)(READ_FLASH_INDEXED(pBaseAddress, QS_DEVGEOM_OFFSET + nCount) & 0xFF);
        }
    }
    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...
    //
    if (g_FMDInfo.Geometry.NumEraseBlocks != 1)
    {
        RETAILMSG(1, (TEXT("ERROR: InitializeFlash: more than one block per erase region (%d).\r\n"),
			g_FMDInfo.Geometry.NumEraseBlocks));
        return(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.
    g_FMDInfo.BlockSize           = (g_FMDInfo.Geometry.EraseRegionSize * REGION_SIZE_MULT);
    if (g_bPairedFlash) 
    {
        g_FMDInfo.BlockSize *= 2;
    }
    RETAILMSG(1, (TEXT("InitializeFlash: (%d -- %d --%d).\r\n"),
		g_FMDInfo.Geometry.NumEraseBlocks,
		g_FMDInfo.Geometry.EraseRegionSize,
		g_FMDInfo.BlockSize
		));
    // 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 (!IS_BLOCK_ALIGNED(pBaseAddressPh) || !IS_BLOCK_ALIGNED(FlashLength))
    {
        RETAILMSG(1, (TEXT("ERROR: InitializeFlash: base address and length must be block-aligned (Base=0x%x, Length=0x%x).\r\n"),
			(ULONG)pBaseAddressPh, FlashLength));
        return(FALSE);
    }

    // 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(pBaseAddress, READ_ARRAY_CMD);

    return(TRUE);
}

⌨️ 快捷键说明

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