下边是完整的工程
运行平台:mini2440
启动代码ourdev_444408.rar(文件大小:61K) (原文件名:MicroOS.rar)
;---------------------------------------------------------------------
;startup.s
;系统启动代码
;起始时间 : 2009.5.7 ----->2009.5.11
;---------------------------------------------------------------------
;---------------------------------------------------------------------
GET ./Include/s3c2440.inc ;寄存器地址信息
GET ./Include/memcfg.inc ;内存控制器配置信息
;处理器模式
USERMODE EQU 0x10
FIQMODE EQU 0x11
IRQMODE EQU 0x12
SVCMODE EQU 0x13
ABORTMODE EQU 0x17
UNDEFMODE EQU 0x1b
SYSMODE EQU 0x1f
;相关掩码
MODEMASK EQU 0x1f
NOINT EQU 0xc0
;各个处理器模式下堆栈设置
_STACK_BASEADDRESS EQU 0x33ff8000 ;BANK6 64MB顶部
UserStack EQU (_STACK_BASEADDRESS-0x3800) ;0x33ff4800 ~
SVCStack EQU (_STACK_BASEADDRESS-0x2800) ;0x33ff5800 ~
UndefStack EQU (_STACK_BASEADDRESS-0x2400) ;0x33ff5c00 ~
AbortStack EQU (_STACK_BASEADDRESS-0x2000) ;0x33ff6000 ~
IRQStack EQU (_STACK_BASEADDRESS-0x1000) ;0x33ff7000 ~
FIQStack EQU (_STACK_BASEADDRESS-0x0) ;0x33ff8000 ~
;导入操作系统入口函数
IMP
;导入外部C语言编写的异常与中断处理函数
IMP
IMP
IMP
IMP
IMP
IMP
;导入镜像装载域段起始地址
IMP
IMP
IMP
IMP
;--------------------------------------------------------------------
;------------------------------------------------------
AREA startup, CO
ENTRY
;系统向量表
b vectorRESET ;复位向量
b vectorUNDEF ;未定义指令
b vectorSWI ;软中断
b vectorPABT ;预取指终止
b vectorDABT ;数据终止
b . ;系统保留
b vectorIRQ ;外部中断
b vectorFIQ ;快速中断
;-------------------------------------------------------
;--------------------------------------------------------------------------
;复位向量
;复位向量是ARM处理器上电后第一个被执行的异常
;此时系统处理管理(SVC)模式
vectorRESET
;复位向量有以下六件事要做
;第一步 : 关闭看门狗定时器屏蔽所有中断
;第二步 : 配置系统时钟
;第三步 : 配置内存控制器
;第四步 : 配置每种处理器模式下堆栈指针
;第五步 : 初始化镜像运行域
;第六步 : 跳转到操作系统入口
;------------------------------------------
;第一步 : 关闭看门狗定时器
;具体内容请参看s3c2440a数据手册的第18章
ldr r0, =WTCON
ldr r1, =0x0
str r1, [r0, #0x0]
;屏蔽所有中断
ldr r0, =INTMSK
ldr r1, =0xffffffff
str r1, [r0]
;------------------------------------------
;------------------------------------------
;第二步 : 配置系统时钟
;具体内容请看手册第7章
;先减少锁相环锁定时间,s3c2440a要求PLL
;锁定时间>300us,在上电时s3c2440a预设值
;mpll为晶体频率,我用的晶体频率为12MHz
;300us*12M = 3600设置LOCKTIME = 0xfff
;足够了
ldr r0, =LOCKTIME
ldr r1, =0xfff0fff0 ;高16为对应UPLL
;低16为对应MPLL
str r1, [r0, #0x0]
;根据器件手册我们还有以下几个事要做
;step1.配置UPLL
;step2.配置MPLL
;注:手册要求先配置UPLL后MPLL
; 且之间要间隔7NOP
; 详请看手册第7-21.
;step3.配置分频系数
;step1:
ldr r0, =UPLLCON
ldr r1, =((56<<12) + (2<<4) + 2)
ldr r1, [r0]
;按手册要求插入7个NOP
nop
nop
nop
nop
nop
nop
nop
;step2:
ldr r0, =MPLLCON
ldr r1, =((127<<12) + (2<<4) + 1)
ldr r1, [r0]
;step3:
ldr r0, =CLKDIVN
ldr r1, =((0<<3) + (2 << 2) + 1)
ldr r1, [r0]
;------------------------------------------
;------------------------------------------
;第三步 : 配置内存控制器
;内存控制内的寄存器器地址是连续分布的
;从0x4800_0000 -- 0x4800_0030,所以可以
;通过一个循环依次填入各个寄存器的内容
ldr r0, =SMRDATA ;装入配置值的地址
ldr r1, =BWSCON ;装入起始寄存器地址
add r2, r0, #0x34 ;计算结束地址
;下面是用于向内存控制器
;装入配置信息的循环
0
ldr r3, [r0], #4 ;装入配置值到r3,后变址
str r3, [r1], #4 ;把r3内包含的配置值写入
;内存控制器的寄存器
cmp r2, r0 ;结束否?
bne %B0 ;没结束则继续
;------------------------------------------
;------------------------------------------
;第四步 : 配置每种处理器模式下堆栈指针
;方法与原则:
;1: 通过CPSR寄存器切换处理器模式
;2: 对CPSR的操作方式为 读-修改-写回
;3: 绝对不要跳到用户模式,跳过去容易
; 回来就难了
;4: 切到新处理器模式后要屏蔽IRQ和FIQ
; 防止在未设置好堆栈前进入中断处理
; 程序,但是在启动代码的最先我们已
; 经屏蔽了所有的32个中断源,所以感
; 觉是否屏蔽都可以
;step1: 先把程序状态寄存器读到r0
mrs r0, cpsr
;step2: 清除处理器模式位(最前面5位)
bic r0, r0, #MODEMASK
;step3: 设置未定义状态下的堆栈指针
orr r1, r0, #UNDEFMODE|NOINT
msr cpsr_cxsf, r1 ;UndefMode
ldr sp, =UndefStack ;UndefStack=0x33FF_5C00
;step4: 设置终止状态下的堆栈指针
orr r1, r0, #ABORTMODE|NOINT
msr cpsr_cxsf, r1 ;AbortMode
ldr sp, =AbortStack ;AbortStack=0x33FF_6000
;step5: 设置中断模式下的堆栈指针
orr r1, r0, #IRQMODE|NOINT
msr cpsr_cxsf, r1 ;IRQMode
ldr sp, =IRQStack ;IRQStack=0x33FF_7000
;step6: 设置快速中断模式下的堆栈指针
orr r1, r0, #FIQMODE|NOINT
msr cpsr_cxsf, r1 ;FIQMode
ldr sp, =FIQStack ;FIQStack=0x33FF_8000
;step7: 设置管理模式下的堆栈指针
orr r1, r0, #SVCMODE|NOINT
msr cpsr_cxsf, r1 ;SVCMode
ldr sp, =SVCStack ;SVCStack=0x33FF_5800
;step8: 因为管理模式与用户模式共用
; 堆栈指针,所以借着系统模式
; 来设置用户模式的堆栈指针
orr r1, r0, #SYSMODE|NOINT
msr cpsr_cxsf, r1 ;SYSMode
ldr sp, =UserStack ;SVCStack & USERMode=0x33ff4800
;现在处理器处于系统模式
;------------------------------------------
;------------------------------------------
;第五步 : 初始化镜像运行域
;复制RW段和ZI段到SDRAM指定地址
LDR r0, =|Image$$RO$$Limit| ; 装入RO段结束地址
LDR r1, =|Image$$RW$$Base| ; 装入RW段起始地址
LDR r3, =|Image$$ZI$$Base| ; 装入ZI段起始地址
;|Image$$RO$$Limit| == |Image$$RW$$Base| ? 跳过RW段复制 : 复制RW段
CMP r0, r1
BEQ %F2
;复制RW段
1
CMP r1, r3
LDRCC r2, [r0], #4
STRCC r2, [r1], #4
BCC %B1
2
LDR r1, =|Image$$ZI$$Limit|
MOV r2, #0
;构造ZI段
3
CMP r3, r1
STRCC r2, [r3], #4
BCC %B3
;------------------------------------------
;------------------------------------------
;第六步 : 跳转到操作系统入口
b OSEntry ;不要使用main,因为如果使用main
;ads还会调用_main()初始化RW和ZI
;段,但是那里的数据和本程序不同
b .
;------------------------------------------
;---------------------------------------------------------------------------
SMRDATA DA
;这里是内存控制器的配置数据
;配置数据需要根据你使用的存储器修改
;在第三步时会将以下数据写入
;内存控制器的相关寄存器中
;共13个寄存器的配置值
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)+(Trc<<18)+(Tchr<<16)+REFCNT)
DCD 0x32 ;SCLK power saving mode, BANKSIZE 128M/128M
DCD 0x30 ;MRSR6 CL=3clk
DCD 0x30 ;MRSR7 CL=3clk
ALIGN ;数据边界对齐
END
我在写一个arm920T的微型OS,主要是想借着写OS的过程学习ARM的底层编程,然后跳到Linux。启动代码是固件的一部分,最经学校要搞个设计,不知OS什么时候能写好,反正搞定后立即发帖。
;*
;* 文件名称 : 2410INIT.S
;* 文件功能 : S3C2410 启动代码,配置存储器,ISR,堆栈,初始化C向量地址
;* 补充说明 :
;*-------------------------------------------- 最新版本信息 -------------------------------------------------
;* 修改作者 : ARM开发小组
;* 修改日期 : 2004/00/00
;* 版本声明 : V0.1
;*-------------------------------------------- 历史版本信息 -------------------------------------------------
;* 文件作者 : kwtark(samsung)
;* 创建日期 : 2002/02/25
;* 版本声明 : ver 0.0
; 2002/03/20: purnnamu: Add some functions for testing STOP,POWER_OFF mode
; 2002/04/10: SJS:sub interrupt disable 0x3ff -> 0x7ff
;*-----------------------------------------------------------------------------------------------------------
;*************************************************************************************************************
;*/
GET 2410addr.s ;定义了2410各各寄存器的地址
GET memcfg.s ;定义了2410各内存bank的带宽值和访问参数
BIT_SELFREFRESH EQU (1<<22) ;定义了几个常数 _STACK_BASEADDRESS EQU 0x33ff8000 堆栈基地址
; _ISR_STARTADDRESS EQU 0x33ffff00 中断向量表基地址
;Pre-defined constants 处理器模式预定义常量
USERMODE EQU 0x10
FIQMODE EQU 0x11
IRQMODE EQU 0x12
SVCMODE EQU 0x13
ABORTMODE EQU 0x17
UNDEFMODE EQU 0x1b
MODEMASK EQU 0x1f
NOINT EQU 0xc0 ;屏蔽中断位
;/*************定义处理器各模式下堆栈地址常量*******************/
UserStack EQU (_STACK_BASEADDRESS-0x3800) ;0x33ff4800 ~
SVCStack EQU (_STACK_BASEADDRESS-0x2800) ;0x33ff5800 ~
UndefStack EQU (_STACK_BASEADDRESS-0x2400) ;0x33ff5c00 ~
AbortStack EQU (_STACK_BASEADDRESS-0x2000) ;0x33ff6000 ~
IRQStack EQU (_STACK_BASEADDRESS-0x1000) ;0x33ff7000 ~
FIQStack EQU (_STACK_BASEADDRESS-0x0) ;0x33ff8000 ~
;/* Check if tasm.exe(armasm -16 ...@ADS 1.0) is used. ADS编译器的检查 */
GBLL THUMBCODE
[ {CONFIG} = 16
THUMBCODE SETL {TRUE}
CO
|
THUMBCODE SETL {FALSE}
]
MACRO
MOV_PC_LR
[ THUMBCODE
bx lr
|
mov pc,lr
]
MEND
MACRO
MOVEQ_PC_LR
[ THUMBCODE
bxeq lr
|
moveq pc,lr
]
MEND
;/*******************************************************************************************************/
; 正式代码的开始,首先是分配中断向表
;/******************************************************************************************************/
MACRO ;先定义了一个负责处理中断宏
$HandlerLabel HANDLER $HandleLabel
$HandlerLabel
sub sp,sp,#4 ;减少sp,保存跳转地址
stmfd sp!,{r0} ;PUSH the work register to stack(lr does't push because it return to original address)
ldr r0,=$HandleLabel ;load the address of HandleXXX to r0
ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX
str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack
ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)
MEND
IMP
IMP
IMP
IMP
IMP
;指示编译器的符号不是在本源文件中定义的,而是在其他源文件中
;定义的,在本源文件中可能引用该符号
AREA Init,CO
ENTRY ;程序的入口点
;//1)The co
;//2)The following little endian co
;// The co
;//3)The pseudo instruction,DCD can't be used here because the linker generates error.
ASSERT :DEF:ENDIAN_CHANGE ;//断言已经定义大端模式
[ ENDIAN_CHANGE
ASSERT :DEF:ENTRY_BUS_WIDTH
[ ENTRY_BUS_WIDTH=32
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
]
b HandlerUndef ;handler for Undefined mode
b HandlerSWI ;handler for SWI interrupt
b HandlerPabort ;handler for PAbort
b HandlerDabort ;handler for DAbort
b . ;reserved
b HandlerIRQ ;handler for IRQ interrupt
b HandlerFIQ ;handler for FIQ interrupt
;//@0x20
b EnterPWDN
ChangeBigEndian
;//@0x24
[ 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
]
[ 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 similar with NOP and run well in both endian mode.
DCD 0xffffffff
DCD 0xffffffff
DCD 0xffffffff
DCD 0xffffffff
b ResetHandler
;//Function for entering power down mode
;// 1. SDRAM should be in self-refresh mode.
;// 2. All interrupt should be maksked for SDRAM/DRAM self-refresh.
;// 3. LCD controller should be disabled for SDRAM/DRAM self-refresh.
;// 4. The I-cache may have to be turned on.
;// 5. The location of the following co
;//void EnterPWDN(int CLKCON);
EnterPWDN
mov r2,r0 ;r2=rCLKCON
tst r0,#0x8 ;POWER_OFF mode?
bne ENTER_POWER_OFF
ENTER_STOP
ldr r0,=REFRESH
ldr r3,[r0] ;r3=rREFRESH
mov r1, r3
orr r1, r1, #BIT_SELFREFRESH
str r1, [r0] ;Enable SDRAM self-refresh
mov r1,#16 ;wait until self-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 is in effect.
bne %B0 ;2) Or wait here until the CPU&Peripherals will be turned-off
; Entering POWER_OFF mode, on
ldr r0,=REFRESH ;exit from SDRAM self refresh mode.
str r3,[r0]
MOV_PC_LR
ENTER_POWER_OFF
;//NOTE.
;//1) rGSTATUS3 should have the return address after wake-up from POWER_OFF mode.
ldr r0,=REFRESH
ldr r1,[r0] ;r1=rREFRESH
orr r1, r1, #BIT_SELFREFRESH
str r1, [r0] ;Enable SDRAM self-refresh
mov r1,#16 ;Wait until self-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) ;Make sure that SCLK0:SCLK->0, SCLK1:SCLK->0, SCKE="L" during boot-up
str r0,[r1]
ldr r0,=CLKCON
str r2,[r0]
b . ;CPU will die here.
WAKEUP_POWER_OFF
;Release SCLKn after wake-up from the POWER_OFF mode.
ldr r1,=MISCCR
ldr r0,[r1]
bic r0,r0,#(7<<17) ;SCLK0:0->SCLK, SCLK1:0->SCLK, SCKE:L->H
str r0,[r1]
;Set memory control registers
ldr r0,=SMRDATA
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
mov r1,#256
0 subs r1,r1,#1 ;1) wait until the SelfRefresh is released.
bne %B0
ldr r1,=GSTATUS3 ;GSTATUS3 has the start address just after POWER_OFF wake-up
ldr r0,[r1]
mov pc,r0
LTORG
HandlerFIQ HANDLER HandleFIQ
HandlerIRQ HANDLER HandleIRQ
HandlerUndef HANDLER HandleUndef
HandlerSWI HANDLER HandleSWI
HandlerDabort HANDLER HandleDabort
HandlerPabort HANDLER HandlePabort
IsrIRQ
sub sp,sp,#4 ;reserved for PC
stmfd sp!,{r8-r9}
ldr r9,=INTOFFSET
ldr r9,[r9]
ldr r8,=HandleEINT0
add r8,r8,r9,lsl #2
ldr r8,[r8]
str r8,[sp,#8]
ldmfd sp!,{r8-r9,pc}
;================================================================================================
; ENTRY 将看门狗、中断之类的程序关掉,省得他们来打扰初始化程序的进行
;=================================================================================================
ResetHandler
ldr r0,=WTCON ;watch dog disable
ldr r1,=0x0
str r1,[r0]
ldr r0,=INTMSK
ldr r1,=0xffffffff ;all interrupt disable
str r1,[r0]
ldr r0,=INTSUBMSK
ldr r1,=0x7ff ;all sub interrupt disable, 2002/04/10
str r1,[r0]
[ {FALSE}
;rGPFDAT = (rGPFDAT & ~(0xf<<4)) | ((~da
;Led_Display
ldr r0,=GPFCON
ldr r1,=0x5500
str r1,[r0]
ldr r0,=GPFDAT
ldr r1,=0x10
str r1,[r0]
]
;To reduce PLL lock time, adjust the LOCKTIME register.
ldr r0,=LOCKTIME
ldr r1,=0xffffff
str r1,[r0]
[ PLL_ON_START
;Configure MPLL
ldr r0,=MPLLCON ;//设置时钟频率
ldr r1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV) ;Fin=12MHz,Fout=50MHz
str r1,[r0]
]
;Check if the boot is caused by the wake-up from POWER_OFF mode.
ldr r1,=GSTATUS2
ldr r0,[r1]
tst r0,#0x2
;In case of the wake-up from POWER_OFF mode, go to POWER_OFF_WAKEUP handler.
bne WAKEUP_POWER_OFF
EXPORT StartPointAfterPowerOffWakeUp
StartPointAfterPowerOffWakeUp
;Set memory control registers
ldr r0,=SMRDATA
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
;Initialize stacks
bl InitStacks
;Setup IRQ handler
ldr r0,=HandleIRQ ;This routine is needed
ldr r1,=IsrIRQ ;if there isn't 'subs pc,lr,#4' at 0x18, 0x1c
str r1,[r0]
;Copy and paste RW da
ldr r0, =|Image$$RO$$Limit| ; Get pointer to ROM da
ldr r1, =|Image$$RW$$Base| ; and RAM copy
ldr r3, =|Image$$ZI$$Base|
;Zero init base => top of initialised da
cmp r0, r1 ;Check that they are different
beq %F2
1
cmp r1, r3 ;Copy init da
ldrcc r2, [r0], #4 ;--> LDRCC r2, [r0] + ADD r0, r0, #4
strcc r2, [r1], #4 ;--> STRCC r2, [r1] + ADD r1, r1, #4
bcc %B1
2
ldr r1, =|Image$$ZI$$Limit| ;Top of zero init segment
mov r2, #0
3
cmp r3, r1 ; Zero init
strcc r2, [r3], #4
bcc %B3
[ :LNOT:THUMBCODE
bl Main ;Don't use main() because ......
b .
]
[ THUMBCODE ;for start-up co
orr lr,pc,#1
bx lr
CO
bl Main ;Don't use main() because ......
b .
CO
]
;//function initializing stacks 初始化堆栈
InitStacks
;Don't use DRAM,such as stmfd,ldmfd......
;SVCstack is initialized before
;Under toolkit 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
orr r1,r0,#ABORTMODE|NOINT
msr cpsr_cxsf,r1 ;AbortMode
ldr sp,=AbortStack
orr r1,r0,#IRQMODE|NOINT
msr cpsr_cxsf,r1 ;IRQMode
ldr sp,=IRQStack
orr r1,r0,#FIQMODE|NOINT
msr cpsr_cxsf,r1 ;FIQMode
ldr sp,=FIQStack
bic r0,r0,#MODEMASK|NOINT
orr r1,r0,#SVCMODE
msr cpsr_cxsf,r1 ;SVCMode
ldr sp,=SVCStack
;USER mode has not be initialized.
mov pc,lr
;The LR register won't be valid if the current mode is not SVC mode.
LTORG
SMRDATA DA
;// Memory configuration should be optimized for 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 for HCLK="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)+(Trc<<18)+(Tchr<<16)+REFCNT)
DCD 0x32 ;SCLK power saving mode, BANKSIZE 128M/128M
DCD 0x30 ;MRSR6 CL="3clk"
DCD 0x30 ;MRSR7
; // DCD 0x20 ;MRSR6 CL="2clk"
; // DCD 0x20 ;MRSR7
ALIGN
AREA RamData, DA
^ _ISR_STARTADDRESS
HandleReset # 4
HandleUndef # 4
HandleSWI # 4
HandlePabort # 4
HandleDabort # 4
HandleReserved # 4
HandleIRQ # 4
HandleFIQ # 4
;//Don't use the label 'IntVectorTable',
;//The value of IntVectorTable is different with the address you think it may be.
;//IntVectorTable
HandleEINT0 # 4
HandleEINT1 # 4
HandleEINT2 # 4
HandleEINT3 # 4
HandleEINT4_7 # 4
HandleEINT8_23 # 4
HandleRSV6 # 4
HandleBATFLT # 4
HandleTICK # 4
HandleWDT # 4
HandleTIMER0 # 4
HandleTIMER1 # 4
HandleTIMER2 # 4
HandleTIMER3 # 4
HandleTIMER4 # 4
HandleUART2 # 4
HandleLCD # 4
HandleDMA0 # 4
HandleDMA1 # 4
HandleDMA2 # 4
HandleDMA3 # 4
HandleMMC # 4
HandleSPI0 # 4
HandleUART1 # 4
HandleRSV24 # 4
HandleUSBD # 4
HandleUSBH # 4
HandleIIC # 4
HandleUART0 # 4
HandleSPI1 # 4
HandleRTC # 4
HandleADC # 4
END
;=========================================
; NAME: 2410INIT.S
; DESC: C start up codes
; Configure memory, ISR ,stacks
; Initialize C-variables
; HISTORY:
; 2002.02.25:kwtark: ver 0.0
; 2002.03.20:purnnamu: Add some functions for testing STOP,POWER_OFF mode
;=========================================
GET option.s
GET memcfg.s
GET 2410addr.s
BIT_SELFREFRESH EQU (1<<22)
;ARM异常模式的定义
;Pre-defined constants
USERMODE EQU 0x10
FIQMODE EQU 0x11
IRQMODE EQU 0x12
SVCMODE EQU 0x13
ABORTMODE EQU 0x17
UNDEFMODE EQU 0x1b
MODEMASK EQU 0x1f
NOINT EQU 0xc0
;ARM个异常模式堆栈
;The location of stacks
UserStack EQU (_STACK_BASEADDRESS-0x3800) ;0x33ff4800 ~
SVCStack EQU (_STACK_BASEADDRESS-0x2800) ;0x33ff5800 ~
UndefStack EQU (_STACK_BASEADDRESS-0x2400) ;0x33ff5c00 ~
AbortStack EQU (_STACK_BASEADDRESS-0x2000) ;0x33ff6000 ~
IRQStack EQU (_STACK_BASEADDRESS-0x1000) ;0x33ff7000 ~
FIQStack EQU (_STACK_BASEADDRESS-0x0) ;0x33ff8000 ~
;Check if tasm.exe(armasm -16...@ADS1.0) is used.
GBLL THUMBCODE
[ {CONFIG} = 16 ;[ = IF
THUMBCODE SETL {TRUE}
CO
| ;| = ELSE
THUMBCODE SETL {FALSE}
] ;] = ENDIF
;宏定义MOV_PC_LR
MACRO
MOV_PC_LR
[ THUMBCODE
bx lr
|
mov pc,lr
]
MEND
MACRO
MOVEQ_PC_LR
[ THUMBCODE
bxeq lr
|
moveq pc,lr
]
MEND
;宏定义-进入异常流程
;HANDLER-宏的名称
;$HandleLabel-宏的参数
;这个宏的作用是把各个中断程序的地址装入当前的PC,2410有两种装断模式 一种是没有中断向量表,一种是使用中断向量表的
;使用中断向量表只能是IRQ方式,当使用中断向量表的时候,中断发生时由2410的中断控制器自动跳转到
;相应的位置。
MACRO
$HandlerLabel HANDLER $HandleLabel
$HandlerLabel
sub sp,sp,#4 ;decrement sp(to store jump address)
stmfd sp!,{r0} ;PUSH the work register to stack(lr doest push because it return to original address)!表示数据传送完毕后,将最后的地址写入基址寄存器
ldr r0,=$HandleLabel;load the address of Handle1XXX to r0
ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX
str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack
ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)
MEND
;连接器生成的输出段相关的符号
;引入连接器生成的映象文件的各个部分地址。
;OR-只读区域、RW-读写区域、ZI-初始化为0的区域。
IMP
IMP
IMP
IMP
IMP
;引入外部函数Main,进入C程序。
IMP
;IMP
;定义ARM汇编程序段,段名为SelfBoot,程序段为只读的代码段。
AREA SelfBoot, CO
;程序入口地址
ENTRY
ResetEntry
;程序段执行的第一跳指令,为8个异常中断处理向量,要按顺序放置。
b ResetHandler
b HandlerUndef ;handler for Undefined mode
b HandlerSWI ;handler for SWI interrupt
b HandlerPabort ;handler for PAbort
b HandlerDabort ;handler for DAbort
b . ;reserved
b HandlerIRQ ;handler for IRQ interrupt
b HandlerFIQ ;handler for FIQ interrupt
LTORG ;声明一个数据缓冲池的开始
HandlerFIQ HANDLER HandleFIQ
HandlerIRQ HANDLER HandleIRQ
HandlerUndef HANDLER HandleUndef
HandlerSWI HANDLER HandleSWI
HandlerDabort HANDLER HandleDabort
HandlerPabort HANDLER HandlePabort
;采用INTOFFSET寄存器判定IRQ中断源
IsrIRQ
sub sp,sp,#4
stmfd sp!,{r8-r9}
ldr r9,=INTOFFSET
ldr r9,[r9]
ldr r8,=HandleEINT0
add r8,r8,r9,lsl #2
ldr r8,[r8]
str r8,[sp,#8]
ldmfd sp!,{r8-r9,pc}
;======================================================
; ENTRY
;======================================================
;初始化程序入口指令
ResetHandler
ldr r0,=WTCON ;watch dog disable
ldr r1,=0x0
str r1,[r0]
ldr r0,=INTMSK
ldr r1,=0xffffffff ;all interrupt disable
str r1,[r0]
ldr r0,=INTSUBMSK
ldr r1,=0x3ff ;all sub interrupt disable
str r1,[r0]
;To reduce PLL lock time, adjust the LOCKTIME register.
ldr r0,=LOCKTIME
ldr r1,=0xffffff
str r1,[r0]
;Configure MPLL
ldr r0,=MPLLCON
ldr r1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV) ;Fin=12MHz,Fout=50MHz
str r1,[r0]
;设置存储器控制寄存器。
;Set memory control registers
adr r0, SMRDATA
ldr r1,=BWSCON ;BWSCON Address
add r2, r0, #52 ;End address of SMRDATA一共13个寄存器
0
ldr r3, [r0], #4
str r3, [r1], #4
cmp r2, r0
bne %B0
;禁止Icache和Dcache,禁止MMU
;IMP
;bl MMU_DisableICache ;
;IMP
;bl MMU_DisableDCache ;
;IMP
;bl MMU_InvalidateICache ;
;IMP
;bl MMU_DisableMMU ;
;初始化堆栈
;Initialize stacks
bl InitStacks
;建立IRQ中断
; Setup IRQ handler
ldr r0,=HandleIRQ ;This routine is needed
ldr r1,=IsrIRQ ;if there isn't 'subs pc,lr,#4' at 0x18, 0x1c'
str r1,[r0]
;===========================================================
adr r0, ResetEntry
ldr r2, BaseOfROM
cmp r0, r2
ldreq r0, TopOfROM
beq InitRam
ldr r3, TopOfROM
;将RO区域的代码copy到RW域中并且将ZI区域初始化为0。
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 ;copy 初始化代码
ldrcc r1, [r0], #4
strcc r1, [r2], #4
bcc %B0
mov r0, #0 ;初始化ZI区域为0
ldr r3, EndOfBSS
1
cmp r2, r3
strcc r0, [r2], #4
bcc %B1
bl Main ;bl Main ;Dont use main() because ......
b .
;堆栈初始化
;function initializing stacks
InitStacks
;Don't use DRAM,such as stmfd,ldmfd......
;SVCstack is initialized before
;Under toolkit ver 2.5, 'msr cpsr,r1' can be used instead of 'msr cpsr_cxsf,r1
;UndefMode堆栈
mrs r0,cpsr
bic r0,r0,#MODEMASK
orr r1,r0,#UNDEFMODE|NOINT
msr cpsr_cxsf,r1 ;UndefMode
ldr sp,=UndefStack
;AbortMode堆栈
orr r1,r0,#ABORTMODE|NOINT
msr cpsr_cxsf,r1 ;AbortMode
ldr sp,=AbortStack
;IRQMode堆栈
orr r1,r0,#IRQMODE|NOINT
msr cpsr_cxsf,r1 ;IRQMode
ldr sp,=IRQStack
;FIQMode堆栈
orr r1,r0,#FIQMODE|NOINT
msr cpsr_cxsf,r1 ;FIQMode
ldr sp,=FIQStack
;SVCMode堆栈
bic r0,r0,#MODEMASK|NOINT
orr r1,r0,#SVCMODE
msr cpsr_cxsf,r1 ;SVCMode
ldr sp,=SVCStack
;USER mode has not be initialized.
mov pc,lr
;The LR register won't be valid if the current mode is not SVC mode.'
LTORG ;声明一个数据缓冲池的开始
SMRDATA DA
; Memory configuration should be optimized for 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 for HCLK=75Mhz.
DCD (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28));BWSCON=0x2211D110
DCD ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC)) ;GCS0 BANK0CON=0x0700
DCD ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC)) ;GCS1 BANK1CON=0x7FFC
DCD ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC)) ;GCS2 BANKCON2=0x0700
DCD 0x1f7c;((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC)) ;GCS3 BANKCON3=0x0700
DCD ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC)) ;GCS4 BANKCON4=0x0700
DCD ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC)) ;GCS5 BANKCON5=0x0700
DCD ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)) ;GCS6 BANKCON6=0x18005
DCD ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) ;GCS7 BANKCON7=0x18005
DCD ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT) ;REFRESH=0x008E0459
DCD 0x32 ;SCLK power saving mode, BANKSIZE 128M/128M ;BANKSIZE=0x32
DCD 0x30 ;MRSR6 CL=3clk ;MRSRB6=0x30
DCD 0x30 ;MRSR7 ;MRSRB7=0x30
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 ;通过添加补丁字节使当前位置满足一定的对齐方式
;可读写的数据段
AREA RamData, DA
;^=MAP:定义一个结构化的内存表(storage map)的首地址,地址为0x33ff8000
^ _ISR_STARTADDRESS ;0x33ff8000
HandleReset # 4 ;#--Field:定义一个结构化内存表中的数据域,该域为4个字节
HandleUndef # 4
HandleSWI # 4
HandlePabort # 4
HandleDabort # 4
HandleReserved # 4
HandleIRQ # 4
HandleFIQ # 4
;Don't use the label 'IntVectorTable',
;The value of IntVectorTable is different with the address you think it may be.
;IntVectorTable'
HandleEINT0 # 4
HandleEINT1 # 4
HandleEINT2 # 4
HandleEINT3 # 4
HandleEINT4_7 # 4
HandleEINT8_23 # 4
HandleRSV6 # 4
HandleBATFLT # 4
HandleTICK # 4
HandleWDT # 4
HandleTIMER0 # 4
HandleTIMER1 # 4
HandleTIMER2 # 4
HandleTIMER3 # 4
HandleTIMER4 # 4
HandleUART2 # 4
HandleLCD # 4
HandleDMA0 # 4
HandleDMA1 # 4
HandleDMA2 # 4
HandleDMA3 # 4
HandleMMC # 4
HandleSPI0 # 4
HandleUART1 # 4
HandleRSV24 # 4
HandleUSBD # 4
HandleUSBH # 4
HandleIIC # 4
HandleUART0 # 4
HandleSPI1 # 4
HandleRTC # 4
HandleADC # 4
END
上一篇:关于S3C2410时钟
下一篇:ARM代码域和段的概念
推荐阅读最新更新时间:2024-03-16 15:03