![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
;
=========================================
; 文件名称:S3C244xInit.s
; 说 明:ARM内核初始化
; 作 者:温子祺
; 创建时间:2010-06-10
; 功能说明:ARM内核初始化,并将RO、RW、ZI段的所有
; 内容全部复制到RAM当中
; 文件名称:S3C244xInit.s
; 说 明:ARM内核初始化
; 作 者:温子祺
; 创建时间:2010-06-10
; 功能说明:ARM内核初始化,并将RO、RW、ZI段的所有
; 内容全部复制到RAM当中
;开发平台:RealView MDK 4
; =========================================
; IMPORT __use_no_semihosting_swi
GET MemConfig. inc
GET S3C244x. inc
_STACK_BASEADDRESS EQU 0x34000000
; 管理模式堆栈栈顶地址
SVCStack EQU _STACK_BASEADDRESS ; 0x33ff5800 ~
; ---------------------------------------------------------------------------
IMPORT __use_no_semihosting_swi
IMPORT |Image$$ER_ROM1$$RO$$Limit| ; 加载域中RO段起始地址
IMPORT |Image$$RW_RAM1$$RW$$Base| ; 加载域中RO结束地址加1,即加载域中RW段的起始地址
IMPORT |Image$$RW_RAM1$$ZI$$Base| ; 运行域中RW段起始地址
IMPORT |Image$$RW_RAM1$$ZI$$Limit| ; 运行域中RW段结束地址加1,即ZI段的起始地址
IMPORT Main ; The main entry of mon program
CODE32
PRESERVE8
AREA Init,CODE,READONLY
ENTRY
b ResetHandler
b . ; handler for Undefined mode
b . ; handler for SWI interrupt
b . ; handler for PAbort
b . ; handler for DAbort
b . ; reserved
b . ; handler for IRQ interrupt
b . ; handler for FIQ interrupt
; ======================================================================================
; ENTRY
; ======================================================================================
ResetHandler
; ARM重启后,看门狗是默认打开的
ldr r0,=WTCON ; 禁止看门狗
ldr r1,=0x0
str r1,[r0]
ldr r0,=INTMSK
ldr r1,=0xffffffff ; 所有中断禁止
str r1,[r0]
ldr r0,=INTSUBMSK
ldr r1,=0x7ff ; 所有子中断禁止
str r1,[r0]
ldr r0,=GPGCON
ldr r1,=0xFD95ffba ; set output
str r1,[r0]
ldr r0,=GPGDAT ; set high.
ldr r1,=0x1000
str r1,[r0]
ldr r0,=GPGUP
ldr r1,=0xffff
str r1,[r0]
; //初始化PLL和时钟
ldr r0,=LOCKTIME ; PLL重置延迟
ldr r1,=0xffffff ; 由于配置或其他原因导致主频变化时
; PLL新的输出需要一个稳定过度的时间
str r1,[r0]
ldr r0,=CLKDIVN ; 设置分频数
ldr r1,= 7
str r1,[r0]
; 当设置UPLLCON和MPLLCON时,需要先设置UPLLCON
ldr r0,=UPLLCON ; USB时钟
ldr r1,=(( 56 << 12 )+( 2 << 4 )+ 2 ) ; Fin=12MHz,Fout=48MHz
str r1,[r0]
nop ; USB时钟设置后需要7个时钟延时
nop
nop
nop
nop
nop
nop
nop
nop
; Configure MPLL ;锁相环控制寄存器
ldr r0,=MPLLCON
ldr r1,=(( 92 << 12 )+( 1 << 4 )+ 1 )
str r1,[r0]
; :::::::::::::::::::::::::::::::::::::::::::::
; BEGIN: Power Management
; - - - - - - - - - - - - - - - - - - - - - - -
; 检查复位状态,复位状态含看门狗复位、唤醒复位、电源复位
ldr r1,=GSTATUS2
ldr r0,[r1]
tst r0,#0x2 ; 检测是否唤醒复位
beq %F4 ; 若是唤醒复位,跳转到4
ldr r1, =MISCCR
ldr r0, [r1]
bic r0, r0, #( 3 << 17 ) ; SCLK0:0->SCLK, SCLK1:0->SCLK, SCKE:L->H
; 位清除指令,即将[17:18]位清零
str r0, [r1]
; 设置内存控制寄存器
; ldr r0, =SMRDATA ; 获取SMRDATA地址
add r0, pc, #SMRDATA - (. + 8 ) ; r0=pc+&SMRDATA-pc-8
ldr r1, =BWSCON ; 获取BWSCON地址
add r2, r0, # 52 ; SMRDATA变量结束地址r2=SMRDATA地址+52
; 从下面定义SMRDATA变量中总共DCD了13个地址
; 52=13*4
loop10 ; 将SMRDATA地址上的内容赋给BWSCON、BANKCON0-BANKCON7、BANKSIZE等寄存器
; 这个可以从后面SMRDATA的内容可以获得
ldr r3, [r0], # 4 ; 读取r0地址上的内容赋给r3,并且r0=r0-4
str r3, [r1], # 4 ; r3内容写入r1,并且r1=r1+4
cmp r2, r0 ; 比较r2(r0+52)、r0的内容,总共比较14次
bne loop10 ; 若不同跳转到10
mov r1, # 256
loop11
subs r1, r1, # 1 ; 延时一段时间
bne loop11
; ldr r1,=GSTATUS3 ;GSTATUS3保存的是掉电模式的保存的PC地址
; 如何保证跳过去的前提是内存数据正确!
ldr r2, =0x201000 ; 内存地址偏移量
add r2, r2, #0x30000000 ; 内存物理地址基址
bx r2 ; 调到内存地址0x30000000+0x201000=0x3020100地址处
nop ; 为了防止程序跑飞,可以在mov pc,rn语句中加nop和b.
nop
nop
b .
; - - - - - - - - - - - - - - - - - - - - - - -
; END: Power Management
; :::::::::::::::::::::::::::::::::::::::::::::
4
; Configure memory controller
; ldr r0,=SMRDATA
add r0, pc, #SMRDATA - (. + 8 )
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
ldr sp,=SVCStack ; 获取管理模式堆栈栈顶指针
; 将RW段拷贝至RAM,将ZI段清零
ldr r0, =|Image$$ER_ROM1$$RO$$Limit| ; 加载域中RO段地址+1->ro,即加载域中RW段起始地址
ldr r1, =|Image$$RW_RAM1$$RW$$Base| ; 运行域中RW段的开始地址->r1
ldr r3, =|Image$$RW_RAM1$$ZI$$Base| ; 运行域中ZI开始地址->r3
cmp r0, r1 ; 比较加载域中RW段开始地址和运行域中RW段开始地址
beq %F2 ; 若相同,则RW段无需拷贝,跳至2执行,否则跳过这一句
1
; 将加载域中RW段复制到运行域,r0、r1中的地址会每次以4字节的幅度改变
cmp r1, r3 ; 比较r1和r3的值,判断RW段是否复制完毕
ldrcc r2, [r0], # 4 ; 相等(未复制完毕)则将r0地址的内容复制到r2中,r0=r0+4
strcc r2, [r1], # 4 ; 相等则将r2的内容复制到r1中,r1=r1+4
bcc %B1 ; (跳转条件就是无符号数比较小于)不相等的话执行1
2 ; 以下为清零ZI段
ldr r1, =|Image$$RW_RAM1$$ZI$$Limit| ;
mov r2, # 0
3 ; 开始清零,r3中的地址会每次以4字节的幅度改变
cmp r3, r1 ; 比较,判断是否清零完毕
strcc r2, [r3], # 4 ; 如果清零未完毕,则将r3中地址开始的地方的4个字节数据清零
bcc %B3 ; (跳转条件就是无符号数比较小于)如果清零未完毕,则继续执行3
b Main ; Dont use main() because ......
b .
LTORG ; 文字词
; SMRDATA
SMRDATA DATA
; 注意SMRDATA与 SMRDATA DATA的效果是一样的
; 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寄存器
DCD ((B0_Tacs<< 13 )+(B0_Tcos<< 11 )+(B0_Tacc<< 8 )+(B0_Tcoh<< 6 )+(B0_Tah<< 4 )+(B0_Tacp<< 2 )+(B0_PMC)) ; BANKCON0
DCD ((B1_Tacs<< 13 )+(B1_Tcos<< 11 )+(B1_Tacc<< 8 )+(B1_Tcoh<< 6 )+(B1_Tah<< 4 )+(B1_Tacp<< 2 )+(B1_PMC)) ; BANKCON1
DCD ((B2_Tacs<< 13 )+(B2_Tcos<< 11 )+(B2_Tacc<< 8 )+(B2_Tcoh<< 6 )+(B2_Tah<< 4 )+(B2_Tacp<< 2 )+(B2_PMC)) ; BANKCON2
DCD ((B3_Tacs<< 13 )+(B3_Tcos<< 11 )+(B3_Tacc<< 8 )+(B3_Tcoh<< 6 )+(B3_Tah<< 4 )+(B3_Tacp<< 2 )+(B3_PMC)) ; BANKCON3
DCD ((B4_Tacs<< 13 )+(B4_Tcos<< 11 )+(B4_Tacc<< 8 )+(B4_Tcoh<< 6 )+(B4_Tah<< 4 )+(B4_Tacp<< 2 )+(B4_PMC)) ; BANKCON4
DCD ((B5_Tacs<< 13 )+(B5_Tcos<< 11 )+(B5_Tacc<< 8 )+(B5_Tcoh<< 6 )+(B5_Tah<< 4 )+(B5_Tacp<< 2 )+(B5_PMC)) ; BANKCON5
DCD ((B6_MT<< 15 )+(B6_Trcd<< 2 )+(B6_SCAN)) ; BANKCON6(SDRAM)
DCD ((B7_MT<< 15 )+(B7_Trcd<< 2 )+(B7_SCAN)) ; BANKCON7(SDRAM)
DCD ((REFEN<< 23 )+(TREFMD<< 22 )+(Trp<< 20 )+(Tsrc<< 18 )+(Tchr<< 16 )+REFCNT) ; REFERSH寄存器(SDRAM)
; ;;
; DCD 0x00aC03F4 ;refresh
DCD 0xB2 ; SCLK power saving mode, BANKSIZE 128M/128M;BANKSIZE寄存器(128MB)
DCD 0x30 ; MRSR6寄存器 CL=3clk
DCD 0x30 ; MRSR7寄存器 CL=3clk
ALIGN ; 字节对齐(不对齐的时候自动加上补丁字节)
END
; =========================================
; IMPORT __use_no_semihosting_swi
GET MemConfig. inc
GET S3C244x. inc
_STACK_BASEADDRESS EQU 0x34000000
; 管理模式堆栈栈顶地址
SVCStack EQU _STACK_BASEADDRESS ; 0x33ff5800 ~
; ---------------------------------------------------------------------------
IMPORT __use_no_semihosting_swi
IMPORT |Image$$ER_ROM1$$RO$$Limit| ; 加载域中RO段起始地址
IMPORT |Image$$RW_RAM1$$RW$$Base| ; 加载域中RO结束地址加1,即加载域中RW段的起始地址
IMPORT |Image$$RW_RAM1$$ZI$$Base| ; 运行域中RW段起始地址
IMPORT |Image$$RW_RAM1$$ZI$$Limit| ; 运行域中RW段结束地址加1,即ZI段的起始地址
IMPORT Main ; The main entry of mon program
CODE32
PRESERVE8
AREA Init,CODE,READONLY
ENTRY
b ResetHandler
b . ; handler for Undefined mode
b . ; handler for SWI interrupt
b . ; handler for PAbort
b . ; handler for DAbort
b . ; reserved
b . ; handler for IRQ interrupt
b . ; handler for FIQ interrupt
; ======================================================================================
; ENTRY
; ======================================================================================
ResetHandler
; ARM重启后,看门狗是默认打开的
ldr r0,=WTCON ; 禁止看门狗
ldr r1,=0x0
str r1,[r0]
ldr r0,=INTMSK
ldr r1,=0xffffffff ; 所有中断禁止
str r1,[r0]
ldr r0,=INTSUBMSK
ldr r1,=0x7ff ; 所有子中断禁止
str r1,[r0]
ldr r0,=GPGCON
ldr r1,=0xFD95ffba ; set output
str r1,[r0]
ldr r0,=GPGDAT ; set high.
ldr r1,=0x1000
str r1,[r0]
ldr r0,=GPGUP
ldr r1,=0xffff
str r1,[r0]
; //初始化PLL和时钟
ldr r0,=LOCKTIME ; PLL重置延迟
ldr r1,=0xffffff ; 由于配置或其他原因导致主频变化时
; PLL新的输出需要一个稳定过度的时间
str r1,[r0]
ldr r0,=CLKDIVN ; 设置分频数
ldr r1,= 7
str r1,[r0]
; 当设置UPLLCON和MPLLCON时,需要先设置UPLLCON
ldr r0,=UPLLCON ; USB时钟
ldr r1,=(( 56 << 12 )+( 2 << 4 )+ 2 ) ; Fin=12MHz,Fout=48MHz
str r1,[r0]
nop ; USB时钟设置后需要7个时钟延时
nop
nop
nop
nop
nop
nop
nop
nop
; Configure MPLL ;锁相环控制寄存器
ldr r0,=MPLLCON
ldr r1,=(( 92 << 12 )+( 1 << 4 )+ 1 )
str r1,[r0]
; :::::::::::::::::::::::::::::::::::::::::::::
; BEGIN: Power Management
; - - - - - - - - - - - - - - - - - - - - - - -
; 检查复位状态,复位状态含看门狗复位、唤醒复位、电源复位
ldr r1,=GSTATUS2
ldr r0,[r1]
tst r0,#0x2 ; 检测是否唤醒复位
beq %F4 ; 若是唤醒复位,跳转到4
ldr r1, =MISCCR
ldr r0, [r1]
bic r0, r0, #( 3 << 17 ) ; SCLK0:0->SCLK, SCLK1:0->SCLK, SCKE:L->H
; 位清除指令,即将[17:18]位清零
str r0, [r1]
; 设置内存控制寄存器
; ldr r0, =SMRDATA ; 获取SMRDATA地址
add r0, pc, #SMRDATA - (. + 8 ) ; r0=pc+&SMRDATA-pc-8
ldr r1, =BWSCON ; 获取BWSCON地址
add r2, r0, # 52 ; SMRDATA变量结束地址r2=SMRDATA地址+52
; 从下面定义SMRDATA变量中总共DCD了13个地址
; 52=13*4
loop10 ; 将SMRDATA地址上的内容赋给BWSCON、BANKCON0-BANKCON7、BANKSIZE等寄存器
; 这个可以从后面SMRDATA的内容可以获得
ldr r3, [r0], # 4 ; 读取r0地址上的内容赋给r3,并且r0=r0-4
str r3, [r1], # 4 ; r3内容写入r1,并且r1=r1+4
cmp r2, r0 ; 比较r2(r0+52)、r0的内容,总共比较14次
bne loop10 ; 若不同跳转到10
mov r1, # 256
loop11
subs r1, r1, # 1 ; 延时一段时间
bne loop11
; ldr r1,=GSTATUS3 ;GSTATUS3保存的是掉电模式的保存的PC地址
; 如何保证跳过去的前提是内存数据正确!
ldr r2, =0x201000 ; 内存地址偏移量
add r2, r2, #0x30000000 ; 内存物理地址基址
bx r2 ; 调到内存地址0x30000000+0x201000=0x3020100地址处
nop ; 为了防止程序跑飞,可以在mov pc,rn语句中加nop和b.
nop
nop
b .
; - - - - - - - - - - - - - - - - - - - - - - -
; END: Power Management
; :::::::::::::::::::::::::::::::::::::::::::::
4
; Configure memory controller
; ldr r0,=SMRDATA
add r0, pc, #SMRDATA - (. + 8 )
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
ldr sp,=SVCStack ; 获取管理模式堆栈栈顶指针
; 将RW段拷贝至RAM,将ZI段清零
ldr r0, =|Image$$ER_ROM1$$RO$$Limit| ; 加载域中RO段地址+1->ro,即加载域中RW段起始地址
ldr r1, =|Image$$RW_RAM1$$RW$$Base| ; 运行域中RW段的开始地址->r1
ldr r3, =|Image$$RW_RAM1$$ZI$$Base| ; 运行域中ZI开始地址->r3
cmp r0, r1 ; 比较加载域中RW段开始地址和运行域中RW段开始地址
beq %F2 ; 若相同,则RW段无需拷贝,跳至2执行,否则跳过这一句
1
; 将加载域中RW段复制到运行域,r0、r1中的地址会每次以4字节的幅度改变
cmp r1, r3 ; 比较r1和r3的值,判断RW段是否复制完毕
ldrcc r2, [r0], # 4 ; 相等(未复制完毕)则将r0地址的内容复制到r2中,r0=r0+4
strcc r2, [r1], # 4 ; 相等则将r2的内容复制到r1中,r1=r1+4
bcc %B1 ; (跳转条件就是无符号数比较小于)不相等的话执行1
2 ; 以下为清零ZI段
ldr r1, =|Image$$RW_RAM1$$ZI$$Limit| ;
mov r2, # 0
3 ; 开始清零,r3中的地址会每次以4字节的幅度改变
cmp r3, r1 ; 比较,判断是否清零完毕
strcc r2, [r3], # 4 ; 如果清零未完毕,则将r3中地址开始的地方的4个字节数据清零
bcc %B3 ; (跳转条件就是无符号数比较小于)如果清零未完毕,则继续执行3
b Main ; Dont use main() because ......
b .
LTORG ; 文字词
; SMRDATA
SMRDATA DATA
; 注意SMRDATA与 SMRDATA DATA的效果是一样的
; 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寄存器
DCD ((B0_Tacs<< 13 )+(B0_Tcos<< 11 )+(B0_Tacc<< 8 )+(B0_Tcoh<< 6 )+(B0_Tah<< 4 )+(B0_Tacp<< 2 )+(B0_PMC)) ; BANKCON0
DCD ((B1_Tacs<< 13 )+(B1_Tcos<< 11 )+(B1_Tacc<< 8 )+(B1_Tcoh<< 6 )+(B1_Tah<< 4 )+(B1_Tacp<< 2 )+(B1_PMC)) ; BANKCON1
DCD ((B2_Tacs<< 13 )+(B2_Tcos<< 11 )+(B2_Tacc<< 8 )+(B2_Tcoh<< 6 )+(B2_Tah<< 4 )+(B2_Tacp<< 2 )+(B2_PMC)) ; BANKCON2
DCD ((B3_Tacs<< 13 )+(B3_Tcos<< 11 )+(B3_Tacc<< 8 )+(B3_Tcoh<< 6 )+(B3_Tah<< 4 )+(B3_Tacp<< 2 )+(B3_PMC)) ; BANKCON3
DCD ((B4_Tacs<< 13 )+(B4_Tcos<< 11 )+(B4_Tacc<< 8 )+(B4_Tcoh<< 6 )+(B4_Tah<< 4 )+(B4_Tacp<< 2 )+(B4_PMC)) ; BANKCON4
DCD ((B5_Tacs<< 13 )+(B5_Tcos<< 11 )+(B5_Tacc<< 8 )+(B5_Tcoh<< 6 )+(B5_Tah<< 4 )+(B5_Tacp<< 2 )+(B5_PMC)) ; BANKCON5
DCD ((B6_MT<< 15 )+(B6_Trcd<< 2 )+(B6_SCAN)) ; BANKCON6(SDRAM)
DCD ((B7_MT<< 15 )+(B7_Trcd<< 2 )+(B7_SCAN)) ; BANKCON7(SDRAM)
DCD ((REFEN<< 23 )+(TREFMD<< 22 )+(Trp<< 20 )+(Tsrc<< 18 )+(Tchr<< 16 )+REFCNT) ; REFERSH寄存器(SDRAM)
; ;;
; DCD 0x00aC03F4 ;refresh
DCD 0xB2 ; SCLK power saving mode, BANKSIZE 128M/128M;BANKSIZE寄存器(128MB)
DCD 0x30 ; MRSR6寄存器 CL=3clk
DCD 0x30 ; MRSR7寄存器 CL=3clk
ALIGN ; 字节对齐(不对齐的时候自动加上补丁字节)
END