⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nand.c

📁 Sirf/Centrality公司GPS平台AtlasIII芯片AT640的Nboot源码
💻 C
📖 第 1 页 / 共 3 页
字号:
//
// 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.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
--*/
#include "def.h"
#include "AT4X0f.h"
#include <cspregs.h>

#include <string.h>
#define _DEFINE_CSP_REGS_
#include <drvlib.h>
#include "debug.h"
#include "nand.h"
#include "fmdext.h"
#include "smecc.h"
#include <loader.h>
#include <macros.h>
#include "oem.h"
#include "cachesync.h"
#include <macros.h>

#ifndef CACHE_SYSNC_DISCARD
#define CACHE_SYSNC_DISCARD 0
#endif

#undef  RETAILMSG
#define RETAILMSG(cond,expr)

FlashInfoEx g_FlashExtInfo;
PFlashInfoEx pFlashExtInfo = &g_FlashExtInfo;


static BOOL NandCheckAndReserveBlock(DWORD dwBlockIndex);
BOOL FMD_SetBlockStatus(DWORD blockID, DWORD dwStatus);
BOOL  FMDVerifyWrite(DWORD cs);

#define logh(val)	do { \
	NandDbgPutString ("\r\n" #val " = "); \
	NandDbgPutHex ((DWORD)val); \
} while (0)

#define IS_BLOCK_BAD(blockID) ((FMD_GetBlockStatus (blockID) & BLOCK_STATUS_BAD) > 0)
#define IS_BLOCK_READONLY(blockID) ((FMD_GetBlockStatus (blockID) & BLOCK_STATUS_READONLY) > 0)
#define IS_BLOCK_RESERVED(blockID) ((FMD_GetBlockStatus (blockID) & BLOCK_STATUS_RESERVED) > 0)
#define IS_BLOCK_UNUSABLE(blockID) ((FMD_GetBlockStatus (blockID) & (BLOCK_STATUS_BAD|BLOCK_STATUS_RESERVED)) > 0)

// fs: file size in bytes
// returns sector aligned value
DWORD FILE_TO_SECTOR_SIZE (DWORD fs) { return 1 + ((fs - 1) >> g_FlashExtInfo.ucSectorSizeBits); }
DWORD FILE_TO_BLOCK_SIZE (DWORD fs) { return 1 +  ((fs - 1) >> g_FlashExtInfo.ucBlockSizeBits); }
// ns: number of sectors
// N.B: returns sector aligned value since we can't tell
DWORD SECTOR_TO_FILE_SIZE (DWORD ns) { return ns << g_FlashExtInfo.ucSectorSizeBits; }

// FMD block status definitions.
#define BLOCK_STATUS_UNKNOWN	0x01
#define BLOCK_STATUS_BAD		0x02
#define BLOCK_STATUS_READONLY	0x04
#define BLOCK_STATUS_RESERVED	0x08

// FMD OEM reserved area bitfield.
#define OEM_BLOCK_RESERVED	0x01
#define OEM_BLOCK_READONLY	0x02

#define ATLAS_IMAGE_WINDOWS_CE_NBOOT	3
#define ATLAS_IMAGE_WINDOWS_CE_EBOOT	4
#define ATLAS_IMAGE_WINDOWS_NK_NB0	5
#define ATLAS_IMAGE_WINDOWS_CE_DM	7	//leon01 add for DM

#define  TOC_RESERVED_BLOCK_SIZE	1
#define  EBOOT_RESERVED_BLOCK_SIZE	10
#define  DM_RESERVED_BLOCK_SIZE		35	//leon01 add for DM

#define NBOOT_VERSION			0x300B  // Version number: AAAA.BBBB.CCCCCCCC one word, 3.0.11

#define MAX_BAD_BLOCKS			10

#define pDriverGlobals			((PDRIVER_GLOBALS) 0xC0002000)  

DWORD dwDmaPhysAddr		= SMDF_DMA_START_PHYSICAL;
DWORD g_nNandCS			= 0;	//default to 0
DWORD g_nCurImg			= ATLAS_IMAGE_WINDOWS_CE_NBOOT;

//DWORD g_dwNBootBlock;
DWORD g_dwTocBlock;
DWORD g_dwEBootBlock;
DWORD g_dwNKBlock;
DWORD g_dwDMBlock		= 0;	//leon01 add for DM entry

DWORD g_dwSecureBlock;
DWORD g_dwSecureBlockSize = 0;

SectorInfo g_SI;
BYTE tocTemp[2048+64];
TOC* g_pTOC = (TOC*) tocTemp;

#ifndef BUILDING_NBOOT_ICE
static DWORD g_dwEbootBlockSize=EBOOT_RESERVED_BLOCK_SIZE;
static DWORD g_dwDMBlockSize=DM_RESERVED_BLOCK_SIZE;

static DWORD g_dwEbootLaunchAddr=0x8c04c000;
static DWORD g_dwEbootLoadAddr=0x8c04c000;
static DWORD g_dwDMLaunchAddr=0x8c04c000;
static DWORD g_dwDMLoadAddr=0x8c04c000;

static DWORD g_dwTOCBlockSize=TOC_RESERVED_BLOCK_SIZE;
#endif

volatile PUCHAR	v_pDMAAddr					= (volatile PUCHAR)(SMDF_DMA_START_PHYSICAL&~0xc0000000);

#ifndef BUILDING_NBOOT_ICE
extern DWORD g_iCurImgLength;
#endif
extern DWORD g_dwJumpAddr;
extern DWORD g_dwEntry;
extern DWORD g_dwIoClock;

BYTE WriteSectBuf[2048+64];
BYTE ReadSectBuf[2048+64];

int g_bNandDbgMuted = 0;

UCHAR g_ucNandcs[4];

#define PROTECT_NAND()	do{	\
	GPIO2_PAD_EN |= 0x40;	\
	GPIO2_CTRL6	= 0x100;	\
	GPIO2_CTRL6	|= 0x20;	\
	}while(0)
	
#define UNPROTECT_NAND()	do {	\
	GPIO2_PAD_EN |= 0x40;	\
	GPIO2_CTRL6	= 0x140;	\
	GPIO2_CTRL6	|= 0x20;	\
	}while(0)
	
// When using serial port to update image, 
// we don't allow any debug message through this port.
void	NandDbgPutHex(unsigned long i)	{ if (!g_bNandDbgMuted) DbgPutHex (i); }
void	NandDbgPutString(char* s)	{ if (!g_bNandDbgMuted) DbgPutString (s); }


void FMDSetAddress (DWORD dwSectorAddr, WORD wOffsetLarge, WORD wOffsetSmall)
{
	if (g_FlashExtInfo.bHighDensity)
	{
		NF_SET_ADDR((dwSectorAddr<<16) + wOffsetLarge/(g_FlashExtInfo.ucDataWidth/8));
		NF_SET_ADDR_HI(dwSectorAddr>>16);
	}
	else
	{
		NF_SET_ADDR((dwSectorAddr<<8) + wOffsetSmall);
		NF_SET_ADDR_HI(0);
	}
}

void FMDChangePointer(BOOL bDataArea)
{
	if (!g_FlashExtInfo.bHighDensity)
	{
		NF_CMD_MODE();
		NF_ADDR_CYCLE_NUM(0);
		// 
		if (bDataArea)
		{
			//change the write pointer to the data area by issueing a read cmd1
			NF_CMD(SMDF_CMD_READ1);
		}
		else
		{
			//change the write pointer to the spare area by issueing a read cmd2
			NF_CMD(SMDF_CMD_READ2);
		}
	}
}

void FMDWriteFifo (PDWORD pData, DWORD dwLength)
{
	DWORD dwFifoNum;
	for (dwFifoNum=0; dwFifoNum<dwLength/4; dwFifoNum++)
	{
		NF_WR_FIFO((*(pData+dwFifoNum)));
	}
}

void FMDReadFifo (PDWORD pData, DWORD dwLength)
{
	DWORD dwFifoNum;
	for (dwFifoNum=0; dwFifoNum<dwLength/4; dwFifoNum++)
	{
		NF_RD_FIFO((*(pData+dwFifoNum)));
	}
}

void FMDPageProgram (void)
{
	NF_CMD_MODE ();
	NF_ADDR_CYCLE_NUM (0);
	NF_CLR_INT (SMDF_ADD_INT);
	NF_CMD (SMDF_CMD_PAGE_PROGRAM);
	NF_WAIT_INT (SMDF_ADD_INT);
}

void FMDInitHardware()
{

	int nand_cs = OEMGetNandCs();

	if(OEMIsNorBoot())
	{
		nand_cs &= ~1;
		//Default the cs to cs3 
		g_nNandCS = 3;
	}
	WRITE_BITFIELD(struct RSCPinMuxBits, &(v_pRscRegs->rscPinMux), nand, nand_cs);

	if (0 == (v_pSMDFRegs->SmDirectRead & 0x10)) {
		WRITE_BITFIELD(struct RSCPinMuxBits, &(v_pRscRegs->rscPinMux), cam, 0x1);
	}

	// Map SMDF register space
	v_pSMDFRegs->SmDirectRead &= ~0x1;

	v_pSMDFRegs->SmWait = 0x1878;
	v_pSMDFRegs->SmFIFOOp = 1;

	NF_INIT_DMA();
	NF_INT_MASK(0);

	// ENABLE POWER MANAGER CLOCK ENABLE REGISTER
	WRITE_BITFIELD(struct pwrclkenable, &(v_pPowerRegs->pmr_clkenable), dma, 1);
	WRITE_BITFIELD(struct pwrclkenable, &(v_pPowerRegs->pmr_clkenable), rom, 1);

	NF_CS(~(1 << g_nNandCS));
}


BOOL FMDReadFlashID()
{
	DWORD dwRead;
	DWORD dwDeviceId;
	DWORD dwManufactureId;

	g_FlashExtInfo.wCmdSeqDataIn			= 0x80;
	g_FlashExtInfo.wCmdPageProg				= 0x10;
	g_FlashExtInfo.wCmdReadStat				= 0x70;
	g_FlashExtInfo.wCmdReadId				= 0x90;
	g_FlashExtInfo.wCmdBlockErase			= 0xd060;
	g_FlashExtInfo.wCmdReset				= 0xff;
	g_FlashExtInfo.wLock					= 0x0;
	g_FlashExtInfo.wUnlock					= 0x0;
	g_FlashExtInfo.wLockTight				= 0x0;
	g_FlashExtInfo.wReadLockStat			= 0x0;

	g_FlashExtInfo.wCmdCacheProg			= 0x1580;
	g_FlashExtInfo.wCmdCBProg				= 0x1085;
	g_FlashExtInfo.wCmdRandInput			= 0x85;
	g_FlashExtInfo.wCmdRandOutput			= 0xe005;
	g_FlashExtInfo.wCmdReadLast				= 0x0;

	//
	// force to use 8-bit mode to read Flash ID
	//
	v_pSMDFRegs->SmDirectRead &= ~0x2;

	NF_RESET_FIFO();
	NF_IO_RD_MODE();
	NF_LEN(4);
	NF_ADDR_CYCLE_NUM(1);
	NF_SET_ADDR(0);
	NF_CMD(SMDF_CMD_READ_ID);

	while(NF_FIFO_EMPTY());

	NF_RD_FIFO(dwRead);

	dwManufactureId = (dwRead & 0xff);
	dwDeviceId = ((dwRead >> 8) & 0xff);

#if 0
	NandDbgPutString("Manufacture ID: ");
	NandDbgPutHex(dwManufactureId);
	NandDbgPutString("\r\nDevice ID: ");
	NandDbgPutHex(dwDeviceId);
	NandDbgPutString("\r\n");
#endif

	switch (dwDeviceId)
	{
	case DEVICE_ID_16M:
	case DEVICE_ID_32M:
	case DEVICE_ID_64M:
	case DEVICE_ID_128M:
		v_pSMDFRegs->SmDirectRead				&= ~8;
		g_FlashExtInfo.ucSectorSizeBits			= SHIFT_512_BYTES;
		g_FlashExtInfo.ucSectorsPerBlockBits	= 5;

		// Set flash command set
		g_FlashExtInfo.wCmdReadFirst			= 0x00;
		g_FlashExtInfo.wCmdReadLast				= 0x01;
		g_FlashExtInfo.wCmdReadShare			= 0x50;

		g_FlashExtInfo.wCmdCacheProg			= 0x00;
		g_FlashExtInfo.wCmdCBProg				= 0x00;
		g_FlashExtInfo.wCmdRandInput			= 0x00;
		g_FlashExtInfo.wCmdRandOutput			= 0x00;

	case DEVICE_ID_K9K2G08Q0M:
	case DEVICE_ID_K9K2G08U0M:
	case DEVICE_ID_K9K4G08U0M:
	case DEVICE_ID_128M_F1:
		g_FlashExtInfo.ucDataWidth				= 8;
		break;

	case DEVICE_ID_128M_16BITS:
	case DEVICE_ID_K9K2G16Q0M:
	case DEVICE_ID_K9K2G16U0M:
		v_pSMDFRegs->SmDirectRead				|= 0x2;
		g_FlashExtInfo.ucDataWidth				= 16;
		break;
	default:
        if (!OEMGetFlashExtInfo (dwManufactureId, dwDeviceId, &g_FlashExtInfo))
        {
			NandDbgPutString ("\r\nID lost.");
			PWR_CLOCK_DISABLE (PWRCLK_USB_EN);
			while (1);
		}
        break;
	}

	switch (dwDeviceId) 
	{
	case DEVICE_ID_16M:
		g_FlashExtInfo.fi.dwNumBlocks			= 1024;
		g_FlashExtInfo.ucChipAddrCycleNum		= 3;
		break;

	case DEVICE_ID_32M:
		g_FlashExtInfo.fi.dwNumBlocks			= 2048;
		g_FlashExtInfo.ucChipAddrCycleNum		= 3;
		break;

	case DEVICE_ID_64M:
		g_FlashExtInfo.fi.dwNumBlocks			= 4096;
		g_FlashExtInfo.ucChipAddrCycleNum		= 4;
		break;

	case DEVICE_ID_128M:
		g_FlashExtInfo.fi.dwNumBlocks			= 8192;
		g_FlashExtInfo.ucChipAddrCycleNum		= 4;
		break;

	case DEVICE_ID_128M_F1:
		g_FlashExtInfo.fi.dwNumBlocks			= 1024;
		g_FlashExtInfo.ucSectorSizeBits			= SHIFT_2048_BYTES;
		g_FlashExtInfo.ucSectorsPerBlockBits	= 6;

		g_FlashExtInfo.ucChipAddrCycleNum		= 4;

		// Set flash command set
		g_FlashExtInfo.wCmdReadFirst			= 0x3000;
		g_FlashExtInfo.wCmdReadShare			= 0x3000;
		break;

	case DEVICE_ID_128M_16BITS:
		g_FlashExtInfo.ucSectorSizeBits			= SHIFT_2048_BYTES;
		g_FlashExtInfo.ucSectorsPerBlockBits	= 6;
		g_FlashExtInfo.fi.dwNumBlocks			= 512;
		g_FlashExtInfo.ucChipAddrCycleNum		= 4;

		// These codes still not verified.
		// Set flash command set
		g_FlashExtInfo.wCmdReadFirst			= 0x3000;
		g_FlashExtInfo.wCmdReadShare			= 0x3000;
		break;

	case DEVICE_ID_K9K2G08Q0M:
	case DEVICE_ID_K9K2G08U0M:
	case DEVICE_ID_K9K2G16Q0M:
	case DEVICE_ID_K9K2G16U0M:
		g_FlashExtInfo.ucSectorSizeBits			= SHIFT_2048_BYTES;
		g_FlashExtInfo.ucSectorsPerBlockBits	= 6;
		g_FlashExtInfo.fi.dwNumBlocks			= 2048;
		g_FlashExtInfo.ucChipAddrCycleNum		= 5;

		// Set flash command set
		g_FlashExtInfo.wCmdReadFirst			= 0x3000;
		g_FlashExtInfo.wCmdReadShare			= 0x3000;
		break;
		
	case DEVICE_ID_K9K4G08U0M:
		g_FlashExtInfo.ucSectorSizeBits			= SHIFT_2048_BYTES;
		g_FlashExtInfo.ucSectorsPerBlockBits	= 6;
		g_FlashExtInfo.fi.dwNumBlocks			= 4096;
		g_FlashExtInfo.ucChipAddrCycleNum		= 5;

		// Set flash command set
		g_FlashExtInfo.wCmdReadFirst			= 0x3000;
		g_FlashExtInfo.wCmdReadShare			= 0x3000;
		break;

	}

	g_FlashExtInfo.ucBlockSizeBits = g_FlashExtInfo.ucSectorSizeBits+g_FlashExtInfo.ucSectorsPerBlockBits;
	g_FlashExtInfo.fi.wSectorsPerBlock		= 1 << g_FlashExtInfo.ucSectorsPerBlockBits;
	g_FlashExtInfo.fi.wDataBytesPerSector	= 1 << g_FlashExtInfo.ucSectorSizeBits;
	g_FlashExtInfo.fi.dwBytesPerBlock		= 1 << g_FlashExtInfo.ucBlockSizeBits;
	g_FlashExtInfo.wSpareDataLength			= g_FlashExtInfo.fi.wDataBytesPerSector * 16 / 512;
	g_FlashExtInfo.dwTotalSize				= g_FlashExtInfo.fi.dwNumBlocks << g_FlashExtInfo.ucBlockSizeBits;
	v_pSMDFRegs->SmPageSize	= g_FlashExtInfo.dwPageSize
							= g_FlashExtInfo.fi.wDataBytesPerSector + g_FlashExtInfo.wSpareDataLength;

	if (g_FlashExtInfo.ucSectorSizeBits > 9)
	{
		g_FlashExtInfo.bHighDensity = 1;
		g_FlashExtInfo.ucNumBlockCycles = g_FlashExtInfo.ucChipAddrCycleNum - 2;
	}
	else
	{
		g_FlashExtInfo.bHighDensity = 0;
		g_FlashExtInfo.ucNumBlockCycles = g_FlashExtInfo.ucChipAddrCycleNum - 1;
	}

	return TRUE;
}

#if 0
void FMDReadUUID(void)
{
	int i;
	DWORD dwRead;
	DWORD dwSig;

	FMDInitHardware();
	FMDReadFlashID();

	NF_CMD_MODE();
	NF_SET_ADDR(0);
	NF_SET_ADDR_HI(0);
	NF_ADDR_CYCLE_NUM(0);
	NF_LEN(0);

	NF_CMD(0x30);
	NF_CMD_MODE();
	NF_ADDR_CYCLE_NUM(0);
	NF_CMD(0x65);
	NF_CMD_MODE();
	NF_ADDR_CYCLE_NUM(g_FlashExtInfo.ucChipAddrCycleNum+1);
	NF_LEN(g_FlashExtInfo.dwPageSize);
	NF_CMD(SMDF_CMD_READ1);
   	NF_IO_RD_MODE();

	for (i=0;i<(g_FlashExtInfo.dwPageSize)/4; i++)
	{
		while(NF_FIFO_EMPTY());
		NF_RD_FIFO(dwRead);

		if (g_FlashExtInfo.bHighDensity)
		{
			if(i<16)
			{

⌨️ 快捷键说明

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