nand.cpp

来自「SAMSUNG S3C6410 CPU BSP for winmobile6」· C++ 代码 · 共 1,317 行 · 第 1/4 页

CPP
1,317
字号
//
// 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 <XSR.h>

DWORD g_TOC_BLOCK;
DWORD g_TOC_SECTOR;

extern DWORD        g_ImageType;
extern UCHAR        g_TOC[NAND_SECTOR_SIZE];
extern const PTOC   g_pTOC;
extern DWORD        g_dwTocEntry;
extern PBOOT_CFG    g_pBootCfg;
extern BOOL         g_bBootMediaExist;
extern MultiBINInfo g_BINRegionInfo;
}
BOOL WriteBlock(DWORD dwBlock, LPBYTE pbBlock, PSectorInfo pSectorInfoTable);
BOOL ReadBlock(DWORD dwBlock, LPBYTE pbBlock, PSectorInfo pSectorInfoTable);
BOOL WritePage(DWORD dwPage, LPBYTE pbPage, PSectorInfo pSectorInfo);


extern DWORD 		g_dwLastWrittenLoc;                     //  Defined in bootpart.lib
extern PSectorInfo 	g_pSectorInfoBuf;
extern FlashInfo 	g_FlashInfo;
static UCHAR 		toc[NAND_SECTOR_SIZE];

BOOL  FMD_ReadSector_BML (SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors)
{
	if ((pSectorBuff == NULL) || (pSectorInfoBuff != NULL)){
		RETAILMSG(1, (L"FMD_ReadSector : pSetorBuff null or pSectorInfoBuff not null\r\n"));
		return(FALSE);
	}

	if(BML_MRead(0, (startSectorAddr << 2), (dwNumSectors << 2), pSectorBuff, NULL,
			BML_FLAG_ECC_ON | BML_FLAG_BBM_ON)!=BML_SUCCESS) {
	    RETAILMSG(1, (L"FMD_ReadSector : BML_MRead is failed.\r\n"));
//	    while(1);
	}

	return(TRUE);
}

BOOL  FMD_WriteSector_BML(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors)
{
    if ((pSectorBuff == NULL) || (pSectorInfoBuff != NULL)){
		RETAILMSG(1, (L"FMD_WriteSector : pSetorBuff null or pSectorInfoBuff not null\r\n"));
		return(FALSE);
	}

	if(BML_MWrite(0, (startSectorAddr << 2),(dwNumSectors << 2), pSectorBuff, NULL,
			BML_FLAG_SYNC_OP | BML_FLAG_ECC_ON)!=BML_SUCCESS) {
	    RETAILMSG(1, (L"FMD_WriteSector : BML_MRead is failed.\r\n"));
	    while(1);
	}

	return(TRUE);
}

BOOL  FMD_EraseBlock_BML(DWORD/*BLOCK_ID*/ blockID)
{
	if(BML_EraseBlk(0,(UINT32)blockID,BML_FLAG_SYNC_OP)!=BML_SUCCESS) {
	    RETAILMSG(1, (L"FMD_EraseBlock : BML_EraseBlk(#%d) is failed.\r\n",blockID));
	    while(1);
	}
	else {
	    //RETAILMSG(1, (L"FMD_EraseBlock : BML_EraseBlk(#%d) is ok.\r\n",blockID));
	}

	return(TRUE);
}


// 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_DEBUGGER;

    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;
	INT32 nErr;
	XSRPartEntry pstPartEntry;

    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));

	nErr = BML_LoadPIEntry(0,PARTITION_ID_EBOOT,&pstPartEntry);
	if(nErr!=BML_SUCCESS) {
	    RETAILMSG(1, (L"TOC_Read : BML_LoadPIEntry is failed.\r\n"));
	    return FALSE;
	}

    // init boot cfg
    BootConfigInit(dwEntry);

    // update our index
    g_dwTocEntry = dwEntry;

    // 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(pstPartEntry.n1stVbn);
    g_pTOC->id[0].sgList[0].dwLength = g_pTOC->id[0].dwTtlSectors;

	nErr = BML_LoadPIEntry(0,PARTITION_ID_COPIEDOS,&pstPartEntry);
	if(nErr!=BML_SUCCESS) {
	    RETAILMSG(1, (L"TOC_Read : BML_LoadPIEntry is failed.\r\n"));
	    return FALSE;
	}

    // 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(pstPartEntry.n1stVbn);
    g_pTOC->id[dwEntry].sgList[0].dwLength = g_pTOC->id[dwEntry].dwTtlSectors;

    TOC_Print();

    return TRUE;
}

//
// Retrieve TOC from Nand.
//
BOOL TOC_Read(void)
{
    UINT32 nErr;
	BMLVolSpec pstVolSpec;
	XSRPartEntry pstPartEntry;

//	EdbgOutputDebugString("+TOC_Read\r\n");
	nErr = BML_GetVolInfo(0,&pstVolSpec);
	if(nErr!=BML_SUCCESS) {
	    RETAILMSG(1, (L"FMD_GetInfo : BML_GetVolInfo is failed.\r\n"));
	    return FALSE;
	}

	nErr = BML_LoadPIEntry(0, PARTITION_ID_EBOOTCFG, &pstPartEntry);
	if(nErr!=BML_SUCCESS) {
	    RETAILMSG(1, (L"TOC_Read : BML_LoadPIEntry is failed.\r\n"));
	    return FALSE;
	}

	g_TOC_BLOCK = (pstPartEntry.n1stVbn);
	g_TOC_SECTOR = (pstPartEntry.n1stVbn)*(pstVolSpec.nPgsPerBlk)*(pstVolSpec.nSctsPerPg >> 2);

    RETAILMSG(1, (L"TOC_Read : pstPartEntry.n1stVbn = 0x%x \r\n", pstPartEntry.n1stVbn));
    RETAILMSG(1, (L"TOC_Read : pstVolSpec.nPgsPerBlk = 0x%x \r\n", pstVolSpec.nPgsPerBlk));
    RETAILMSG(1, (L"TOC_Read : pstVolSpec.nSctsPerPg = 0x%x \r\n", pstVolSpec.nSctsPerPg >> 2));

    if ( !g_bBootMediaExist ) {
        EdbgOutputDebugString("TOC_Read ERROR: no boot media\r\n");
        return FALSE;
    }

    if ( !FMD_ReadSector_BML(g_TOC_SECTOR, (PUCHAR)g_pTOC, NULL, 1) ) {
		TOC_Init(DEFAULT_IMAGE_DESCRIPTOR, (IMAGE_TYPE_RAMIMAGE|IMAGE_TYPE_BINFS), 0, 0, 0);
		return TRUE;
    }

//	EdbgOutputDebugString("VALID_TOC\r\n");
    // 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;

    // 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)
{
    //EdbgOutputDebugString("+TOC_Write\r\n");

⌨️ 快捷键说明

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