📄 fmd.cpp
字号:
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 + -