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

📄 fmd.cpp

📁 mx27 f14v2 源代码。包括ADS板上诸多驱动的源码。
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//     518 doesn't divide by 4 evenly).  
//     Furthemore, we see that this NOR Flash memory can map (504*256)==>129,024 
//     physical sectors.
// 
//     Note:
//     Unlike NAND, the sector meta info is groups together at the end of the
//     flash block.
// 
//     Two other points are worth mentioning:
//         1) NOR Flash memory is guaranteed by manufacturing to ship with no 
//            bad Flash blocks.
//         2) NOR Flash memory doesn't suffer from electrical leakage currents
//            (like NAND Flash) and does not require error-correction codes 
//            (ECC) to insure data integrity.
// 
// Environment:  
//     As noted, this media driver works on behalf of the FAL to directly
//     access the underlying FLASH hardware.  Consquently, this module 
//     needs to be linked with FAL.LIB to produce the device driver 
//     named FLASHDRV.DLL.
//
// Parameters:
//      pGeometry
//          [in] pointer to flash geometry information
//
//      pLayout
//          [out] pointer to virtual layout infomation.
//
// Returns:  
//      TRUE if successful, FALSE otherwise.
//
//------------------------------------------------------------------------------
static BOOL DefineLayout(BOOL bIsPaired, CFI_FLASH_GEOMETRY_INFO *pGeometry,
    NOR_FMD_FLASH_INFO *pInfo)
{
    ULONG FMDBase;
    ULONG FMDLength;
    ULONG FlashWalkAddr;
    ULONG EraseBlockSize;
    ULONG MaxEraseBlockSize;
    BOOL bFMDStartAligned;
    ULONG i;
    ULONG j;
    DWORD NumBlocks;
    ULONG LogicalBlockSize;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("DefineLayout+\r\n")));

    // Currently CE only supported sector size of 512.
    FMDBase = pInfo->BaseAddress + pInfo->FMDBaseOffset;
    FMDLength = pInfo->FlashLength - pInfo->FMDBaseOffset;
    DEBUGMSG(ZONE_FUNCTION, (TEXT("FMDBase 0x%08X FMDLength 0x%08X+\r\n"),
        FMDBase, FMDLength));

    // Get max block size and check FMD allocation is aligned.
    MaxEraseBlockSize = 0;
    FlashWalkAddr = pInfo->BaseAddress;
    bFMDStartAligned = FALSE;
    
    for (i = 0; i < pGeometry->NumEraseBlockRegions; i++) {
        EraseBlockSize = pGeometry->EraseBlockInfo[i].EraseBlockSize
            * CFI_ERASE_BLOCK_SIZE_MULTP;
        EraseBlockSize += bIsPaired ? EraseBlockSize : 0;
        
        for (j = 0; 
            j < (ULONG)(pGeometry->EraseBlockInfo[i].NumIdentEraseBlocks + 1);
            j++) {
            // Don't care sectors before FMD allocation
            if (FlashWalkAddr < FMDBase) {
                FlashWalkAddr += EraseBlockSize;
                continue;
            }
            
            // Check for FMD allocation start alignment with physical NOR sectors.
            // Shift FMD allocation if not aligned.
            if (bFMDStartAligned == FALSE) {
                if (FlashWalkAddr > FMDBase) {
                    // Align FMDBase to physical sector and adjust allocated 
                    // FMD flash accordingly.
                    DEBUGMSG(ZONE_INFO, 
                        (TEXT("INFO: 0x%08x not NOR sector aligned! Shifted to 0x%08x\r\n"),
                        FMDBase, FlashWalkAddr));
                    
                    FMDLength -= (FlashWalkAddr - FMDBase);
                    FMDBase = FlashWalkAddr;
                }
                bFMDStartAligned = TRUE;
            } else {
                // Get max erase block size within FMD reserved region.
                MaxEraseBlockSize = MAX(MaxEraseBlockSize, EraseBlockSize);
            }

            // Increment walk address
            FlashWalkAddr += EraseBlockSize;
        }
    }
    
    DEBUGMSG(ZONE_INFO, (TEXT("INFO: MaxEraseBlockSize 0x%08x\r\n"), 
        MaxEraseBlockSize));
    DEBUGMSG(ZONE_INFO, 
        (TEXT("INFO: Sector aligned FMDBase 0x%08x FMDLength 0x%08x\r\n"), 
        FMDBase, FMDLength));

    // Check for blocks of < max size and combine them if possible to get
    // uniform blocks.
    // Assumptions:
    // 1. Blocks that are less than the basis block size are grouped sequentially.
    // 2. Such a grouping of lesser blocks will amount to one basis block.
    // 3. Such groupings can only occur at the beginning or end of flash device
    FlashWalkAddr = pInfo->BaseAddress;
    NumBlocks = 0;
    LogicalBlockSize = 0;
    
    for (i = 0; i < pGeometry->NumEraseBlockRegions; i++) {
        EraseBlockSize = pGeometry->EraseBlockInfo[i].EraseBlockSize
            * CFI_ERASE_BLOCK_SIZE_MULTP;
        EraseBlockSize += bIsPaired ? EraseBlockSize : 0;
        
        for (j = 0; 
            j < (ULONG)(pGeometry->EraseBlockInfo[i].NumIdentEraseBlocks + 1);
            j++) {
            if (FlashWalkAddr >= FMDBase) {
                if (EraseBlockSize < MaxEraseBlockSize) {
                    // Combine all smaller blocks into single larger logical block
                    DEBUGMSG(ZONE_FUNCTION, 
                        (TEXT("INFO: EraseBlockSize 0x%08x CombineBlockSize 0x%08x\r\n"), 
                        EraseBlockSize, LogicalBlockSize));

                    LogicalBlockSize += EraseBlockSize;

                    if (LogicalBlockSize == MaxEraseBlockSize) {
                        LogicalBlockSize = 0;
                        NumBlocks++;
                        DEBUGMSG(ZONE_FUNCTION, 
                            (TEXT("INFO: Combine blocks success! NumLogicalBlocks 0x%08X\r\n"), 
                            NumBlocks));
                    }
                } else {
                    // Trap combine blocks at start of flash error condition
                    if (LogicalBlockSize != 0 && LogicalBlockSize < MaxEraseBlockSize) {
                        // Combination of blocks is insufficient to form a basis block!
                        // Shift the FMD allocation base in this case
                        ERRORMSG(ZONE_ERROR, 
                            (TEXT("ERROR: unable to combine blocks! Shifted FMD start to 0x%08x\r\n"),
                            FlashWalkAddr));
                        
                        FMDBase = FlashWalkAddr;
                        FMDLength -= LogicalBlockSize;
                        LogicalBlockSize = 0; 
                        NumBlocks = 0;
                    }
                    NumBlocks++;
                    
                    DEBUGMSG(ZONE_FUNCTION, 
                        (TEXT("INFO: Found blocks %d FlashWalkAddr 0x%08X\r\n"), 
                        NumBlocks, FlashWalkAddr));
                    
                    DEBUGMSG(ZONE_FUNCTION, 
                        (TEXT("INFO: i %d j %d\r\n"), 
                        i, j));
                }
            }
            DEBUGMSG(ZONE_FUNCTION, (TEXT("INFO: FlashWalkAddr 0x%08X\r\n"), 
                FlashWalkAddr));
            
            FlashWalkAddr += EraseBlockSize;
        }
    }
    
    // Trap combine blocks at end of flash error condition
    if (LogicalBlockSize != 0 && LogicalBlockSize < MaxEraseBlockSize) {
        // Should never be here!
        ERRORMSG(ZONE_ERROR, 
            (TEXT("ERROR: unable to combine blocks at flash end!\r\n")));
        return FALSE;
    }

    // Return values
    pInfo->FMDBaseOffset = FMDBase - pInfo->BaseAddress;
    pInfo->BytesPerSector = SECTOR_SIZE;
    
    if (!g_bXIPMode) {
        pInfo->SectorsPerBlock = 
            (WORD)(MaxEraseBlockSize / (pInfo->BytesPerSector + sizeof(SectorInfo)));
        
        pInfo->SectorInfoOffset = SECTOR_SIZE * pInfo->SectorsPerBlock;
    } else {
        pInfo->SectorsPerBlock = (WORD)(MaxEraseBlockSize / pInfo->BytesPerSector);
        pInfo->SectorInfoOffset = 0;
    }
    pInfo->NumBlocks = NumBlocks;
    pInfo->EraseBlockSize = MaxEraseBlockSize;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("DefineLayout-\r\n")));
    return TRUE;
}

//------------------------------------------------------------------------------
//
// Function: GetPhysicalSectorAddress
//
// Function returns the actual physical address for start of the sector passed in.
//
// Parameters:
//          dwSector
//          [in] sector number
//
//          pStartSectorAddr
//          [out] physical address.
//
// Returns:  
//      None
//
//------------------------------------------------------------------------------
static void GetPhysicalSectorAddress(DWORD dwSector, PSECTOR_ADDR pStartSectorAddr, PSECTOR_ADDR pStartSectorInfoAddr)
{
    DEBUGMSG(ZONE_FUNCTION, (TEXT("GetPhysicalSectorAddress+\r\n")));

    // Determine the block this sector resides in
    DWORD dwBlockID = dwSector / g_FMDInfo.SectorsPerBlock;
    DWORD dwSectorOffset = dwSector % g_FMDInfo.SectorsPerBlock;
    SECTOR_ADDR BlockAddr;
    
    BlockAddr = g_FMDInfo.BaseAddress + g_FMDInfo.FMDBaseOffset + (dwBlockID * g_FMDInfo.EraseBlockSize);
    *pStartSectorAddr = BlockAddr + (dwSectorOffset * g_FMDInfo.BytesPerSector);

    if(pStartSectorInfoAddr && !g_bXIPMode)
    {
        *pStartSectorInfoAddr = BlockAddr + g_FMDInfo.SectorInfoOffset + (dwSectorOffset * sizeof(SectorInfo));
    }
    DEBUGMSG(ZONE_FUNCTION, (TEXT("GetPhysicalSectorAddress-\r\n")));
}

//------------------------------------------------------------------------------
//
// Function: GetMappedSectorAddress
//
// Function returns the mapped address for start of the sector passed in.
//
// Parameters:
//      dwSector
//          [in] sector number
//
//      pStartSectorAddr
//          [out] mapped sector address.
//
//      pStartSectorInfoAddr
//          [out] mapped sector info address.
//
// Returns:  
//      None
//
//------------------------------------------------------------------------------
static void GetMappedSectorAddress(DWORD dwSector, 
    PSECTOR_ADDR pStartSectorAddr, PSECTOR_ADDR pStartSectorInfoAddr)
{
    DEBUGMSG(ZONE_FUNCTION, 
        (TEXT("GetMappedSectorAddress+, 0x%08X\r\n"), dwSector));

    // Determine the block this sector resides in
    DWORD dwBlockID = dwSector / g_FMDInfo.SectorsPerBlock;
    DWORD dwSectorOffset = dwSector % g_FMDInfo.SectorsPerBlock;
    SECTOR_ADDR BlockAddr;
    
    DEBUGMSG(ZONE_FUNCTION, (TEXT("dwBlockID 0x%08X dwSectorOffset 0x%08X\r\n"), 
        dwBlockID, dwSectorOffset));

    BlockAddr = (ULONG)g_pNORFlashBase + g_FMDInfo.FMDBaseOffset + 
        (dwBlockID * g_FMDInfo.EraseBlockSize);
    
    *pStartSectorAddr = BlockAddr + (dwSectorOffset * g_FMDInfo.BytesPerSector);

    if (pStartSectorInfoAddr && !g_bXIPMode)
        *pStartSectorInfoAddr = BlockAddr + g_FMDInfo.SectorInfoOffset + 
        (dwSectorOffset * sizeof(SectorInfo));

    DEBUGMSG(ZONE_FUNCTION, (TEXT("GetMappedSectorAddress-\r\n")));
}

//------------------------------------------------------------------------------
//
// Function: SetBlockLock
//
// Function locks given number of blocks.
//
// Parameters:
//          blockID
//          [in] start block ID
//
//          NumBlocks
//          [in] number of blocks to lock.
//
//          bLock
//          [in] TRUE to lock blocks
//
// Returns:  
//      FALSE on failure
//
//------------------------------------------------------------------------------
static BOOL SetBlockLock(BLOCK_ID blockID, ULONG NumBlocks, BOOL bLock)
{
    ULONG ulBlockAddress = 0;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("SetBlockLock+\r\n")));
    while(NumBlocks--)
    {
        // Compute the block address.
        ulBlockAddress  =  (ULONG)g_pNORFlashBase + g_FMDInfo.FMDBaseOffset + (blockID * g_FMDInfo.EraseBlockSize);

        if(bLock)
        {
            if(!NORLockSector(ulBlockAddress))
            {
        	    ERRORMSG(ZONE_ERROR, (TEXT("ERROR: Cannot lock block 0x%08X\r\n"), ulBlockAddress));
                return FALSE;
            }
        }
        else
        {
            if(!NORUnlockSector(ulBlockAddress))
            {
        	    ERRORMSG(ZONE_ERROR, (TEXT("ERROR: Cannot unlock block 0x%08X\r\n"), ulBlockAddress));
                return FALSE;
            }
        }
    }

    DEBUGMSG(ZONE_FUNCTION, (TEXT("SetBlockLock-\r\n")));
    return TRUE;
}

//------------------------------------------------------------------------------
// END OF FILE
//------------------------------------------------------------------------------

⌨️ 快捷键说明

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