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

📄 fmd.cpp

📁 微软提供的Flash驱动程序
💻 CPP
📖 第 1 页 / 共 4 页
字号:
            BaseAddress |= 0xFFFF0000;
        }
        
        if (Reg & 1) {
            // IO space
            Size = ~(BaseAddress & 0xFFFFFFFC);

            if ((BaseAddress != 0) && (BaseAddress != 0xFFFFFFFF) && (((Size + 1) & Size) == 0)) {
                // BAR has valid format (consecutive high 1's and consecutive low 0's)
                pInfo->IoLen.Reg[IoIndex] = Size + 1;
                pInfo->IoLen.Num++;
                pInfo->IoBase.Reg[IoIndex++] = Reg & 0xFFFFFFFC;
                pInfo->IoBase.Num++;
            } else {
                // BAR invalid => skip to next one
                continue;
            }
        } else {
            // Memory space
            // TODO: don't properly handle the MEM20 case
            Size = ~(BaseAddress & 0xFFFFFFF0);
            
            if ((BaseAddress != 0) && (BaseAddress != 0xFFFFFFFF) && (((Size + 1) & Size) == 0)) {
                // BAR has valid format (consecutive high 1's and consecutive low 0's)
                pInfo->MemLen.Reg[MemIndex] = Size + 1;
                pInfo->MemLen.Num++;
                pInfo->MemBase.Reg[MemIndex++] = Reg & 0xFFFFFFF0;
                pInfo->MemBase.Num++;
            } else {
                // BAR invalid => skip to next one
                continue;
            }
        }

        //
        // check for 64 bit device - BAR is twice as big
        //
        if ((pInfo->Cfg.u.type0.BaseAddresses[i] & 0x7) == 0x4) {
            // 64 bit device - BAR is twice as wide - zero out high part
            Offset += 4;
            i++;
        }
    }

    return TRUE;
}

/*

    PCI Scan: Scan PCI BUS to find FLASH hardware.

*/
BOOL ScanPCI(PPCI_REG_INFO pRegIn, PPCI_REG_INFO pRegOut)
{
    PCI_COMMON_CONFIG pciConfig;
    int bus, device, function;
    int length;

    PCI_SLOT_NUMBER slotNumber;
    if (pRegIn !=NULL) { // We just use this one.
        if (pRegIn->IoBase.Num >=2 ) { // We found correct. Do not need scan bus.
            IoAddr = pRegIn->IoBase.Reg[1];
            if (pRegOut)
                memcpy(pRegOut, pRegIn,sizeof(PCI_REG_INFO));
             return TRUE;
        }
        
    }
    // Scan CardBus
    for (bus=0;bus<3;bus++)
    for (device = 0; device < PCI_MAX_DEVICES; device++) {
        slotNumber.u.bits.DeviceNumber = device;
        for (function = 0; function < PCI_MAX_FUNCTION; function++) {
            slotNumber.u.bits.FunctionNumber = function;
            pciConfig.VendorID = 0xFFFF;
            pciConfig.HeaderType = 0;
            
            length = HalGetBusData(
                PCIConfiguration,
                bus,
                slotNumber.u.AsULONG,
                &pciConfig,
                sizeof(pciConfig) - sizeof(pciConfig.DeviceSpecific)
                );
            
            if (length == 0 || pciConfig.VendorID == 0xFFFF) {
                // Device does not exist
                break;
            }
            

            if (pciConfig.VendorID == 0x15B7 && pciConfig.DeviceID == 0x1230) {
                // PCI905bdb-091b 11.2.1
                // Found Card, Mapping address
                IoAddr = pciConfig.u.type0.BaseAddresses[2] & 0xfffffffc;
                ASSERT((pciConfig.u.type0.BaseAddresses[2] & 1)!=0);
                if (pRegOut) {
                    pRegOut->RegPath[0]=0;
                    pRegOut->Bus = bus;
                    pRegOut->Device = device;
                    pRegOut->Function = function;
                    memcpy(&pRegOut->Cfg,&pciConfig,sizeof(pRegOut->Cfg));
                    pRegOut->MemBase.Num = 0;
                    pRegOut->MemLen.Num = 0;
                    pRegOut->IoBase.Num = 0;
                    pRegOut->IoLen.Num = 0 ;
                    pRegOut->SysIntr = 0;
                    PCIReadBARs(pRegOut);
                }
                return TRUE;

            }
            if (function == 0 && !(pciConfig.HeaderType & PCI_MULTIFUNCTION)) {
                // Not a multi-function device, continue on to next device
                break;
            }
        }
        
        // Error on HalGetBusData, move on to next bus
        if (length == 0) {
            break;
        }
    }
    return FALSE;
} 


//
//  IsBlockBad
//
//  Check to see if the given block is bad. A block is bad if the 517th byte on
//  the first or second page is not 0xff. 
//
//  blockID:    The block address. We need to convert this to page address
//
//


BOOL IsBlockBad(BLOCK_ID blockID)
{
    UCHAR  addr1, addr2, addr3, wData;
    DWORD  dwPageID = blockID*g_wPagesPerBlock;   //  Get the first page of the blcok

    addr1 = (UCHAR) ((dwPageID) & 0xff);
    addr2 = (UCHAR) ((dwPageID >> 8) & 0xff);
    addr3 = (UCHAR) ((dwPageID >> 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);    // check ready

    //  Check the first page.
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CMD_PORT, CMD_READ2);
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_ADDR_PORT, VALIDADDR);
    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);

    wData = FMD_READ_PORT_UCHAR((PUCHAR) NAND_DATA_PORT);
    if(0xff != wData) {
        FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CS_PORT,(UCHAR)1);    // disable chip
        return TRUE;
    }

    //  Check the second page
 
    CheckStatus((DWORD) -1);    // check ready
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CMD_PORT, CMD_READ2);
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_ADDR_PORT, VALIDADDR);
    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);

    wData = FMD_READ_PORT_UCHAR((PUCHAR) NAND_DATA_PORT);
    if(0xff != wData) {
        FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CS_PORT,(UCHAR)1);    // disable chip
        return TRUE;
    }

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


/* 
 *  MarkBlockBad
 *
 *  Mark the block as a bad block. We need to write a 00 to the 517th byte 
 */

BOOL MarkBlockBad(BLOCK_ID blockID)
{
    UCHAR  addr1, addr2, addr3, status;
    DWORD   dwStartPage = blockID*g_wPagesPerBlock;

    //  We will try to write 00 to the 517th byte of the first page
    addr1 = (UCHAR) ( (dwStartPage) & 0xff );
    addr2 = (UCHAR) ( (dwStartPage >> 8) & 0xff );
    addr3 = (UCHAR) ( (dwStartPage >> 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
    //  Start writing to the first page of the block
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CMD_PORT, (UCHAR) CMD_WRITE);
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_ADDR_PORT, VALIDADDR);
    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);
    }

    //  Put a zero in the block valid address. 
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_DATA_PORT, BADBLOCKMARK);

    //  Close out the write.
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CMD_PORT, (UCHAR) CMD_WRITE2);

    //  Check the status
    status = GetStatus((DWORD) -1);
    if(status & STATUS_ERROR) {
        RETAILMSG(1, (TEXT("######## Failed to mark the block bad!\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;
}


/* 
 *  NAND_ReadSectorInfo
 *
 *  Read SectorInfo out of the spare area. The current implementation only handles
 *  one sector at a time.
 */
void NAND_ReadSectorInfo(SECTOR_ADDR sectorAddr, PSectorInfo pInfo)
{
    UCHAR  addr1, addr2, addr3, wData;

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

    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CS_PORT,(UCHAR)0);    // enable chip
    CheckStatus((DWORD) -1);    // check for ready
    //  Issue Read command, reading from the spare bits
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CMD_PORT, (UCHAR) CMD_READ2);
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_ADDR_PORT, 0x00);
    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 SectorInfo data (we only need to read first 8 bytes) 
    //  NOTE: The bytes are swapped because of Little Endian.
    wData = FMD_READ_PORT_UCHAR((PUCHAR) NAND_DATA_PORT);               // First reserved field (DWORD)
    pInfo->dwReserved1   = (wData);
    wData = FMD_READ_PORT_UCHAR((PUCHAR) NAND_DATA_PORT);               
    pInfo->dwReserved1  |= (wData << 8);
    wData = FMD_READ_PORT_UCHAR((PUCHAR) NAND_DATA_PORT);               
    pInfo->dwReserved1  |= (wData << 16);
    wData = FMD_READ_PORT_UCHAR((PUCHAR) NAND_DATA_PORT);               
    pInfo->dwReserved1  |= (wData<<24);


    wData = FMD_READ_PORT_UCHAR((PUCHAR) NAND_DATA_PORT);               // OEM byte
    pInfo->bOEMReserved = (wData);
    wData = FMD_READ_PORT_UCHAR((PUCHAR) NAND_DATA_PORT);               // Bad block byte
    pInfo->bBadBlock    = (wData);

    wData = FMD_READ_PORT_UCHAR((PUCHAR) NAND_DATA_PORT);               // Second reserved field (WORD)
    pInfo->wReserved2   = (wData );
    wData = FMD_READ_PORT_UCHAR((PUCHAR) NAND_DATA_PORT);               
    pInfo->wReserved2  |= (wData << 8);  
    
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CS_PORT,(UCHAR)1);    // disable chip
}

/* 
 *  NAND_WriteSectorInfo
 *
 *  Write SectorInfo out to the spare area. The current implementation only handles
 *  one sector at a time.
 */
BOOL NAND_WriteSectorInfo(SECTOR_ADDR sectorAddr, PSectorInfo pInfo)
{
    UCHAR  addr1, addr2, addr3, status;

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

    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CS_PORT,(UCHAR)0);    // enable chip
    CheckStatus((DWORD) -1);    // check for ready
    //  First we set the pointer to point to the spare area
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CMD_PORT, (UCHAR) CMD_READ2);

    //  Next we issue the write command
    CheckStatus((DWORD) -1);    // check ready
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CMD_PORT, (UCHAR) CMD_WRITE);

    //  Now issue the addresses
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_ADDR_PORT, 0x00);
    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);
    }

    //  Since there is not any ECC information, we only need to write the SectorInfo data
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_DATA_PORT, (UCHAR)((pInfo->dwReserved1 & 0x000000FF))); // Reserved field 1 
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_DATA_PORT, (UCHAR)((pInfo->dwReserved1 & 0x0000FF00) >> 8)); 
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_DATA_PORT, (UCHAR)((pInfo->dwReserved1 & 0x00FF0000) >> 16));
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_DATA_PORT, (UCHAR)((pInfo->dwReserved1 & 0xFF000000) >> 24));   

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

    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_DATA_PORT, (UCHAR)((pInfo->wReserved2 & 0x00FF))); // Reserved field 2
    FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_DATA_PORT, (UCHAR)((pInfo->wReserved2 & 0xFF00) >> 8));          

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

⌨️ 快捷键说明

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