?? 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>
#include <VFLBuffer.h>
#include <WMRTypes.h>
#include <VFL.h>
#include <FIL.h>
#include "InitialImage_rgb16_320x240.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?
// MLC low level test function
// by dodan2 061102
extern UINT32 MLC_Read_RAW(UINT32 nBank, UINT32 nPpn, UINT8 *pMBuf, UINT8 *pSBuf);
extern UINT32 MLC_Write_RAW(UINT32 nBank, UINT32 nPpn, UINT8 *pMBuf, UINT8 *pSBuf);
extern UINT32 MLC_Erase_RAW(UINT32 nBank, UINT32 nBlock);
extern void _Read_512Byte(UINT8* pBuf);
extern void _Read_512Byte_Unaligned(UINT8* pBuf);
extern void _Write_512Byte(UINT8* pBuf);
extern void _Write_512Byte_Unaligned(UINT8* pBuf);
}
BOOL WriteBlock(DWORD dwBlock, LPBYTE pbBlock, PSectorInfo pSectorInfoTable);
BOOL ReadBlock(DWORD dwBlock, LPBYTE pbBlock, PSectorInfo pSectorInfoTable);
#define WMRBUFSIZE (8192 + 256) // the maximum size of 2-plane data for 4KByte/Page NAND flash Device
extern DWORD g_dwLastWrittenLoc; // Defined in bootpart.lib
extern PSectorInfo g_pSectorInfoBuf;
extern FlashInfo g_FlashInfo;
static UCHAR toc[SECTOR_SIZE];
extern BOOL IsValidMBRSector();
extern BOOL CreateMBR();
extern UCHAR WMRBuf[];
void MLC_Print_Page_Data(unsigned char *pMBuf, unsigned char *pSBuf);
// Define a dummy SetKMode function to satisfy the NAND FMD.
//
DWORD SetKMode (DWORD fMode)
{
return(1);
}
void BootConfigPrint(void)
{
EdbgOutputDebugString( "BootCfg { \r\n");
EdbgOutputDebugString( " ConfigFlags: 0x%x\r\n", g_pBootCfg->ConfigFlags);
EdbgOutputDebugString( " BootDelay: 0x%x\r\n", g_pBootCfg->BootDelay);
EdbgOutputDebugString( " ImageIndex: %d \r\n", g_pBootCfg->ImageIndex);
EdbgOutputDebugString( " IP: %s\r\n", inet_ntoa(g_pBootCfg->EdbgAddr.dwIP));
EdbgOutputDebugString( " MAC Address: %B:%B:%B:%B:%B:%B\r\n",
g_pBootCfg->EdbgAddr.wMAC[0] & 0x00FF, g_pBootCfg->EdbgAddr.wMAC[0] >> 8,
g_pBootCfg->EdbgAddr.wMAC[1] & 0x00FF, g_pBootCfg->EdbgAddr.wMAC[1] >> 8,
g_pBootCfg->EdbgAddr.wMAC[2] & 0x00FF, g_pBootCfg->EdbgAddr.wMAC[2] >> 8);
EdbgOutputDebugString( " Port: %s\r\n", inet_ntoa(g_pBootCfg->EdbgAddr.wPort));
EdbgOutputDebugString( " SubnetMask: %s\r\n", inet_ntoa(g_pBootCfg->SubnetMask));
EdbgOutputDebugString( "}\r\n");
}
// Set default boot configuration values
static void BootConfigInit(DWORD dwIndex)
{
EdbgOutputDebugString("+BootConfigInit\r\n");
g_pBootCfg = &g_pTOC->BootCfg;
memset(g_pBootCfg, 0, sizeof(BOOT_CFG));
g_pBootCfg->ImageIndex = dwIndex;
g_pBootCfg->ConfigFlags = BOOT_TYPE_MULTISTAGE | CONFIG_FLAGS_KITL;
g_pBootCfg->BootDelay = CONFIG_BOOTDELAY_DEFAULT;
g_pBootCfg->SubnetMask = inet_addr("255.255.255.0");
EdbgOutputDebugString("-BootConfigInit\r\n");
return;
}
void ID_Print(DWORD i) {
DWORD j;
EdbgOutputDebugString("ID[%u] {\r\n", i);
EdbgOutputDebugString(" dwVersion: 0x%x\r\n", g_pTOC->id[i].dwVersion);
EdbgOutputDebugString(" dwSignature: 0x%x\r\n", g_pTOC->id[i].dwSignature);
EdbgOutputDebugString(" String: '%s'\r\n", g_pTOC->id[i].ucString);
EdbgOutputDebugString(" dwImageType: 0x%x\r\n", g_pTOC->id[i].dwImageType);
EdbgOutputDebugString(" dwTtlSectors: 0x%x\r\n", g_pTOC->id[i].dwTtlSectors);
EdbgOutputDebugString(" dwLoadAddress: 0x%x\r\n", g_pTOC->id[i].dwLoadAddress);
EdbgOutputDebugString(" dwJumpAddress: 0x%x\r\n", g_pTOC->id[i].dwJumpAddress);
EdbgOutputDebugString(" dwStoreOffset: 0x%x\r\n", g_pTOC->id[i].dwStoreOffset);
for (j = 0; j < MAX_SG_SECTORS; j++) {
if ( !g_pTOC->id[i].sgList[j].dwLength )
break;
EdbgOutputDebugString(" sgList[%u].dwSector: 0x%x\r\n", j, g_pTOC->id[i].sgList[j].dwSector);
EdbgOutputDebugString(" sgList[%u].dwLength: 0x%x\r\n", j, g_pTOC->id[i].sgList[j].dwLength);
}
EdbgOutputDebugString("}\r\n");
}
void TOC_Print(void)
{
int i;
EdbgOutputDebugString("TOC {\r\n");
EdbgOutputDebugString("dwSignature: 0x%x\r\n", g_pTOC->dwSignature);
BootConfigPrint( );
for (i = 0; i < MAX_TOC_DESCRIPTORS; i++) {
if ( !VALID_IMAGE_DESCRIPTOR(&g_pTOC->id[i]) )
break;
ID_Print(i);
}
// Print out Chain Information
EdbgOutputDebugString("chainInfo.dwLoadAddress: 0X%X\r\n", g_pTOC->chainInfo.dwLoadAddress);
EdbgOutputDebugString("chainInfo.dwFlashAddress: 0X%X\r\n", g_pTOC->chainInfo.dwFlashAddress);
EdbgOutputDebugString("chainInfo.dwLength: 0X%X\r\n", g_pTOC->chainInfo.dwLength);
EdbgOutputDebugString("}\r\n");
}
// init the TOC to defaults
BOOL TOC_Init(DWORD dwEntry, DWORD dwImageType, DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr)
{
DWORD dwSig = 0;
EdbgOutputDebugString("TOC_Init: dwEntry:%u, dwImageType: 0x%x, dwImageStart: 0x%x, dwImageLength: 0x%x, dwLaunchAddr: 0x%x\r\n",
dwEntry, dwImageType, dwImageStart, dwImageLength, dwLaunchAddr);
if (0 == dwEntry) {
EdbgOutputDebugString("\r\n*** WARNING: TOC_Init blasting Eboot ***\r\n");
return FALSE;
}
switch (dwImageType) {
case IMAGE_TYPE_LOADER:
dwSig = IMAGE_EBOOT_SIG;
break;
case IMAGE_TYPE_RAMIMAGE:
dwSig = IMAGE_RAM_SIG;
break;
default:
EdbgOutputDebugString("ERROR: OEMLaunch: unknown image type: 0x%x \r\n", dwImageType);
return FALSE;
}
memset(g_pTOC, 0, sizeof(g_TOC));
// init boof cfg
BootConfigInit(dwEntry);
// update our index
g_dwTocEntry = dwEntry;
// debugger enabled?
g_bWaitForConnect = (g_pBootCfg->ConfigFlags & CONFIG_FLAGS_KITL) ? TRUE : FALSE;
// init TOC...
//
g_pTOC->dwSignature = TOC_SIGNATURE;
// init TOC entry for Eboot
// Those are hard coded numbers from boot.bib
g_pTOC->id[0].dwVersion = (EBOOT_VERSION_MAJOR << 16) | EBOOT_VERSION_MINOR;
g_pTOC->id[0].dwSignature = IMAGE_EBOOT_SIG;
memcpy(g_pTOC->id[0].ucString, "eboot.nb0", sizeof("eboot.nb0")+1); // NUll terminate
g_pTOC->id[0].dwImageType = IMAGE_TYPE_RAMIMAGE;
g_pTOC->id[0].dwLoadAddress = EBOOT_RAM_IMAGE_BASE;
g_pTOC->id[0].dwJumpAddress = EBOOT_RAM_IMAGE_BASE;
g_pTOC->id[0].dwTtlSectors = FILE_TO_SECTOR_SIZE(EBOOT_RAM_IMAGE_SIZE);
// 1 contigious segment
g_pTOC->id[0].sgList[0].dwSector = BLOCK_TO_SECTOR(EBOOT_BLOCK);
g_pTOC->id[0].sgList[0].dwLength = g_pTOC->id[0].dwTtlSectors;
// init the TOC entry
g_pTOC->id[dwEntry].dwVersion = 0x001;
g_pTOC->id[dwEntry].dwSignature = dwSig;
memset(g_pTOC->id[dwEntry].ucString, 0, IMAGE_STRING_LEN);
g_pTOC->id[dwEntry].dwImageType = dwImageType;
g_pTOC->id[dwEntry].dwLoadAddress = dwImageStart;
g_pTOC->id[dwEntry].dwJumpAddress = dwLaunchAddr;
g_pTOC->id[dwEntry].dwStoreOffset = 0;
g_pTOC->id[dwEntry].dwTtlSectors = FILE_TO_SECTOR_SIZE(dwImageLength);
// 1 contigious segment
g_pTOC->id[dwEntry].sgList[0].dwSector = BLOCK_TO_SECTOR(g_dwImageStartBlock);
g_pTOC->id[dwEntry].sgList[0].dwLength = g_pTOC->id[dwEntry].dwTtlSectors;
TOC_Print();
return TRUE;
}
//
// Retrieve TOC from Nand.
//
BOOL TOC_Read(void)
{
LowFuncTbl *pLowFuncTbl;
DWORD dwBlock;
INT32 nRet;
UINT8 *pSBuf;
EdbgOutputDebugString("TOC_Read\r\n");
if ( !g_bBootMediaExist )
{
EdbgOutputDebugString("TOC_Read ERROR: no boot media\r\n");
return FALSE;
}
pLowFuncTbl = FIL_GetFuncTbl();
pSBuf = WMRBuf + BYTES_PER_MAIN_SUPAGE;
dwBlock = TOC_BLOCK;
while(1)
{
if (dwBlock == (TOC_BLOCK+TOC_BLOCK_SIZE+TOC_BLOCK_RESERVED))
{
OALMSG(TRUE, (TEXT("TOC_Read Failed !!!\r\n")));
OALMSG(TRUE, (TEXT("Too many Bad Block\r\n")));
return FALSE;
}
IS_CHECK_SPARE_ECC = FALSE32;
pLowFuncTbl->Read(0, dwBlock*PAGES_PER_BLOCK+PAGES_PER_BLOCK-1, 0x0, enuLEFT_PLANE_BITMAP, NULL, pSBuf, TRUE32, FALSE32);
IS_CHECK_SPARE_ECC = TRUE32;
if (pSBuf[0] == 0xff)
{
nRet = pLowFuncTbl->Read(0, dwBlock*PAGES_PER_BLOCK, 0x01, enuLEFT_PLANE_BITMAP, (UINT8 *)g_pTOC, NULL, FALSE32, FALSE32);
if (nRet != FIL_SUCCESS)
{
OALMSG(TRUE, (TEXT("[ERR] FIL Read Error @ %d Block %d Page, Skipped\r\n"), dwBlock, 0));
dwBlock++;
continue;
}
else
{
break;
}
}
else
{
OALMSG(TRUE, (TEXT("Bad Block %d Skipped\r\n"), dwBlock));
dwBlock++;
continue;
}
}
// is it a valid TOC?
if ( !VALID_TOC(g_pTOC) )
{
EdbgOutputDebugString("TOC_Read ERROR: INVALID_TOC Signature: 0x%x\r\n", g_pTOC->dwSignature);
return FALSE;
}
// update our boot config
g_pBootCfg = &g_pTOC->BootCfg;
// update our index
g_dwTocEntry = g_pBootCfg->ImageIndex;
// debugger enabled?
g_bWaitForConnect = (g_pBootCfg->ConfigFlags & CONFIG_FLAGS_KITL) ? TRUE : FALSE;
// cache image type
g_ImageType = g_pTOC->id[g_dwTocEntry].dwImageType;
EdbgOutputDebugString("-TOC_Read\r\n");
return TRUE;
}
//
// Store TOC to Nand
// BUGBUG: only uses 1 sector for now.
//
BOOL TOC_Write(void)
{
LowFuncTbl *pLowFuncTbl;
DWORD dwBlock;
INT32 nRet;
UINT8 *pSBuf;
UINT32 nSyncRet;
EdbgOutputDebugString("+TOC_Write\r\n");
if ( !g_bBootMediaExist )
{
EdbgOutputDebugString("TOC_Write WARN: no boot media\r\n");
return FALSE;
}
// is it a valid TOC?
if ( !VALID_TOC(g_pTOC))
{
EdbgOutputDebugString("TOC_Write ERROR: INVALID_TOC Signature: 0x%x\r\n", g_pTOC->dwSignature);
return FALSE;
}
// is it a valid image descriptor?
if ( !VALID_IMAGE_DESCRIPTOR(&g_pTOC->id[g_dwTocEntry]) )
{
EdbgOutputDebugString("TOC_Write ERROR: INVALID_IMAGE[%u] Signature: 0x%x\r\n",
g_dwTocEntry, g_pTOC->id[g_dwTocEntry].dwSignature);
return FALSE;
}
pLowFuncTbl = FIL_GetFuncTbl();
memset(WMRBuf, '\0', WMRBUFSIZE);
pSBuf = WMRBuf + BYTES_PER_MAIN_SUPAGE;
dwBlock = TOC_BLOCK;
while(1)
{
if (dwBlock == (TOC_BLOCK+TOC_BLOCK_SIZE+TOC_BLOCK_RESERVED))
{
OALMSG(TRUE, (TEXT("TOC_Write Failed !!!\r\n")));
OALMSG(TRUE, (TEXT("Too many Bad Block\r\n")));
return FALSE;
}
IS_CHECK_SPARE_ECC = FALSE32;
pLowFuncTbl->Read(0, dwBlock*PAGES_PER_BLOCK+PAGES_PER_BLOCK-1, 0x0, enuLEFT_PLANE_BITMAP, NULL, pSBuf, TRUE32, FALSE32);
IS_CHECK_SPARE_ECC = TRUE32;
if (pSBuf[0] == 0xff)
{
pLowFuncTbl->Erase(0, dwBlock, enuLEFT_PLANE_BITMAP);
nRet = pLowFuncTbl->Sync(0, &nSyncRet);
if ( nRet != FIL_SUCCESS)
{
OALMSG(TRUE, (TEXT("[ERR] FIL Erase Error @ %d block, Skipped\r\n"), dwBlock));
goto MarkAndSkipBadBlock;
}
pLowFuncTbl->Write(0, dwBlock*PAGES_PER_BLOCK, 0x01, enuLEFT_PLANE_BITMAP, (UINT8 *)g_pTOC, NULL);
nRet = pLowFuncTbl->Sync(0, &nSyncRet);
if (nRet != FIL_SUCCESS)
{
OALMSG(TRUE, (TEXT("[ERR] FIL Write Error @ %d Block %d Page, Skipped\r\n"), dwBlock, 0));
goto MarkAndSkipBadBlock;
}
nRet = pLowFuncTbl->Read(0, dwBlock*PAGES_PER_BLOCK, 0x01, enuLEFT_PLANE_BITMAP, toc, NULL, FALSE32, FALSE32);
if (nRet != FIL_SUCCESS)
{
OALMSG(TRUE, (TEXT("[ERR] FIL Read Error @ %d Block %d Page, Skipped\r\n"), dwBlock, 0));
goto MarkAndSkipBadBlock;
}
if (0 != memcmp(toc, (UINT8 *)g_pTOC, SECTOR_SIZE))
{
OALMSG(TRUE, (TEXT("[ERR] Verify Error @ %d Block %d Page, Skipped\r\n"), dwBlock, 0));
goto MarkAndSkipBadBlock;
}
OALMSG(TRUE, (TEXT("[OK] Write %d th Block Success\r\n"), dwBlock));
break;
MarkAndSkipBadBlock:
pLowFuncTbl->Erase(0, dwBlock, enuLEFT_PLANE_BITMAP);
memset(pSBuf, 0x0, BYTES_PER_SPARE_PAGE);
IS_CHECK_SPARE_ECC = FALSE32;
pLowFuncTbl->Write(0, dwBlock*PAGES_PER_BLOCK+PAGES_PER_BLOCK-1, 0x0, enuLEFT_PLANE_BITMAP, NULL, pSBuf);
IS_CHECK_SPARE_ECC = TRUE32;
dwBlock++;
continue;
}
else
{
OALMSG(TRUE, (TEXT("Bad Block %d Skipped\r\n"), dwBlock));
dwBlock++;
continue;
}
}
EdbgOutputDebugString("-TOC_Write\r\n");
return TRUE;
}
extern DWORD g_dwMBRSectorNum;
/*
@func BOOL | WriteOSImageToBootMedia | Stores the image cached in RAM to the Boot Media.
The image may be comprised of one or more BIN regions.
@rdesc TRUE = Success, FALSE = Failure.
@comm
@xref
*/
BOOL WriteOSImageToBootMedia(DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr)
{
BYTE nCount;
DWORD dwNumExts;
PXIPCHAIN_SUMMARY pChainInfo = NULL;
EXTENSION *pExt = NULL;
DWORD dwBINFSPartLength = 0;
HANDLE hPart;
DWORD dwStoreOffset;
DWORD dwMaxRegionLength[BL_MAX_BIN_REGIONS] = {0};
DWORD dwChainStart, dwChainLength;
DWORD dwBlock;
DWORD nBlockNum;
// DWORD checksum = 0;
// Initialize the variables
dwChainStart = dwChainLength = 0;
OALMSG(OAL_FUNC, (TEXT("+WriteOSImageToBootMedia\r\n")));
OALMSG(TRUE, (TEXT("+WriteOSImageToBootMedia: g_dwTocEntry =%d, ImageStart: 0x%x, ImageLength: 0x%x, LaunchAddr:0x%x\r\n"),
g_dwTocEntry, dwImageStart, dwImageLength, dwLaunchAddr));
if ( !g_bBootMediaExist )
{
OALMSG(OAL_ERROR, (TEXT("ERROR: WriteOSImageToBootMedia: device doesn't exist.\r\n")));
return(FALSE);
}
if (g_ImageType == IMAGE_TYPE_RAMIMAGE)
{
g_dwMBRSectorNum = BLOCK_TO_SECTOR(IMAGE_START_BLOCK);
OALMSG(TRUE, (TEXT("g_dwMBRSectorNum = 0x%x\r\n"), g_dwMBRSectorNum));
dwBlock = IMAGE_START_BLOCK; //by hmseo - 20061124 This block is to MBR
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -