mini2440启动代码分析之第十篇

;堆栈初始化的顺序决定系统最后运行在哪种处理器模式,最后初始化哪种模式的堆栈,系统就运行在哪种模式。

InitStacks
 mrs r0,cpsr
 bic r0,r0,#MODEMASK         ;屏蔽低5位
 orr r1,r0,#UNDEFMODE|NOINT  ;屏蔽6、7位和选择未定义模式
 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

 mov pc,lr

[ {TRUE}
 |
ReadNandID
 mov      r7,#NFCONF
 ldr      r0,[r7,#4]  ;NFChipEn();
 bic      r0,r0,#2
 str      r0,[r7,#4]
 mov      r0,#0x90  ;WrNFCmd(RdIDCMD);
 strb     r0,[r7,#8]
 mov      r4,#0   ;WrNFAddr(0);
 strb     r4,[r7,#0xc]
1       ;while(NFIsBusy());
 ldr      r0,[r7,#0x20]
 tst      r0,#1
 beq      %B1
 ldrb     r0,[r7,#0x10] ;id  = RdNFDat()<<8;
 mov      r0,r0,lsl #8
 ldrb     r1,[r7,#0x10] ;id |= RdNFDat();
 orr      r5,r1,r0
 ldr      r0,[r7,#4]  ;NFChipDs();
 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();
 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);
 strb     r0,[r1,#8]
 mov      pc,lr

;============================================================================

CheckBadBlk
 mov  r7, lr
 mov  r5, #NFCONF
 
 bic      r0,r0,#0x1f ;addr &= ~0x1f;
 ldr      r1,[r5,#4]  ;NFChipEn()
 bic      r1,r1,#2
 str      r1,[r5,#4]

 mov      r1,#0x50  ;WrNFCmd(READCMD2)
 strb     r1,[r5,#8]
 mov      r1, #5;6  ;6->5
 strb     r1,[r5,#0xc] ;WrNFAddr(5);(6) 6->5
 strb     r0,[r5,#0xc] ;WrNFAddr(addr)
 mov      r1,r0,lsr #8 ;WrNFAddr(addr>>8)
 strb     r1,[r5,#0xc]
 cmp      r6,#0   ;if(NandAddr)  
 movne    r0,r0,lsr #16 ;WrNFAddr(addr>>16)
 strneb   r0,[r5,#0xc]
 
; bl  WaitNandBusy ;WaitNFBusy()
 ;do not use WaitNandBusy, after WaitNandBusy will read part A!
 mov r0, #100
1
 subs r0, r0, #1
 bne %B1
2
 ldr r0, [r5, #0x20]
 tst r0, #1
 beq %B2 

 ldrb r0, [r5,#0x10] ;RdNFDat()
 sub  r0, r0, #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] 

 mov      r1,#0   ;WrNFCmd(READCMD0)
 strb     r1,[r5,#8] 
 strb     r1,[r5,#0xc] ;WrNFAddr(0)
 strb     r0,[r5,#0xc] ;WrNFAddr(addr)
 mov      r1,r0,lsr #8 ;WrNFAddr(addr>>8)
 strb     r1,[r5,#0xc] 
 cmp      r6,#0   ;if(NandAddr)  
 movne    r0,r0,lsr #16 ;WrNFAddr(addr>>16)
 strneb   r0,[r5,#0xc]
 
 ldr      r0,[r5,#4]  ;InitEcc()
 orr      r0,r0,#0x10
 str      r0,[r5,#4]
 
 bl       WaitNandBusy ;WaitNFBusy()
 
 mov      r0,#0   ;for(i=0; i<512; i++)
1
 ldrb     r1,[r5,#0x10] ;buf[i] = RdNFDat()
 strb     r1,[r4,r0]
 add      r0,r0,#1
 bic      r0,r0,#0x10000
 cmp      r0,#0x200
 bcc      %B1
 
 ldr      r0,[r5,#4]  ;NFChipDs()
 orr      r0,r0,#2
 str      r0,[r5,#4]
  
 mov   pc,r7
 ]

;===================================================================================

 LTORG

;GCS0->SST39VF1601
;GCS1->16c550
;GCS2->IDE
;GCS3->CS8900
;GCS4->DM9000
;GCS5->CF Card
;GCS6->SDRAM
;GCS7->unused

SMRDATA DATA  ;SMRDATA是段名,DATA是属性(定义为数据段)

;DCD指令用于分配一片连续的字存储单元并用伪指令中指定的表达式初始化
 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 0x30     ;MRSR6 CL=3clk
 DCD 0x30     ;MRSR7 CL=3clk
 
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      ;LIGN 伪指令通过添加补丁字节使当前位置满足一定的对齐方式. 

;void EnterPWDN(int CLKCON);

EnterPWDN

    mov r2,r0               ;r2=rCLKCON 保存原始数据 0x4c00000c 使能各模块的时钟输入

    tst r0,#0x8              ;测试bit[3] SLEEP mode? 1=>sleep

    bne ENTER_SLEEP          ;C=0,即TST结果非0,bit[3]=1


;//进入PWDN后如果不是sleep则进入stop

ENTER_STOP   ;//进入Stop mode

       ldr r0,=REFRESH   ;0x48000024   DRAM/SDRAM refresh config

       ldr r3,[r0]              ;r3=rREFRESH

       mov r1, r3

       orr r1, r1, #BIT_SELFREFRESH  ;BIT_SELFREFRESH EQU (1<<22) ;SDRAM自刷新标志位

       str r1, [r0]             ;Enable SDRAM self-refresh



      mov r1,#16                   ;wait until self-refresh is issued(完成)not be needed.

0     subs r1,r1,#1

       bne %B0

 ;//wait 16 fclks for self-refresh

       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    ;back to main process

你可能感兴趣的:(mini2440启动代码分析之第十篇)