fmd_tyax.cpp

来自「该BSP是基于PXA270+WINCE的BSP」· C++ 代码 · 共 1,678 行 · 第 1/5 页

CPP
1,678
字号

    SECTOR_ADDR Sector = GetStartSectorInBlock(blockID);        // virtual block.
    if (Sector == INVALID_SECTOR_ADDR)
    {
        LOGMSG(1, (TEXT("FMD_GetBlockStatus:  INVALID_SECTOR_ADDR.  GetStartSectorInBlock() returns 0x%x\r\n"), Sector));
        return(BLOCK_STATUS_UNKNOWN);
    }

    SectorInfo SI;
    DWORD dwResult = 0;

    if (!FMD_ReadSector(Sector, NULL, &SI, 1))
    {
        LOGMSG(1, (TEXT("FMD_GetBlockStatus:  BLOCK_STATUS_UNKNOWN.  FMD_ReadSector returned FALSE\r\n")));
        return(BLOCK_STATUS_UNKNOWN);
    }

    //if (!(SI.bOEMReserved & OEM_BLOCK_READONLY))
    //dwResult |= BLOCK_STATUS_READONLY;

    if (!(SI.bOEMReserved & OEM_BLOCK_RESERVED))
        dwResult |= BLOCK_STATUS_RESERVED;

    //DBGMSG(1, (TEXT("FMD_GetBlockStatus:  dwResult = 0x%x\r\n"), dwResult));

    return(dwResult);
}



/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:       FMD_SetBlockStatus()

Description:    Sets the status of a block.

Returns:        TRUE if no errors in setting.
------------------------------------------------------------------------------*/

BOOL FMD_SetBlockStatus(BLOCK_ID blockID, DWORD dwStatus)
{
    DBGMSG(1, (TEXT("FMD_SetBlockStatus(0x%x,0x%x):\r\n"), blockID, dwStatus));
    // Don't allow setting block status for reserved or XIP blocks.
    if (IsReservedTableBlock(blockID))
        {
        LOGMSG(1, (TEXT("FMD_SetBlockStatus(0x%x,0x%x): Reserved block\r\n"), blockID, dwStatus));
        return(FALSE);
        }

    DWORD dwRegion = GetRegion(blockID);
    if (dwRegion == INVALID_BLOCK_ID)
        {
        LOGMSG(1, (TEXT("FMD_SetBlockStatus(0x%x,0x%x): Invalid block\r\n"), blockID, dwStatus));
        return(FALSE);
        }

    if (g_pRegionTable[dwRegion].regionType == XIP)
        {
        LOGMSG(1, (TEXT("FMD_SetBlockStatus(0x%x,0x%x): XIP block\r\n"), blockID, dwStatus));
        return(FALSE);
        }

    if (dwStatus & (BLOCK_STATUS_READONLY | BLOCK_STATUS_RESERVED))
    {

        SECTOR_ADDR Sector = GetStartSectorInBlock(blockID);
        if (Sector == INVALID_SECTOR_ADDR)
            {
            LOGMSG(1, (TEXT("FMD_SetBlockStatus(0x%x,0x%x): Invalid sector\r\n"), blockID, dwStatus));
            return(FALSE);
            }

        SectorInfo SI;

        if (!FMD_ReadSector(Sector, NULL, &SI, 1))
        {
            LOGMSG(1, (TEXT("FMD_SetBlockStatus(0x%x,0x%x): FMD_ReadSector failed\r\n"), blockID, dwStatus));
            return(FALSE);
        }

        if (dwStatus & BLOCK_STATUS_READONLY)
        {
            SI.bOEMReserved &= ~OEM_BLOCK_READONLY;
        }

        if (dwStatus & BLOCK_STATUS_RESERVED)
        {
            SI.bOEMReserved &= ~OEM_BLOCK_RESERVED;
        }

        if (!FMD_WriteSector (Sector, NULL, &SI, 1))
        {
            LOGMSG(1, (TEXT("FMD_SetBlockStatus(0x%x,0x%x): FMD_WriteSector failed\r\n"), blockID, dwStatus));
            return(FALSE);
        }

    }

    return(TRUE);
}


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:       FMD_EraseBlock()

Description:    Erases the specified Flash block.

