📄 cstartup.s
字号:
;------------------------------------------------------------------------------
;;#------------------------------------------------------------------------------
INCLUDE AT91SAM7X256.inc
RamEnd EQU 0x00210000
;;#------------------------------------------------------------------------------
;;#- Area Definition
;;#------------------------------------------------------------------------------
;;#---------------------------------------------------------------
;;# ?RESET
;;# Reset Vector.
;;# Normally, segment INTVEC is linked at address 0.
;;# For debugging purposes, INTVEC may be placed at other
;;# addresses.
;;# A debugger that honors the entry point will start the
;;# program in a normal way even if INTVEC is not at address 0.
;;#-------------------------------------------------------------
IMPORT OS_CPU_IRQ_ISR
;.text
;;# PROGRAM ?RESET
;;# RSEG INTRAMSTART_REMAP
;;# RSEG INTRAMEND_REMAP
;;# RSEG ICODE:CODE:ROOT(2)
; CODE 32 /*; Always ARM mode after reset*/
;;# org 0
AREA reset, CODE, READONLY
;ENTRY
;EXPORT entry
entry
;;#------------------------------------------------------------------------------
;;#- Exception vectors
;;#--------------------
;;#- These vectors can be read at address 0 or at RAM address
;;#- They ABSOLUTELY requires to be in relative addresssing mode in order to
;;#- guarantee a valid jump. For the moment, all are just looping.
;;#- If an exception occurs before remap, this would result in an infinite loop.
;;#- To ensure if a exeption occurs before start application to infinite loop.
;;#------------------------------------------------------------------------------
re_set
B InitReset ;/* 0x00 Reset handler*/
undefvec
B undefvec ;/* 0x04 Undefined Instruction */
swivec
B swivec ;/* 0x08 Software Interrupt*/
pabtvec
B pabtvec ;/* 0x0C Prefetch Abort*/
dabtvec
B dabtvec ;/* 0x10 Data Abort*/
rsvdvec
B rsvdvec ;/* 0x14 reserved*/
irqvec
;ldr pc, [pc,#-0xF20] ; IRQ : read the AIC
ldr pc,=OS_CPU_IRQ_ISR
fiqvec ;/* 0x1c FIQ*/
;;#------------------------------------------------------------------------------
;;#- Function : FIQ_Handler_Entry
;;#- Treatments : FIQ Controller Interrupt Handler.
;;#- Called Functions : AIC_FVR[interrupt]
;;#------------------------------------------------------------------------------
FIQ_Handler_Entry
;#- Switch in SVC/User Mode to allow User Stack access for C code
;;# because the FIQ is not yet acknowledged
;;;#;#- Save and r0 in FIQ_Register
mov r9, r0
ldr r0, [r8, #AIC_FVR]
msr CPSR_c, #I_BIT | F_BIT | ARM_MODE_SVC
;#- Save scratch/used registers and LR in User Stack
stmfd sp!, { r1-r3, r12, lr}
;#- Branch to the routine pointed by the AIC_FVR
mov r14, pc
bx r0
;#- Restore scratch/used registers and LR from User Stack
ldmia sp!, { r1-r3, r12, lr}
;#- Leave Interrupts disabled and switch back in FIQ mode
msr CPSR_c, #I_BIT | F_BIT | ARM_MODE_FIQ
;#- Restore the R0 ARM_MODE_SVC register
mov r0,r9
;#- Restore the Program Counter using the LR_fiq directly in the PC
subs pc,lr,#4
InitReset
;#------------------------------------------------------------------------------
;#- configure the reset mode register . user reset enable
;#------------------------------------------------------------------------------
ldr r0,=0xFFFFFD08
ldr r1,=0xa5000001
str r1,[r0]
;#------------------------------------------------------------------------------
;#- Low level Init (PMC, AIC, ? ....) by C function AT91F_LowLevelInit
;#------------------------------------------------------------------------------
EXTERN AT91F_LowLevelInit
;#define __iramend SFB(INTRAMEND_REMAP)
;#- minumum C initialization
;#- call AT91F_LowLevelInit( void)
ldr r13,=RamEnd ; temporary stack in internal RAM*/
;#--Call Low level init function in ABSOLUTE through the Interworking
ldr r0,=AT91F_LowLevelInit
mov lr, pc
bx r0
;#------------------------------------------------------------------------------
;#- Stack Sizes Definition
;#------------------------
;#- Interrupt Stack requires 2 words x 8 priority level x 4 bytes when using
;#- the vectoring. This assume that the IRQ management.
;#- The Interrupt Stack must be adjusted depending on the interrupt handlers.
;#- Fast Interrupt not requires stack If in your application it required you must
;#- be definehere.
;#- The System stack size is not defined and is limited by the free internal
;#- SRAM.
;#------------------------------------------------------------------------------
;#------------------------------------------------------------------------------
;#- Top of Stack Definition
;#-------------------------
;#- Interrupt and Supervisor Stack are located at the top of internal memory in
;#- order to speed the exception handling context saving and restoring.
;#- ARM_MODE_SVC (Application, C) Stack is located at the top of the external memory.
;#------------------------------------------------------------------------------
IRQ_STACK_SIZE equ (2*8*64)
;2 words per interrupt priority level
ARM_MODE_USER EQU 0x10
ARM_MODE_FIQ EQU 0x11
ARM_MODE_IRQ EQU 0x12
ARM_MODE_SVC EQU 0x13
ARM_MODE_ABORT EQU 0x17
ARM_MODE_UNDEF EQU 0x1B
ARM_MODE_SYS EQU 0x1F
I_BIT equ 0x80
F_BIT equ 0x40
;#------------------------------------------------------------------------------
;#- Setup the stack for each mode
;#-------------------------------
ldr r0, =RamEnd
;#- Set up Fast Interrupt Mode and set FIQ Mode Stack
msr CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT
;#- Init the FIQ register
ldr r8, =AT91C_BASE_AIC
;#- Set up Interrupt Mode and set IRQ Mode Stack
msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT
mov r13, r0 ; Init stack IRQ*/
sub r0, r0, #IRQ_STACK_SIZE
;#- Enable interrupt & Set up Supervisor Mode and set Supervisor Mode Stack
msr CPSR_c, #ARM_MODE_SVC
mov r13, r0
;#---------------------------------------------------------------
;# ?CSTARTUP
;#---------------------------------------------------------------
;# .EXTERN __segment_init
;# Initialize segments.
;# __segment_init is assumed to use
;# instruction set and to be reachable by BL from the ICODE segment
;# (it is safest to link them in segment ICODE).
;# ldr r0,=__segment_init
;# mov lr, pc
;# bx 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 main
global __main
jump_to_main
ldr lr,=call_exit
ldr r0,=main
__main
bx r0
;#------------------------------------------------------------------------------
;#- Loop for ever
;#---------------
;#- End of application. Normally, never occur.
;#- Could jump on Software Reset ( B 0x0 ).
;#------------------------------------------------------------------------------
call_exit
End
b End
;#------------------------------------------------------------------------------
;#- Manage exception
;#---------------
;#- This module The exception must be ensure in ARM mode
;#------------------------------------------------------------------------------
;#------------------------------------------------------------------------------
;#- Function : IRQ_Handler_Entry
;#- Treatments : IRQ Controller Interrupt Handler.
;#- Called Functions : AIC_IVR[interrupt]
;#------------------------------------------------------------------------------
IRQ_Handler_Entry
;#- Manage Exception Entry
;#- Adjust and save LR_irq in IRQ stack
sub lr, lr, #4
stmfd sp!, {lr}
;#- Save and r0 in IRQ stack
stmfd sp!, {r0}
;#- Write in the IVR to support Protect Mode
;#- No effect in Normal Mode
;#- De-assert the NIRQ and clear the source in Protect Mode
ldr r14, =AT91C_BASE_AIC
ldr r0 , [r14, #AIC_IVR]
str r14, [r14, #AIC_IVR]
;#- Enable Interrupt and Switch in Supervisor Mode
msr CPSR_c, #ARM_MODE_SVC
;#- Save scratch/used registers and LR in User Stack
stmfd sp!, { r1-r3, r12, r14}
;#- Branch to the routine pointed by the AIC_IVR
mov r14, pc
bx r0
;#- Restore scratch/used registers and LR from User Stack
ldmia sp!, { r1-r3, r12, r14}
;#- Disable Interrupt and switch back in IRQ mode
msr CPSR_c, #I_BIT | ARM_MODE_IRQ
;#- Mark the End of Interrupt on the AIC
ldr r14, =AT91C_BASE_AIC
str r14, [r14, #AIC_EOICR]
;#- Restore SPSR_irq and r0 from IRQ stack
ldmia sp!, {r0}
;#- Restore adjusted LR_irq from IRQ stack directly in the PC
ldmia sp!, {pc}^
reinter mov r2,#AT91C_ISRAM
mov r3,#0
rein ldr r1,[r3]
str r1,[r2]
add r3,r3,#1
cmp r3,#4
bne rein
;#---------------------------------------------------------------
;# ?EXEPTION_VECTOR
;# This module is only linked if needed for closing files.
;#---------------------------------------------------------------
global AT91F_Default_FIQ_handler
global AT91F_Default_IRQ_handler
global AT91F_Spurious_handler
;CODE 32 /*; Always ARM mode after exeption*/
AT91F_Default_FIQ_handler
b AT91F_Default_FIQ_handler
AT91F_Default_IRQ_handler
b AT91F_Default_IRQ_handler
AT91F_Spurious_handler
b AT91F_Spurious_handler
;# ENDMOD
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -