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

📄 fmd.cpp

📁 微软提供的Flash驱动程序
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                        DWORD dwNumSectors)
{
    UCHAR  addr1, addr2, addr3, status;
    DWORD   i,count;

    //  Sanity check
    //  BUGBUGBUG: I need to come back to support dwNumSectors > 1
    //
    if((!pSectorBuff && !pSectorInfoBuff) || dwNumSectors == 0) {
        RETAILMSG(1, (TEXT("Invalid parameters!\n")));
        return FALSE;
    }

    // We don't really need to reset the chip. Just set the offset to beginning
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CS_PORT,(UCHAR)0);    // enable chip
    CheckStatus((DWORD) -1);    // check ready
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CMD_PORT, (UCHAR) CMD_READ);
    
    for (count=0;count<dwNumSectors;count++) {
        CheckStatus((DWORD) -1);

        if(!pSectorBuff) {
            //  If we are asked just to write the SectorInfo, we will do that separately
            if(!NAND_WriteSectorInfo(startSectorAddr, pSectorInfoBuff)) {
                FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CS_PORT,(UCHAR)1);    // disable chip
                return FALSE;
            }
            pSectorInfoBuff ++;
        }
        else {
            addr1 = (UCHAR) ((startSectorAddr) & 0xff);
            addr2 = (UCHAR) ((startSectorAddr >> 8) & 0xff);
            addr3 = (UCHAR) ((startSectorAddr >> 16) & 0xff);

            //  Issue write command
            FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CMD_PORT, (UCHAR) CMD_WRITE);
            FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_ADDR_PORT, 0x0);
            FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_ADDR_PORT, addr1);
            FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_ADDR_PORT, addr2);

            if(NEED_EXT_ADDR) {
                FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_ADDR_PORT, addr3);
            }

            //  Write the data
            for(i=0; i<SECTOR_SIZE; i++) {
                FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_DATA_PORT, (UCHAR) pSectorBuff[i]);
            }
            
            
            // Write the SectorInfo data to the media
            if(pSectorInfoBuff)
            {
                FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_DATA_PORT, (UCHAR)((pSectorInfoBuff->dwReserved1 & 0x000000FF))); // Reserved field 1 
                FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_DATA_PORT, (UCHAR)((pSectorInfoBuff->dwReserved1 & 0x0000FF00) >> 8)); 
                FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_DATA_PORT, (UCHAR)((pSectorInfoBuff->dwReserved1 & 0x00FF0000) >> 16));
                FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_DATA_PORT, (UCHAR)((pSectorInfoBuff->dwReserved1 & 0xFF000000) >> 24)); 

                FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_DATA_PORT, (UCHAR)(pSectorInfoBuff->bOEMReserved));                      // OEM byte
                FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_DATA_PORT, (UCHAR)(pSectorInfoBuff->bBadBlock));                         // Bad block byte

                FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_DATA_PORT, (UCHAR)((pSectorInfoBuff->wReserved2 & 0x000000FF)));
                FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_DATA_PORT, (UCHAR)((pSectorInfoBuff->wReserved2 & 0x0000FF00) >> 8));    // Reserved field 2
                
                pSectorInfoBuff ++;

            }else
            {
                // Make sure we advance the Flash's write pointer (even though we aren't writing the SectorInfo data)
                for(i=0; i<sizeof(SectorInfo); i++)
                {
                    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_DATA_PORT, (UCHAR)(0xFF));           
                }
            }

            // Compute the ECC for this data (only 6 of the available 8 bytes are used)
            if(!ECC_ComputeECC(pSectorBuff, SECTOR_SIZE, ECC, ECC_BUFF_LEN))
            {
                RETAILMSG(1, (TEXT("FMD: Unable to compute ECC(sector 0x%x) !!!\r\n"),startSectorAddr));
            }

            // Write the sector info and ECC into the spare area
            for(i=0; i<ECC_SIZE; i++) {
                FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_DATA_PORT, ECC[i]);
            }

            // Instruct the Flash to commit the data to the media
            FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CMD_PORT, (UCHAR) CMD_WRITE2);

            //  Check the status of the write.
            status = GetStatus((DWORD) -1);
            if(status & STATUS_ERROR) {
                RETAILMSG(1, (TEXT("######## Error Programing page %d!\n"), startSectorAddr));
                FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CS_PORT,(UCHAR)1);    // disable chip
                return FALSE;
            }
            pSectorBuff += SECTOR_SIZE;
        }
        startSectorAddr ++;
    }
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CS_PORT,(UCHAR)1);    // edisable chip
    return TRUE;
}


