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

📄 nandboot.c

📁 dm6437的NAND Secondary Boot
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  ============================================================================
 *   Copyright (c) Texas Instruments Inc 2002, 2003, 2004
 *
 *   Use of this software is controlled by the terms and conditions found in the
 *   license agreement under which this software has been supplied.
 *   ===========================================================================
 */

/** @file nandboot.c
 *
 *  @brief File contains code for boot from EMIF/Nand Flash @a performEmifBoot()
 *
 *  Description
 *    - The @a performEmifBoot() function definition & it's associated functions
 *
 *  Modification 1
 *    - Created on: Jan 10, 2006
 *    - Reason: created the sources
 *
 *  @author anonymous
 */
 
#include <stdBoot.h>
#include <stdNandBoot.h>
#include <target.h>
 
StdNANDInfoObj gNandInfo;
StdNANDBootInfoObj gNandBootInfo;

 far TISTDBOOTStatusObj TARGET_BOOT_STATUS;  

//-----------------------------------------------------------
// To Specify Detial for My NAND device define the following
// expectedDeviceId, idIndex
//  expectedDeviceID - is decvice ID code that should 
//                     be returned from READID command
//  idIndex   - is index in device support matrix for the
//              specified device
//  for example if expectedDeviceID is 0x76
//  then idIndex = 12
//-----------------------------------------------------------
Uint32 expectedDeviceID = 0x76;
Uint32 idIndex = 12;

/* Details of NAND device sizes supported */
// Table of ROM supported NAND devices
const far StdNANDDeviceInfoObj gNandDevInfo[] = 
{ // devID, numBlocks,  pagesPerBlock,  bytesPerPage
    {0xE3,  512,        16,             512+16},	/* 4 MB , index 0*/
    {0xE5,  512,        16,             512+16},	/* 4 MB , index 1*/
    {0xE6,  1024,	    16,             512+16},	/* 8 MB , index 2*/
    {0x39,  1024,   	16,             512+16},	/* 8 MB , index 3*/
    {0x6B,  1024,       16,             512+16},	/* 8 MB , index 4*/
    {0x73,  1024,       32,             512+16},	/* 16 MB, index 5 */
    {0x33,  1024,       32,             512+16},	/* 16 MB, index 6 */
    {0x75,  2048,       32,             512+16},	/* 32 MB, index 7 */
    {0x35,  2048,       32,             512+16},	/* 32 MB, index 8 */
    {0x36,  4096,       32,             512+16},	/* 64 MB, index 9 */
    {0x46,  4096,       32,             512+16},    /* 64 MB 0x1346, index 10 */
    {0x56,  4096,       32,             512+16},    /* 64 MB 0x1356, index 11 */
    {0x76,  4096,       32,             512+16},	/* 64 MB , index 12*/
    {0x74,  8192,       32,             512+16},    /* 128 MB 0x1374, index 13 */
    {0x79,  8192,       32,             512+16},	/* 128 MB , index 14 */
    {0x71,  16384,      32,             512+16},	/* 256 MB , index 15 */
    {0xF1,  1024,       64,             2048+64},   /* 128 MB - Big Block, index 16 */
    {0xA1,  1024,       64,             2048+64},	/* 128 MB - Big Block, index 17 */
    {0xAA,  2048,       64,             2048+64},	/* 256 MB - Big Block, index 18 */
    {0xDA,  2048,       64,             2048+64},	/* 256 MB - Big Block, index 19 */
    {0xDC,  4096,       64,             2048+64},	/* 512 MB - Big Block, index 20 */
    {0xAC,  4096,       64,             2048+64},   /* 512 MB - Big Block, index 21 */
    {0xB1,  1024,       64,             2048+64},   /* 128 MB - Big Block 0x22B1, index 22 */
    {0xC1,  1024,       64,             2048+64},   /* 128 MB - Big Block 0x22C1, index 23 */
    {0xD3,  16384,      64,             2048+64},   /* 16GBit(2Gx8), index 24 */
    {0xD5,  8192,       64,             4096+128},  /* 16GBit */
    {0x00,	0,          0,              0}	        /* Dummy null entry to indicate end of table*/
};


