📄 nandflash.c
字号:
/*if(TargetAdd)
{
ulong sBlock;
sBlock = Flash_Info.TargetAddr >> 14;
Current_Block_No = sBlock;
Current_Page_No = Current_Block_No*PAGE_CNT;
}
else
{
Current_Block_No = 0;
Current_Page_No = 0;
}*/
}
void FlashConfig(void) /* This cofiguration fits for 512 byte page */
{
rNFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<0);
// TACLS [14:12] CLE&ALE duration = HCLK*TACLS.
// TWRPH0 [10:8] TWRPH0 duration = HCLK*(TWRPH0+1)
// TWRPH1 [6:4] TWRPH1 duration = HCLK*(TWRPH1+1)
// AdvFlash(R) [3] Advanced NAND, 0:256/512, 1:1024/2048
// PageSize(R) [2] NAND memory page size
// when [3]==0, 0:256, 1:512 bytes/page.
// when [3]==1, 0:1024, 1:2048 bytes/page.
// AddrCycle(R) [1] NAND flash addr size
// when [3]==0, 0:3-addr, 1:4-addr.
// when [3]==1, 0:4-addr, 1:5-addr.
// BusWidth(R/W) [0] NAND bus width. 0:8-bit, 1:16-bit.
rNFCONT = (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0);
// Lock-tight [13] 0:Disable lock, 1:Enable lock.
// Soft Lock [12] 0:Disable lock, 1:Enable lock.
// EnablillegalAcINT[10] Illegal access interupt control. 0:Disable, 1:Enable
// EnbRnBINT [9] RnB interrupt. 0:Disable, 1:Enable
// RnB_TrandMode[8] RnB transition detection config. 0:Low to High, 1:High to Low
// SpareECCLock [6] 0:Unlock, 1:Lock
// MainECCLock [5] 0:Unlock, 1:Lock
// InitECC(W) [4] 1:Init ECC decoder/encoder.
// Reg_nCE [1] 0:nFCE=0, 1:nFCE=1.
// NANDC Enable [0] operating mode. 0:Disable, 1:Enable.
}
void NF_Reset(void)
{
int i;
NF_nFCE_L();
NF_CMD(RESET_CTRL);
for(i=0;i<10;i++);
NF_DETECT_RB();
NF_nFCE_H();
}
void NF_CHECKID(void)
{
int i;
NF_nFCE_L();
rNFCMD = ID_CMD;
rNFADDR = 0x0;
for(i=0;i<10;i++);
NF_nFCE_H();
}
#ifdef SAMSUNG
int Bad_Block_Check(ulong block)
{
ulong page_address, i;
uchar data;
page_address = block << 5;
NF_nFCE_L();
NF_CLEAR_RB();
/* Spare array read command */
rNFCMD = READ_CMD;
/* Read the mark of bad block in spare arrary */
rNFADDR = (517&0xf);
/* For block number A[17:0] */
rNFADDR = (page_address&0xff);
/* For block number A[24:17] */
rNFADDR = ((page_address>>8)&0xff);
/* For block number A[25] */
rNFADDR = ((page_address>>16)&0xff);
for(i=0;i<10;i++);
NF_DETECT_RB();
data = NF_RDDATA();
NF_nFCE_H();
if( (data & 0xFF ) != 0xFF )
{
return 0;
}
return 1;
} /* End of samsung_nand_bad_block_check */
#endif
#ifdef TOSHIBA
int Bad_Block_Check(ulong block)
{
int i;
ulong page_address, status, page_no, first_page_no;
ulong sram_buffer=0x0;
int block_size_shift;
ushort no_of_shifts = 1;
int block_size=PAGE_CNT;
int page_size=PAGE_SIZE;
ulong ecc;
block_size_shift=PAGE_CNT;
while ( block_size_shift != 2 )
{
block_size_shift = block_size_shift >> 1;
no_of_shifts++;
}
/*Reset sram memory */
for (i = 0; i < page_size/4; i++)
*(data_reg + i) = 0;
/* Set the first page number */
first_page_no = block << no_of_shifts;
for ( page_no = first_page_no ; page_no < first_page_no+block_size ; page_no++ )
{
page_address = page_no << 9;
*ale_reg = page_address;
*cle_reg = READ_DATA;
status = *status_reg;
while ( status & READ_DATA != 0)
{
status = *status_reg;
}
status = *status_reg;
if ( (status & FS_NAND_OP_ERR_MASK != 0) ||
(status & FS_NAND_ECC_SELF_ERR_MASK != 0) ||
(status & FS_NAND_READ_ECC_ERR_MASK != 0) )
{
return 0;
}
/* TESTING ecc malfunction !!*/
ecc = *ecc_read_reg;
if ( ((ecc & FS_NAND_READ_ECC_ERR_MASK) != 0) || ((ecc & FS_NAND_ECC_UC_ERR_MASK) != 0 ))
{
/*printf("fs_nand_common_fnc: fs_nand_read_page - error bad ecc 0: 0x%08x", ecc);*/
status = *status_reg;
if ( (status & FS_NAND_OP_ERR_MASK != 0) ||
(status & FS_NAND_ECC_SELF_ERR_MASK != 0) ||
(status & FS_NAND_READ_ECC_ERR_MASK != 0) )
{
/* printf("ecc was bad and status was also bad\n");*/
}
}
/* Reading the sram buffer in chunks of 4 bytes */
for (i = 0; i < page_size/4; i++)
{
sram_buffer = *(data_reg + i);
if ( (sram_buffer & 0xFFFFFFFF ) != 0xFFFFFFFF )
return 0;
sram_buffer=0x0;
}
}
return 1;
} /* End of toshiba_nand_bad_block_check */
#endif
///////////////////////////////////////////////////////////
/* MMU Initialization */
///////////////////////////////////////////////////////////
#ifdef CACHE
#define R1_I (1<<12)
#define R1_M (1)
#define R1_C (1<<2)
#define R1_A (1<<1)
#define DESC_SEC (0x2|(1<<4))
#define CB (3<<2) //cache_on, write_back
#define CNB (2<<2) //cache_on, write_through
#define NCB (1<<2) //cache_off,WR_BUF on
#define NCNB (0<<2) //cache_off,WR_BUF off
#define AP_RW (3<<10) //supervisor=RW, user=RW
#define AP_RO (2<<10) //supervisor=RW, user=RO
#define DOMAIN_FAULT (0x0)
#define DOMAIN_CHK (0x1)
#define DOMAIN_NOTCHK (0x3)
#define DOMAIN0 (0x0<<5)
#define DOMAIN1 (0x1<<5)
#define _MMUTT_STARTADDRESS 0x33ff8000
#define DOMAIN0_ATTR (0x1<<0)
#define DOMAIN1_ATTR (0x0<<2)
#define RW_CB (AP_RW|DOMAIN0|CB|DESC_SEC)
#define RW_CNB (AP_RW|DOMAIN0|CNB|DESC_SEC)
#define RW_NCNB (AP_RW|DOMAIN0|NCNB|DESC_SEC)
#define RW_FAULT (AP_RW|DOMAIN1|NCNB|DESC_SEC)
void MMU_Init(void)
{
int i,j;
//========================== IMPORTANT NOTE =========================
// D and I Cache turn on in order to speed up download
//===================================================================
MMU_DisableDCache();
MMU_DisableICache();
//If write-back is used,the DCache should be cleared.
for(i=0;i<64;i++)
for(j=0;j<8;j++)
MMU_CleanInvalidateDCacheIndex((i<<26)|(j<<5));
MMU_InvalidateICache();
#if 0
//To complete MMU_Init() fast, Icache may be turned on here.
MMU_EnableICache();
#endif
MMU_DisableMMU();
MMU_InvalidateTLB();
//MMU_SetMTT(int vaddrStart,int vaddrEnd,int paddrStart,int attr)
MMU_SetMTT(0x00000000,0x07f00000,0x00000000,RW_CNB); //bank0
MMU_SetMTT(0x08000000,0x0ff00000,0x08000000,RW_CNB); //bank1
MMU_SetMTT(0x10000000,0x17f00000,0x10000000,RW_NCNB); //bank2
MMU_SetMTT(0x18000000,0x1ff00000,0x18000000,RW_NCNB); //bank3
//MMU_SetMTT(0x20000000,0x27f00000,0x20000000,RW_CB); //bank4
MMU_SetMTT(0x20000000,0x27f00000,0x20000000,RW_CNB); //bank4 for STRATA Flash
MMU_SetMTT(0x28000000,0x2ff00000,0x28000000,RW_NCNB); //bank5
MMU_SetMTT(0x30000000,0x30f00000,0x30000000,RW_CB); //bank6-1
MMU_SetMTT(0x31000000,0x33e00000,0x31000000,RW_NCNB); //bank6-2
MMU_SetMTT(0x33f00000,0x33f00000,0x33f00000,RW_CB); //bank6-3
MMU_SetMTT(0x38000000,0x3ff00000,0x38000000,RW_NCNB); //bank7
MMU_SetMTT(0x40000000,0x47f00000,0x40000000,RW_NCNB); //SFR
MMU_SetMTT(0x48000000,0x5af00000,0x48000000,RW_NCNB); //SFR
MMU_SetMTT(0x5b000000,0xfff00000,0x5b000000,RW_FAULT);//not used
MMU_SetTTBase(_MMUTT_STARTADDRESS);
MMU_SetDomain(0x55555550|DOMAIN1_ATTR|DOMAIN0_ATTR);
//DOMAIN1: no_access, DOMAIN0,2~15=client(AP is checked)
MMU_SetProcessId(0x0);
MMU_EnableAlignFault();
MMU_EnableMMU();
MMU_EnableICache();
MMU_EnableDCache(); //DCache should be turned on after MMU is turned on.
}
void MMU_SetMTT(int vaddrStart,int vaddrEnd,int paddrStart,int attr)
{
ulong *pTT;
int i,nSec;
pTT=(ulong *)_MMUTT_STARTADDRESS+(vaddrStart>>20);
nSec=(vaddrEnd>>20)-(vaddrStart>>20);
for(i=0;i<=nSec;i++)*pTT++=attr |(((paddrStart>>20)+i)<<20);
}
/* Define Inline Functions */
__inline void MMU_DisableDCache(void)
{
__asm
{
mrc p15,0,r0,c1,c0,0
bic r0,r0,#R1_C
mcr p15,0,r0,c1,c0,0
}
}
__inline void MMU_DisableICache(void)
{
__asm
{
mrc p15,0,r0,c1,c0,0
bic r0,r0,#R1_I
mcr p15,0,r0,c1,c0,0
}
}
__inline void MMU_CleanInvalidateDCacheIndex(ulong index)
{
//int r0;
__asm
{
mov r0, index
mcr p15,0,r0,c7,c14,2
//MOV_PC_LR
}
}
__inline void MMU_InvalidateICache(void)
{
__asm
{
mcr p15,0,r0,c7,c5,0
}
}
__inline void MMU_DisableMMU(void)
{
__asm
{
mrc p15,0,r0,c1,c0,0
bic r0,r0,#R1_M
mcr p15,0,r0,c1,c0,0
}
}
__inline void MMU_InvalidateTLB(void)
{
__asm
{
mcr p15,0,r0,c8,c7,0
}
}
__inline void MMU_EnableMMU(void)
{
__asm
{
mrc p15,0,r0,c1,c0,0
orr r0,r0,#R1_M
mcr p15,0,r0,c1,c0,0
}
}
__inline void MMU_EnableDCache(void)
{
__asm
{
mrc p15,0,r0,c1,c0,0
orr r0,r0,#R1_C
mcr p15,0,r0,c1,c0,0
}
}
__inline void MMU_EnableICache(void)
{
__asm
{
mrc p15,0,r0,c1,c0,0
orr r0,r0,#R1_I
mcr p15,0,r0,c1,c0,0
}
}
__inline void MMU_SetTTBase(int base)
{
//int r0;
__asm
{
mov r0, base //;ro=TTBase
mcr p15,0,r0,c2,c0,0
}
}
__inline void MMU_SetDomain(int domain)
{
//int r0;
__asm
{
mov r0, domain //;ro=domain
mcr p15,0,r0,c3,c0,0
}
}
__inline void MMU_SetProcessId(ulong pid)
{
//int r0;
__asm
{
mov r0, pid //ro=pid
mcr p15,0,r0,c13,c0,0
}
}
__inline void MMU_EnableAlignFault(void)
{
__asm
{
mrc p15,0,r0,c1,c0,0
orr r0,r0,#R1_A
mcr p15,0,r0,c1,c0,0
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -