|
ClearSdram
mov r1,#0
mov r2,#0
mov r3,#0
mov r4,#0
mov r5,#0
mov r6,#0
mov r7,#0
mov r8,#0
ldr r9,=0x00700000 ;for wince
ldr r0,=0x30000000
0
stmia r0!,{r1-r8}
subs r9,r9,#32
bne %B0
mov pc,lr
;===========================================================
;function initializing stacks
InitStacks
;進入各種模式,分別配置各種模式的
堆棧地址
;Don t use DRAM,such as stmfd,ldmfd......
;SVCstack is initialized before
;Under toolkit ver 2.5, 'msr cpsr,r1' can be used instead of 'msr cpsr_cxsf,r1'
mrs r0,cpsr
bic r0,r0,#MODEMASK
orr r1,r0,#UNDEFMODE|NOINT
msr cpsr_cxsf,r1 ;UndefMode
ldr sp,=UndefStack ; UndefStack=0x33FF_5C00
orr r1,r0,#ABORTMODE|NOINT
msr cpsr_cxsf,r1 ;AbortMode
ldr sp,=AbortStack ; AbortStack=0x33FF_6000
orr r1,r0,#IRQMODE|NOINT
msr cpsr_cxsf,r1 ;IRQMode
ldr sp,=IRQStack ; IRQStack=0x33FF_7000
orr r1,r0,#FIQMODE|NOINT
msr cpsr_cxsf,r1 ;FIQMode
ldr sp,=FIQStack ; FIQStack=0x33FF_8000
bic r0,r0,#MODEMASK|NOINT
orr r1,r0,#SVCMODE
msr cpsr_cxsf,r1 ;SVCMode
ldr sp,=SVCStack ; SVCStack=0x33FF_5800
;USER mode has not be initialized.
mov pc,lr
;The LR register won t be valid if the current mode is not SVC mode.
;===========================================================
ReadNandID
mov r7,#NFCONF
ldr r0,[r7,#4] ;NFChipEn();
;使能NandFlash芯片
bic r0,r0,#2
str r0,[r7,#4]
mov r0,#0x90 ;WrNFCmd(RdIDCMD);
strb r0,[r7,#8]
;命令寄存器,寫90h,讀ID
mov r4,#0 ;WrNFAddr(0);
strb r4,[r7,#0xc]
;讀命令第二步,地址寫0
1 ;while(NFIsBusy());
ldr r0,[r7,#0x20]
;判斷是否忙,狀態寄存器
tst r0,#1
beq %B1
ldrb r0,[r7,#0x10] ;id = RdNFDat()<<8; ;從
讀數據ID,讀取ID,前兩個周期即可分辨芯片
mov r0,r0,lsl #8
ldrb r1,[r7,#0x10] ;id |= RdNFDat();
orr r5,r1,r0
ldr r0,[r7,#4] ;NFChipDs();
;禁止NandFlash芯片
orr r0,r0,#2
str r0,[r7,#4]
mov pc,lr
ReadNandStatus
mov r7,#NFCONF
ldr r0,[r7,#4] ;NFChipEn();
bic r0,r0,#2
str r0,[r7,#4]
mov r0,#0x70 ;WrNFCmd(QUERYCMD);
;命令為讀狀態寄存器
strb r0,[r7,#8]
ldrb r1,[r7,#0x10] ;r1 = RdNFDat();
;狀態數據存在R1中
ldr r0,[r7,#4] ;NFChipDs();
orr r0,r0,#2
str r0,[r7,#4]
mov pc,lr
WaitNandBusy
mov r0,#0x70 ;WrNFCmd(QUERYCMD);
mov r1,#NFCONF
strb r0,[r1,#8]
1 ;while(!(RdNFDat()&0x40));
ldrb r0,[r1,#0x10]
tst r0,#0x40
beq %B1
mov r0,#0 ;WrNFCmd(READCMD0);
;00h 老操作的結束,新操作的開始
strb r0,[r1,#8]
mov pc,lr
;===============================================================================================;
; Samsung makes sure that either the 1st or 2nd page of every
;
; 壞快標志的檢測步驟
;
; 1.Set Block Address = 0
;
; 2.Check "FFh" at the column address 2048,of the 1st and 2nd page in the block
;
; 3.Check "FFh" ? Y->繼續 N->記錄壞快進入壞塊表
;
; 4.判斷Last Block ? Y->檢測完成 N->塊數加1,跳轉到地2歩
;
;===============================================================================================;
;initial invalid block has non-FFh data at the column address of 2048
CheckBadBlk
mov r7, lr
mov r5, #NFCONF
bic r0,r0,#0x3f ;addr &= ~0x3f;
;r0中存放的是頁數
ldr r1,[r5,#4] ;NFChipEn()
bic r1,r1,#2
str r1,[r5,#4]
mov r1,#0x00 ;WrNFCmd(READCMD)
strb r1,[r5,#8]
mov r1, #0 ;2048&0xff
strb r1,[r5,#0xc] ;WrNFAddr(2048&0xff);
mov r1, #8 ;(2048>>8)&0xf
;這里的壞快檢測操作就是獲取每頁1K地址處的值,看看是不是為0xff
strb r1,[r5,#0xc]
strb r0,[r5,#0xc] ;WrNFAddr(addr)
mov r1,r0,lsr #8 ;WrNFAddr(addr>>8)
strb r1,[r5,#0xc]
cmp r6,#0 ;if(NandAddr)
movne r1,r0,lsr #16 ;WrNFAddr(addr>>16)
strb r1,[r5,#0xc]
mov r1,#0x30 ;WrNFCmd(0x30)
strb r1,[r5,#8]
; cmp r6,#0 ;if(NandAddr)
; movne r0,r0,lsr #16 ;WrNFAddr(addr>>16)
; strneb r0,[r5,#0xc]
; bl WaitNandBusy ;WaitNFBusy()
;don t use WaitNandBusy, after WaitNandBusy will read part A!
mov r0, #100
1
subs r0, r0, #1
bne %B1
2
ldr r0, [r5, #0x20]
;1歩與2歩都在等待
tst r0, #1
beq %B2
ldrb r0, [r5,#0x10] ;RdNFDat()
sub r0, r0, #0xff
;r0中的數據為nandflash中該地址數據減去0xff
,因為非壞塊時該處值為0xff
; mov r1,#0 ;WrNFCmd(READCMD0)
; strb r1,[r5,#8]
ldr r1,[r5,#4] ;NFChipDs()
orr r1,r1,#2
str r1,[r5,#4]
mov pc, r7
ReadNandPage
mov r7,lr
mov r4,r1
mov r5,#NFCONF
ldr r1,[r5,#4] ;NFChipEn()
bic r1,r1,#2
str r1,[r5,#4]
;===============================================================================================;
; K9F2G08UXA的地址傳送方式如下 ;
; I/O0 I/O1 I/O2 I/O3 I/O4
I/O5 I/O6 I/O7
;
; 1st 0 1 2
3 4 5 6
7
;
; 2st 8 9 10
11 L L L
L L(Low) ;
; 3st 12 13 14 15
16 17 18 19
;
; 4st 20 21 22 23
24 25 26 27
;
; 5st 28 L L
L L L L
L
;
; K9F2G08UXA的讀地址中數據的流程為:(一下程序段即此過程展示)
;
; 1. Write 00h
;
; 2. Write Address
;
; 3. Write 30h
;
; 4. Read Data
;
; 5. ECC Generation
;
; 6. Verify ECC并判斷是否正確(硬件自動實現)
;
; 7. 完成
;
;===============================================================================================;
mov r1,#0 ;WrNFCmd(READCMD0)
strb r1,[r5,#8]
;Waiting for next command
strb r1,[r5,#0xc] ;WrNFAddr(0)
;輸入地址,地址從小地址開始寫
strb r1,[r5,#0xc] ;WrNFAddr(0)
strb r0,[r5,#0xc] ;WrNFAddr(addr)
;R8-》R0中保存的是當前檢測的頁面數
mov r1,r0,lsr #8 ;WrNFAddr(addr>>8)
strb r1,[r5,#0xc]
cmp r6,#0 ;if(NandAddr)
;提供一個判斷條件,判斷是否是增強型的Flash 是的一頁2K字節
movne r1,r0,lsr #16 ;WrNFAddr(addr>>16)
;K9F2G08UXA所以頁均可以這種方式讀出。
strb r1,[r5,#0xc]
mov r1,#0x30 ;WrNFCmd(0x30)
strb r1,[r5,#8]
ldr r0,[r5,#4] ;InitEcc()
orr r0,r0,#0x10
str r0,[r5,#4]
bl WaitNandBusy ;WaitNFBusy()
mov r0,#0 ;for(i=0; i<2048; i++)
1
ldrb r1,[r5,#0x10] ;buf[i] = RdNFDat()
strb r1,[r4,r0]
;r4中存放的是RO中程序段對應復制頁的地址
add r0,r0,#1
bic r0,r0,#0x10000 ;?
;最大1G
cmp r0,#0x800
;一頁有2048個字節,全部放入執行段中去
bcc %B1
ldr r0,[r5,#4] ;NFChipDs()
orr r0,r0,#2
str r0,[r5,#4]
mov pc,r7
;--------------------LED test------------------------------
EXPORT Led_Test
;LED測試代碼,沒有太多分析價值
Led_Test
mov r0, #0x56000000
mov r1, #0x5500
str r1, [r0, #0x50]
0
mov r1, #0x50
str r1, [r0, #0x54]
mov r2, #0x100000
1
subs r2, r2, #1
bne %B1
mov r1, #0xa0
str r1, [r0, #0x54]
mov r2, #0x100000
2
subs r2, r2, #1
bne %B2
b %B0
mov pc, lr
;===========================================================
LTORG
;GCS0->SST39VF1601
;GCS1->16c550
;GCS2->IDE
;GCS3->CS8900
;GCS4->DM9000
;GCS5->CF Card
;GCS6->SDRAM
;GCS7->unused
SMRDATA DATA
; Memory configuration should be optimized for best performance
; The following parameter is not optimized.
; Memory access cycle parameter strategy
; 1) The memory settings is safe parameters even at HCLK=75Mhz.
; 2) SDRAM refresh period is for HCLK<=75Mhz.
DCD (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
DCD ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC)) ;GCS0
DCD ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC)) ;GCS1
DCD ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC)) ;GCS2
DCD ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC)) ;GCS3
DCD ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC)) ;GCS4
DCD ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC)) ;GCS5
DCD ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)) ;GCS6
DCD ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) ;GCS7
DCD ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Tsrc<<18)+(Tchr<<16)+REFCNT)
DCD 0x32 ;SCLK power saving mode, BANKSIZE 128M/128M
;DCD 0x02 ;SCLK power saving disable, BANKSIZE 128M/128M
DCD 0x20 ;MRSR6 CL=2clk
DCD 0x20 ;MRSR7 CL=2clk
BaseOfROM DCD |Image$$RO$$Base|
TopOfROM DCD |Image$$RO$$Limit|
BaseOfBSS DCD |Image$$RW$$Base|
BaseOfZero DCD |Image$$ZI$$Base|
EndOfBSS DCD |Image$$ZI$$Limit|
ALIGN
;Function for entering power down mode
; 1. SDRAM should be in self-refresh mode.
; 2. All interrupt should be maksked for SDRAM/DRAM self-refresh.
; 3. LCD controller should be disabled for SDRAM/DRAM self-refresh.
; 4. The I-cache may have to be turned on.
; 5. The location of the following code may have not to be changed.
;void EnterPWDN(int CLKCON);
EnterPWDN
;其實bootload根本不會執行
到下面的代碼,下面關于EnterPWDN的代碼純屬廢碼
mov r2,r0 ;r2=rCLKCON
tst r0,#0x8 ;SLEEP mode?
bne ENTER_SLEEP
ENTER_STOP
ldr r0,=REFRESH
;2440addr.inc中定義REFRESH EQU
0x48000024 ;DRAM/SDRAM refresh
ldr r3,[r0] ;r3=rREFRESH
mov r1, r3
orr r1, r1, #BIT_SELFREFRESH
str r1, [r0] ;Enable SDRAM self-refresh
mov r1,#16 ;wait until self-refresh is issued. may not be needed.
0 subs r1,r1,#1
bne %B0
ldr r0,=CLKCON ;enter STOP mode.
str r2,[r0]
mov r1,#32
0 subs r1,r1,#1 ;1) wait until the STOP mode is in effect.
bne %B0 ;2) Or wait here until the CPU&Peripherals will be turned-off
; Entering SLEEP mode, only the reset by wake-up is available.
ldr r0,=REFRESH ;exit from SDRAM self refresh mode.
str r3,[r0]
MOV_PC_LR
ENTER_SLEEP
;NOTE.
;1) rGSTATUS3 should have the return address after wake-up from SLEEP mode.
ldr r0,=REFRESH
ldr r1,[r0] ;r1=rREFRESH
orr r1, r1, #BIT_SELFREFRESH
str r1, [r0] ;Enable SDRAM self-refresh
mov r1,#16 ;Wait until self-refresh is issued,which may not be needed.
0 subs r1,r1,#1
bne %B0 |
|