Returns:        Boolean indicating success.
------------------------------------------------------------------------------*/
BOOL  FMD_EraseBlock(BLOCK_ID blockID)
{
    //USHORT loopCnt, x;
    //ULONG BlockAdx;
    volatile ULONG ulBlockAddress = 0;
    BOOL bRetVal = TRUE;
#ifndef UNDER_BOOTLOADER
    BOOL bLastMode;
#endif
    BYTE cNullSignature[BLOCK_SIG_BYTES]  = {0};
    struct FMDHAL_CmdStruct CurrCmd;
    DWORD dwRegion = GetRegion(blockID);
    if (dwRegion == INVALID_BLOCK_ID)
    {
        LOGMSG(1, (TEXT("FMD:FMD_EraseBlock: ERROR!  INVALID_BLOCK_ID 0x%x\r\n"), blockID));
        return(FALSE);
    }

    DWORD region_type   = g_pRegionTable[dwRegion].regionType;
    BOOL bXIPBlock      = (region_type == XIP);
    BOOL bReservedBlock = (FMD_GetBlockStatus(blockID) & BLOCK_STATUS_RESERVED);

#ifndef UNDER_BOOTLOADER
    bLastMode = SetKMode(TRUE);
#endif
    // Determine the address for the specified virtual block.
    ulBlockAddress  =  g_FMDInfo.BaseAddress + (blockID * g_FMDInfo.BlockSize);
    DBGMSG(1, (TEXT("FMD:FMD_EraseBlock(0x%x): ba=0x%x\r\n"), blockID, ulBlockAddress));

    CurrCmd.pTargetAddress = (ULONG *)ulBlockAddress;
    CurrCmd.uCmd = FMDHAL_CMD_ERASE;

    // Grab the Flash block mutex
    WAIT_FMD_FLASH_MUTEX(ghFlashMutex);

    if (!FMD_OEMIoControl(IOCTL_FMDHAL_FLASH_CMD,(PBYTE) &CurrCmd, sizeof(struct FMDHAL_CmdStruct),
                          NULL, NULL, NULL))
    {
        bRetVal = FALSE;
        // Release Mutex if erase failed
        RELEASE_FMD_FLASH_MUTEX(ghFlashMutex);
        goto Error;
    }

    // Release Mutex when EraseBlock completes
    RELEASE_FMD_FLASH_MUTEX(ghFlashMutex);

    // Sign the block/  This will only work because the block has already been ERASED.
    //

    if (bXIPBlock || bReservedBlock)
    {
        DBGMSG(1, (TEXT("FMD:FMD_EraseBlock(x%08x): Skipping SignBlock (bXIPBlock=%u, bReservedBlock=%u)\r\n"),
                   blockID, bXIPBlock, bReservedBlock));
    }
    else if (!SignBlock(ulBlockAddress, (PUCHAR) gc_dwBlockSig))
    {
        LOGMSG(1, (TEXT("FMD:FMD_EraseBlock(x%08x): SignBlock failed (status=x%08x)\r\n"), blockID, last_status));
        bRetVal = FALSE;
        goto Error;
    }
Error:

#ifndef UNDER_BOOTLOADER
    SetKMode(bLastMode);
#endif

    return(bRetVal);
}

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:       FMD_PowerUp()

Description:    Restores power to the Flash memory device (if applicable).

Returns:        None.
------------------------------------------------------------------------------*/
VOID  FMD_PowerUp(VOID)
{
        ULONG unlock_ret;
    unlock_ret = UnlockFILESYSRegions();
    DBGMSG(1, (TEXT("FMD_PowerUp: %u blocks in %u regions unlocked\r\n"), unlock_ret & 0xffff, unlock_ret >> 16));
    return;
}


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:       FMD_PowerDown()

Description:    Suspends power to the Flash memory device (if applicable).

