📄 cstartup.s
字号:
.extern at91_default_fiq_handler
.extern at91_default_irq_handler
.extern at91_spurious_handler
PtDefaultHandler:
.long at91_default_fiq_handler
.long at91_default_irq_handler
.long 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 */
add r9, pc,#-(8+.-VectorTable) /* @ where to read values (relative) */
ldmia r9!, {r0-r7} /* read 8 vectors */
.IFDEF SEMIHOSTING /* SWI it used to Ssemihosting features */
stmia r8!, {r0-r1} /* store SoftReset ,UndefHandler */
add r8, r8,#4 /* r2 = SWIHandler used for semihosting */
stmia r8!, {r3-r7} /* store SoftReset ,UndefHandler */
.ELSE /* Without SEMIHOSTING */
stmia r8!, {r0-r7} /* store them */
.ENDIF /* End SEMIHOSTING */
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:
.long 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.
#;------------------------------------------------------------------------------
.EQU IRQ_STACK_SIZE, (3*8*4) /* 3 words per interrupt priority level */
.EQU FIQ_STACK_SIZE, (3*4) /* 3 words */
.EQU ABT_STACK_SIZE, (1*4) /* 1 word */
.EQU UND_STACK_SIZE, (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.
#;------------------------------------------------------------------------------
.EQU TOP_APPLICATION_STACK, 0x2040000 /* Defined in Target */
#;------------------------------------------------------------------------------
#;- Setup the stack for each mode
#;-------------------------------
ldr r2, =SF_BASE /* Get the SF_BASE.SF_CIDR */
ldr r2, [R2,#SF_CIDR]
ldr r1, =SF_VDSIZ_MASK_SHIFT /* Get Mask Ram size */
and r0,R1,R2, lsr #6 /* Get the Internal Ram size */
#;- Set up Fast Interrupt Mode and set FIQ Mode Stack
msr CPSR_c, #ARM_MODE_FIQ | I_BIT | 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 | I_BIT | 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 | I_BIT | 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 | I_BIT | 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 | I_BIT | F_BIT
mov r13, r0 /* Init stack Sup */
#;------------------------------------------------------------------------------
#;- 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).
#;------------------------------------------------------------------------------
msr CPSR_c, #ARM_MODE_USER /* set User mode */
ldr r13, =TOP_APPLICATION_STACK /* Init stack User */
#;------------------------------------------------------------------------------
#;- 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
.IFDEF SEMIHOSTING
#;------------------------------------------------------------------------------
#;- Branch on Entry point
#;- ---------------------
#;- Allows semihosting initialisation
#;- you must be set the semihosting debugger for ARM SDT :$top_of_memory = ...
#;- for Aspex :top_memory = ... in bcd board description
#;------------------------------------------------------------------------------
.extern __entry
.EQU SEMIHOSTING_STACK_SIZE, (8*1024)
ldr r0, = SEMIHOSTING_STACK_SIZE
sub r13, r13,r0
b __entry
.ELSE /* not use SEMIHOSTING */
#;------------------------------------------------------------------------------
#;- 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
.ENDIF /* endif SEMIHOSTING */
#;------------------------------------------------------------------------------
#;- Loop for ever
#;---------------
#;- End of application. Normally, never occur.
#;- Could jump on Software Reset ( B 0x0 ).
#;------------------------------------------------------------------------------
End:
b End
#; Call __low_level_init to perform initialization before initializing
#; AIC and calling main.
#; Pll Initialization
#;----------------------------------------------------------------------
__low_level_init:
#;- Speed up the System Frequency.
#;---------------------------------
ldr r0, =0x002F0002 /* MOSCEN = 1, OSCOUNT = 47 (1.4ms/30祍) */
ldr r1, =APMC_BASE /* Get the APMC Base Address */
str r0, [r1, #APMC_CGMR] /* Store the configuration of the Clock Generator */
#;- Reading the APMC Status register to detect when the oscillator is stabilized
#;------------------------------------------------------------------------------
mov r4, #APMC_MOSCS
MoscsLoop:
ldr r2, [r1, #APMC_SR]
and r2, r4,r2
cmp r2, #APMC_MOSCS
bne MoscsLoop
#;- Commuting from Slow Clock to Main Oscillator (16Mhz)
#;------------------------------------------------------
ldr r0, =0x002F4002 /* MOSCEN = 1, OSCOUNT = 47 (1.4ms/30祍) */
str r0, [r1, #APMC_CGMR] /* Store the configuration of the Clock Generator */
#;-Setup the PLL
#;---------------
ldr r0, =0x032F4102 /* MUL = 1, PLLCOUNT = 3, CSS = 1 */
str r0, [r1, #APMC_CGMR] /* Store the configuration of the Clock Generator */
#;- Reading the APMC Status register to detect when the PLL is stabilized
#;-----------------------------------------------------------------------
mov r4, #APMC_PLL_LOCK
Pll_Loop:
ldr r3, [r1, #APMC_SR]
and r3, r4,r3
cmp r3, #APMC_PLL_LOCK
bne Pll_Loop
#;- Commuting from 16Mhz to PLL @ 32MHz
#;--------------------------------------
ldr r0, =0x032F8102 /* CSS = 2, MUL = 1 */
str r0, [r1, #APMC_CGMR] /* Store the configuration of the Clock Generator */
#;- Now the Master clock is the output of PLL @ 32MHz
#;----------------------------------------------------
mov pc,r14 /* Return */
.global __gccmain
__gccmain:
mov pc, lr
# END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -