📄 nand.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
extern "C"
{
#include <windows.h>
#include <bsp.h>
#include "loader.h"
#include <fmd.h>
extern DWORD g_ImageType;
extern UCHAR g_TOC[SECTOR_SIZE];
extern const PTOC g_pTOC;
extern DWORD g_dwTocEntry;
extern PBOOT_CFG g_pBootCfg;
extern BOOL g_bBootMediaExist;
extern MultiBINInfo g_BINRegionInfo;
extern DWORD g_dwImageStartBlock;
extern BOOL g_bWaitForConnect; // Is there a SmartMedia card on this device?
}
BOOL WriteBlock(DWORD dwBlock, LPBYTE pbBlock, PSectorInfo pSectorInfoTable);
BOOL ReadBlock(DWORD dwBlock, LPBYTE pbBlock, PSectorInfo pSectorInfoTable);
extern DWORD g_dwLastWrittenLoc; // Defined in bootpart.lib
extern PSectorInfo g_pSectorInfoBuf;
extern FlashInfo g_FlashInfo;
static UCHAR toc[SECTOR_SIZE];
// Define a dummy SetKMode function to satisfy the NAND FMD.
//
DWORD SetKMode (DWORD fMode)
{
return(1);
}
void Uart_GetString(char *string)
{
char *string2 = string;
char InChar;
while((InChar = OEMReadDebugByte())!='\r')
{
if (InChar != OEM_DEBUG_COM_ERROR && InChar != OEM_DEBUG_READ_NODATA)
{
if(InChar == '\b')
{
if( (int)string2 < (int)string )
{
RETAILMSG(1, (TEXT("\b \b")));
string--;
}
}
else
{
*string++ = InChar;
OEMWriteDebugByte(InChar);
}
}
}
*string='\0';
OEMWriteDebugByte('\n');
}
int IsAlpha(char c)
{
if ( c >= 'A' && c < 'Z' )
{
return c;
}
else
{
if ( c >= 'a' && c < 'z' )
{
return c;
}
return 0;
}
}
int IsUpper(char c)
{
if ( c >= 'A' && c < 'Z' )
{
return c;
}
return 0;
}
//=====================================================================
int Uart_GetIntNum(void)
{
char str[30];
char *string = str;
int base = 10;
int minus = 0;
int result = 0;
int lastIndex;
int i;
Uart_GetString(string);
if(string[0]=='-')
{
minus = 1;
string++;
}
if(string[0]=='0' && (string[1]=='x' || string[1]=='X'))
{
base = 16;
string += 2;
}
lastIndex = strlen(string) - 1;
if(lastIndex<0)
return 0;
if(string[lastIndex]=='h' || string[lastIndex]=='H' )
{
base = 16;
string[lastIndex] = 0;
lastIndex--;
}
if(base==10)
{
result = atoi(string);
result = minus ? (-1*result):result;
}
else
{
for(i=0;i<=lastIndex;i++)
{
if(IsAlpha(string[i]))
{
if(IsUpper(string[i]))
result = (result<<4) + string[i] - 'A' + 10;
else
result = (result<<4) + string[i] - 'a' + 10;
}
else
result = (result<<4) + string[i] - '0';
}
result = minus ? (-1*result):result;
}
return result;
}
#if 1
void NANDFlashTest()
{
BYTE KeySelect = 0;
CHAR szCount[16];
USHORT cwNumChars = 0;
USHORT InChar = 0;
DWORD dwBlockNumber, dwSectorNumber;
SectorInfo si;
unsigned char tbuf[2048+64];
int i, j;
DWORD dwMECC0;
DWORD dwSECC;
BOOL bReadSpareOnly = FALSE;
DWORD dwStartSector;
BOOL bCleanSector = TRUE;
EdbgOutputDebugString ( "BLOCK_STATUS_BAD : %x , BLOCK_STATUS_READONLY : %x , BLOCK_STATUS_RESERVED : %x ",
BLOCK_STATUS_BAD,BLOCK_STATUS_READONLY,BLOCK_STATUS_RESERVED);
while(TRUE)
{
KeySelect = 0;
bReadSpareOnly = FALSE;
EdbgOutputDebugString ( "\r\nTest :\r\n\r\n");
EdbgOutputDebugString ( "E) Erase Block \r\n");
EdbgOutputDebugString ( "R) Read Page \r\n");
EdbgOutputDebugString ( "S) Read Spare Only \r\n");
EdbgOutputDebugString ( "F) Find ECC value different sectors \r\n");
EdbgOutputDebugString ( "\r\nEnter your selection: ");
while (! ( ( (KeySelect >= '0') && (KeySelect <= '8') ) ||
( (KeySelect == 'E') || (KeySelect == 'e') ) ||
( (KeySelect == 'S') || (KeySelect == 's') ) ||
( (KeySelect == 'F') || (KeySelect == 'f') ) ||
( (KeySelect == 'R') || (KeySelect == 'r') ) ||
( (KeySelect == 0x1B) )))
{
KeySelect = OEMReadDebugByte();
}
EdbgOutputDebugString ( "%c\r\n", KeySelect);
switch(KeySelect)
{
case 'E':
case 'e':
InChar = 0;
cwNumChars = 0;
EdbgOutputDebugString("\r\nEnter Block Number(-1 for All Erase) : ");
dwBlockNumber = Uart_GetIntNum();
EdbgOutputDebugString("Erase 0x%x Block : \r\n", dwBlockNumber);
if ( dwBlockNumber == -1 )
{
for ( i = 0; i < 1024; i++ );
FMD_EraseBlock(i);
}
else
FMD_EraseBlock(dwBlockNumber);
break;
case 'S':
case 's':
bReadSpareOnly = TRUE;
case 'R':
case 'r':
InChar = 0;
cwNumChars = 0;
EdbgOutputDebugString("\r\nEnter Block Number : ");
dwBlockNumber = Uart_GetIntNum();
EdbgOutputDebugString("\r\nEnter Sector Number : ");
dwSectorNumber = Uart_GetIntNum();
//dwBlockNumber += dwSectorNumber/64;
//dwSectorNumber = dwSectorNumber%64;
do
{
EdbgOutputDebugString("\r\n");
EdbgOutputDebugString("ReadSector : 0x%x page(%d Block %d Page) \r\n", dwBlockNumber*64 + dwSectorNumber, dwBlockNumber, dwSectorNumber);
for(j=0;j<4;j++)
{
FMD_ReadSector(dwBlockNumber*256 + (dwSectorNumber*4)+j, tbuf, &si, 1);
// NF_ReadPage( dwBlockNumber, dwSectorNumber, tbuf, &dwMECC0, &dwSECC );
if ( bReadSpareOnly == TRUE )
{
dwStartSector = 2048;
}
else
{
dwStartSector = 0;
}
// for ( i = dwStartSector; i < 2048+64; i++ )
for ( i = dwStartSector; i < 512; i++ )
{
if ( i % 16 == 0 ) RETAILMSG(1, (TEXT("%04X : "), i+j*512));
RETAILMSG(1, (TEXT("%02X "), tbuf[i]));
if ( i%16 == 15 )
EdbgOutputDebugString("\r");
//if ( i == 2048-1 )
//EdbgOutputDebugString("------------------------------------------------------\r");
}
RETAILMSG(1, (TEXT("bOEMReseved = %x , bBadBlock = %x "),si.bOEMReserved,si.bBadBlock));
// RETAILMSG(1, (TEXT("MECC0 = %08X \r\n"), dwMECC0));
// RETAILMSG(1, (TEXT("SECC0 = %08X \r\n"), dwSECC));
// if ( dwMECC0 != ((DWORD *)tbuf)[(2048+8)/4] )
// {
// RETAILMSG(1, (TEXT("Main ECC values are different!!!!!!!!!! \r\n")));
// RETAILMSG(1, (TEXT("((DWORD *)tbuf)[(2048+8)/4] = %08X \r\n"), ((DWORD *)tbuf)[(2048+8)/4]));
// }
// if ( dwSECC != ((DWORD *)tbuf)[(2048+12)/4] )
// {
// RETAILMSG(1, (TEXT("Spare ECC values are different!!!!!!!!!! \r\n")));
// RETAILMSG(1, (TEXT("((DWORD *)tbuf)[(2048+12)/4] = %08X \r\n"), ((DWORD *)tbuf)[(2048+12)/4]));
// }
// EdbgOutputDebugString("si.dwReserved1 : %x\r\n", si.dwReserved1);
// EdbgOutputDebugString("si.bOEMReserved : %x\r\n", si.bOEMReserved);
// EdbgOutputDebugString("si.bBadBlock : %x\r\n", si.bBadBlock);
// EdbgOutputDebugString("si.wReserved2 : %x\r\n", si.wReserved2);
}
EdbgOutputDebugString("\r\nPress Enter to read next sector (or +,-,u,d,r,s key) : ");
InChar = 0;
LOOP:
InChar = OEMReadDebugByte();
if (InChar != OEM_DEBUG_COM_ERROR && InChar != OEM_DEBUG_READ_NODATA)
{
if (InChar == 0x1B) // Escape
{
break;
}
else if (InChar == 0x0d || InChar == 0x0a || InChar == 0x2b) // Enter, +
{
dwSectorNumber ++;
if ( dwSectorNumber > 63 )
{
dwBlockNumber ++;
dwSectorNumber = 0;
}
continue;
}
else if (InChar == 0x2d) // -
{
if ( dwSectorNumber == 0 )
{
dwBlockNumber --;
dwSectorNumber = 63;
}
else
{
dwSectorNumber --;
}
continue;
}
else if (InChar == 'U' || InChar == 'u')
{
dwBlockNumber ++;
continue;
}
else if (InChar == 'D' || InChar == 'd')
{
dwBlockNumber --;
continue;
}
else if (InChar == 'R' || InChar == 'r')
{
bReadSpareOnly = FALSE;
continue;
}
else if (InChar == 'S' || InChar == 's')
{
bReadSpareOnly = TRUE;
continue;
}
}
goto LOOP;
} while(TRUE);
break;
case 'F':
case 'f':
for ( i = 0; i < 1024; i++ )
{
for ( j = 0; j < 64; j++ )
{
InChar = 0;
InChar = OEMReadDebugByte();
if (InChar != OEM_DEBUG_COM_ERROR && InChar != OEM_DEBUG_READ_NODATA)
{
if (InChar == 0x1B) // Escape
{
goto EXITLOOP;
}
}
//bCleanSector = NF_ReadPage( i, j, tbuf, &dwMECC0, &dwSECC );
if ( bCleanSector == TRUE )
continue;
if ( dwMECC0 != ((DWORD *)tbuf)[(2048+8)/4] )
{
EdbgOutputDebugString("\r\n");
EdbgOutputDebugString("ReadSector : 0x%x page(%d Block %d Page) \r\n", i*64 + j, i, j);
RETAILMSG(1, (TEXT("Main ECC values are different!!!!!!!!!! \r\n")));
RETAILMSG(1, (TEXT("MECC0 = %08X \r\n"), dwMECC0));
RETAILMSG(1, (TEXT("((DWORD *)tbuf)[(2048+8)/4] = %08X \r\n"), ((DWORD *)tbuf)[(2048+8)/4]));
}
if ( dwSECC != ((DWORD *)tbuf)[(2048+12)/4] )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -