您的位置 首页 主动

ARM发动文件2440init.s剖析

;=========================================;NAME:2440INITS;DESC:Cstartupcodes;Configurememory,ISR,sta

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

; NAME: 2440INIT.S
; DESC: C start up codes
; Configure memory, ISR ,stacks
;Initialize C-variables
;=========================================
;留意:axd调试时,能够看到指令pc地址从0x30000000开端,这是由于ram的开端地址是0x30000000.
;并且假如从nand发动,则处理器主动把nand首部的4k字节,仿制到ram中,然后pc跳到0x30000000,开端履行。
;此源文件一般包括一些宏界说和常量界说
;通用的《发动流程图》:
;进口->屏蔽一切间断,制止看门狗->依据作业频率设置PLL寄存器->初始化存储操控相关寄存器
;->初始化各形式下的栈指针->设置缺省间断处理函数->将数据拷贝到RAM中,数据段清零
;->跳转到c言语main进口函数中
;GET伪指令用于将一个源文件包括到当时源文件中,并将被包括文件在当时方位进行汇编处理
;类似于c的include指令
;GET INLCUDE伪指令不能用来包括方针文件,INCBIN伪指令能够包括方针文件,
;被INCBIN伪指令包括的文件,不进行汇编处理,该履行文件或数据直接放入当时文件,
;编译器从INCBIN后边开端持续处理
GET option.inc ;界说芯片相关装备
GET memcfg.inc ;界说存储器装备
GET 2440addr.inc ;界说寄存器符号
;REFRESH寄存器[22]bit :SDRAM改写形式 0 – auto refresh
; 1 – self refresh
;用于节电形式中,SDRAM主动改写
BIT_SELFREFRESH EQU (1<<22)
;Pre-defined constants
;形式预界说常量,给cpsr【4-0】赋值,改动运转形式
USERMODE EQU 0x10
FIQMODE EQU 0x11
IRQMODE EQU 0x12
SVCMODE EQU 0x13
ABORTMODE EQU 0x17
UNDEFMODE EQU 0x1b
MODEMASK EQU 0x1f ;形式屏蔽位
NOINT EQU 0xc0 ;1100 0000,间断屏蔽掩码
;The location of stacks
;0x30000000 = 768M
;界说各形式下的仓库常量,是一个递减栈,后边标上了各个栈的巨细
UserStack EQU (_STACK_BASEADDRESS-0x3800) ; ~ 0x33ff4800 巨细不定,跟堆巨细相对应
;究竟是用户态栈
SVCStack EQU (_STACK_BASEADDRESS-0x2800) ; ~ 0x33ff5800 4M
UndefStack EQU (_STACK_BASEADDRESS-0x2400) ; ~ 0x33ff5c00 1M
AbortStack EQU (_STACK_BASEADDRESS-0x2000) ; ~ 0x33ff6000 1M
IRQStack EQU (_STACK_BASEADDRESS-0x1000) ; ~ 0x33ff7000 4M
FIQStack EQU (_STACK_BASEADDRESS-0x0) ; ~ 0x33ff8000 4M
;处理器分为16位 32位两种作业状况程序的编译器也是分16位和32两种编译方法
;下面程序依据处理器作业状况确认编译器编译方法
;code16伪指令指示汇编编译器后边的指令为16位的thumb指令
;code32伪指令指示汇编编译器后边的指令为32位的arm指令
;Arm上电时处于ARM状况,故不管指令为ARM集或Thumb集,都先强制成ARM集,待init.s初始化完成后,再依据用
;户的编译装备转化成相应的指令形式。为此,界说变量THUMBCODE作为指示,跳转到main之前依据其值切换指令
;形式
;Check if tasm.exe(armasm -16 …@ADS 1.0)is used.
;检测作业形式,依据CONFIG的数值,确认作业形式
;{CONFIG}应该来自于ADS环境,在本环境中设置是进入时在ARM环境下,没有设置ARM/THUMB混合环境
;关于是否设置混合编程,在环境设置选项里的ARM Assembler 选项下,由ATPCS -> ARM/Thumb interworking选
;项担任
;IF ELSE ENDIF指令
;[ 为 IF ; | 为 ELSE ; ] 为 ENDIF
GBLL THUMBCODE
[{CONFIG} = 16
THUMBCODE SETL {TRUE} ;假如设置了config,则答应thumb指令,
;但THUMBCODE为真并不标明以下便是thumb指令,仅仅答应
CODE32 ;code32表明以下是arm指令,在处理器刚开端时,有必要以arm形式运转
| ;此处简单产生幻觉,丢掉CODE32这一行
THUMBCODE SETL {FALSE}
]
;————————————————————————————————-
;bx是带状况切换的跳转指令,跳转到Rm指定的地址履行程序,若Rm的位[0]为1,则跳转时主动将CPSR的标志T
;T置位,即把方针地址的代码解释为Thumb代码;若Rm的位[0]为0,则跳转时主动将CPSR中的标志T复位,即把
;方针地址的代码解释为ARM代码
;界说两个宏,宏的效果:子函数回来(无条件,有条件)。
MACRO
MOV_PC_LR
[ THUMBCODE ;假如答应thumb指令,则需求依据最低位设置状况。
bx lr ;跳转,顺便状况切换
|
mov pc,lr
]
MEND
MACRO
MOVEQ_PC_LR ;持平则跳转,持平与否由寄存器某些位确认,在此处,有其上一句的指令履行成果决议
[ THUMBCODE
bxeq lr
|
moveq pc,lr
]
MEND
;MACRO和MEND伪指令用于宏界说,MACRO标识开端,MEND标识完毕。用MACRO和MEND界说的一段代码,称为宏界说
;体,这样在程序中就能够经过宏指令屡次调用该代码段。
;伪指令格局:
;MACRO
;{$label} macroname {$parameter} {$parameter} …
;宏界说体
;MEND
;其间 $label 宏指令被打开时,label可被替换成相应的符号,一般为一个标号,
;在一个标号前运用$表明被汇编时将运用相应的值替代$后的符号。
;macroname 所界说的宏的称号
;$parameter 宏指令的参数,当宏指令被打开时将被替换成相应的值,类似于函数中的形式参数
;关于子程序代码较短,而需求传递的参数比较多的情况下,能够运用汇编技能。
;首要要用MACRO和MEND伪指令界说宏,包括宏界说体代码。在MACRO伪指令之后的榜首行界说宏的原型,其间包
;含该宏界说的称号,及需求的参数。在汇编程序中能够经过该宏界说的称号来调用它,当源程序被汇编时,汇
;编编译器将打开每个宏调用,用宏界说体替代源程序中的宏界说的称号,并用实践的参数值替代宏界说时的形
;式参数
;————————————————————————————————-
;在arm中,用的是满递减仓库:stmfd,ldmfd,假如用其他的方法,arm或许不能有用辨认
;留意:满递减指的是在入栈时的操作方法,在出栈时则正好相反的次第
;比如:
;STMFD sp!,{R0-R7,LR}:(满递减:先减再放数值)sp依据数据个数,减小相应个数值的数据单位(一步到
;位),然后运用for循环句子,从当时sp方位,顺次存储R0-R7,LR.即:sp处最终指向的是R0数据处
;LDMFD sp!,{R0-R7,LR}:仿制一个变量为sp值,用该变量顺次将数据存入R0-R7,LR,变量值添加,最终,变量指
;向下一个即将取的值,完成后sp获得该变量值;
;要点剖析下面这个宏,它对间断处理函数的调用很重要
;切当说,这是宏函数,编译时对调用句子要做相应的打开
MACRO
$HandlerLabel HANDLER $HandleLabel
$HandlerLabel ;标号
sub sp,sp,#4 ;留出一个空间,为了寄存跳转地址给pc。
stmfd sp!,{r0} ;把r0中的内容入栈,保存起来
ldr r0,=$HandleLabel ;这是一个伪指令,不是汇编指令
;意图:把$HandleLabel自身地点的地址给r0
ldr r0,[r0] ;把$HandleLabel所指向的内容(也便是间断程序的进口地址)放入r0
str r0,[sp,#4] ;把进口地址放入方才留出的一个空间里
ldmfd sp!,{r0,pc} ;出栈的方法康复r0原值和为pc设定新值(也就完成了到ISR的转跳)。
;注:栈中r0内容在低地址
MEND
;————————————————————————————————-
;下面几个变量是ads环境下主动设置的,能够见环境装备选项里:ARM Linker->Output下,RO Base,RW Base
;IMPORT 引证变量
IMPORT |Image$$RO$$Base| ; Base of ROM code
IMPORT |Image$$RO$$Limit| ; End of ROM code (=start of ROM data)
IMPORT |Image$$RW$$Base| ; Base of RAM to initialise
IMPORT |Image$$ZI$$Base| ; Base and limit of area to zero initialise
IMPORT |Image$$ZI$$Limit|
IMPORT MMU_SetAsyncBusMode
IMPORT MMU_SetFastBusMode ;想知道代码详细内容见cp15手册,并以cp15指令内容查找2440a手册
IMPORT Main ;The main entry of mon program
IMPORT RdNF2SDRAM ;Copy Image from Nand Flash to SDRAM
;————————————————————————————————-
;AREA伪指令用于界说一个代码段或数据段,一个ARM源程序至少需求一个代码段,大的程序能够包括多个代码段
;及数据段
;格局:AREA sectionname {,attr} {,attr}…
AREA Init,CODE,READONLY
;————————————————————————————————-
;ENTRY伪指令用于指定程序的进口点
;一个程序(能够包括多个源文件)中至少要有一个ENTRY,能够有多个ENTRY,但一个源文件中最多只有一个
;ENTRY.
ENTRY
;————————————————————————————————-
;EXPORT声明一个符号能够被其他文件引证,相当于声明晰一个全局变量。GLOBAL与EXPORT相同
;格局:EXPORT symbol{[WEAK]} [WEAK]声明其他的同名符优先于本符号被引证
;导出符号__ENTRY
EXPORT __ENTRY
;————————————————————————————————-
__ENTRY
ResetEntry
;1)The code, which converts to Big-endian, should be in little endian code.
;2)The following little endian code will be compiled in Big-Endian mode.
; The code byte order should be changed as thememory bus width.
;3)Thepseudo instruction,DCD can not be used here because the linker generates error.
;条件编译,在编译成机器码前就设定好巨细端转化
;判别ENDIAN_CHANGE是否已界说,ASSERT 是断语伪指令,语法是:ASSERT + 逻辑表达式,def 是逻辑伪操作符,
;格局为::DEF:label,效果是:判别label是否界说过
ASSERT :DEF:ENDIAN_CHANGE
[ ENDIAN_CHANGE ;在 option.inc 有界说。默许是FALSE,所以此句不会参加代码中
ASSERT :DEF:ENTRY_BUS_WIDTH ;断语指令,检测是否界说该变量,若未界说,报错
[ ENTRY_BUS_WIDTH=32 ;defined in option.inc
b ChangeBigEndian ;DCD 0xea000007
;假如是大端,则这是榜首条指令,先设置成大端,
;再到复位指令
]
[ ENTRY_BUS_WIDTH=16
andeq r14,r7,r0,lsl #20 ;DCD 0x0007ea00
]
[ ENTRY_BUS_WIDTH=8
streq r0,[r0,-r10,ror #1] ;DCD 0x070000ea
]
|
b ResetHandler ;本硬件用的是小端形式,这是榜首个履行句子,
;直接跳转到复位指令处 0X00
]
;————————————————————————————————-
;这7个间断,每个间断都有固定的间断进口地址,它们坐落代码的最前端,不答应另作他用
b HandlerUndef ;handler for Undefined mode 0X04
b HandlerSWI ;handlerfor SWI interrupt 0X08
b HandlerPabort ;handler for PAbort,指令预取间断 0X0C
b HandlerDabort ;handler for DAbort,数据间断 0X10
b . ;reserved 保存未用 留意小圆点 0X14
b HandlerIRQ ;handlerfor IRQ interrupt 0X18
b HandlerFIQ ;handlerfor FIQ interrupt 0X1C
;————————————————————————————————-
;@0x20
b EnterPWDN ;Must be @0x20
;————————————————————————————————
;下面是改动巨细端的程序,选用直接界说 <机器码> 的方法,为什么这么做就得问三星了
;横竖咱们程序里这段代码也不会去履行,不必去管它
;每一个汇编指令,都对应着一个二进制机器码,这儿没有运用指令,直接用了机器码,意义不知道
ChangeBigEndian
;@0x24
;对存储器操控寄存器操作,指定内存形式为Big-endian
;由于刚开端CPU都是依照32位总线的指令格局运转的,假如选用其他的话,CPU运转不了,有必要转化
;但当体系初始化好今后,则CPU能主动辨认
[ ENTRY_BUS_WIDTH=32
DCD 0xee110f10 ;0xee110f10 => mrc p15,0,r0,c1,c0,0
DCD 0xe3800080 ;0xe3800080 => orr r0,r0,#0x80; //Big-endian
DCD 0xee010f10 ;0xee010f10 => mcr p15,0,r0,c1,c0,0
]
;由于选用Big-endian形式,选用16位总线时,物理地址的高位和数据的方位对应
;所以指令的机器码也相应的凹凸对调
[ ENTRY_BUS_WIDTH=16
DCD 0x0f10ee11
DCD 0x0080e380
DCD 0x0f10ee01
]
[ ENTRY_BUS_WIDTH=8
DCD 0x100f11ee
DCD 0x800080e3
DCD 0x100f01ee
]
DCD 0xffffffff ;swinv 0xffffff is similarwith NOP and run well in both endian mode.
DCD 0xffffffff
DCD 0xffffffff
DCD 0xffffffff
DCD 0xffffffff
b ResetHandler ;设置成大端后,再次跳到复位指令处
;————————————————————————————————-
;本文件底部界说了一个数据区(在文件最终),34个字空间,寄存相应间断服务程序的首地址。每个字空间都
;有一个标号,以Handle***命名。
;这是宏实例,在这儿Handler***便是经过HANDLER这个宏和Handle***树立联络的.
;详细剖析:
;Handle*** 这是宏示例,也便是宏的调用指令,当编译时编译器会把宏调用指令打开
;Handler*** 这是向量间断
;打开方法(举例):
;HandlerFIQ HANDLER HandleFIQ
;打开后变成:
;标号HandlerFIQ,由 ” b HandlerFIQ “指令运用(见上,复位处)
; sub sp,sp,#4
;留出一个空间,为了寄存跳转地址给pc。见:str r0,[sp,#4] ,留意sp值并未改动
; stmfd sp!,{r0}
;把r0中的内容入栈,保存起来
; ldr r0,=HandleFIQ
;HandleFIQ标号,在本文件最下方界说
; ldr r0,[r0]
;把 HandleFIQ所指向的内容(也便是间断程序的进口地址)放入r0
; str r0,[sp,#4]
;把进口地址放入方才留出的一个空间里
; ldmfd sp!,{r0,pc}
;出栈的方法康复r0原值和为pc设定新值(也就完成了到ISR的转跳)。注:栈中r0内容在低地址
;后边的句子打开方法,同上。编译后,代码都打开放置
HandlerFIQ HANDLER HandleFIQ
HandlerIRQ HANDLER HandleIRQ
HandlerUndef HANDLER HandleUndef
HandlerSWI HANDLER HandleSWI
HandlerDabort HANDLER HandleDabort
HandlerPabort HANDLER HandlePabort
;————————————————————————————————-
;非向量间断总进口(需求自己判别间断类型,而不是直接跳转到相应程序)
;产生间断后,需求间断服务程序自己来判别,到底是哪个间断请求,依据的便是INTOFFSET寄存器中的偏移,再
;核算间断服务地址
IsrIRQ
sub sp,sp,#4 ;reserved for PC,预留回来指针的存储方位
stmfd sp!,{r8-r9}
ldr r9,=INTOFFSET ;the interrupt request source offset
ldr r9,[r9]
ldr r8,=HandleEINT0 ;HandleEINT0 ,在本文件最下边界说的
add r8,r8,r9,lsl #2 ;r9中仅仅偏移单位的个数,需求*4变成详细字节偏移(相关于EINT0)
ldr r8,[r8]
str r8,[sp,#8] ;pc值放在了高方位
ldmfd sp!,{r8-r9,pc}
;————————————————————————————————-
;LTORG用于声明一个文字池,在运用LDR伪指令时,要在恰当的当地参加LTORG声明文字池,这样就会把要加载的
;数据保存在文字池内,再用ARM的《加载指令》读出数据。(若没有运用LTORG声明文字池,则汇编器会在程序
;结尾主动声明)
;LTORG 伪指令常放在无条件跳转指令之后,或许子程序回来指令之后,这样处理器就不会过错地将文字池中的
;数据作为指令来履行
;注:在此,文字池内存储的是INTOFFSET宏所代表的值:0x4a000014 。究竟,当把指令编译成二进制代码时,
;arm指令(32位)不能既表明出指令内容,又表明出数据地址(32位)。估量在编译时,会被汇编成其他的加载
;指令,再编译成机器码
;LTORG 只需独自写出来就能够了,其他的交给编译器来做,并且它跟它下面的代码没有任何联系
LTORG
;————————————————————————————————-
;=======
; ENTRY
;=======
ResetHandler
;关看门狗
ldr r0,=WTCON ;watch dog disable 编译时便是 ldr r0,=53000000;伪指令有=号
ldr r1,=0x0 ;这些宏界说都坐落2440addr.inc中。 区别:变量界说 && 宏界说
str r1,[r0]
;————————————————————————————————-

;屏蔽一切间断

ldr r0,=INTMSK ;在 INTMSK 寄存器设置屏蔽一切间断
ldr r1,=0xffffffff ;all interrupt disable 要了解子间断和间断之间的联系
str r1,[r0]
ldr r0,=INTSUBMSK ;INTSUBMSK子间断屏蔽寄存器,屏蔽一切子间断
ldr r1,=0x7fff ;allsub interrupt disable
str r1,[r0]
;————————————————————————————————-
[ {FALSE}
;rGPFDAT = (rGPFDAT & ~(0xf<<4)) | ((~data & 0xf)<<4);
;Led_Display
ldr r0,=GPBCON
ldr r1,=0x00555555
str r1,[r0]
ldr r0,=GPBDAT
ldr r1,=0x07fe
str r1,[r0]
]
;————————————————————————————————-
;初始化PLL和时钟

;锁相环 PLL ,效果是将外部晶振的输入频率倍频到一个较高的频率

;To reduce PLL lock time, adjust the LOCKTIME register.
ldr r0,=LOCKTIME ;LOCKTIME确定时刻计数寄存器
ldr r1,=0xffffff
str r1,[r0]
[ PLL_ON_START ;defined inoption.inc {TRUE},挑选要不要设置频率值
;Added for confirm clock divide. for 2440.
;Setting value Fclk:Hclk:Pclk
ldr r0,=CLKDIVN ;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]
;programhas not been copied, so use these directly
[ CLKDIV_VAL>1 ; means Fclk:Hclk is not 1:1.
;Fclk为cpu的运转时钟,Hclk驱动 AHB总线设备(例如:SDRAM)
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
]
;在装备UPLLCON和MPLLCON寄存器时,有必要先装备UPLLCON,然后再装备MPLLCON,并且两者之间要有7 nop的间
;隔。(这是2440文档明确要求的)
;Configure UPLL
ldr r0,=UPLLCON ;UPLLCON: UPLL configuration register
ldr r1,=((U_MDIV<<12)+(U_PDIV<<4)+U_SDIV) ;Fin = 12.0MHz, UCLK =48MHz,
;关于usb来说有必要是48MHz
str r1,[r0]
nop ; Caution: After UPLL setting, at least7-clocks delay must be inserted
; for setting hardware be completed.
nop
nop
nop
nop
nop
nop
;Configure MPLL
ldr r0,=MPLLCON ;MPLLCON: MPLL configuration register
ldr r1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV) ;Fin = 12.0MHz, FCLK= 400MHz
str r1,[r0]
]
;————————————————————————————————-
;Check if the boot is caused by the wake-up from SLEEP mode.
ldr r1,=GSTATUS2 ;这个寄存器数值表明哪个信号引起的复位动作产生
;检测 GSTATUS2[2]来判别是否是由 sleep 形式唤醒引起的电源敞开。
ldr r0,[r1]
tst r0,#0x2
;Incase of the wake-up from SLEEP mode, go to SLEEP_WAKEUP handler.
bne WAKEUP_SLEEP
;————————————————————————————————-
;设置总线宽度&等候状况操控寄存器
EXPORT StartPointAfterSleepWakeUp
StartPointAfterSleepWakeUp
;Set memory control registers
;ldr r0,=SMRDATA ;(等效于下边的指令)
adrl r0,SMRDATA ;be careful!中等规模的地址读取伪指令,
;用法类似于ldr(大规模地址读取)伪指令
ldr r1,=BWSCON ;BWSCON Address 总线宽度&等候状况操控寄存器
add r2, r0, #52 ;End address of SMRDATA,共有13个寄存器地址(4字节)需求赋值,13*4=52字节
0
ldr r3, [r0], #4 ;这些都是后变址指令
str r3, [r1], #4
cmp r2, r0
bne % B0 ;当<的时分,跳转到0标号处持续履行
;————————————————————————————————
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;; When EINT0 is pressed, Clear SDRAM
;假如 EINT0 产生(这间断便是咱们按键产生的), 就铲除SDRAM ,不过如同没人会在这个时分按
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; check if EIN0 button is pressed
ldr r0,=GPFCON ;input,无上拉电阻
ldr r1,=0x0
str r1,[r0]
ldr r0,=GPFUP
ldr r1,=0xff
str r1,[r0]
ldr r1,=GPFDAT
ldr r0,[r1]
bic r0,r0,#(0x1e<<1) ; bit clear
tst r0,#0x1
bne� % F1��� ;当按键0没有被按下的时分,也便是不持平,则向下跳到1标号
; 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
ldr r9,=0x4000000 ;64MB ,这几条指令意图是:擦除sdram的一切数据
ldr r0,=0x30000000
0
stmia r0!,{r1-r8}
subs r9,r9,#32
bne �% B0�
;Clear SDRAM End
1
;Initializestacks
bl InitStacks
;————————————————————————————————
;===========================================================
;OM0是flash挑选开关,OM0接地时从nand 发动,悬空时(中心板上有上拉电阻)从nor发动
;OM1在中心板上,始终是接地,为0
;OM1:OM0取值:00 nandflash mode
; 01 16bit nor
; 10 32bit nor
; 11 test mode
;详见:s3c2440 用户手册 5.memory controller 一节
;ands指令,加s表明成果影响cpsr寄存器的值
ldr r0, =BWSCON ;BWSCON总线宽度&等候操控寄存器
ldr r0, [r0]
ands r0, r0, #6 ;OM[1:0]!= 0, NOR FLash boot
bne copy_proc_beg ;do not read nand flash
adr r0, ResetEntry ;OM[1:0] == 0, NAND FLash boot
cmp r0, #0 ;ifuse Multi-ice,
bne copy_proc_beg ;donot read nand flash for boot
;nop
;===========================================================
;把nand中的数据,拷贝到ram中
nand_boot_beg
[ {TRUE}
bl RdNF2SDRAM
]
ldr pc, =copy_proc_beg
;===========================================================
;这儿的一段代码时对内存数据的初始化,触及代码段,数据段,bss段等
;因对这儿的变量设置等有贰言,暂时未全面剖析,可是基本原理想通,便是一个比较地址,仿制数据的进程
copy_proc_beg
adr r0, ResetEntry
ldr r2, BaseOfROM
cmp r0, r2
ldreq r0, TopOfROM
beq InitRam
ldrr3, TopOfROM
0
ldmia r0!, {r4-r7}
stmia r2!, {r4-r7}
cmp r2, r3
bcc % B0���
sub r2, r2, r3
sub r0, r0, r2
InitRam
ldr r2, BaseOfBSS
ldr r3, BaseOfZero
0
cmp r2, r3
ldrcc r1, [r0], #4
strcc r1, [r2], #4
bcc % B0���
mov r0, #0
ldr r3, EndOfBSS
1
cmp r2, r3
strcc r0, [r2], #4
bcc % B1���
ldr pc, = % F2 ;gotocompiler address
2
; [CLKDIV_VAL>1 ; meansFclk:Hclk is not 1:1.
; bl MMU_SetAsyncBusMode
; |
; blMMU_SetFastBusMode ; default value.
; ]
;===========================================================
; Setup IRQ handler
; 把间断服务函数的总进口地址,赋给HandleIRQ地址(文件最低端界说)
ldr r0,=HandleIRQ ;Thisroutine is needed
ldr r1,=IsrIRQ ;ifthere is not subs pc,lr,#4 at 0x18, 0x1c
str r1,[r0]
[ :LNOT:THUMBCODE
bl Main ;Do not use main() because ……
b .
]
[ THUMBCODE ;for start-up code for Thumbmode
orr lr,pc,#1
bx lr
CODE16
bl Main ;Do not use main() because ……
b .
CODE32
]
;————————————————————————————————
;function initializing stacks
; 初始化栈空间(各个形式下的),为c函数运转做准备
InitStacks
;Donot use DRAM,such as stmfd,ldmfd……
;SVCstackis initialized before
;Undertoolkit 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
;USERmode has not be initialized.
mov pc,lr
;TheLR register will not be valid if the current mode is not SVC mode.
LTORG
;————————————————————————————————
SMRDATA DATA
;装备存储器的管理方法
; Memory configuration should be optimizedfor 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 forHCLK<=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 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 ;依照4的倍数对齐
;————————————————————————————————
;Function for entering power down mode
; 1. SDRAM should be in self-refresh mode.
; 2. All interrupt should be maksked forSDRAM/DRAM self-refresh.
; 3. LCD controller should be disabled forSDRAM/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
mov r2,r0 ;r2=rCLKCON
tst r0,#0x8 ;SLEEP mode?
bne ENTER_SLEEP
ENTER_STOP
ldr r0,=REFRESH ;REFRESH 是改写操控寄存器
ldr r3,[r0] ;r3=rREFRESH
mov r1, r3
orr r1, r1, #BIT_SELFREFRESH
str r1, [r0] ;Enable SDRAMself-refresh
mov r1,#16 ;wait untilself-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 isin effect.
bne� % B0 ;2) Or wait here until theCPU&Peripherals will be turned-off
;Entering SLEEP mode, only the reset bywake-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 SDRAMself-refresh
mov r1,#16 ;Wait untilself-refresh is issued,which may not be needed.
0 subs r1,r1,#1
bne� % B0�
ldr r1,=MISCCR
ldr r0,[r1]
orr r0,r0,#(7<<17) ;Set SCLK0=0, SCLK1=0, SCKE=0.
str r0,[r1]
ldr r0,=CLKCON ; Enter sleep mode
str r2,[r0]
b . ;CPU will die here.
WAKEUP_SLEEP
;ReleaseSCLKn after wake-up from the SLEEP mode.
ldr r1,=MISCCR
ldr r0,[r1]
bic r0,r0,#(7<<17) ;SCLK0:0->SCLK, SCLK1:0->SCLK,SCKE:0->=SCKE.
str r0,[r1]
;Setmemory control registers
ldr r0,=SMRDATA ;be careful!
ldr r1,=BWSCON ;BWSCONAddress
add r2, r0, #52 ;Endaddress of SMRDATA
0
ldr r3, [r0], #4
str r3, [r1], #4
cmp r2, r0
bne % B0��
mov r1,#256
0 subs r1,r1,#1 ;1) wait until the SelfRefreshis released.
bne� % B0�
ldr r1,=GSTATUS3 ;GSTATUS3 has the startaddress just after SLEEP wake-up
ldr r0,[r1]
mov pc,r0
;=====================================================================
; Clock division test
; Assemble code, because VSYNC time is veryshort
;=====================================================================
EXPORT CLKDIV124
EXPORT CLKDIV144
CLKDIV124
ldr r0, = CLKDIVN ;CLKDIVN 时钟分频器操控寄存器
ldr r1, = 0x3 ;0x3 = 1:2:4
str r1, [r0]
; waituntil clock is stable
nop
nop
nop
nop
nop
ldr r0, = REFRESH
ldr r1, [r0]
bic r1, r1, #0xff
bic r1, r1, #(0x7<<8)
orr r1, r1, #0x470 ; REFCNT135
str r1, [r0]
nop
nop
nop
nop
nop
mov pc, lr
CLKDIV144
ldr r0, = CLKDIVN
ldr r1, = 0x4 ;0x4 = 1:4:4
str r1, [r0]
; waituntil clock is stable
nop
nop
nop
nop
nop
ldr r0, = REFRESH
ldr r1, [r0]
bic r1, r1, #0xff
bic r1, r1, #(0x7<<8)
orr r1, r1, #0x630 ; REFCNT675 – 1520
str r1, [r0]
nop
nop
nop
nop
nop
mov pc, lr
;————————————————————————————————
ALIGN
;————————————————————————————————
;界说数据段
;^ 标志等价于MAP伪指令
;MAP用于界说一个结构化的内存表首地址,此刻内存表的方位计数器值,也变成该首地址值,就相当于在这个地
;址处操作
;#于FIELD同义,用于界说一个结构化的内存表的数据域,后边数字表明该数据占用的字节数
;Handle*** 在此便是一个标号,为了标明数据量
;用法:把对应的终端处理函数的首地址,放到这儿的对应的预留空间处,当产生间断时,就能依据宏函数,直
;接跳转
AREA RamData, DATA, READWRITE
^ _ISR_STARTADDRESS ; _ISR_STARTADDRESS=0x33FF_FF00
HandleReset # 4
HandleUndef # 4
HandleSWI # 4
HandlePabort # 4
HandleDabort # 4
HandleReserved # 4
HandleIRQ # 4
HandleFIQ # 4
;Do not use the label IntVectorTable,
;The value of IntVectorTable is differentwith the address you think it may be.
;IntVectorTable
;@0x33FF_FF20
HandleEINT0 # 4
HandleEINT1 # 4
HandleEINT2 # 4
HandleEINT3 # 4
HandleEINT4_7 # 4
HandleEINT8_23 # 4
HandleCAM # 4 ;Added for 2440.
HandleBATFLT # 4
HandleTICK # 4
HandleWDT # 4
HandleTIMER0 # 4
HandleTIMER1 # 4
HandleTIMER2 # 4
HandleTIMER3 # 4
HandleTIMER4 # 4
HandleUART2 # 4
;@0x33FF_FF60
HandleLCD # 4
HandleDMA0 # 4
HandleDMA1 # 4
HandleDMA2 # 4
HandleDMA3 # 4
HandleMMC # 4
HandleSPI0 # 4
HandleUART1 # 4
HandleNFCON # 4 ;Added for 2440.
HandleUSBD # 4
HandleUSBH # 4
HandleIIC # 4
HandleUART0 # 4
HandleSPI1 # 4
HandleRTC # 4
HandleADC # 4
;@0x33FF_FFA0
END

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/ziliao/zhudong/261583.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部