📄 nand.cpp
字号:
{
OALMSG(OAL_ERROR, (TEXT("ERROR: ReadOSImageFromBootMedia: Failed to open existing partition.\r\n")));
return(FALSE);
}
// Set the partition file pointer to the correct offset for the kernel region.
//
if ( !BP_SetDataPointer(hPart, g_pTOC->id[g_dwTocEntry].dwStoreOffset) )
{
OALMSG(OAL_ERROR, (TEXT("ERROR: ReadOSImageFromBootMedia: Failed to set data pointer in partition (offset=0x%x).\r\n"),
g_pTOC->id[g_dwTocEntry].dwStoreOffset));
return(FALSE);
}
// Read the kernel region from the Boot Media into RAM.
//
if ( !BP_ReadData( hPart,
(LPBYTE)(g_pTOC->id[g_dwTocEntry].dwLoadAddress),
SECTOR_TO_FILE_SIZE(g_pTOC->id[g_dwTocEntry].dwTtlSectors)) )
{
OALMSG(OAL_ERROR, (TEXT("ERROR: ReadOSImageFromBootMedia: Failed to read kernel region from partition.\r\n")));
return(FALSE);
}
if (!g_pTOC->chainInfo.dwLoadAddress)
{
chainaddr = g_pTOC->chainInfo.dwLoadAddress;
flashaddr = g_pTOC->chainInfo.dwFlashAddress;
for ( i = 0; i < (g_pTOC->chainInfo.dwLength); i++ )
{
OALMSG(TRUE, (TEXT("chainaddr=0x%x, flashaddr=0x%x\r\n"), chainaddr, flashaddr+i));
if ( !FMD_ReadSector(flashaddr+i, (PUCHAR)(chainaddr), &si, 1) )
{
OALMSG(OAL_ERROR, (TEXT("TOC ERROR: Unable to read/verify TOC\r\n")));
return FALSE;
}
chainaddr += 512;
}
}
OALMSG(OAL_FUNC, (TEXT("_ReadOSImageFromBootMedia\r\n")));
return(TRUE);
}
BOOL ReadBlock(DWORD dwBlock, LPBYTE pbBlock, PSectorInfo pSectorInfoTable)
{
for (int iSector = 0; iSector < g_FlashInfo.wSectorsPerBlock; iSector++) {
if (!FMD_ReadSector(dwBlock * g_FlashInfo.wSectorsPerBlock + iSector, pbBlock, pSectorInfoTable, 1))
return FALSE;
if (pbBlock)
pbBlock += g_FlashInfo.wDataBytesPerSector;
if (pSectorInfoTable)
pSectorInfoTable++;
}
return TRUE;
}
BOOL WriteBlock(DWORD dwBlock, LPBYTE pbBlock, PSectorInfo pSectorInfoTable, DWORD dwImageType)
{
for (int iSector = 0; iSector < g_FlashInfo.wSectorsPerBlock; iSector++) {
if(dwImageType == IMAGE_TYPE_LOADER)
{
if (!FMD_WriteSector(dwBlock * g_FlashInfo.wSectorsPerBlock + iSector, pbBlock, pSectorInfoTable, 1))
return FALSE;
}
else if(dwImageType == IMAGE_TYPE_STEPLDR)
{
if(IS_LB)
{
if (!FMD_LB_WriteSector_Steploader(dwBlock * g_FlashInfo.wSectorsPerBlock + iSector, pbBlock, pSectorInfoTable, 1, USE_NFCE))
return FALSE;
}
else
{
if(!FMD_SB_WriteSector_Steploader(dwBlock * g_FlashInfo.wSectorsPerBlock + iSector, pbBlock, pSectorInfoTable, 1, USE_NFCE))
return FALSE;
}
}
if (pbBlock)
pbBlock += g_FlashInfo.wDataBytesPerSector;
if (pSectorInfoTable)
pSectorInfoTable++;
}
return TRUE;
}
BOOL WriteRawImageToBootMedia(DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr)
{
DWORD dwBlock,dwNumBlocks;
LPBYTE pbBuffer;
SectorInfo si;
OALMSG(OAL_FUNC, (TEXT("+WriteRawImageToBootMedia\r\n")));
if ( !g_bBootMediaExist )
{
OALMSG(OAL_ERROR, (TEXT("ERROR: WriteRawImageToBootMedia: device doesn't exist.\r\n")));
return(FALSE);
}
if (g_ImageType == IMAGE_TYPE_LOADER)
{
dwBlock = EBOOT_BLOCK;
if ( !VALID_TOC(g_pTOC) )
{
OALMSG(OAL_WARN, (TEXT("WARN: WriteRawImageToBootMedia: INVALID_TOC\r\n")));
if ( !TOC_Init(g_dwTocEntry, g_ImageType, dwImageStart, dwImageLength, dwLaunchAddr) )
{
OALMSG(OAL_ERROR, (TEXT("ERROR: INVALID_TOC\r\n")));
return(FALSE);
}
}
}
else if (g_ImageType == IMAGE_TYPE_STEPLDR)
{
dwBlock = NBOOT_BLOCK;
dwImageStart += dwLaunchAddr;
dwImageLength = 0x1000; //step loader can support 4k bytes only.
}
pbBuffer = OEMMapMemAddr(dwImageStart, dwImageStart);
// Compute number of blocks.
//dwNumBlocks = (dwImageLength / 0x4000) + 1;
dwNumBlocks = (dwImageLength / (g_FlashInfo.wDataBytesPerSector*g_FlashInfo.wSectorsPerBlock)) + (dwImageLength%(g_FlashInfo.wDataBytesPerSector*g_FlashInfo.wSectorsPerBlock) ? 1: 0);
OALMSG(TRUE, (TEXT("dwImageLength = 0x%x \r\n"), dwImageLength));
OALMSG(TRUE, (TEXT("dwNumBlocks = 0x%x \r\n"), dwNumBlocks));
while (dwNumBlocks--)
{
// If the block is marked bad, skip to next block. Note that the assumption in our error checking
// is that any truely bad block will be marked either by the factory during production or will be marked
// during the erase and write verification phases. If anything other than a bad block fails ECC correction
// in this routine, it's fatal.
OALMSG(TRUE, (TEXT("dwBlock(0x%x) X "), dwBlock));
OALMSG(TRUE, (TEXT("g_FlashInfo.wSectorsPerBlock(0x%x)"), g_FlashInfo.wSectorsPerBlock));
OALMSG(TRUE, (TEXT(" = 0x%x \r\n"), dwBlock*g_FlashInfo.wSectorsPerBlock));
if (g_ImageType == IMAGE_TYPE_LOADER)
{
FMD_ReadSector(dwBlock*g_FlashInfo.wSectorsPerBlock, NULL, &si, 1);
// Stepldr & Eboot image in nand flash
// block mark as BLOCK_STATUS_RESERVED & BLOCK_STATUS_READONLY & BLOCK_STATUS_BAD
if ((si.bBadBlock == 0x0) && (si.bOEMReserved !=3 ))
{
++dwBlock;
++dwNumBlocks; // Compensate for fact that we didn't write any blocks.
continue;
}
if (!ReadBlock(dwBlock, NULL, g_pSectorInfoBuf))
{
OALMSG(OAL_ERROR, (TEXT("WriteData: failed to read block (0x%x).\r\n"), dwBlock));
return(FALSE);
}
}
if (!FMD_EraseBlock(dwBlock))
{
OALMSG(OAL_ERROR, (TEXT("WriteData: failed to erase block (0x%x).\r\n"), dwBlock));
return FALSE;
}
if (!WriteBlock(dwBlock, pbBuffer, g_pSectorInfoBuf,g_ImageType))
{
OALMSG(OAL_ERROR, (TEXT("WriteData: failed to write block (0x%x).\r\n"), dwBlock));
return(FALSE);
}
++dwBlock;
pbBuffer += g_FlashInfo.dwBytesPerBlock;
}
if (g_ImageType == IMAGE_TYPE_LOADER)
{
g_pTOC->id[0].dwLoadAddress = dwImageStart;
g_pTOC->id[0].dwJumpAddress = 0;
g_pTOC->id[0].dwTtlSectors = FILE_TO_SECTOR_SIZE(dwImageLength);
g_pTOC->id[0].sgList[0].dwSector = BLOCK_TO_SECTOR(EBOOT_BLOCK);
g_pTOC->id[0].sgList[0].dwLength = g_pTOC->id[0].dwTtlSectors;
}
OALMSG(OAL_FUNC, (TEXT("_WriteRawImageToBootMedia\r\n")));
return TRUE;
}
/*
int CorrectECC8Data(unsigned char *pEncodingBaseAddr)
{
unsigned int i,uErrorByte[9];
unsigned char uErrorBit[9];
unsigned int uErrorType;
uErrorType = (s2450NAND->NF8ECCERR0>>25)&0xf;// Searching Error Type //How many Error bits does exist?
uErrorByte[1] = s2450NAND->NF8ECCERR0&0x3ff;// Searching Error Byte //Where is the error byte?
uErrorByte[2] = (s2450NAND->NF8ECCERR0>>15)&0x3ff;
uErrorByte[3] = (s2450NAND->NF8ECCERR1)&0x3ff;
uErrorByte[4] = (s2450NAND->NF8ECCERR1>>11)&0x3ff;
uErrorByte[5] = (s2450NAND->NF8ECCERR1>>22)&0x3ff;
uErrorByte[6] = (s2450NAND->NF8ECCERR2)&0x3ff;
uErrorByte[7] = (s2450NAND->NF8ECCERR2>>11)&0x3ff;
uErrorByte[8] = (s2450NAND->NF8ECCERR2>>22)&0x3ff;
uErrorBit[1] = s2450NAND->NFMLC8BITPT0&0xff;// Searching Error Bit //Where is the error bit?
uErrorBit[2] = (s2450NAND->NFMLC8BITPT0>>8)&0xff;
uErrorBit[3] = (s2450NAND->NFMLC8BITPT0>>16)&0xff;
uErrorBit[4] = (s2450NAND->NFMLC8BITPT0>>24)&0xff;
uErrorBit[5] = s2450NAND->NFMLC8BITPT1&0xff;
uErrorBit[6] = (s2450NAND->NFMLC8BITPT1>>8)&0xff;
uErrorBit[7] = (s2450NAND->NFMLC8BITPT1>>16)&0xff;
uErrorBit[8] = (s2450NAND->NFMLC8BITPT1>>24)&0xff;
if(uErrorType == 0x0)
{
RETAILMSG(1, (TEXT("++++++++++ ECC No ERROR +++++++++++\r\n")));
return 0;
}
if(uErrorType == 0x9)
{
RETAILMSG(1, (TEXT("++++++++++ ECC Uncorrectable ERROR +++++++++++\r\n")));
return 1;
}
for(i=1;i<=uErrorType ;i++)
{
if(uErrorByte[i] < 512)
pEncodingBaseAddr[uErrorByte[i]]^=uErrorBit[i];
else
{;}
}
RETAILMSG(1, (TEXT("++++++++++ ECC correctable ERROR +++++++++++\r\n")));
return 0;
}
*/
BOOL FMD_LB_WriteSector_Steploader(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors, int mode)
{
DWORD i;
UINT16 nSectorLoop;
volatile DWORD wrdata;
int NewSpareAddr = 0x0;
int NewDataAddr = 0;
int NewSectorAddr = startSectorAddr;
MECC8 t8MECC[4];
//Check Parameters.
if (!pSectorBuff && !pSectorInfoBuff)
{
return(FALSE);
}
if ( dwNumSectors > 1 )
{
RETAILMSG(1, (TEXT("######## FATAL ERROR => FMD::FMD_WriteSector->dwNumsectors is bigger than 1. \r\n")));
return FALSE;
}
BOOL bLastMode = SetKMode(TRUE); // dummy function.
s2450NAND->NFCONF = (s2450NAND->NFCONF & ~(1<<30)) | (1<<23) | NF_TACLS(DEFAULT_TACLS) | NF_TWRPH0(DEFAULT_TWRPH0) | NF_TWRPH1(DEFAULT_TWRPH1);
s2450NAND->NFCONT |= (1<<18)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9);
s2450NAND->NFSTAT |= ((1<<6)|(1<<5)|(1<<4));
// Enable Chip
NF_nFCE_L(); // NFCONT狼 [1]甫 0栏肺 努府绢 ... Force nFCE to low
// Issue command
NF_CMD(CMD_WRITE); //0x80
// Setup address to write Main data
NF_ADDR((NewDataAddr)&0xff); // 2bytes for column address
NF_ADDR((NewDataAddr>>8)&0xff);
NF_ADDR((NewSectorAddr)&0xff); // 3bytes for row address
NF_ADDR((NewSectorAddr>>8)&0xff);
NF_ADDR((NewSectorAddr>>16)&0xff);
// initialize variable.
for(i = 0; i < 4; i++) {
t8MECC[i].n8MECC0 = 0x0;
t8MECC[i].n8MECC1 = 0x0;
t8MECC[i].n8MECC2 = 0x0;
t8MECC[i].n8MECC3 = 0x0;
}
// Write each Sector in the Page. (4 Sector per Page, Loop 4 times.)
for (nSectorLoop = 0; nSectorLoop < SECTORS_PER_PAGE; nSectorLoop++)
{
// Initialize ECC register
NF_MECC_UnLock();
NF_RSTECC();
// Special case to handle un-aligned buffer pointer.
if( ((DWORD) (pSectorBuff+nSectorLoop*SECTOR_SIZE)) & 0x3)
{
// Write the data
for(i=0; i<SECTOR_SIZE/sizeof(DWORD); i++)
{
wrdata = (pSectorBuff+nSectorLoop*SECTOR_SIZE)[i*4+0];
wrdata |= (pSectorBuff+nSectorLoop*SECTOR_SIZE)[i*4+1]<<8;
wrdata |= (pSectorBuff+nSectorLoop*SECTOR_SIZE)[i*4+2]<<16;
wrdata |= (pSectorBuff+nSectorLoop*SECTOR_SIZE)[i*4+3]<<24;
NF_WRDATA_WORD(wrdata);
}
}
else
{
WrPage512(pSectorBuff+nSectorLoop*SECTOR_SIZE);
}
NF_MECC_Lock();
while(!(s2450NAND->NFSTAT&(1<<7))) ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -