📄 init.s
字号:
; bit field of CPSR/SPSR
Mode_USR EQU 0x10 ; user mode
Mode_FIQ EQU 0x11 ; FIQ mode
Mode_IRQ EQU 0x12 ; IRQ mode
Mode_SVC EQU 0x13 ; supervisor mode
Mode_ABT EQU 0x17 ; abort mode
Mode_UND EQU 0x1B ; undefined mode
Mode_SYS EQU 0x1F ; system mode
T_Bit EQU 0x20 ; Thumb mode flag
F_Bit EQU 0x40 ; FIQ disable flag
I_Bit EQU 0x80 ; IRQ disable flag
;------------------------------------------------------------------------------
;- Stack Area Definition
;-----------------------
; --- Amount of memory (in bytes) allocated for stacks 16K byte
Len_SVC_Stack EQU 8*1024
Len_IRQ_Stack EQU 6*1024
Len_FIQ_Stack EQU 256
Len_ABT_Stack EQU 256
Len_USR_Stack EQU 256
Len_UND_Stack EQU 0
Len_SYS_Stack EQU 0
; Add lengths >0 for FIQ_Stack, ABT_Stack, UND_Stack if you need them.
; Offsets will be loaded as immediate values.
; Offsets must be 8 byte aligned.
RAM_BASE EQU 0x00200000 ;boottom of internal static ram
FIQ_Stack EQU RAM_BASE+1024+ Len_FIQ_Stack
ABT_Stack EQU FIQ_Stack + Len_ABT_Stack
UND_Stack EQU ABT_Stack + Len_UND_Stack
USR_Stack EQU UND_Stack + Len_USR_Stack
SYS_Stack EQU USR_Stack
IRQ_Stack EQU USR_Stack + Len_IRQ_Stack
SVC_Stack EQU IRQ_Stack + Len_SVC_Stack
;other define
SdramBase EQU 0x20000000
MC_MCR EQU 0xffffff00
RAMCntBase EQU RAM_BASE+1024
dwAbortCnt EQU RAMCntBase-12
dwUndefCnt EQU RAMCntBase-8
dwPrefCnt EQU RAMCntBase-4
AREA describe, DATA, NOINIT
; Create dummy variable used to locate bottom of flash
FlashBase SPACE 1
AREA reset, CODE, READONLY
;------------------------------------------------------------------------------
;- Define the entry point
;------------------------
EXPORT __ENTRY
__ENTRY
;------------------------------------------------------------------------------
;- Exception vectors ( before Remap )
;------------------------------------
;- These vectors are read at address 0.
;- They absolutely requires to be in relative addresssing mode in order to
;- guarantee a valid jump. For the moment, all are just looping (what may be
;- dangerous in a final system). If an exception occurs before remap, this
;- would result in an infinite loop.
;------------------------------------------------------------------------------
LDR PC, Reset_Addr ; reset
LDR PC, Undefined_Addr ; Undefined Instruction
LDR PC, SWI_Addr ; Software Interrupt
LDR PC, Prefetch_Addr ; Prefetch Abort
LDR PC, Abort_Addr ; Data Abort
LDR PC, Reserve_Addr ; Reserved vector
LDR PC, [PC,#-&F20] ; IRQ : read the AIC
LDR PC, FIQ_Addr ; FIQ
Reset_Addr DCD Reset_Handler
Undefined_Addr DCD Undefined_Handler
SWI_Addr DCD SWI_Handler
Prefetch_Addr DCD Prefetch_Handler
Abort_Addr DCD Abort_Handler
Reserve_Addr DCD Reserve_Handler
FIQ_Addr DCD FIQ_Handler
;-------------------
;- The reset handler
;-------------------
Reset_Handler
;------------------------------------------------------------------------------
;- Setup the stack for each mode
;-------------------------
;- The processor will remain in the last initialized mode.
;------------------------------------------------------------------------------
mov r0, #Mode_SVC:OR:I_Bit:OR:F_Bit ;no interrupts
msr CPSR_c, r0
ldr r13, =SVC_Stack ;set SVC mode STACK.
mov r0, #Mode_IRQ:OR:I_Bit:OR:F_Bit ;no interrupts
msr CPSR_c, R0
ldr r13, =IRQ_Stack ;set IRQ mode stack.
mov r0, #Mode_SYS:OR:I_Bit:OR:F_Bit ;no interrupts
msr CPSR_c, r0
ldr r13, =SYS_Stack ;set SYS mode STACK.
mov r0, #Mode_ABT:OR:I_Bit:OR:F_Bit ;no interrupts
msr CPSR_c, r0
ldr r13, =ABT_Stack ;set ABT mode STACK.
mov r0, #Mode_FIQ:OR:I_Bit:OR:F_Bit ;no interrupts
msr CPSR_c, r0
ldr r13, =FIQ_Stack ;set FIQ mode STACK.
mov r0, #Mode_UND:OR:I_Bit:OR:F_Bit ;no interrupts
msr CPSR_c, r0
ldr r13, =UND_Stack ;set UND mode STACK.
mov r0, #Mode_SVC:OR:I_Bit:OR:F_Bit ;no interrupts
msr CPSR_c, r0
;------------------------------------------------------------------------------
;- Low level Init is performed in a C function: AT91F_LowLevelInit (APMC, AIC, EBI, ....)
;- Init Stack Pointer to a valid memory area before calling AT91F_LowLevelInit
;----------------------------------------------------------------------
IMPORT AT91F_BSPInit
ldr r0, = AT91F_BSPInit
mov r1,pc
ands r1,r1,#0xf0000000
ldreq r1, = SdramBase
ldreq r2, = FlashBase
subeq r0,r0,r1 ;sub addr at flash = addr - sdram + flash
addeq r0,r0,r2
mov lr, pc
bx r0
;------------------------------------------------------------------------------
;- copy code to sdram
;------------------------
IMPORT |Image$$RO$$Length|
IMPORT |Image$$RW$$Length|
mov r3,pc
ands r3,r3,#0xf0000000
ldrne pc,=copy_end
ldreq r0,= |Image$$RO$$Length|
addeq r0,r0,#|Image$$RW$$Length|
mov r4,#0
copy_loop
cmp r4,r0
ldrne r3,[r2],#4
strne r3,[r1],#4
addne r4,r4,#1
bne copy_loop
copy_loop_end
ldr pc,=copy_end
copy_end
;------------------------------------------------------------------------------
;- clear internal ram
;------------------------
ldr r0,= RAM_BASE
mov r1,#0
mov r2,r0
add r2,r2,#4*1024
clr_loop
cmp r0,r2
strne r1,[r0],#4
bne clr_loop
;------------------------------------------------------------------------------
;- Initialise vactor
;------------------------
ldr r0,= RAM_BASE
ldr r1,= FlashBase
mov r2,r0
add r2,r2,#15*4
copy_vactor
cmp r0,r2
ldrne r3,[r1],#4
strne r3,[r0],#4
bne copy_vactor
;------------------------------------------------------------------------------
;- remap
;------------------------
ldr r0,= MC_MCR
mov r1,#1
str r1,[r0]
IMPORT |Image$$ZI$$Length|
ldr r0,= |Image$$ZI$$Length|
; --- initialize memory required by C code
IMPORT |Image$$RO$$Limit| ;end of ROM code (=start of ROM data)
IMPORT |Image$$RW$$Base| ;base of RAM to initialize
IMPORT |Image$$ZI$$Base| ;base and limit of area
IMPORT |Image$$ZI$$Limit| ;to zero initialize
ldr r0,=|Image$$RO$$Limit| ;get pointer to ROM data
ldr r1,=|Image$$RW$$Base| ;and RAM copy
ldr r3,=|Image$$ZI$$Base| ;zero init base => top of initialized data
cmp r0,r1 ;check that they are different
beq %F1
0 cmp r1,r3 ;copy init data
ldrcc r2,[r0],#4
strcc r2,[r1],#4
bcc %B0
1 ldr r1,=|Image$$ZI$$Limit| ;top of zero init segment
mov r2,#0
2 cmp r3,r1 ;zero init
strcc r2,[r3],#4
bcc %B2
;------------------------------------------------------------------------------
;- Branch on C code Main function (with interworking)
;----------------------------------------------------
; --- now enter the C code
IMPORT C_Entry
ldr r0,=C_Entry
mov lr,pc
bx r0 ;branch to C_Entry function.
;------------------------------------------------------------------------------
;- Loop for ever
;---------------
;- End of application. Normally, never occur.
;- Could jump on Software Reset ( B 0x0 ).
;------------------------------------------------------------------------------
End
b End
Undefined_Handler
ldr r0,=dwUndefCnt
mov r2,r14
b Error_end
SWI_Handler
Prefetch_Handler
ldr r0,=dwPrefCnt
sub r2,r14,#4
b Error_end
Abort_Handler
ldr r0,=dwAbortCnt
sub r2,r14,#8
b Error_end
Reserve_Handler
ldr r0,=dwAbortCnt
sub r2,r14,#8
b Error_end
FIQ_Handler
ldr r0,=dwAbortCnt
sub r2,r14,#8
b Error_end
Error_end
ldr r1,[r0]
add r1,r1,#1
str r1,[r0]
mov r0, #Mode_SVC:OR:I_Bit:OR:F_Bit ;no interrupts
msr CPSR_c, r0
b Reset_Handler
EXPORT StackData
StackData
DCD IRQ_Stack
DCD SYS_Stack
DCD SVC_Stack
DCD USR_Stack
DCD FIQ_Stack
DCD ABT_Stack
DCD UND_Stack
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -