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

📄 fmd.cpp

📁 我自己编译的armv4i wince60模拟器的bps源文件,已经验证可以使用,欢迎下载
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        }

        ASSERT(0);
        return;
    }

    
    virtual BOOL DefineLayout()
    {
        PFlashRegion pRegion = NULL;

        ASSERT(m_cbSector);

        // Find the MBR to determine if there is a flash layout sector
        LPBYTE pFlashAddress = (LPBYTE)m_dwBaseAddr;
        m_cRegions = 0;

        // Don't read FLS if g_bXIPEntire is set.
        if (!m_fXIPEntire) 
        {
            for (UINT i = 0; i < m_cBlocks; i++)
            {
                // compare the signatures
                if (IS_VALID_BOOTSEC(pFlashAddress)) 
                {
                    pFlashAddress += m_cbSector;
                    if (IS_VALID_FLS(pFlashAddress)) 
                    {
                        // Cache the flash layout sector information
                        PFlashLayoutSector pFLS = (PFlashLayoutSector)pFlashAddress;
                        m_cReserved = pFLS->cbReservedEntries / sizeof(ReservedEntry);
                        m_cRegions = pFLS->cbRegionEntries / sizeof(FlashRegion);

                        // ReservedEntry table starts at the end of the PFlashLayoutSector struct.                
                        PReservedEntry pEntry = (PReservedEntry)(pFLS+1);

                        if (m_cReserved)
                        {
#ifdef UNDER_BOOTLOADER
                            // Not enough room in the statically allocated buffer to store reserved table.
                            if (m_cReserved > MAX_RESERVES)
                                return FALSE;
#else                    
                            m_pReservedTable = (PReservedEntry)LocalAlloc (0, m_cReserved * sizeof(ReservedEntry));
                            if (!m_pReservedTable)
                                return FALSE;
#endif
                            memcpy (m_pReservedTable, pEntry, m_cReserved * sizeof(ReservedEntry));
                        }
                        
                        // FlashRegion table starts after the ReservedEntry table. 
                        if (m_cRegions)
                        {
                            pRegion = (PFlashRegion)((LPBYTE)pEntry + pFLS->cbReservedEntries); 
                        }
                    }
                    break;        
                }

                pFlashAddress += m_cbBlock;
            }
        }
        
        if (!m_cRegions) 
        {
            m_cRegions = 1;
        }

#ifdef UNDER_BOOTLOADER
        // Not enough room in the statically allocated buffer to store region table.
        if (m_cRegions > MAX_REGIONS)
            return FALSE;
#else                    
        m_pRegionTable = (PFlashRegion)LocalAlloc (0, m_cRegions * sizeof(FlashRegion));
        m_pStartSectorTable = (PDWORD)LocalAlloc (0, m_cRegions * sizeof(DWORD));
        if (!m_pRegionTable || !m_pStartSectorTable)
            return FALSE;
#endif

        if (pRegion)
        {
            memcpy (m_pRegionTable, pRegion, m_cRegions * sizeof(FlashRegion));
        }
        else
        {
            m_pRegionTable[0].dwStartPhysBlock = 0;
            m_pRegionTable[0].dwNumPhysBlocks = m_cBlocks;
            m_pRegionTable[0].dwBytesPerBlock = m_cbBlock;
            m_pRegionTable[0].dwNumLogicalBlocks = FIELD_NOT_IN_USE;
       
            if (m_fXIPEntire)
            {
                m_pRegionTable[0].regionType = XIP;
                m_pRegionTable[0].dwSectorsPerBlock = m_cbBlock / m_cbSector;
                m_pRegionTable[0].dwCompactBlocks = 0;
            }
            else 
            {
                m_pRegionTable[0].regionType = FILESYS;
                m_pRegionTable[0].dwSectorsPerBlock = m_cbBlock / (m_cbSector + sizeof(SectorInfo));
                m_pRegionTable[0].dwCompactBlocks = DEFAULT_COMPACTION_BLOCKS;
            }
        }

        DWORD dwStartSector = 0;
        for (DWORD iRegion = 0; iRegion < m_cRegions; iRegion++)
        {
            m_pStartSectorTable[iRegion] = dwStartSector;
            dwStartSector += m_pRegionTable[iRegion].dwNumPhysBlocks * m_pRegionTable[iRegion].dwSectorsPerBlock;
        }
        
        return TRUE;
    }

    virtual BOOLEAN SetBlockLock(BLOCK_ID blockID, ULONG NumBlocks, BOOL fLock) {
        return FALSE;
    }

    virtual BOOL ReadWriteReserved (PReservedReq pReq, BOOL fRead)
    {
        PCSTR szName = pReq->szName;
        LPBYTE pBuffer = pReq->pBuffer;

        for (DWORD i = 0; i < m_cReserved; i++)
        {
            if (_strnicmp(szName, m_pReservedTable[i].szName, RESERVED_NAME_LEN) == 0)
            {
                //
                // Found a region name match
                //
                
                // Verify the request is in the valid range
                DWORD dwRegionSize = m_pReservedTable[i].dwNumBlocks * m_cbBlock;
                if ((pReq->dwStart >= dwRegionSize) || (pReq->dwStart + pReq->dwLen > dwRegionSize)) 
                {
                    DEBUGMSG(ZONE_ERROR, (TEXT("ReadWriteReserved: Invalid request.  Start: 0x%x.  Len: 0x%x\r\n"), pReq->dwStart, pReq->dwLen));
                    goto Error;
                }

                if (fRead)
                {
                    PVOID pStartAddress = (PVOID)(m_dwBaseAddr + m_pReservedTable[i].dwStartBlock * m_cbBlock + pReq->dwStart);
                    memcpy (pBuffer, pStartAddress, pReq->dwLen);
                }
                else
                {
                    // 
                    // Write flash case
                    //

                    if (pReq->dwStart % m_cbSector)
                    {
                        DEBUGMSG(ZONE_ERROR, (TEXT("ReadWriteReserved: Invalid write request.  Start: 0x%x is not sector aligned.\r\n"), pReq->dwStart));
                        goto Error;
                    }

                    DWORD dwStartBlock = pReq->dwStart / m_cbBlock + m_pReservedTable[i].dwStartBlock;
                    DWORD dwEndBlock = (pReq->dwStart + pReq->dwLen - 1) / m_cbBlock + m_pReservedTable[i].dwStartBlock;
                    DWORD dwWriteRemain = pReq->dwLen;

                    for (DWORD iBlock = dwStartBlock; iBlock <= dwEndBlock; iBlock++)
                    {
                        DWORD dwBlockWriteLen = MIN (m_cbBlock, dwWriteRemain);
                        DWORD dwBlockOffset = 0;

                        // If this is the first block, then start at the appropriate offset within the block
                        if (iBlock == dwStartBlock)
                        {   
                            dwBlockOffset = pReq->dwStart % m_cbBlock;
                            dwBlockWriteLen = MIN (dwBlockWriteLen, m_cbBlock - dwBlockOffset);
                        }

                        if (!EraseBlock(iBlock)) {
                            DEBUGMSG(ZONE_ERROR, (TEXT("ReadWriteReserved: EraseBlock failed (0x%x).\r\n"), iBlock));
                            goto Error;
                        }


                        if (!WriteBlock (iBlock, pBuffer, dwBlockOffset, dwBlockWriteLen)) 
                        {
                            DEBUGMSG(ZONE_ERROR, (TEXT("ReadWriteReserved: WriteBlock failed (0x%x).\r\n"), iBlock));
                            goto Error;
                        }
                            
                        pBuffer += dwBlockWriteLen;
                        dwWriteRemain -= dwBlockWriteLen;

                    }                                
                }
                
                return TRUE;

            }
        }

    Error:
        return FALSE;    
    }


    BOOL RawWriteBlocks (PRawWriteBlocksReq pReq) 
    {
        DWORD dwEndBlock = pReq->dwStartBlock + pReq->dwNumBlocks - 1;
        LPBYTE pBuffer = pReq->pBuffer;
        BOOL fRet = FALSE;
        
        if (pReq->dwStartBlock >= m_cBlocks || 
             dwEndBlock >= m_cBlocks ||
             dwEndBlock < pReq->dwStartBlock)
        {
            DEBUGMSG(ZONE_ERROR, (TEXT("RawWriteBlocks: Invalid request: (0x%x, 0x%x)\r\n"), pReq->dwStartBlock, pReq->dwNumBlocks));
            goto Error;
        }  

        if (pReq->cbBuffer < (pReq->dwNumBlocks * m_cbBlock))
        {
            DEBUGMSG(ZONE_ERROR, (TEXT("RawWriteBlocks: Insufficient buffer: (0x%x)\r\n"), pReq->cbBuffer));
            goto Error;
        }  
             
        for (DWORD dwBlock = pReq->dwStartBlock; dwBlock <= dwEndBlock; dwBlock++)
        {   
            if (!WriteBlock (dwBlock, pBuffer, 0, m_cbBlock))
            {
                DEBUGMSG(ZONE_ERROR, (TEXT("RawWriteBlocks: WriteBlock failed (0x%x).\r\n"), dwBlock));
                goto Error;
            }
                
            PREFAST_SUPPRESS (12008, "pReq->dwNumBlocks is validated above");
            pBuffer += m_cbBlock;
        }

        fRet = TRUE;

    Error:
        return fRet;    
    }



    static DWORD BLOCK_SIG_LOC(DWORD dwBlockStart, DWORD cbBlock) 
    {
        return dwBlockStart + cbBlock - sizeof(m_rgdwBlockSig);
    }
    

    BOOL VerifySignatures()
    {
        if (m_fXIPEntire)
            return TRUE;
        
        ULONG iRetVal;
        ULONG ulBlockStart;

        for (UINT iRegion = 0; iRegion < m_cRegions; iRegion++)
        {
            if (m_pRegionTable[iRegion].regionType == XIP)
                continue;
            
            ulBlockStart = m_dwBaseAddr + (m_pRegionTable[iRegion].dwStartPhysBlock * m_cbBlock);

            for (UINT iBlock = m_pRegionTable[iRegion].dwStartPhysBlock; iBlock < m_pRegionTable[iRegion].dwStartPhysBlock + m_pRegionTable[iRegion].dwNumPhysBlocks; iBlock++)
            {
                if (!(FMD_GetBlockStatus(iBlock) & BLOCK_STATUS_RESERVED))
                {
                    // compare the signatures
                    iRetVal = memcmp((void *) BLOCK_SIG_LOC(ulBlockStart, m_cbBlock),
                    				 m_rgdwBlockSig, 
                    				 sizeof(m_rgdwBlockSig));

                    if (iRetVal != 0)
                    {
                        DEBUGMSG(ZONE_ERROR, (TEXT("VerifySignatures: invalid block detected, calling FMD_EraseBlock\r\n")));
                        if (!FMD_EraseBlock(iBlock))
                        {
                            DEBUGMSG(ZONE_ERROR, (TEXT("VerifySignatures: error in FMD_EraseBlock, bailing\r\n")));
                            return FALSE;
                        }
                    }
                }
                
                // increment to the next block
                ulBlockStart += m_cbBlock;
            }
        }
        
        return TRUE;
    }


    virtual BOOL WriteBlock (DWORD dwBlock, LPBYTE pBuffer, DWORD dwStartByteOffset, DWORD dwByteLen) = 0;


    static  const DWORD   m_rgdwBlockSig[8];


    DWORD   m_dwBaseAddr;
    DWORD   m_dwLength;

    DWORD   m_cbSector;
    DWORD   m_cbBlock;
    DWORD   m_cBlocks;
    
    DWORD   m_cRegions;
    DWORD   m_cReserved;
    
    BOOL    m_fXIPEntire;
    BOOL    m_fUpdateMode;

#ifdef UNDER_BOOTLOADER
    ReservedEntry    m_pReservedTable[MAX_RESERVES];
    FlashRegion      m_pRegionTable[MAX_REGIONS];
    DWORD            m_pStartSectorTable[MAX_REGIONS];
#else
    // Dynamically allocate this under the OS
    PReservedEntry   m_pReservedTable;
    PFlashRegion     m_pRegionTable;
    PDWORD           m_pStartSectorTable;
#endif
};


// We sign the last 32 bytes of each flash block so we can verify that the block
// is valid at boot time.  OEMs should feel free to modify gc_dwBlockSig
const DWORD CNorFmd::m_rgdwBlockSig[8] = {0xC1552106, 0xDF9C29D5, 0xBAB8EAB8, 0x82D3F9F3,
    0x3B438A47, 0xA9D92AE6, 0x09396731, 0x12BF6753};


#define CB_USABLE_FLASH_OFFSET  IMAGE_IPL_SIZE
#define CB_USABLE_FLASH         (AMD_FLASH_SIZE - CB_USABLE_FLASH_OFFSET)
#define CB_BLOCK                0x10000
#define CB_SECTOR               0x1000
#define BLOCK_COUNT             (CB_USABLE_FLASH / CB_BLOCK)


class CAmdNorFmd : public CNorFmd {
public:
    CAmdNorFmd() : CNorFmd() {}
    virtual ~CAmdNorFmd() {}

    virtual PVOID Init(LPCTSTR lpActiveReg, PPCI_REG_INFO pRegIn, PPCI_REG_INFO pRegOut) {
        PVOID pvRet = NULL;

        DEBUGMSG(ZONE_INIT, (TEXT("FMD_Init(0x%x, 0x%x, 0x%x)\r\n"), lpActiveReg, pRegIn, pRegOut));

#ifdef UNDER_BOOTLOADER
        // Get flash base address and length from caller.
        if (!pRegIn || !pRegIn->MemBase.Num || !pRegIn->MemLen.Num) {

⌨️ 快捷键说明

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