📄 nandboot.c
字号:
/* ============================================================================
* 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 + -