.equ User_Mode, 0x10汽车mode是什么意思含义

ARM启动文件2440init.s分析
;=========================================
; NAME: 2440INIT.S
; DESC: C start up codes
&Configure memory, ISR ,stacks
;Initialize C-variables
;=========================================&
;注意:axd调试时,可以看到指令pc地址从0x开始,这是因为ram的起始地址是0x.
;并且如果从nand启动,则处理器自动把nand首部的4k字节,复制到ram中,然后pc跳到0x,开始执行。
;此源文件通常包含一些宏定义和常量定义
;通用的《启动流程图》:
;入口-&屏蔽所有中断,禁止看门狗-&根据工作频率设置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
;用于节电模式中,SDRAM自动刷新
BIT_SELFREFRESH EQU &
;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 0x1模式屏蔽位
&EQU 0xc0 ;,中断屏蔽掩码
;The location of stacks
;0x = 768M&
;定义各模式下的堆栈常量,是一个递减栈,后边标上了各个栈的大小
UserStack & &
& (_STACK_BASEADDRESS-0x3800) ; ~ 0x33ff4800
大小不定,跟堆大小相对应
;毕竟是用户态栈
SVCStack & &
& (_STACK_BASEADDRESS-0x2800) &;
~ 0x33ff5800 & &
UndefStack & & EQU
(_STACK_BASEADDRESS-0x2400) &; ~ 0x33ff5c00
AbortStack & & EQU
(_STACK_BASEADDRESS-0x2000) &; ~ 0x33ff6000
IRQStack & &
& (_STACK_BASEADDRESS-0x1000) &;
~ 0x33ff7000 & &
FIQStack & &
& (_STACK_BASEADDRESS-0x0) &
& ; ~ 0x33ff8000 &
;处理器分为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
&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代码
;定义两个宏,宏的作用:子函数返回(无条件,有条件)。
&[ THUMBCODE & &
&;如果允许thumb指令,则需要根据最低位设置状态。
;跳转,附带状态切换
&MOVEQ_PC_LR &
;相等则跳转,相等与否由寄存器某些位确定,在此处,有其上一句的指令执行结果决定
&[ THUMBCODE
&moveq pc,lr
;MACRO和MEND伪指令用于宏定义,MACRO标识开始,MEND标识结束。用MACRO和MEND定义的一段代码,称为宏定义
;体,这样在程序中就可以通过宏指令多次调用该代码段。
;伪指令格式:
;{$label} macroname {$parameter} {$parameter} ...
& ;宏定义体
;其中 &$label
宏指令被展开时,label可被替换成相应的符号,通常为一个标号,
;在一个标号前使用$表示被汇编时将使用相应的值替代$后的符号。
;macroname 所定义的宏的名称
;$parameter 宏指令的参数,当宏指令被展开时将被替换成相应的值,类似于函数中的形式参数
;对于子程序代码较短,而需要传递的参数比较多的情况下,可以使用汇编技术。
;首先要用MACRO和MEND伪指令定义宏,包括宏定义体代码。在MACRO伪指令之后的第一行定义宏的原型,其中包
;含该宏定义的名称,及需要的参数。在汇编程序中可以通过该宏定义的名称来调用它,当源程序被汇编时,汇
;编编译器将展开每个宏调用,用宏定义体代替源程序中的宏定义的名称,并用实际的参数值代替宏定义时的形
;-------------------------------------------------------------------------------------------------
;在arm中,用的是满递减堆栈:stmfd,ldmfd,如果用其他的方式,arm可能不能有效识别
;注意:满递减指的是在入栈时的操作方式,在出栈时则正好相反的次序
sp!,{R0-R7,LR}:(满递减:先减再放数值)sp根据数据个数,减小相应个数值的数据单位(一步到
;位),然后利用for循环语句,从当前sp位置,依次存储R0-R7,LR.即:sp处最后指向的是R0数据处
sp!,{R0-R7,LR}:复制一个变量为sp值,用该变量依次将数据存入R0-R7,LR,变量值增加,最后,变量指
;向下一个将要取的值,完成后sp获得该变量值;
;重点分析下面这个宏,它对中断处理函数的调用很重要
;确切说,这是宏函数,编译时对调用语句要做相应的展开
$HandlerLabel HANDLER $HandleLabel
$HandlerLabel & &
&sp,sp,#4 & &
& & ;留出一个空间,为了存放跳转地址给pc。
& stmfd &sp!,{r0}
& ;把r0中的内容入栈,保存起来
&r0,=$HandleL这是一个伪指令,不是汇编指令,
& ;目的:把$HandleLabel本身所在的地址给r0
& ldr & &r0,[r0]
& &;把$HandleLabel所指向的内容(也就是中断程序的入口地址)放入r0
&r0,[sp,#4] & &
& ;把入口地址放入刚才留出的一个空间里
& ldmfd &sp!,{r0,pc}
&;出栈的方式恢复r0原值和为pc设定新值(也就完成了到ISR的转跳)。
& ;注:栈中r0内容在低地址
;-------------------------------------------------------------------------------------------------
;下面几个变量是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
&|Image$$ZI$$Limit|&
&IMPORT MMU_SetAsyncBusMode
&IMPORT MMU_SetFastBusMode
;想知道代码具体内容见cp15手册,并以cp15指令内容搜索2440a手册
&IMPORT &Main &
& &;The main entry of mon
&IMPORT &RdNF2SDRAM
& & &;Copy Image
from Nand Flash to SDRAM
;-------------------------------------------------------------------------------------------------
;AREA伪指令用于定义一个代码段或数据段,一个ARM源程序至少需要一个代码段,大的程序可以包含多个代码段
;格式:AREA sectionname {,attr} {,attr}...
&Init,CODE,READONLY
;-------------------------------------------------------------------------------------------------
;ENTRY伪指令用于指定程序的入口点
;一个程序(可以包含多个源文件)中至少要有一个ENTRY,可以有多个ENTRY,但一个源文件中最多只有一个
;-------------------------------------------------------------------------------------------------
;EXPORT声明一个符号可以被其他文件引用,相当于声明了一个全局变量。GLOBAL与EXPORT相同
;格式:EXPORT symbol{[WEAK]} &
[WEAK]声明其他的同名符优先于本符号被引用
;导出符号__ENTRY
&EXPORT __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
& 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个中断,每个中断都有固定的中断入口地址,它们位于代码的最前端,不允许另作他用
HandlerUndef &;handler for Undefined mode
HandlerSWI & &;handlerfor SWI
interrupt & & &
& & & 0X08
HandlerPhandler for PAbort,指令预取中止 &
& 0X0C & &
HandlerDhandler for DAbort,数据中止 &
& & & 0X10
& & & ;reserved
保留未用 注意小圆点 & & &
HandlerIRQ & &;handlerfor IRQ
interrupt & & &
& & & 0X18
HandlerFIQ & &;handlerfor FIQ
interrupt & & &
& & & 0X1C
;-------------------------------------------------------------------------------------------------
&b & & EnterPWDN
& & ;Must be @0x20
;------------------------------------------------------------------------------------------------
;下面是改变大小端的程序,采用直接定义
&的方式,为什么这么做就得问三星了
;反正我们程序里这段代码也不会去执行,不用去管它
;每一个汇编指令,都对应着一个二进制机器码,这里没有使用指令,直接用了机器码,含义未知
ChangeBigEndian
;对存储器控制寄存器操作,指定内存模式为Big-endian
;因为刚开始CPU都是按照32位总线的指令格式运行的,如果采用其他的话,CPU运行不了,必须转化
;但当系统初始化好以后,则CPU能自动识别&
&[ ENTRY_BUS_WIDTH=32
& 0xee110f10 & &
;0xee110f10 =& mrc p15,0,r0,c1,c0,0
& 0xe3800080 & &
;0xe3800080 =& orr r0,r0,#0x80;
&//Big-endian
& 0xee010f10 & &
;0xee010f10 =& mcr p15,0,r0,c1,c0,0
;因为采用Big-endian模式,采用16位总线时,物理地址的高位和数据的地位对应
;所以指令的机器码也相应的高低对调
&[ ENTRY_BUS_WIDTH=16
& DCD 0x0f10ee11
& DCD 0x0f10ee01
&[ ENTRY_BUS_WIDTH=8
& DCD 0x100f11ee
& 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 &
;展开后变成:
;标号&HandlerFIQ,由 " b
& & & HandlerFIQ
&"指令使用(见上,复位处)
&sp,sp,#4 & &
;留出一个空间,为了存放跳转地址给pc。见:str r0,[sp,#4] ,注意sp值并未改变
& stmfd sp!,{r0} &
;把r0中的内容入栈,保存起来
&r0,=HandleFIQ &
;HandleFIQ标号,在本文件最下方定义
& ldr & &r0,[r0]
;把 HandleFIQ&所指向的内容(也就是中断程序的入口地址)放入r0
&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寄存器中的偏移,再
;计算中断服务地址
&sub & &sp,sp,#4
& &;reserved for
PC,预留返回指针的存储位置
&stmfd &sp!,{r8-r9}
&r9,=INTOFFSET &
& ;the interrupt request source offset
&r8,=HandleEINT0 & ;HandleEINT0
,在本文件最下边定义的
&r8,r8,r9,lsl #2 &
;r9中只是偏移单位的个数,需要*4变成具体字节偏移(相对于EINT0)
&r8,[sp,#8] & &
& &;pc值放在了高位置
&ldmfd &sp!,{r8-r9,pc}
;-------------------------------------------------------------------------------------------------
;LTORG用于声明一个文字池,在使用LDR伪指令时,要在适当的地方加入LTORG声明文字池,这样就会把要加载的
;数据保存在文字池内,再用ARM的《加载指令》读出数据。(若没有使用LTORG声明文字池,则汇编器会在程序
;末尾自动声明)
伪指令常放在无条件跳转指令之后,或者子程序返回指令之后,这样处理器就不会错误地将文字池中的
;数据当做指令来执行
;注:在此,文字池内存储的是INTOFFSET宏所代表的值:0x4a000014
&。毕竟,当把指令编译成二进制代码时,
;arm指令(32位)不能既表示出指令内容,又表示出数据地址(32位)。估计在编译时,会被汇编成其他的加载
;指令,再编译成机器码
只要单独写出来就可以了,其他的交给编译器来做,而且它跟它下面的代码没有任何关系
;-------------------------------------------------------------------------------------------------
;======= & &
ResetHandler & &
&ldr & r0,=WTCON
& & & ;watch dog
disable & 编译时就是 ldr r0,=;伪指令有=号
&ldr & r1,=0x0 &
;这些宏定义都位于2440addr.inc中。 & 区分:变量定义
;-------------------------------------------------------------------------------------------------
;屏蔽所有中断
&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,=0x
& str & r1,[r0]
& ldr & r0,=GPBDAT
& ldr & r1,=0x07fe
& str & r1,[r0]
;-------------------------------------------------------------------------------------------------
;初始化PLL和时钟
;锁相环 PLL ,作用是将外部晶振的输入频率倍频到一个较高的频率
&;To reduce PLL lock time, adjust the LOCKTIME
&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
时钟分频控制寄存器
& 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,
&;programhas not been copied, so use these
& [ CLKDIV_VAL&1 &
& ; means Fclk:Hclk is not 1:1.
&;Fclk为cpu的运行时钟,Hclk驱动 AHB总线设备(例如:SDRAM)
&p15,0,r0,c1,c0,0
&r0,r0,#0xc0000000 ;R1_nF:OR:R1_iA
&p15,0,r0,c1,c0,0
&p15,0,r0,c1,c0,0
&r0,r0,#0xc0000000 ;R1_iA:OR:R1_nF
&p15,0,r0,c1,c0,0
;在配置UPLLCON和MPLLCON寄存器时,必须先配置UPLLCON,然后再配置MPLLCON,而且两者之间要有7
;隔。(这是2440文档明确要求的)
& ;Configure UPLL
& ldr & r0,=UPLLCON
& &;UPLLCON: UPLL configuration
r1,=((U_MDIV&&12)+(U_PDIV&&4)+U_SDIV)
&;Fin = 12.0MHz, UCLK =48MHz,
&;对于usb来说必须是48MHz
&&; Caution: After UPLL setting,
at least7-clocks delay must be inserted
& & ; for setting hardware be
completed.
& ;Configure MPLL
& ldr & r0,=MPLLCON
& & &;MPLLCON:
MPLL configuration register & &
r1,=((M_MDIV&&12)+(M_PDIV&&4)+M_SDIV)
& &;Fin = 12.0MHz, FCLK=
;-------------------------------------------------------------------------------------------------
&;Check if the boot is caused by the wake-up from
SLEEP mode.
&ldr & r1,=GSTATUS2
& & ;这个寄存器数值表示哪个信号引起的复位动作产生
& & & ;检测
GSTATUS2[2]来判断是否是由 sleep 模式唤醒引起的电源开启。
&ldr & r0,[r1]
&;Incase of the wake-up from SLEEP mode, go to
SLEEP_WAKEUP handler.
&bne &WAKEUP_SLEEP
;-------------------------------------------------------------------------------------------------
;设置总线宽度&等待状态控制寄存器
&StartPointAfterSleepWakeUp
StartPointAfterSleepWakeUp
& & & ;Set
memory control registers
& & & ;ldr
r0,=SMRDATA &;(等效于下边的指令)
& & & adrl
r0,SMRDATA & ;be careful!中等范围的地址读取伪指令,
;用法类似于ldr(大范围地址读取)伪指令
&r1,=BWSCON & ;BWSCON Address
总线宽度&等待状态控制寄存器
&r2, r0, #52 &;End address of
SMRDATA,共有13个寄存器地址(4字节)需要赋值,13*4=52字节
&ldr & r3, [r0], #4
&;这些都是后变址指令
&str & r3, [r1], #4
&cmp & r2, r0
&bne & % B0 &
;当&的时候,跳转到0标号处继续执行
;------------------------------------------------------------------------------------------------&
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;; & &
& When EINT0 is pressed, &Clear
;如果 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]
r0,r0,#(0x1e&&1) &;
&tst & r0,#0x1
&bne� % F1��� &
&;当按键0没有被按下的时候,也就是不相等,则向下跳到1标号
; Clear SDRAM Start
&ldr &r0,=GPFCON
&ldr &r1,=0x55aa
&str &r1,[r0]
; & & &ldr
&r0,=GPFUP
; & & &ldr
; & & &str
&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,=0x
&stmia &r0!,{r1-r8}
&subs & r9,r9,#32
&bne &�% B0�
;Clear SDRAM End
&;Initializestacks
&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
&bne & copy_proc_beg
& & ;do not read nand
&adr & r0, ResetEntry
& &;OM[1:0] == 0, NAND FLash
&cmp & r0, #0 &
& &;ifuse Multi-ice,
&bne & copy_proc_beg
& & ;donot read nand flash for
;===========================================================
;把nand中的数据,拷贝到ram中
nand_boot_beg
& bl RdNF2SDRAM &
&ldr & pc, =copy_proc_beg
;===========================================================
;这里的一段代码时对内存数据的初始化,涉及代码段,数据段,bss段等
;因对这里的变量设置等有异议,暂时未全面分析,但是基本原理想通,就是一个比较地址,复制数据的过程
copy_proc_beg
&adr & & r0,
ResetEntry
&ldr & & r2,
&cmp & & r0,
&ldreq & r0, TopOfROM
&beq & & InitRam
&ldrr3, &TopOfROM
&ldmia &r0!, {r4-r7}
&stmia &r2!, {r4-r7}
&cmp & &r2,
B0���
&sub &r2, r2, r3
&sub &r0, r0, r2
&ldr & r2, BaseOfBSS
&ldr & r3, BaseOfZero
&cmp & r2, r3
&ldrcc r1, [r0], #4
&strcc r1, [r2], #4
&bcc & % B0��� &
&mov & r0, #0
&ldr & r3, EndOfBSS
&cmp & r2, r3
&strcc r0, [r2], #4
&bcc & % B1���
&ldr & pc, = % F2
& & ;gotocompiler address
&[CLKDIV_VAL&1 &
meansFclk:Hclk is not 1:1.
& &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,
&str & r1,[r0]
& & [ :LNOT:THUMBCODE
&bl & &Main
& & & ;Do not
use main() because ......
& & [ THUMBCODE
& ;for start-up code for Thumbmode
&orr & lr,pc,#1
&bl & &Main
& & & ;Do not
use main() because ......
;------------------------------------------------------------------------------------------------
;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
r1,r0,#UNDEFMODE|NOINT
&msr &cpsr_cxsf,r1
& &;UndefMode
&ldr & sp,=UndefStack
UndefStack=0x33FF_5C00
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
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.
;------------------------------------------------------------------------------------------------
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.
(0+(B1_BWSCON&&4)+(B2_BWSCON&&8)+(B3_BWSCON&&12)+(B4_BWSCON&&16)+(B5_BWSCON&&20)+(B6_BWSCON&&24)+(B7_BWSCON&&28))
((B0_Tacs&&13)+(B0_Tcos&&11)+(B0_Tacc&&8)+(B0_Tcoh&&6)+(B0_Tah&&4)+(B0_Tacp&&2)+(B0_PMC))
((B1_Tacs&&13)+(B1_Tcos&&11)+(B1_Tacc&&8)+(B1_Tcoh&&6)+(B1_Tah&&4)+(B1_Tacp&&2)+(B1_PMC))
((B2_Tacs&&13)+(B2_Tcos&&11)+(B2_Tacc&&8)+(B2_Tcoh&&6)+(B2_Tah&&4)+(B2_Tacp&&2)+(B2_PMC))
((B3_Tacs&&13)+(B3_Tcos&&11)+(B3_Tacc&&8)+(B3_Tcoh&&6)+(B3_Tah&&4)+(B3_Tacp&&2)+(B3_PMC))
((B4_Tacs&&13)+(B4_Tcos&&11)+(B4_Tacc&&8)+(B4_Tcoh&&6)+(B4_Tah&&4)+(B4_Tacp&&2)+(B4_PMC))
&DCD((B5_Tacs&&13)+(B5_Tcos&&11)+(B5_Tacc&&8)+(B5_Tcoh&&6)+(B5_Tah&&4)+(B5_Tacp&&2)+(B5_PMC))
((B6_MT&&15)+(B6_Trcd&&2)+(B6_SCAN))
((B7_MT&&15)+(B7_Trcd&&2)+(B7_SCAN))
((REFEN&&23)+(TREFMD&&22)+(Trp&&20)+(Tsrc&&18)+(Tchr&&16)+REFCNT)
&DCD 0x32 & &
& & &;SCLK power
saving mode, BANKSIZE 128M/128M
&DCD 0x30 & &
& & &;MRSR6
&DCD 0x30 & &
& & &;MRSR7
;分配一个字的空间,并用后边的数值来初始化该空间,这里命名有些混乱
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
;void EnterPWDN(int CLKCON);
&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
&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
&;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
&bne� % B0�
&ldr & r1,=MISCCR
&ldr & r0,[r1]
r0,r0,#(7&&17) &
& ;Set SCLK0=0, SCLK1=0, SCKE=0.
&str & r0,[r1]
&ldr & r0,=CLKCON
& &; Enter sleep mode
&str & r2,[r0]
& ;CPU will die here.
WAKEUP_SLEEP
&;ReleaseSCLKn after wake-up from the SLEEP
&ldr & r1,=MISCCR
&ldr & r0,[r1]
r0,r0,#(7&&17)
&;SCLK0:0-&SCLK,
SCLK1:0-&SCLK,SCKE:0-&=SCKE.
&str & r0,[r1]
&;Setmemory control registers
&ldr & r0,=SMRDATA
&ldr & r1,=BWSCON
;BWSCONAddress
&add & r2, r0, #52
& & &;Endaddress
of SMRDATA
&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
&ldr & r0, = CLKDIVN
& & ;CLKDIVN
&时钟分频器控制寄存器
&ldr & r1, = 0x3
& ;0x3 = 1:2:4
&str & r1, [r0]
&waituntil clock is stable
&ldr & & r0, =
&ldr & & r1,
&bic & & r1, r1,
&bic & & r1, r1,
&orr & & r1, r1,
#0x470 ; REFCNT135
&str & & r1,
&mov & & pc,
&ldr & & r0, =
&ldr & & r1, =
& ;0x4 = 1:4:4
&str & & r1,
&waituntil clock is stable
&ldr & & r0, =
&ldr & & r1,
&bic & & r1, r1,
&bic & & r1, r1,
&orr & & r1, r1,
#0x630 ; REFCNT675 - 1520
&str & & r1,
&mov & & pc,
;------------------------------------------------------------------------------------------------&
;------------------------------------------------------------------------------------------------&
;定义数据段
;^ 标志等价于MAP伪指令
;MAP用于定义一个结构化的内存表首地址,此时内存表的位置计数器值,也变成该首地址值,就相当于在这个地
;#于FIELD同义,用于定义一个结构化的内存表的数据域,后边数字表示该数据占用的字节数
;Handle*** 在此就是一个标号,为了标示数据量
;用法:把对应的终端处理函数的首地址,放到这里的对应的预留空间处,当发生中断时,就能根据宏函数,直
&AREA RamData, DATA, READWRITE
&^ & _ISR_STARTADDRESS
&; _ISR_STARTADDRESS=0x33FF_FF00
HandleReset & & #
HandleUndef & & #
HandleSWI & &
HandlePabort & &#
HandleDabort & &#
HandleReserved &# & 4
HandleIRQ & &
HandleFIQ & &
;Do not use the label 'IntVectorTable',
;The value of IntVectorTable is differentwith the address you
think it may be.
;IntVectorTable
;@0x33FF_FF20
HandleEINT0 & &
HandleEINT1 & &
HandleEINT2 & &
HandleEINT3 & &
HandleEINT4_7 & &
HandleEINT8_23 & & #
HandleCAM & &
&;Added for 2440.
HandleBATFLT & &
HandleTICK & &
HandleWDT & &
HandleTIMER0 & & #
HandleTIMER1 & & #
HandleTIMER2 & & #
HandleTIMER3 & & #
HandleTIMER4 & & #
HandleUART2 & &
;@0x33FF_FF60
HandleLCD & &
HandleDMA0 & &
HandleDMA1 & &
HandleDMA2 & &
HandleDMA3 & &
HandleMMC & &
HandleSPI0 & &
HandleUART1 & &
HandleNFCON & &
& &;Added for 2440.
HandleUSBD & &
HandleUSBH & &
HandleIIC & &
HandleUART0 & &
HandleSPI1 & &
HandleRTC & &
HandleADC & &
;@0x33FF_FFA0
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

我要回帖

更多关于 boot mode是什么意思 的文章

 

随机推荐