/* 
 *  FMD_GetBlockStatus
 *
 *  Returns the status of a block.  For read-only blocks, checks the sector info data for the first sector of the block. 
 */
DWORD FMD_GetBlockStatus(BLOCK_ID blockID)
{
    SECTOR_ADDR Sector = blockID * g_wPagesPerBlock;
    SectorInfo SI;
    DWORD dwResult = 0;
    
    if (IsBlockBad (blockID))
        return BLOCK_STATUS_BAD;

    if (!FMD_ReadSector(Sector, NULL, &SI, 1)) 
        return BLOCK_STATUS_UNKNOWN;

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

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

    return dwResult;
}

/* 
 *  FMD_SetBlockStatus
 *
 *  Sets the status of a block.  
 *  Returns TRUE if no errors in setting.
 */
 
BOOL FMD_SetBlockStatus(BLOCK_ID blockID, DWORD dwStatus)
{
    if (dwStatus & BLOCK_STATUS_BAD) {
        if (!MarkBlockBad (blockID))
            return FALSE;
    }

    if (dwStatus & (BLOCK_STATUS_READONLY | BLOCK_STATUS_RESERVED)) {
        
        SECTOR_ADDR Sector = blockID * g_wPagesPerBlock;
        SectorInfo SI;

        if (!FMD_ReadSector(Sector, NULL, &SI, 1)) {
            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)) {
            return FALSE;
        }

    }    
    
    return TRUE;
}



//  FMD_PowerUp
//
//  Performs any necessary powerup procedures...
//
VOID FMD_PowerUp(VOID)
{
    return;
}


//  FMD_PowerDown
//
//  Performs any necessary powerdown procedures...
//
VOID FMD_PowerDown(VOID)
{
    return;
}


//  FMD_OEMIoControl
//
//  Used for any OEM defined IOCTL operations
//
BOOL  FMD_OEMIoControl(DWORD dwIoControlCode, PBYTE pInBuf, DWORD nInBufSize, 
                       PBYTE pOutBuf, DWORD nOutBufSize, PDWORD pBytesReturned)
{
    return TRUE;
}



//------------------------------- Private Interface (NOT used by the FAL) --------------------------

//  FMD_GetOEMReservedByte
//
//  Retrieves the OEM reserved byte (for metadata) for the specified physical sector.
// 
//
BOOL FMD_GetOEMReservedByte(SECTOR_ADDR physicalSectorAddr, PBYTE pOEMReserved)
{
    UCHAR  addr1, addr2, addr3, wData;

    // Check the parameters
    if(pOEMReserved == NULL)
    {
        return FALSE;
    }

    addr1 = (UCHAR) ((physicalSectorAddr) & 0xff);
    addr2 = (UCHAR) ((physicalSectorAddr >> 8) & 0xff);
    addr3 = (UCHAR) ((physicalSectorAddr >> 16) & 0xff);

    //  For our NAND flash, we don't have to issue two read command. We just need
    //  to issue one read command and do contiquous read

    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CS_PORT,(UCHAR)0);    // enable chip
    CheckStatus((DWORD) -1);

    // Seek to the correct byte in the spare area
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CMD_PORT, CMD_READ2);
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_ADDR_PORT, OEMADDR);
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_ADDR_PORT, addr1);
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_ADDR_PORT, addr2);

    if(NEED_EXT_ADDR) {
        FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_ADDR_PORT, addr3);
    }

    CheckStatus((DWORD) -1);

    // Read the data from the media
    wData = FMD_READ_PORT_UCHAR((PUCHAR) NAND_DATA_PORT);

    *pOEMReserved = wData;

    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CS_PORT,(UCHAR)1);    // disable chip
    return TRUE;

}


//  FMD_SetOEMReservedByte
//
//  Sets the OEM reserved byte (for metadata) for the specified physical sector.
//
BOOL FMD_SetOEMReservedByte(SECTOR_ADDR physicalSectorAddr, BYTE bOEMReserved)
{
    UCHAR  addr1, addr2, addr3, status;

    //  We will try to write the OEM data to the 516th byte of the first page
    addr1 = (UCHAR) ( (physicalSectorAddr) & 0xff );
    addr2 = (UCHAR) ( (physicalSectorAddr >> 8) & 0xff );
    addr3 = (UCHAR) ( (physicalSectorAddr >> 16) & 0xff );
   
    //  Wait for our term!
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CS_PORT,(UCHAR)0);    // enable chip
    CheckStatus((DWORD) -1);
    
    //  First we set the pointer to point to the spare area
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CMD_PORT, (UCHAR) CMD_READ2);

    CheckStatus((DWORD) -1);    // check ready
    // Seek to the correct byte in the spare area
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CMD_PORT, (UCHAR) CMD_WRITE);
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_ADDR_PORT, OEMADDR);
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_ADDR_PORT, addr1);
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_ADDR_PORT, addr2);

    if(NEED_EXT_ADDR) {
        FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_ADDR_PORT, addr3);
    }

    //  Write the OEM data to the media 
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_DATA_PORT, bOEMReserved);

    //  Close out the write.
    CheckStatus((DWORD) -1);    // check ready
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CMD_PORT, (UCHAR) CMD_WRITE2);

    status = CheckStatus((DWORD) -1);
    if(status & STATUS_ERROR) {
        RETAILMSG(1, (TEXT("######## Failed to set OEM Reserved byte!\n")));
        FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CS_PORT,(UCHAR)1);    // disable chip
        return FALSE;
    }

    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CS_PORT,(UCHAR)1);    // disable chip
    return TRUE;
}


//---------------------------------------- Helper Functions ----------------------------------------

//  Interface function for testing purpose.
//
BOOL FMD_ReadSpare(DWORD dwStartPage, LPBYTE pBuff, DWORD dwNumPages)
{
    UCHAR  addr1, addr2, addr3, wData;
    DWORD   i, n;

    addr1 = (UCHAR) ( (dwStartPage) & 0xff );
    addr2 = (UCHAR) ( (dwStartPage >> 8) & 0xff );
    addr3 = (UCHAR) ( (dwStartPage >> 16) & 0xff );

    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CS_PORT,(UCHAR)0);    // enable chip
    CheckStatus((DWORD) -1);    // check ready
    
    //  Issue the READ command
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CMD_PORT, (UCHAR) CMD_READ2);
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_ADDR_PORT, 0x0);
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_ADDR_PORT, addr1);
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_ADDR_PORT, addr2);

    if(NEED_EXT_ADDR) {
        FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_ADDR_PORT, addr3);
    }

    CheckStatus((DWORD) -1);

    for(n=0; n<dwNumPages; n++) {
        //  Read the spare area
        for(i=0; i<16; i++) {
            wData = FMD_READ_PORT_UCHAR((PUCHAR) NAND_DATA_PORT);
            pBuff[i] = wData;
        }
    }

    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CS_PORT,(UCHAR)1);    // disable chip
    return TRUE;
}

⌨️ 快捷键说明

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