S3C2440A_NOR FALSH前4K代码复制到SDRAM中并在SDRAM中运行
; Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
Mode_USR EQU 0x10
;----------------------- Stack and Heap Definitions ----------------------------
;// <h> Stack Configuration (Stack Sizes in Bytes)
;// <o0> Undefined Mode <0x0-0xFFFFFFFF:8>
;// <o1> Supervisor Mode <0x0-0xFFFFFFFF:8>
;// <o2> Abort Mode <0x0-0xFFFFFFFF:8>
;// <o3> Fast Interrupt Mode <0x0-0xFFFFFFFF:8>
;// <o4> Interrupt Mode <0x0-0xFFFFFFFF:8>
;// <o5> User/System Mode <0x0-0xFFFFFFFF:8>
;// </h>
UND_Stack_Size EQU 0x00000000
SVC_Stack_Size EQU 0x00000008
ABT_Stack_Size EQU 0x00000000
FIQ_Stack_Size EQU 0x00000000
IRQ_Stack_Size EQU 0x00000080
USR_Stack_Size EQU 0x00000400
ISR_Stack_Size EQU (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
FIQ_Stack_Size + IRQ_Stack_Size)
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE USR_Stack_Size
__initial_sp SPACE ISR_Stack_Size
Stack_Top
;// <h> Heap Configuration
;// <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF>
;// </h>
Heap_Size EQU 0x00000000
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
;----------------------- Watchdog Timer Definitions ----------------------------
WT_BASE EQU 0x53000000 ; Watchdog Timer Base Address
WTCON_OFS EQU 0x00 ; Watchdog Timer Control Register Offset
WTDAT_OFS EQU 0x04 ; Watchdog Timer Data Register Offset
WTCNT_OFS EQU 0x08 ; Watchdog Timer Count Register Offset
;// <e> Watchdog Timer Setup
;// <h> Watchdog Timer Control Register (WTCON)
;// <o1.8..15> Prescaler Value <0-255>
;// <o1.5> Watchdog Timer Enable
;// <o1.3..4> Clock Division Factor
;// <0=> 16 <1=> 32 <2=> 64 <3=> 128
;// <o1.2> Interrupt Generation Enable
;// <o1.0> Reset Enable
;// </h>
;// <h> Watchdog Timer Data Register (WTDAT)
;// <o2.0..15> Count Reload Value <0-65535>
;// </h>
;// </e> Watchdog Timer Setup
WT_SETUP EQU 1
WTCON_Val EQU 0x00000000
WTDAT_Val EQU 0x00008000
;----------------------- CODE --------------------------------------------------
PRESERVE8
; Area Definition and Entry Point
; Startup Code must be linked first at Address at which it expects to run.
AREA RESET, CODE, READONLY
ARM
IF :LNOT::DEF:__EVAL
IMPORT ||Image$$ER_ROM1$$RO$$Length||
IMPORT ||Image$$RW_RAM1$$RW$$Length||
ENDIF
; Exception Vectors
; Mapped to Address 0.
; Absolute addressing mode must be used.
; Dummy Handlers are implemented as infinite loops which can be modified.
; Watchdog Setup ---------------------------------------------------------------
Reset_Handler
LDR R0, =WT_BASE
LDR R1, =WTCON_Val
LDR R2, =WTDAT_Val
STR R2, [R0, #WTCNT_OFS]
STR R2, [R0, #WTDAT_OFS]
STR R1, [R0, #WTCON_OFS]
; Setup Stack for each mode ----------------------------------------------------
LDR R0, =Stack_Top
; Enter User Mode and set its Stack Pointer
MSR CPSR_c, #Mode_USR
MOV SP, R0
SUB SL, SP, #USR_Stack_Size
; Enter the SDRAM dell -------------------------------------------------------------
AREA SDRAM, CODE, READONLY
CODE32
MEM_CTL_BASE EQU 0x48000000
SDRAM_BASE EQU 0x30000000
_start
;bl disable_watch_dog ;关闭WATCHDOG,否则CPU会不断重启
bl memsetup ; 设置存储控制器
bl copy_steppingstone_to_sdram ; 复制代码到SDRAM中
ldr pc, =on_sdram ; 跳到SDRAM中继续执行
on_sdram
IMPORT __main
LDR R0, =__main
BX R0
halt_loop
b halt_loop
copy_steppingstone_to_sdram
; 将Steppingstone的4K数据全部复制到SDRAM中去
; Steppingstone起始地址为0x00000000,SDRAM中起始地址为0x30000000
mov r1, #0
ldr r2, =SDRAM_BASE
mov r3, #4*1024
1
ldr r4, [r1],#4 ; 从Steppingstone读取4字节的数据,并让源地址加4
str r4, [r2],#4 ; 将此4字节的数据复制到SDRAM中,并让目地地址加4
cmp r1, r3 ; 判断是否完成:源地址等于Steppingstone的未地址?
bne 1 ; 若没有复制完,继续
mov pc, lr ; 返回
memsetup
; 设置存储控制器以便使用SDRAM等外设
mov r1, #MEM_CTL_BASE ; 存储控制器的13个寄存器的开始地址
adrl r2, mem_cfg_val ; 这13个值的起始存储地址
add r3, r1, #52 ; 13*4 = 52
1
ldr r4, [r2], #4 ; 读取设置值,并让r2加4
str r4, [r1], #4 ; 将此值写入寄存器,并让r1加4
cmp r1, r3 ; 判断是否设置完所有13个寄存器
bne 1 ; 若没有写成,继续
mov pc, lr ; 返回
ALIGN 4
; 存储控制器13个寄存器的设置值
mem_cfg_val DCD 0x22011110,0x00000700,0x00000700,0x00000700,0x00000700,0x00000700,0x00000700,0x00018005,0x00018005,0x008C07A3,0x000000B1,0x00000030,0x00000030
; User Initial Stack & Heap
AREA |.text|, CODE, READONLY
IMPORT __use_two_region_memory
EXPORT __user_initial_stackheap
__user_initial_stackheap
LDR R0, = Heap_Mem
LDR R1, =(Stack_Mem + USR_Stack_Size)
LDR R2, = (Heap_Mem + Heap_Size)
LDR R3, = Stack_Mem
BX LR
END