/**************************************************************************\
* EMIF/NAND Flash Boot Function Prototypes
\**************************************************************************/ 		
	 static Uint32 performNandBoot(void);
	 static Uint32 nandOpenDevice(void);
	 static Uint32 nandReadWord(void);
     void powerUp(Uint32 LPSCNUM);
     void waitloop(Uint32 cnt);

     /************************************************************
     * Local Functions
     \***********************************************************/
     
     // Generic NAND flash functions
     static VUint8* flash_make_addr (Uint32 baseAddr, Uint32 offset);
     static void flash_write_addr (Uint32 addr);
     static void flash_write_cmd ( Uint32 cmd);
     static void flash_write_addr_cycles( Uint32 block, Uint32 page);
     static void flash_write_addr_bytes( Uint32 numAddrBytes, Uint32 addr);
     static void flash_write_row_addr_bytes( Uint32 block, Uint32 page);
     static void flash_write_data( Uint32 offset, Uint32 data);
     static Uint32 flash_read_data( void );
     static void flash_read_bytes( void *pDest, Uint32 numBytes);
     static void flash_swap_data( Uint32* data);

     //Initialize the NAND registers and structures
     static Uint32 NAND_Init();
     static Uint32 NAND_GetDetails();

     // Page read functions
     static Uint32 NAND_ReadPage(Uint32 block, Uint32 page, Uint8 *dest);
	 
	 // Wait for ready signal seen at NANDFSCR
	 static Uint32 NAND_WaitForRdy();
	 static void NAND_clearEIRR();
     
     // Wait for status result from device to read good */
     static Uint32 NAND_WaitForStatus();
     
     // Read ECC data and restart the ECC calculation
     static Uint32 NAND_ECCReadAndRestart();

     
    /********************************************************************
    * Standard BOOT Target Configuration Structure Definition
    \*******************************************************************/	 	
	const far TargetBootCfgObj TARGET_BOOT_CFG = {
           0,
	       performNandBoot,
	       0,
	       nandOpenDevice,
	       nandReadWord,
	       0,
	       0,
	       0,
	       0,
	       0,
	       0
	};		

	
 void main(void) {
	 initBoot();
	 performNandBoot();
     TARGET_BOOT_STATUS.applicationStart();
 }
 
 
 static Uint32   performNandBoot(void){
	 
	Uint32 count,blockNum;
	Uint32 i;
	Uint32 magicNum;   
	Uint32 readError = BOOT_FAIL;
	Uint8  errCnt = 0;
	
	//=======================================================
	// Try Opening NAND Device - if this fails abort boot
	//=======================================================

	nandOpenDevice();

	if (TARGET_BOOT_STATUS.status) {
	    TARGET_BOOT_STATUS.bootErr = ERR_NAND_ACCESS_TIMEOUT;
		TARGET_BOOT_STATUS.status = BOOT_FAIL;
		abortBoot();
	}

NAND_startAgain:

    
    TARGET_BOOT_STATUS.status = BOOT_SUCCESS;

	blockNum = START_BLOCK_NUM;
	magicNum = 0;

	// Make sure Boot Buffer Is Empty //
	for(i=0;i<BOOT_BUFFER_SIZE;++i) {
		TARGET_BOOT_STATUS.buffer[i] = BOOT_EMPTY_BUFFER;
	}	
	
	/* read data about UBL from the block 1(to TRY_BLOCK_NUM+1), Page 0 */
	
	for(count=blockNum; ((count <= (gNandInfo.numBlocks-1)) && (magicNum != AIS_MAGIC_NUMBER));count++) {
		readError = NAND_ReadPage(count,0,(Uint8 *)&(TARGET_BOOT_STATUS.buffer));

		if(!readError) {
		/* Read was successful*/
		
		   magicNum = TARGET_BOOT_STATUS.buffer[0];

		   /* Magic number found */
		   if((magicNum == AIS_MAGIC_NUMBER))
		   {
		  	blockNum = count;
			break;
		   }
        }  
	}
	
	if(readError != BOOT_SUCCESS){
		TARGET_BOOT_STATUS.status = BOOT_FAIL;
		return BOOT_FAIL;
	} /* NAND boot failed return to main */
		
        gNandBootInfo.numPage = TARGET_BOOT_STATUS.buffer[1];	 /* The second "long" is the number of pages */
        gNandBootInfo.block = TARGET_BOOT_STATUS.buffer[2];	 /* The third "long" is the block where UBL is stored in NAND */
        gNandBootInfo.page = TARGET_BOOT_STATUS.buffer[3];	 /* The fourth "long" is the page number where UBL is stored in NAND */
        
	TARGET_BOOT_STATUS.aisStreamPtr = (Uint32)(&(TARGET_BOOT_STATUS.buffer[4]));
    if (TARGET_BOOT_STATUS.status==0) {
	    TARGET_BOOT_STATUS.status = parseAisData();
    }
	if ((TARGET_BOOT_STATUS.status) && (errCnt < 100)){
	    ++errCnt;
	     goto NAND_startAgain;
	}
	 

	 return TARGET_BOOT_STATUS.status;
 }
 
 
 static Uint32  nandOpenDevice(void){
/* Initialze NAND interface and find the details of the NAND used */
	Uint32 tmp;

	//============================================================
	// Make PINMUX is Set for EMIF/NAND
	//============================================================
 
    SYSTEM->PINMUX[0] =  0x541u;
    SYSTEM->PINMUX[1] = SYSTEM->PINMUX[1] | 0x4000u;	 
    
    //============================================================
    // Make Sure Power Is Enabled to PINS - this should happen
    // by defualt, but let's make sure
	//   Enabled CDCC - bit 1, VENC bit 2, EMCTL - bit3
	//   and EMADDR - bit 12
	//   Note: These are enabled by clearing the corresponding bits
    //============================================================
    
    tmp = SYSTEM->VDD3P3V_PWDN;
    tmp &= ~(0x100Eu);   // CDCC, VENC, EMCTL, EMADDR
    SYSTEM->VDD3P3V_PWDN = tmp;
    	
	//============================================================
	// AEMIF should be powered on by default - but let's make sure
	//============================================================
	LPSCTransition(LPSC_EMIFA, PSC_ENABLE);  
	
	// Init NAND interface and set up device info struct
	TARGET_BOOT_STATUS.status = NAND_Init();
	return  TARGET_BOOT_STATUS.status;
}	 
 
 static Uint32  nandReadWord(void){
	 Uint32 word;
	 Uint32 readError;
	 readError = 0;
	 if (*(Uint32 *)TARGET_BOOT_STATUS.aisStreamPtr == BOOT_EMPTY_BUFFER){
	    gNandBootInfo.page += 1;
		 if (gNandBootInfo.page >= gNandInfo.pagesPerBlock) {
		    gNandBootInfo.block += 1;
		    gNandBootInfo.page = 0;
		 } 

		 do {
			 readError = NAND_ReadPage(gNandBootInfo.block,gNandBootInfo.page,(Uint8 *)&(TARGET_BOOT_STATUS.buffer[0]));
             if (readError) {
	             gNandBootInfo.block += 1;
	             gNandBootInfo.page = 0;   
             }
		 }while((readError) && (gNandBootInfo.block < gNandInfo.numBlocks));
		     
		 TARGET_BOOT_STATUS.aisStreamPtr = (Uint32)(&(TARGET_BOOT_STATUS.buffer[0]));
	 }
	 
	 if (readError) {
		 return BOOT_FAIL;
	 }

	 word = *(Uint32 *)(TARGET_BOOT_STATUS.aisStreamPtr);
	 TARGET_BOOT_STATUS.aisStreamPtr += 4;
	 return word;
 }
  
  
 
  static void NAND_clearEIRR(void) {
	  NAND_NANDEIRR = 0x4u;
	  while((NAND_NANDEIRR & 0x4u) != 0);
  }
 
  
 
 void waitloop(Uint32 cnt) {
    while(cnt > 0) {
      --cnt;
    }
 } 
  

  
/***********************************************************************************
* Local NAND access functions
\***********************************************************************************/

// ***************************************
// Generic Low-level NAND access functions
// ***************************************
static VUint8 *flash_make_addr (Uint32 baseAddr, Uint32 offset)
{
	return ((VUint8 *) ( baseAddr + offset ));
}

static void flash_write_data(Uint32 offset, Uint32 data)
{
	volatile FLASHPtr addr;
	FLASHData dataword;
	dataword.l = data;

	addr.cp = flash_make_addr (gNandInfo.flashBase, offset);
	switch (gNandInfo.busWidth)
	{
	    case BUS_8BIT:
            *addr.cp = dataword.c;
            break;
        case BUS_16BIT:
            *addr.wp = dataword.w;
            break;
	}
}

static void flash_write_cmd (Uint32 cmd)
{
	flash_write_data(NAND_CLE_OFFSET, cmd);
}

static void flash_write_addr (Uint32 addr)
{
	flash_write_data(NAND_ALE_OFFSET, addr);
}

void flash_write_addr_cycles(Uint32 block, Uint32 page)
{
    flash_write_addr_bytes(gNandInfo.numColAddrBytes, 0x00000000);
    flash_write_row_addr_bytes(block, page);
}

void flash_write_addr_bytes(Uint32 numAddrBytes, Uint32 addr)
{    
    Uint32 i;
    for (i=0; i<numAddrBytes; i++)
    {
        flash_write_addr( ( (addr >> (8*i) ) & 0xff) );
	}
}

static void flash_write_row_addr_bytes(Uint32 block, Uint32 page)
{
    Uint32 row_addr;

⌨️ 快捷键说明

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