Returns:        None.
------------------------------------------------------------------------------*/
VOID  FMD_PowerDown(VOID)
{
    return;
}


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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_GET_INTERFACE:
            {
                if (!pOutBuf || nOutBufSize < sizeof(FMDInterface))
                {
                    LOGMSG(1, (TEXT("FMD:FMD_OEMIoControl: IOCTL_FMD_GET_INTERFACE bad parameter(s).\r\n")));
                    return(FALSE);
                }
                DBGMSG(1, (TEXT("FMD_OEMIoControl: IOCTL_FMD_GET_INTERFACE\r\n")));

                PFMDInterface pInterface = (PFMDInterface)pOutBuf;
                pInterface->cbSize = sizeof(FMDInterface);
                pInterface->pInit = FMD_Init;
                pInterface->pDeInit = FMD_Deinit;
                pInterface->pGetInfo = FMD_GetInfo;
                pInterface->pGetInfoEx = FMD_GetInfoEx;
                pInterface->pGetBlockStatus = FMD_GetBlockStatus;
                pInterface->pSetBlockStatus = FMD_SetBlockStatus;
                pInterface->pReadSector = FMD_ReadSector;
                pInterface->pWriteSector = FMD_WriteSector;
                pInterface->pEraseBlock = FMD_EraseBlock;
                pInterface->pPowerUp = FMD_PowerUp;
                pInterface->pPowerDown = FMD_PowerDown;
                pInterface->pGetPhysSectorAddr = FMD_GetPhysSectorAddr;

                break;
            }
        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))
            {
                LOGMSG(1, (TEXT("FMD_OEMIoControl: IOCTL_FMD_SET_XIPMODE bad parameter(s).\r\n")));
                return(FALSE);
            }
            g_bXIPEntire = *(PBOOLEAN)pInBuf;
            break;
        case IOCTL_FMD_GET_XIPMODE:

            if (!pOutBuf || nOutBufSize < sizeof(BOOLEAN))
            {
                LOGMSG(1, (TEXT("FMD_OEMIoControl: IOCTL_FMD_GET_XIPMODE bad parameter(s).\r\n")));
                return(FALSE);
            }
            *(PBOOLEAN)pOutBuf = g_bXIPEntire;
            break;
        case IOCTL_FMD_LOCK_BLOCKS:
            // Lock one of more blocks in a specified range.
            if (!pInBuf || nInBufSize < sizeof(BlockLockInfo))
            {
                LOGMSG(1, (TEXT("FMD_OEMIoControl: IOCTL_FMD_LOCK_BLOCKS bad parameter(s).\r\n")));
                return(FALSE);
            }
            if (!SetBlockLock(((PBlockLockInfo)pInBuf)->StartBlock, ((PBlockLockInfo)pInBuf)->NumBlocks, TRUE))
            {
                LOGMSG(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);
            }
            else
            {
                DBGMSG(1, (TEXT("FMD_OEMIoControl: IOCTL_FMD_LOCK_BLOCKS OK (start=0x%x, number=0x%x).\r\n"), 
                           ((PBlockLockInfo)pInBuf)->StartBlock, ((PBlockLockInfo)pInBuf)->NumBlocks));
            }
            break;
        case IOCTL_FMD_UNLOCK_BLOCKS:
            // Unlock one of more blocks in a specified range.
            if (!pInBuf || nInBufSize < sizeof(BlockLockInfo))
            {
                LOGMSG(1, (TEXT("FMD_OEMIoControl: IOCTL_FMD_UNLOCK_BLOCKS bad parameter(s).\r\n")));
                return(FALSE);
            }
            if (!SetBlockLock(((PBlockLockInfo)pInBuf)->StartBlock, ((PBlockLockInfo)pInBuf)->NumBlocks, FALSE))
            {
                LOGMSG(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);
            }
            else
            {
                DBGMSG(1, (TEXT("FMD_OEMIoControl: IOCTL_FMD_UNLOCK_BLOCKS OK (start=0x%x, number=0x%x).\r\n"), 
                           ((PBlockLockInfo)pInBuf)->StartBlock, ((PBlockLockInfo)pInBuf)->NumBlocks));
            }
            break;
        case IOCTL_FMD_READ_RESERVED:
            // Read from a specified reserved region.
            if (!pInBuf || nInBufSize < sizeof(ReservedReq))
            {
                LOGMSG(1, (TEXT("FMD_OEMIoControl: IOCTL_FMD_READ_RESERVED bad parameter(s).\r\n")));
                return(FALSE);
            }
            return(ReadWriteReserved ((PReservedReq)pInBuf, TRUE));
            break;
        case IOCTL_FMD_WRITE_RESERVED:
            // Write to a specified reserved region.
            if (!pInBuf || nInBufSize < sizeof(ReservedReq))
            {
                LOGMSG(1, (TEXT("FMD_OEMIoControl: IOCTL_FMD_READ_RESERVED bad parameter(s).\r\n")));
                return(FALSE);
            }
            return(ReadWriteReserved ((PReservedReq)pInBuf, FALSE));
            break;

        case IOCTL_FMD_GET_RESERVED_TABLE:
            // Get the reserved table.
            if (!pOutBuf)
            {
                // If no buffer is provided, return the required size.
                if (pBytesReturned)
                    *pBytesReturned = g_dwNumReserved * sizeof(ReservedEntry);
                return(TRUE);
            } else
            {
                DWORD dwTableSize = g_dwNumReserved * sizeof(ReservedEntry);

                if (nOutBufSize < dwTableSize)
                {

⌨️ 快捷键说明

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