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

📄 fmd.cpp

📁 我自己编译的armv4i wince60模拟器的bps源文件,已经验证可以使用,欢迎下载
💻 CPP
📖 第 1 页 / 共 4 页
字号:
            DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: FMD_Init: invalid flash memory base and/or length specified by caller.\r\n")));
            goto EXIT;
        }
        else {
            m_dwBaseAddr = pRegIn->MemBase.Reg[0];
            m_dwLength = pRegIn->MemLen.Reg[0];
        }
#else
        {
            // Get info from the registry
            HKEY hkDevice = OpenDeviceKey(lpActiveReg);
            CReg regDevice(hkDevice, TEXT(""));
            if (hkDevice == NULL) {
                DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: FMD_Init: OpenDeviceKey(%s) failed.\r\n"), lpActiveReg));
                goto EXIT;
            }
            RegCloseKey(hkDevice);

            DDKWINDOWINFO dwi;
            dwi.cbSize = sizeof(dwi);
            if (DDKReg_GetWindowInfo(regDevice, &dwi) != ERROR_SUCCESS) {
                DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: FMD_Init: DDKReg_GetWindowInfo() failed.\r\n")));
                goto EXIT;
            }
            // The first memory window contains the base address and length of our flash part.
            if (dwi.dwNumMemWindows == 0) {
                DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: FMD_Init: DDKReg_GetWindowInfo() found no windows.\r\n")));
                goto EXIT;
            }
                
            m_dwBaseAddr = dwi.memWindows[0].dwBase;
            m_dwLength = dwi.memWindows[0].dwLen;
        }
#endif

        if (!AM29LV800_Init(m_dwBaseAddr - CB_USABLE_FLASH_OFFSET)) {
            DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: FMD_Init: AM29LV800_Init(0x%x) failed.\r\n"), m_dwBaseAddr));
            goto EXIT;
        }

        m_cbSector = CB_SECTOR;
        m_cbBlock = CB_BLOCK;
        m_cBlocks = BLOCK_COUNT;

        if (!DefineLayout()) {
            DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: FMD_Init: DefineLayout failed.\r\n")));
            goto EXIT;
        }

#ifndef UNDER_BOOTLOADER
        // Verify that the block signatures are all intact
        if (!VerifySignatures()) {
            DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: FMD_Init: Error while trying to verify block signatures.\r\n")));
            goto EXIT;
        }
#endif

        pvRet = VALID_FMD_HANDLE;

    EXIT:
        return pvRet;
    }


    virtual BOOL  EraseBlock(BLOCK_ID blockID) {
        DEBUGMSG(ZONE_INIT, (TEXT("FMD_EraseBlock(0x%x)\r\n"), blockID));
        return AM29LV800_EraseFlash((blockID * CB_BLOCK) + CB_USABLE_FLASH_OFFSET, CB_BLOCK);
    }


    virtual BOOL  WriteSector (SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors) {
        DEBUGMSG(ZONE_INIT, (TEXT("FMD_WriteSector(0x%x, 0x%x, 0x%x, 0x%x)\r\n"), startSectorAddr, pSectorBuff, pSectorInfoBuff, dwNumSectors));        
        
        volatile SECTOR_ADDR physicalSectorAddr = 0;
        volatile SECTOR_ADDR physicalSectorInfoAddr = 0;
        BOOL fRet = FALSE;
        
        //----- 1. Check the input parameters -----
        //         NOTE: The FAL insures that the starting sector address is in the allowable range.
        if((dwNumSectors == 0) || ((pSectorBuff == NULL) && (pSectorInfoBuff == NULL)))
        {
            return(FALSE);
        }

        //----- 2. Process the write request(s)... -----
        for(DWORD i = startSectorAddr; i < (startSectorAddr + dwNumSectors); i++)
        {
            //----- Compute the physical address for the requested -----
            GetPhysicalSectorAddress(i, (PSECTOR_ADDR)&physicalSectorAddr, (PSECTOR_ADDR)&physicalSectorInfoAddr);

            //----- Write the necessary sector data -----       
            if(pSectorBuff)
            {
                fRet = AM29LV800_WriteFlash(physicalSectorAddr, pSectorBuff, m_cbSector);
                if (fRet == FALSE) {
                    goto exit;
                }
                
                pSectorBuff += m_cbSector;
            }

            //----- Write the necessary sector info data (metadata) -----
            if (!m_fXIPEntire && pSectorInfoBuff)
            {
                fRet = AM29LV800_WriteFlash(physicalSectorInfoAddr, (PBYTE)pSectorInfoBuff, sizeof(SectorInfo));
                if (fRet == FALSE) {
                    goto exit;
                }
                
                pSectorInfoBuff++;            
            }
        }

        fRet = TRUE;

    exit:

        return fRet;
    }
        


protected:


    BOOL WriteBlock (DWORD dwBlock, LPBYTE pBuffer, DWORD dwStartByteOffset, DWORD dwByteLen)
    {
        if (!EraseBlock(dwBlock)) 
        {
            DEBUGMSG(ZONE_ERROR, (TEXT("ReadWriteReserved: FMD_EraseBlock failed 0x%x.\r\n"), dwBlock));
            return FALSE;
        }

        DWORD dwAddr = CB_USABLE_FLASH_OFFSET + (dwBlock * m_cbBlock) + dwStartByteOffset;

        if (!AM29LV800_WriteFlash(dwAddr, pBuffer, dwByteLen)) {
            return FALSE;
        }
        
        return TRUE;
    }

    
};



#ifdef UNDER_BOOTLOADER
static BYTE s_rgbFmdBuffer[sizeof(CAmdNorFmd)];
static CFmd *s_pFmd = (CFmd*) s_rgbFmdBuffer;
#else
static CAmdNorFmd s_fmd;
CFmd *s_pFmd = &s_fmd;
#endif



/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Function:       FMD_Init()

Description:    This function is called by the by the DLLMain and initializes 
                the flash memory bank.

Parameters:     lpActiveReg [in] 
                    Pointer to the active registry string used to find device 
                    information from the registry. Set to NULL if not needed.
                pRegIn [in] 
                    Pointer to a PCI_REG_INFO structure. Used to find flash 
                    hardware on PCI hardware. Set to NULL if not needed.
                pRegOut [out] 
                    Pointer to a PCI_REG_INFO structure. Used to return flash 
                    information. Set to NULL if not needed.

Return Values:  A handle that can be used in a call to FMD_Deinit. It is the 
                responsibility of the specific Flash Media Driver (FMD) 
                implementation to determine what this value represents. 
                A value of 0 represents failure.

-------------------------------------------------------------------------------*/
PVOID  FMD_Init(LPCTSTR lpActiveReg, PPCI_REG_INFO pRegIn, PPCI_REG_INFO pRegOut)
{
    PREFAST_ASSERT(s_pFmd);
    
#ifdef UNDER_BOOTLOADER
    new (s_pFmd) CAmdNorFmd;
#endif

    return s_pFmd->Init(lpActiveReg, pRegIn, pRegOut);
}

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Function:       FMD_Deinit()

Description:    This function provides the code to clean-up any resources 
                the FMD may have acquired in the course of the operation.

Parameters:     hFMD [in] 
                    The handle returned from FMD_Init.

Return Values:  A boolean indicating function result.
                    TRUE on success. 
                    FALSE on failure.

Remarks:        Always returns TRUE.

-------------------------------------------------------------------------------*/
BOOL  FMD_Deinit(PVOID pv)
{
    PREFAST_ASSERT(s_pFmd);
    BOOL fRet = s_pFmd->Deinit(pv);
    
#ifdef UNDER_BOOTLOADER
    s_pFmd->~CFmd();
#endif

    return fRet;
}


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Function:       FMD_GetInfo()

Description:    This function reports the characteristics for the 
                underlying flash memory.

Parameters:     pFlashInfo [out] 
                    A pointer to a structure that contains the size 
                    characteristics for the flash memory device.

Return Values:  A boolean indicating function result.
                    TRUE on success. 
                    FALSE on failure.

Remarks:        Even for NOR flash memory, the media must be logically divided 
                into sectors.  It is the responsibility of the specific FMD 
                implementation to determine how this is accomplished.

                To compute the number of sectors per block, divide the total 
                Flash block size by the number of bytes per sector and the 
                number bytes for the sector metadata.

-------------------------------------------------------------------------------*/
BOOL  FMD_GetInfo(PFlashInfo pFlashInfo)
{
    PREFAST_ASSERT(s_pFmd);
    return s_pFmd->GetInfo(pFlashInfo);
}

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:       FMD_GetInfoEx()

Description:    Determines the size characteristics for the Flash memory device.
                     Includes support for multiple regions.

Notes:          If pFlashInfo is NULL, then this just returns the number of reserved regions.

Returns:        Boolean indicating success.
------------------------------------------------------------------------------*/
BOOL  FMD_GetInfoEx(PFlashInfoEx pFlashInfo, PDWORD pdwNumRegions)
{
    PREFAST_ASSERT(s_pFmd);
    return s_pFmd->GetInfoEx(pFlashInfo, pdwNumRegions);
}


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:       FMD_GetPhysSectorAddr()

Description:    Returns the physical address for the physical sector passed in.
               
Returns:        None
------------------------------------------------------------------------------*/
VOID FMD_GetPhysSectorAddr (DWORD dwSector, PSECTOR_ADDR pStartSectorAddr)
{
    PREFAST_ASSERT(s_pFmd);
    return s_pFmd->GetPhysSectorAddr(dwSector, pStartSectorAddr);
}


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Function:       FMD_GetBlockStatus()

Description:    This function returns the status of a block.
                Returns the status of a block.  For read-only blocks, checks 
                the sector info data for the first sector of the block.  Block 
                is always good, so no need to check.

Parameters:     blockID [in] 
                    The block number used to check status.
                    
Return Values:  A double word value describing the status of the block.  The 
                values defined are as follows:
                
                    Value                   Description
                    -----                   -----------
                    BLOCK_STATUS_UNKNOWN    The status could not be determined 
                                            as a result of a read error.
                    BLOCK_STATUS_BAD        The block is bad.
                    BLOCK_STATUS_READONLY   The block is read-only.
                    BLOCK_STATUS_RESERVED   The block is reserved.

Remarks:        It is the responsibility of the caller of the FMD to check and 
                interpret the block status.  If the FMD is used with the Flash 
                Abstraction Layer (FAL), then a read-only block will be mapped 
                to a logical sector but will not allow write access.  A 
                reserved block will not be mapped to a logical sector and 
                therefore will not be used by the FAL.  A bad block will be 
                ignored.

-------------------------------------------------------------------------------*/
DWORD FMD_GetBlockStatus(BLOCK_ID blockID)
{
    PREFAST_ASSERT(s_pFmd);
    return s_pFmd->GetBlockStatus(blockID);
}

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Function:       FMD_SetBlockStatus()

Description:    This function sets the status of a block.

Parameters:     blockID [in] 
                    The block number used to set status.
                dwStatus [in] 
                    The status value to set.  The values that can be used to 
                    describe the status of the block are as follows:
                    
                    Value                   Description
                    -----                   -----------
                    BLOCK_STATUS_BAD        The block is bad.
                    BLOCK_STATUS_READONLY   The block is read-only.
                    BLOCK_STATUS_RESERVED   The block is reserved.

Return Values:  A boolean indicating function result.
                    TRUE on success. 
                    FALSE on failure.

------------------------------------------------------------------------------*/
BOOL FMD_SetBlockStatus(BLOCK_ID blockID, DWORD dwStatus)
{
    PREFAST_ASSERT(s_pFmd);
    return s_pFmd->SetBlockStatus(blockID, dwStatus);
}

⌨️ 快捷键说明

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