📄 cstartup_ice.arm
字号:
;- by the boot function.
;------------------------------------------------------------------------------
;- Load System EBI Base address and CSR0 Init Value
ldr r0, PtEBIBase
ldr r1, [pc,#-(8+.-InitTableEBI)] ; values (relative)
;- Speed up code execution by disabling wait state on Chip Select 0
str r1, [r0]
;------------------------------------------------------------------------------
;- low level init
;----------------
; Call __low_level_init to perform initialization before initializing
; AIC and calling main.
;----------------------------------------------------------------------
bl __low_level_init
;------------------------------------------------------------------------------
;- Reset the Interrupt Controller
;--------------------------------
;- Normally, the code is executed only if a reset has been actually performed.
;- So, the AIC initialization resumes at setting up the default vectors.
;------------------------------------------------------------------------------
;- Load the AIC Base Address and the default handler addresses
add r0, pc,AicData-8-. ; @ where to read values (relative)
ldmia r0, {r1-r4}
;- Setup the Spurious Vector
str r4, [r1, #AIC_SPU] ; r4 = spurious handler
;- ICE note : For ICE debug
;- Perform 8 End Of Interrupt Command to make sure AIC will not lock out nIRQ
mov r0, #8
LoopAic0
str r1, [r1, #AIC_EOICR] ; any value written
subs r0, r0, #1
bhi LoopAic0
;- Set up the default interrupt handler vectors
str r2, [r1, #AIC_SVR] ; SVR[0] for FIQ
add r1, r1, #AIC_SVR
mov r0, #31 ; counter
LoopAic1
str r3, [r1, r0, LSL #2] ; SVRs for IRQs
subs r0, r0, #1 ; do not save FIQ
bhi LoopAic1
b EndInitAic
;- Default Interrupt Handlers
AicData
DCD AIC_BASE ; AIC Base Address
;------------------------------------------------------------------------------
;- Default Interrupt Handler
;---------------------------
;- These function are defined in the AT91 library. If you want to change this
;- you can redifine these function in your appication code
;------------------------------------------------------------------------------
IMPORT at91_default_fiq_handler
IMPORT at91_default_irq_handler
IMPORT at91_spurious_handler
PtDefaultHandler
DCD at91_default_fiq_handler
DCD at91_default_irq_handler
DCD at91_spurious_handler
EndInitAic
;------------------------------------------------------------------------------
;- Setup Exception Vectors in Internal RAM before Remap
;------------------------------------------------------
;- That's important to perform this operation before Remap in order to guarantee
;- that the core has valid vectors at any time during the remap operation.
;- Note: There are only 5 offsets as the vectoring is used.
;- ICE note : In this code only the start address value is changed if you use
;- without Semihosting.
;- Before Remap the internal RAM it's 0x300000
;- After Remap the internal RAM it's 0x000000
;- Remap it's already executed it's no possible to write to 0x300000.
;------------------------------------------------------------------------------
;- Copy the ARM exception vectors
; The RAM_BASE = 0 it's specific for ICE
mov r8,#RAM_BASE ; @ of the hard vector after remap in internal RAM 0x0
sub r9, pc,8+.-VectorTable ; @ where to read values (relative)
ldmia r9!, {r0-r7} ; read 8 vectors
stmia r8!, {r0-r7} ; store them
ldmia r9!, {r0-r4} ; read 5 absolute handler addresses
stmia r8!, {r0-r4} ; store them
;------------------------------------------------------------------------------
;- Initialise the Memory Controller
;----------------------------------
;- That's principaly the Remap Command. Actually, all the External Bus
;- Interface is configured with some instructions and the User Interface Image
;- as described above. The jump "mov pc, r12" could be unread as it is after
;- located after the Remap but actually it is thanks to the Arm core pipeline.
;- The IniTableEBI addressing must be relative .
;- The PtInitRemap must be absolute as the processor jumps at this address
;- immediatly after the Remap is performed.
;- Note also that the EBI base address is loaded in r11 by the "ldmia".
;- ICE note :For ICE debug these values already set by the boot function and the
;- Remap it's already executed it's no need to set still.
;------------------------------------------------------------------------------
;- Copy the Image of the Memory Controller
sub r10, pc,#(8+.-InitTableEBI) ; get the address of the chip select register image
ldr r12, PtInitRemap ; get the real jump address ( after remap )
;- Copy Chip Select Register Image to Memory Controller and command remap
ldmia r10!, {r0-r9,r11} ; load the complete image and the EBI base
stmia r11!, {r0-r9} ; store the complete image with the remap command
;- Jump to ROM at its new address
mov pc, r12 ; jump and break the pipeline
PtInitRemap
DCD InitRemap ; address where to jump after REMAP
;------------------------------------------------------------------------------
;- The Reset Handler after Remap
;-------------------------------
;- From here, the code is continous execute from its link address.
;------------------------------------------------------------------------------
InitRemap
;------------------------------------------------------------------------------
;- Stack Sizes Definition
;------------------------
;- Interrupt Stack requires 3 words x 8 priority level x 4 bytes when using
;- the vectoring. This assume that the IRQ_ENTRY/IRQ_EXIT macro are used.
;- The Interrupt Stack must be adjusted depending on the interrupt handlers.
;- Fast Interrupt is the same than Interrupt without priority level.
;- Other stacks are defined by default to save one word each.
;- The System stack size is not defined and is limited by the free internal
;- SRAM.
;- User stack size is not defined and is limited by the free external SRAM.
;------------------------------------------------------------------------------
IRQ_STACK_SIZE EQU (3*8*4) ; 3 words per interrupt priority level
FIQ_STACK_SIZE EQU (3*4) ; 3 words
ABT_STACK_SIZE EQU (1*4) ; 1 word
UND_STACK_SIZE EQU (1*4) ; 1 word
;------------------------------------------------------------------------------
;- Top of Stack Definition
;-------------------------
;- Fast Interrupt, Interrupt, Abort, Undefined and Supervisor Stack are located
;- at the top of internal memory in order to speed the exception handling
;- context saving and restoring.
;- User (Application, C) Stack is located at the top of the external memory.
;------------------------------------------------------------------------------
TOP_EXCEPTION_STACK EQU RAM_LIMIT ; Defined in part
TOP_APPLICATION_STACK EQU EXT_SRAM_LIMIT ; Defined in Target
;------------------------------------------------------------------------------
;- Setup the stack for each mode
;-------------------------------
ldr r0, =TOP_EXCEPTION_STACK
;- Set up Fast Interrupt Mode and set FIQ Mode Stack
msr CPSR_c, #ARM_MODE_FIQ:OR:I_BIT:OR:F_BIT
mov r13, r0 ; Init stack FIQ
sub r0, r0, #FIQ_STACK_SIZE
;- Set up Interrupt Mode and set IRQ Mode Stack
msr CPSR_c, #ARM_MODE_IRQ:OR:I_BIT:OR:F_BIT
mov r13, r0 ; Init stack IRQ
sub r0, r0, #IRQ_STACK_SIZE
;- Set up Abort Mode and set Abort Mode Stack
msr CPSR_c, #ARM_MODE_ABORT:OR:I_BIT:OR:F_BIT
mov r13, r0 ; Init stack Abort
sub r0, r0, #ABT_STACK_SIZE
;- Set up Undefined Instruction Mode and set Undef Mode Stack
msr CPSR_c, #ARM_MODE_UNDEF:OR:I_BIT:OR:F_BIT
mov r13, r0 ; Init stack Undef
sub r0, r0, #UND_STACK_SIZE
;- Set up Supervisor Mode and set Supervisor Mode Stack
msr CPSR_c, #ARM_MODE_SVC:OR:I_BIT:OR:F_BIT
mov r13, r0 ; Init stack Sup
sub r0, r0, #UND_STACK_SIZE
;------------------------------------------------------------------------------
;- Setup Application Operating Mode and Enable the interrupts
;------------------------------------------------------------
;- System Mode is selected first and the stack is setup. This allows to prevent
;- any interrupt occurence while the User is not initialized. System Mode is
;- used as the interrupt enabling would be avoided from User Mode (CPSR cannot
;- be written while the core is in User Mode).
;------------------------------------------------------------------------------
.weak __ghsend_stack
.weak __ghsbegin_heap
msr CPSR_c, #ARM_MODE_USER ; set User mode
ldr R13, =__ghsend_stack
;- intialise the heap
ldr r12, =__ghsbegin_heap ; Get pointer to top of romdata
;------------------------------------------------------------------------------
;- Initialise C variables
;------------------------------------------------------------------------------
;- Clear BSS (zero init)
;- ----------------------
.weak __ghsbegin_bss
.weak __ghsend_bss
ldr r1, =__ghsend_bss ; Get pointer to top of BSS
ldr r3, =__ghsbegin_bss ; Bottom of BSS
mov r2, 0
LoopZI
cmp r3, r1
strcc r2, [r3], 4
bcc LoopZI
;- Clear SBSS (zero init)
;- ----------------------
.weak __ghsbegin_sbss
.weak __ghsend_sbss
ldr r1, =__ghsend_sbss ; Get pointer to top of SBSS
ldr r3, =__ghsbegin_sbss ; Bottom of SBSS
mov r2, 0
LoopZI2
cmp r3, r1
strcc r2, [r3], 4
bcc LoopZI2
;- Copy Initialized data from FLASH to RAM
;- ---------------------------------------
.weak __ghsbegin_data
.weak __ghsend_data
.weak __ghsbegin_romdata
ldr r0, =__ghsbegin_romdata ; Get pointer to top of romdata
ldr r1, =__ghsbegin_data ; Get pointer to top of data
ldr r3, =__ghsend_data ; Get pointer to bottom of data
LoopRW
cmp r1, r3
ldrcc r2, [r0], 4
strcc r2, [r1], 4
bcc LoopRW
;------------------------------------------------------------------------------
;- 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
;------------------------------------------------------------------------------
IMPORT main
ldr r0, =main
mov lr, pc
bx r0
;------------------------------------------------------------------------------
;- Loop for ever
;---------------
;- End of application. Normally, never occur.
;- Could jump on Software Reset ( B 0x0 ).
;------------------------------------------------------------------------------
End_loop
b End_loop
;----------------------------------------------------------------------
; Call __low_level_init to perform initialization before initializing
; AIC and calling main.
; Enable all peripherial clock
; The peripheral clocks are automatically enabled after a reset.
;----------------------------------------------------------------------
__low_level_init
mvn r0,#0 ; R0<- 0xFFFFFFFF
ldr r1,=PS_BASE ; Get Power saving configuartion
str r0,[r1, #PS_PCER] ; Enable all peripherial clock
mov pc,r14
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -