2440init .s解读(三)
转自:http://www.voidcn.com/article/p-auhgvmhq-uz.html ;======= ; ENTRY(CPU复位的入口) ;======= ResetHandler ???????ldr???r0,=WTCON???????;关看门狗 ???????ldr???r1,=0x0 ???????str???r1,[r0] ? ???????ldr???r0,=INTMSK ???????ldr???r1,=0xffffffff??;关中断 ???????str???r1,=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. ;??????] ;===============================================================? ;下面的代码就是实现和上面两函数一样的功能. ;利用的协处理器的命令实现了对总线模式的设置 ???????;program has not been copied,so use these directly ???????[ CLKDIV_VAL>1?????????; means Fclk:Hclk is not 1:1. ???????mrc p15,r0,c1,c0,0 ???????orr r0,#0xc0000000;R1_nF:OR:R1_iA ???????mcr p15,0 ???????| ???????mrc p15,0 ???????bic r0,#0xc0000000;R1_iA:OR:R1_nF ???????mcr p15,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,#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,#(0x1e<<1)??; bit clear ???????tst???r0,#0x1 ???????bne %F1 ?????? ?????? ? ; Clear SDRAM Start ;清楚内存 ???????ldr???r0,=0x55aa ???????str???r1,[r0] ;??????ldr???r0,=GPFUP ;??????ldr???r1,=0xff ;??????str???r1,=GPFDAT ???????ldr???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 ?????? ;64MB的SDRAM,0x30000000—0x34000000 ? ???????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,#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???????;按着读取NAND的ID号,结果保存在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 ;===============================================================? ;一样?也就是说,我如我们编译程序时RO BASE指定的地址在RAM里,而把生成的 ;文件拷到?NAND里运行,由ldr加载的r9的值还是定位在内存. ;Ldr与ADR的区别http://blog.163.com/ncx995/blog/static/28003127200851085043536/ 2???? ???????ands???????r0,r8,#0x1f??????????;凡r8为0x1f(32)的整数倍,eq有效,ne无效 ???????bne????????%F3????????????????;这句的意思是对每个块(32页)进行检错 ???????mov??????????????r0,r8????????????;r8->r0 ???????bl???????????CheckBadBlk?????????;检查NAND的坏区 ???????cmp??????????????r0,#0????????????????;比较r0和0 ???????addne????r8,#32????????????;存在坏块的话就跳过这个坏块 ???????bne????????%F4?????????????????;没有的话就跳到标号4处 3???? ???????mov???????r0,r8?????????????????;当前页号->r0???? ???????mov???????r1,r9?????????????????;当前目标地址->r1 ???????bl????ReadNandPage????????????;读取该页的NAND数据到RAM ???????add?r9,#512????????????????;每一页的大小是512Bytes ???????add?r8,#1?????????????????; r8指向下一页 4???? ???????cmp???????r8,#8192??????????????;比较是否读完8192页 ???????bcc??%B2??????????????????;如果r8小于8192(没读完),就返回前面的标号2处 ?????? ???????mov???????r5,#NFCONF???????????????????;设置NAND FLASH?控制寄存器 ???????ldr???r0,#4] ???????bic r0,#1 ???????str???r0,#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???????????????????;比较r0和r2 ???????ldreq??????r0,TopOfROM???????;如果相等的话(在内存运行),TopOfROM->r0 ???????beq?InitRam?????????????????;同时跳到InitRam (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |