📄 cstartup.s
字号:
/*********************************************************************************************
*文件: Startup.s
*公司: 深圳市英蓓特信息技术有限公司 http://www.embedinfo.com
*部门: 硬件研发部
*作者: 谢文辉 2005年04月06日
*说明: 启动代码
*注释:
*********************************************************************************************/
#7 work mode
.EQU ARM_MODE_USER, 0x10
.EQU ARM_MODE_FIQ, 0x11
.EQU ARM_MODE_IRQ, 0x12
.EQU ARM_MODE_SVC, 0x13
.EQU ARM_MODE_ABORT, 0x17
.EQU ARM_MODE_UNDEF, 0x1B
.EQU ARM_MODE_SYS, 0x1F
#interrupt shield bit
.EQU I_BIT, 0x80
.EQU F_BIT, 0x40
#state shield bit
.EQU T_BIT, 0x20
#Stack Area Definition
.EQU IRQ_STACK_SIZE, 0x100
.EQU FIQ_STACK_SIZE, 0x08 @0x4
.EQU ABT_STACK_SIZE, 0x08 @0x04
.EQU UND_STACK_SIZE, 0x08 @0x04
.EQU SVC_STACK_SIZE, 0x50
.EQU USER_STACK_SIZE, 0x400
.EQU EBI_RCR, 0xFFE00020
# Define the entry point
.globl _start
.code 32
.TEXT
_start:
Vectors:
LDR PC, Reset_Addr
LDR PC, Undef_Addr
LDR PC, SWI_Addr
LDR PC, PAbt_Addr
LDR PC, DAbt_Addr
NOP
LDR pc, [pc,#-0xF20]
LDR PC, FIQ_Addr
Reset_Addr:
.long Reset_Handler @ reset
Undef_Addr:
.long Undef_Handler @ Undefined Instruction
SWI_Addr:
.long SWI_Handler @ Software Interrupt
PAbt_Addr:
.long PAbt_Handler @ Prefetch Abort
DAbt_Addr:
.long DAbt_Handler @ Data Abort
.long 0
IRQ_Addr:
.long 0 @ IRQ : read the AIC
FIQ_Addr:
.long FIQ_Handler @ FIQ
Undef_Handler:
B Undef_Handler
PAbt_Handler:
B PAbt_Handler
DAbt_Handler:
B DAbt_Handler
SWI_Handler:
STMFD sp!, {r0-r3, r12, lr}
MOV r1, sp
MRS r0, spsr
TST r0, #T_BIT
LDRNEH r0, [lr,#-2]
BICNE r0, r0, #0xFF00
LDREQ r0, [lr,#-4]
BICEQ r0, r0, #0xFF000000
# R0 is interrupt NO.
# R1 is stack point
BL SWI_Exception
LDMFD sp!, {r0-r3, r12, pc}^
# FIQ_Handler code
FIQ_Handler:
STMFD SP!, {R0-R3, LR}
# BL FIQ_Exception
LDMFD SP!, {R0-R3, LR}
SUBS PC, LR, #4
# The reset handler
Reset_Handler:
# MOV R0, #0x00200000
# LDR R1, =Vectors
# LDMIA R1!, {R2-R9}
# STMIA R0!, {R2-R9}
# LDMIA R1!, {R2-R9}
# STMIA R0!, {R2-R9}
# LDR R0, =EBI_RCR
# MOV R1, #0x01
# STR R1, [R0]
# .extern AT91F_LowLevelInit
# ldr r1, = AT91_SVC_Stack_Begin
# bic r1, r1, #3 @ Insure word alignement
# mov sp, r1 @ Init stack SYS
# ldr r0, = AT91F_LowLevelInit
# mov lr, pc
# bx r0
# Setup the stack for each mode
# The processor will remain in the last initialized mode.
# Set up Supervisor Mode and set SVC Mode Stack
msr cpsr_c, #ARM_MODE_SVC|I_BIT|F_BIT
ldr r0, =AT91_SVC_Stack_Begin
bic r0, r0, #3
mov sp, r0
# Set up Interrupt Mode and set IRQ Mode Stack
msr CPSR_c, #ARM_MODE_IRQ|I_BIT|F_BIT
ldr r0, =AT91_IRQ_Stack_Begin
bic r0, r0, #3
mov sp, r0
# Set up Fast Interrupt Mode and set FIQ Mode Stack
msr CPSR_c, #ARM_MODE_FIQ|I_BIT|F_BIT
ldr r0, =AT91_FIQ_Stack_Begin
bic r0, r0, #3
mov sp, r0
# Set up Abort Mode and set Abort Mode Stack
msr CPSR_c, #ARM_MODE_ABORT|I_BIT|F_BIT
ldr r0, =AT91_ABT_Stack_Begin
bic r0, r0, #3
mov sp, r0
# Set up Undefined Instruction Mode and set Undef Mode Stack
msr CPSR_c, #ARM_MODE_UNDEF|I_BIT|F_BIT
ldr r0, =AT91_UND_Stack_Begin
bic r0, r0, #3
mov sp, r0
# Set up user Mode and set Undef Mode Stack
msr CPSR_c, #ARM_MODE_SYS|F_BIT
ldr r0, =AT91_USER_Stack_Begin
bic r0, r0, #3
mov sp, r0
#------------------------------------------------------------------------------
#- Initialise C variables
#------------------------
#- Following labels are automatically generated by the linker.
#- RO: Read-only = the code
#- RW: Read Write = the data pre-initialized and zero-initialized.
#- ZI: Zero-Initialized.
#- Pre-initialization values are located after the code area in the image.
#- Zero-initialized datas are mapped after the pre-initialized.
#- Note on the Data position :
#- If using the ARMSDT, when no -rw-base option is used for the linker, the
#- data area is mapped after the code. You can map the data either in internal
#- SRAM ( -rw-base=0x40 or 0x34) or in external SRAM ( -rw-base=0x2000000 ).
#- Note also that to improve the code density, the pre_initialized data must
#- be limited to a minimum.
#------------------------------------------------------------------------------
.extern Image_RO_Limit /* End of ROM code (=start of ROM data) */
.extern Image_RW_Base /* Base of RAM to initialise */
.extern Image_ZI_Base /* Base and limit of area */
.extern Image_ZI_Limit /* to zero initialise */
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 initialised data */
cmp r0, r1 /* Check that they are different */
beq NoRW
LoopRw: cmp r1, r3 /* Copy init data */
ldrcc r2, [r0], #4
strcc r2, [r1], #4
bcc LoopRw
NoRW: ldr r1, =Image_ZI_Limit /* Top of zero init segment */
mov r2, #0
LoopZI: cmp r3, r1 /* Zero init */
strcc r2, [r3], #4
bcc LoopZI
#------------------------------------------------------------------------------
#- Branch on C code Main function (with interworking)
#----------------------------------------------------
#- Branch must be performed by an interworking call as either an ARM or Thumb
#- main C function must be supported. This makes the code not position-
#- independant. A Branch with link would generate errors
#------------------------------------------------------------------------------
.extern Main
ldr r0, =Main
mov lr, pc
BX r0
End:
b End
# Swi interrupt code
SWI_Exception:
STMFD SP!, {R2-R3,LR}
CMP R0, #0
MRSEQ R2, SPSR
STREQ R2, [R1]
ORREQ R2, R2, #0x80
MSREQ SPSR_c, R2
CMP R0, #1
LDREQ R2, [R1]
MSREQ SPSR_c, R2
CMP R0, #11
MRSEQ R2, SPSR
BICEQ R2, R2, #0x1F
ORREQ R2, R2, #ARM_MODE_SYS
MSREQ SPSR_c, R2
CMP R0, #12
MRSEQ R2, SPSR
BICEQ R2, R2, #0x1F
ORREQ R2, R2, #ARM_MODE_USER
MSREQ SPSR_c, R2
LDMFD SP!, {R2-R3,PC}
.DATA
# IRQ stack definition
AT91_IRQ_Stack_End:
.FILL 1, 4, 0x55AA55AA
.SKIP (IRQ_STACK_SIZE - 4)
.EQU AT91_IRQ_Stack_Begin, (AT91_IRQ_Stack_End + (IRQ_STACK_SIZE - 4))
# FIQ stack definition
AT91_FIQ_Stack_End:
.FILL 1, 4, 0x55AA55AA
.SKIP (FIQ_STACK_SIZE - 4)
.EQU AT91_FIQ_Stack_Begin, (AT91_FIQ_Stack_End + (FIQ_STACK_SIZE - 4))
# ABORT stack definition
AT91_ABT_Stack_End:
.FILL 1, 4, 0x55AA55AA
.SKIP (ABT_STACK_SIZE - 4)
.EQU AT91_ABT_Stack_Begin, (AT91_ABT_Stack_End + (ABT_STACK_SIZE - 4))
# UNDEF stack definition
AT91_UND_Stack_End:
.FILL 1, 4, 0x55AA55AA
.SKIP (UND_STACK_SIZE - 4)
.EQU AT91_UND_Stack_Begin, (AT91_UND_Stack_End + (UND_STACK_SIZE - 4))
# SVC stack definition
AT91_SVC_Stack_End:
.FILL 1, 4, 0x55AA55AA
.SKIP (SVC_STACK_SIZE - 4)
.EQU AT91_SVC_Stack_Begin, (AT91_SVC_Stack_End + (SVC_STACK_SIZE-4))
# USER and SYSTEM stack definition
AT91_USER_Stack_End:
.FILL 1, 4, 0x55AA55AA
.SKIP (USER_STACK_SIZE - 4)
.EQU AT91_USER_Stack_Begin, (AT91_USER_Stack_End + (USER_STACK_SIZE-4))
.globl AT91_IRQ_Stack_End
.globl AT91_IRQ_Stack_Begin
.globl AT91_FIQ_Stack_End
.globl AT91_FIQ_Stack_Begin
.globl AT91_ABT_Stack_End
.globl AT91_ABT_Stack_Begin
.globl AT91_UND_Stack_End
.globl AT91_UND_Stack_Begin
.globl AT91_SVC_Stack_End
.globl AT91_SVC_Stack_Begin
.globl AT91_USER_Stack_End
.globl AT91_USER_Stack_Begin
.END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -