努力的小强

追根溯源,重走嵌入式之路。

2440init .s解读(三)

转自:http://blog.csdn.net/garby2004/article/details/4605261

;=======

; ENTRYCPU复位的入口)

;=======

ResetHandler

       ldr   r0,=WTCON       ;关看门狗

       ldr   r1,=0x0

       str   r1,[r0]

 

       ldr   r0,=INTMSK

       ldr   r1,=0xffffffff  ;关中断

       str   r1,[r0]

 

       ldr   r0,=INTSUBMSK

       ldr   r1,=0x7fff           ;关子中断

       str   r1,[r0]

 

       [ {TRUE}

       ;rGPFDAT = (rGPFDAT & ~(0xf<<4)) | ((~data & 0xf)<<4);

       ;led

       ldr   r0,=GPBCON

       ldr   r1,=0x00555555

       str   r1,[r0]

       ldr   r0,=GPBDAT

       ldr   r1,=0x07fe

       str   r1,[r0]

       ]

 

       ;To reduce PLL lock time, adjust the LOCKTIME register.

       ldr   r0,=LOCKTIME

       ldr   r1,=0xffffff

       str   r1,[r0]

 

    [ PLL_ON_START

       ; Added for confirm clock divide. for 2440.

       ; Setting value Fclk:Hclk:Pclk

       ldr   r0,=CLKDIVN

       ldr   r1,=CLKDIV_VAL          ; 0=1:1:1, 1=1:1:2, 2=1:2:2, 3=1:2:4, 4=1:4:4, 5=1:4:8, 6=1:3:3, 7=1:3:6.

       str   r1,[r0]

;      MMU_SetAsyncBusMode and MMU_SetFastBusMode over 4K, so do not call here

;      call it after copy

;      [ CLKDIV_VAL>1         ; means Fclk:Hclk is not 1:1.

;      bl MMU_SetAsyncBusMode

;      |

;      bl MMU_SetFastBusMode     ; default value.

;      ]

;=============================================================== 
;MMU_SetAsyncBusMode 
 MMU_SetFastBusMode 都在4K代码以上(三星就提供4K的内部SRAM,
;
如果你想你编译出来的程序能在NAND上运行的话,就不能在这调用这两函数了
;
如果你不要求的话,你就可以直接调用

;下面的代码就是实现和上面两函数一样的功能.

;利用的协处理器的命令实现了对总线模式的设置
;===============================================================

       ;program has not been copied, so use these directly

       [ CLKDIV_VAL>1         ; means Fclk:Hclk is not 1:1.

       mrc p15,0,r0,c1,c0,0

       orr r0,r0,#0xc0000000;R1_nF:OR:R1_iA

       mcr p15,0,r0,c1,c0,0

       |

       mrc p15,0,r0,c1,c0,0

       bic r0,r0,#0xc0000000;R1_iA:OR:R1_nF

       mcr p15,0,r0,c1,c0,0

       ]

      

       ;Configure UPLL.配置 MPLL 一定要使最后的频率为16.9344MHz,不然你甭想用USB接口了,

       ldr   r0,=UPLLCON

       ldr   r1,=((U_MDIV<<12)+(U_PDIV<<4)+U_SDIV) 

       str   r1,[r0]

       nop ; Caution: After UPLL setting, at least 7-clocks delay must be inserted for setting hardware be completed.

       nop

       nop

       nop

       nop

       nop

       nop

       ;Configure MPLL

       ldr   r0,=MPLLCON

       ldr   r1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV)  ;Fin=16.9344MHz

       str   r1,[r0]

    ]

 

       ;Check if the boot is caused by the wake-up from SLEEP mode.

       ldr   r1,=GSTATUS2

       ldr   r0,[r1]

       tst   r0,#0x2           Check GSTATUS2[2] in order to know whether or not

;the power-up is caused by the wake-up from SLEEP mode.

       bne WAKEUP_SLEEP            ;如果是,则跳转到WAKEUP_SLEEP

 

       EXPORT StartPointAfterSleepWakeUp  ;定义外部的StartPointAfterSleepWakeUp

StartPointAfterSleepWakeUp            

 

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

 ;设置存储器控制寄存器,此段代码把13个存储控制器的内容批量的读取到了对应的特殊功能寄存器中

 ;首先是有一个数据区SMRDATA,在程序的后面有定义,这个数据区给13个寄存器分配52字节的地址空间。在下面

;的代码中,r0是这个数据区的起始地址,r2是数据区的结束地址,r1是寄存器的起始地址。这样,用一个判断语句  

; cmp       r2, r0

 ; bne %B0,就可以把内存中的数据赋给这13个存储控制寄存器了。

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

      ;ldr  r0,=SMRDATA

      adrl r0, SMRDATA    ;be careful!

       ldr   r1,=BWSCON    ;BWSCON Address

       add r2, r0, #52     ;End address of SMRDATA

 

0

       ldr   r3, [r0], #4

       str   r3, [r1], #4

       cmp       r2, r0

       bne %B0

 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;       When EINT0 is pressed,  Clear SDRAM

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; check if EIN0 button is pressed

 

   ldr    r0,=GPFCON

       ldr   r1,=0x0

       str   r1,[r0]           ;F(0:15)input

       ldr   r0,=GPFUP

       ldr   r1,=0xff

       str   r1,[r0]            ;不使用上拉电阻

 

       ldr   r1,=GPFDAT          ; GPFDAT=0xff

       ldr   r0,[r1]

       bic  r0,r0,#(0x1e<<1)  ; bit clear

       tst   r0,#0x1

       bne %F1

      

      

 

; Clear SDRAM Start

;清楚内存

       ldr   r0,=GPFCON

       ldr   r1,=0x55aa

       str   r1,[r0]

;      ldr   r0,=GPFUP

;      ldr   r1,=0xff

;      str   r1,[r0]

       ldr   r0,=GPFDAT

       ldr   r1,=0x0

       str   r1,[r0]    ;LED=****

 

       mov r1,#0

       mov r2,#0

       mov r3,#0

       mov r4,#0

       mov r5,#0

       mov r6,#0

       mov r7,#0

       mov r8,#0

      

;64MBSDRAM0x300000000x34000000

 

       ldr   r9,=0x4000000 

       ldr   r0,=0x30000000

0    

       stmia      r0!,{r1-r8}

       subs       r9,r9,#32

       bne %B0

 

;Clear SDRAM End

 

1

 

             ;Initialize stacks

       bl    InitStacks                 初始化堆栈

 

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

       这段程序能在nor  nand flash 运行,也可以在内存中运行。在nor nand flash运行,需要拷贝数据;

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

 

       ldr   r0, =BWSCON

       ldr   r0, [r0]

       ands       r0, r0, #6              ;OM[1:0] != 0, NOR FLash 或者内存启动

       bne copy_proc_beg         ;不要读取 nand flash

       adr  r0, ResetEntry          ;OM[1:0] == 0, NAND FLash 启动

       cmp      r0, #0                   ;再比较入口是否为0地址处,如果不是则用了仿真器

       bne copy_proc_beg           ;用仿真器的情况也不要用 nand flash启动

       ;nop

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

nand_boot_beg                      ;这一段代码完成从NAND读代码到RAM

       mov       r5, #NFCONF             ;设置NAND FLASH的控制寄存器

       ;set timing value

       ldr   r0,   =(7<<12)|(7<<8)|(7<<4)

       str   r0,   [r5]

       ;enable control

       ldr   r0, =(0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0)

       str   r0, [r5, #4]                         ;设置NFCONT,使能NAND FLASH

;控制;禁止片选;初始化ECC等,具体查看手册

  

       bl    ReadNandID       ;按着读取NANDID,结果保存在r5

       mov       r6, #0          ;r6设初值0.

       ldr   r0, =0xec73         ;期望的NAND ID

       cmp       r5,   r0             ;这里进行比较

       beq %F1              ;相等的话就跳到下一个1标号处

       ldr   r0, =0xec75         ;这是另一个期望值

       cmp       r5, r0              ;再进行比较

       beq %F1               ;相等的话就跳到下一个1标号处

       mov       r6, #1           ;不相等了,设置r6=1.

1    

       bl    ReadNandStatus      ;读取NAND状态,结果放在r1

      

       mov       r8, #0            ;r8设初值0,意义为页号

       ldr   r9, =ResetEntry

;=============================================================== 
注意,在这里使用的是ldr伪指令,而不是上面用的adr伪指令,它加载的是ResetEntry 
的绝对地址,也就是我们期望的RAM中的地址,在这里,它和|Image$$RO$$Base|

;一样 也就是说,我如我们编译程序时RO BASE指定的地址在RAM,而把生成的

;文件拷到 NAND里运行,ldr加载的r9的值还是定位在内存.

;LdrADR的区别http://blog.163.com/ncx995/blog/static/28003127200851085043536/
;===============================================================

2    

       ands       r0, r8, #0x1f          ;r80x1f(32)的整数倍,eq有效,ne无效

       bne        %F3                ;这句的意思是对每个块(32)进行检错

       mov              r0, r8            ;r8->r0

       bl           CheckBadBlk         ;检查NAND的坏区

       cmp              r0, #0                ;比较r00

       addne    r8, r8, #32            ;存在坏块的话就跳过这个坏块

       bne        %F4                 ;没有的话就跳到标号4

3    

       mov       r0, r8                 ;当前页号->r0    

       mov       r1, r9                 ;当前目标地址->r1

       bl    ReadNandPage            ;读取该页的NAND数据到RAM

       add r9, r9, #512                ;每一页的大小是512Bytes

       add r8, r8, #1                 ; r8指向下一页

4    

       cmp       r8, #8192              ;比较是否读完8192

       bcc  %B2                  ;如果r8小于8192(没读完),就返回前面的标号2

      

       mov       r5, #NFCONF                   ;设置NAND FLASH 控制寄存器

       ldr   r0, [r5, #4]

       bic r0, r0, #1

       str   r0, [r5, #4]                    ; NAND flash controller enable

       ldr   pc, =copy_proc_beg             ;copy nand flash ram

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

copy_proc_beg

       adr  r0, ResetEntry           ;ResetEntry->r0

       ldr   r2,                     ;BaseOfROM BaseOfROM(后面有定义)->r2

       cmp       r0, r2                   ;比较r0r2

       ldreq      r0, TopOfROM       ;如果相等的话(在内存运行),TopOfROM->r0

       beq InitRam                 ;同时跳到InitRam

阅读更多
想对作者说点什么? 我来说一句

ADO三大对象详解

2012年10月22日 240KB 下载

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