📄 init.s
字号:
BL a7hal_icu_abortMain ; call the C handler
ENDIF
LDMIA SP!,{R0-IP,PC}^ ; restore the registers
;
; SWI Wrapper saves all of the registers and
; branches to the 'C' routine to handle the
; interrupt.
;
IMPORT a7hal_icu_swiMain
SWI_Wrapper
SUB LR,LR,#4
STMFD SP!,{R0-R12,LR} ; Store all of the registers
MRS v1,SPSR
STMFD SP!,{v1}
LDR R0,[LR]
BIC R0,R0,#0xff000000
LDR R1,=a7hal_icu_swiMain
LDR R1,[R1]
CMP R1,#0
MOVNE LR,PC
MOVNE PC,R1
LDMFD SP!,{v1}
MSR SPSR_cxfs,v1
LDMFD SP!,{R0-R12,PC}^ ; restore the registers
;
; IRQ Wrapper saves all of the registers and
; branches to the 'C' routine to handle the
; interrupt.
;
IMPORT a7hal_icu_isrMain
IMPORT a7hal_icu_fiqMain
IRQ_Wrapper
SUB LR,LR,#4
STMFD SP!,{R0-R12, LR} ; Store all of the registers
MRS v1,SPSR
STMFD SP!,{v1}
LDR a1,=a7hal_icu_IRQEnter
LDR a1,[a1]
CMP a1,#0
MOVNE lr,pc
MOVNE pc,a1
IF :DEF: __THUMB__
LDR R12,=a7hal_icu_isrMain
BL thumb_call
ELSE
BL a7hal_icu_isrMain ; call the C ISR
ENDIF
LDR a1,=a7hal_icu_IRQExit
LDR a1,[a1]
CMP a1,#0
MOVNE lr,pc
MOVNE pc,a1
LDMFD SP!,{v1}
MSR SPSR_cxfs,v1
LDMFD SP!,{R0-R12,PC}^ ; restore the registers
FIQ_Wrapper
SUB LR,LR,#4
STMFD SP!,{R0-R7, LR} ; Store all of the registers
MRS R4,SPSR
STMFD SP!,{v1}
IF :DEF: __THUMB__
LDR R12,=a7hal_icu_fiqMain
BL thumb_call
ELSE
BL a7hal_icu_fiqMain ; call the C ISR
ENDIF
LDMFD SP!,{v1}
MSR SPSR_cxfs,v1
LDMFD SP!,{R0-R7,PC}^ ; restore the registers
Start
;
; Set up the tempory SVC stack pointer
;
MOV R0, #Mode_SVC:OR:I_Bit:OR:F_Bit ; No interrupts
MSR CPSR_c, R0
LDR SP,= 0xd1030000 + 0x00004000
;
; We setup a tempory stack above
; so we can now call the SDRAM
; init function which is written
; in 'C'
;
IMPORT a7hal_sdram_init
IF :DEF: __THUMB__
LDR R12,=a7hal_sdram_init
BL thumb_call
ELSE
BL a7hal_sdram_init
ENDIF
MOV R0,#0x00000000
LDR R1,=__IMAGE_DEST_ADDRESS
CMP R0,R1
BEQ SkipCopy
LDR R2, =|Image$$RW$$ZI$$Base|
l
LDR R3,[R0],#4
STR R3,[R1],#4
CMP R0,R2
BLT l
SkipCopy
; Copy 16K from address 0x00000000 to the scratchpad
; at 0xd1030000, this works around the problem with
; the arm linker scripts where we cannot have a gap
; in the execution sections, they must be contiguous.
; Since scratchpad gets mapped to address 0x00000000
; and is 16K in size if we do not do this copy, it
; will overwrite code and the system will crash.
MOV R0,#0x00000000
LDR R1,=0xd1030000
LDR R2,=0x4000
l2
LDR R3,[R0],#4
STR R3,[R1],#4
CMP R0,R2
BLT l2
;
; Make sure we are running from the real FLASH
; address, not the FLASH alias address.
;
LDR R0,=__PHYSICAL_EXEC_ADDRESS
LDR R1,=HiAddress
ADD R0,R0,R1
MOV PC,R0
HiAddress
;
; Alias the external SDRAM to 0x00000000
;
; This should map the SDRAM only, but because we can
; not have non contigous code sections with the ARM
; compiler we have to map the internal SRAM to 0x00000000
; as well, else we hit problems when the power mode driver
; maps it to address 0x00000000.
LDR R0,=REMAP_ALIAS_ENABLE_REG
LDR R1,=__ALIAS_SETTING
STR R1,[r0,#0]
LDR PC, =LoAddress
LoAddress
; Now running from SDRAM at offset 0x00000000
;
; Initialise stack pointer
; Enter IRQ mode and set up the IRQ stack pointer
;
LDR R1,=__STACK_TOP
LDR R2,=__STACK_SIZE
MOV R0, #Mode_IRQ:OR:I_Bit:OR:F_Bit ; No interrupts
MSR CPSR_c, R0
MOV sp,r1
;
; Enter ABT mode and set up the ABT stack pointer
;
SUB r1,r1,r2
MOV R0, #Mode_ABT:OR:I_Bit:OR:F_Bit ; No interrupts
MSR CPSR_c, R0
MOV sp,r1
;
; Enter FIQ mode and set up the FIQ stack pointer
;
SUB r1,r1,r2
MOV R0, #Mode_FIQ:OR:I_Bit:OR:F_Bit ; No interrupts
MSR CPSR_c, R0
MOV sp,r1
;
; Set up the SVC stack pointer
;
SUB r1,r1,r2
MOV R0, #Mode_SVC:OR:I_Bit:OR:F_Bit ; No interrupts
MSR CPSR_c, R0
MOV SP,r1
;
; Change to user mode and set up user mode stack.
;
SUB r1,r1,r2
; MOV R0, #Mode_USR | F_Bit ; Enable IRQ
; MSR CPSR_c, R0
; MOV sp,r1
SUB r1,r1,r2
MOV sl,r1
;
; Initialise memory required by C code
;
LDR r0, =|Image$$.text$$Limit| ; Get pointer to ROM data
LDR r1, =|Image$$RW$$Base| ; and RAM copy
LDR r3, =|Image$$RW$$ZI$$Base| ; Zero init base to top of initialised data
CMP r0, r1 ; Check that they are different
BEQ L1
L0 CMP r1, r3 ; Copy init data
LDRCC r2, [r0], #4
STRCC r2, [r1], #4
BCC L0
L1
LDR r1, =|Image$$RW$$ZI$$Limit| ; Top of zero init segment
MOV r2, #0
L2 CMP r3, r1 ; Zero init
STRCC r2, [r3], #4
BCC L2
;
; Initialize any configured devices
;
IMPORT a7hal_driverInit
IF :DEF: __THUMB__
LDR R12,=a7hal_driverInit
BL thumb_call
ELSE
BL a7hal_driverInit
ENDIF
;
; Enable interrupts
; Now safe to enable interrupts.
; Enable interrupts and remain in SVC mode.
;
MOV R0, #Mode_SVC ; Enable IRQ
MSR CPSR_c, R0
;
; Jump to __rt_entry instead of __main, since __main will try to
; init the data sections again and overwrite the data structures
; setup in the above device init calls.
;
IF :LNOT: :DEF: _NO_C_LIB
IMPORT __rt_entry
B __rt_entry
ELSE
IMPORT main
B main
ENDIF
EXPORT __writeCPR
IF :DEF: __THUMB__
CODE16
__writeCPR
LDR R3,=skip1
BX R3
CODE32
skip1
ELSE
__writeCPR
ENDIF
CMP R0, #0
BNE reg1
MCR p15,0, R1, c0, c0
B done
reg1
CMP R0, #1
BNE reg2
MCR p15,0, R1, c1, c0
B done
reg2
CMP R0, #2
BNE reg3
MCR p15,0, R1, c2, c0
B done
reg3
CMP R0, #3
BNE reg4
MCR p15,0, R1, c3, c0
B done
reg4
CMP R0, #4
BNE reg5
MCR p15,0, R1, c4, c0
B done
reg5
CMP R0, #5
BNE reg6
MCR p15,0, R1, c5, c0
B done
reg6
CMP R0, #6
BNE reg7
MCR p15,0, R1, c6, c0
B done
reg7
CMP R0, #7
BNE done
MCR p15,0, R1, c7, c0
B done
EXPORT __readCPR
IF :DEF: __THUMB__
CODE16
__readCPR
LDR R3,=skip2
BX R3
CODE32
skip2
ELSE
__readCPR
ENDIF
CMP R0, #0
BNE readreg1
MRC p15,0, R0, c0, c0
MOV PC,LR
readreg1
CMP R0, #1
BNE readreg2
MRC p15,0, R0, c1, c0
B done
readreg2
CMP R0, #2
BNE readreg3
MRC p15,0, R0, c2, c0
B done
readreg3
CMP R0, #3
BNE readreg4
MRC p15,0, R0, c3, c0
B done
readreg4
CMP R0, #4
BNE readreg5
MRC p15,0, R0, c4, c0
B done
readreg5
CMP R0, #5
BNE readreg6
MRC p15,0, R0, c5, c0
B done
readreg6
CMP R0, #6
BNE readreg7
MRC p15,0, R0, c6, c0
B done
readreg7
CMP R0, #7
BNE readregdone
MRC p15,0, R0, c7, c0
readregdone
B done
EXPORT __writeCPRSub
IF :DEF: __THUMB__
CODE16
__writeCPRSub
LDR R3,=skip3
BX R3
CODE32
skip3
ELSE
__writeCPRSub
ENDIF
CMP R1, #0
BNE writesubreg1
MCR p15,0, R2, c6, c0
B done
writesubreg1
CMP R1, #1
BNE writesubreg2
MCR p15,0, R2, c6, c1
B done
writesubreg2
CMP R1, #2
BNE writesubreg3
MCR p15,0, R2, c6, c2
B done
writesubreg3
CMP R1, #3
BNE writesubreg4
MCR p15,0, R2, c6, c3
B done
writesubreg4
CMP R1, #4
BNE writesubreg5
MCR p15,0, R2, c6, c4
B done
writesubreg5
CMP R1, #5
BNE writesubreg6
MCR p15,0, R2, c6, c5
B done
writesubreg6
CMP R1, #6
BNE writesubreg7
MCR p15,0, R2, c6, c6
B done
writesubreg7
CMP R1, #7
BNE writesubdone
MCR p15,0, R2, c6, c7
writesubdone
B done
EXPORT __readCPRSub
IF :DEF: __THUMB__
CODE16
__readCPRSub
LDR R3,=skip4
BX R3
CODE32
skip4
ELSE
__readCPRSub
ENDIF
CMP R1, #0
BNE readsubreg1
MRC p15,0, R0, c6, c0
B done
readsubreg1
CMP R1, #1
BNE readsubreg2
MRC p15,0, R0, c6, c1
B done
readsubreg2
CMP R1, #2
BNE readsubreg3
MRC p15,0, R0, c6, c2
B done
readsubreg3
CMP R1, #3
BNE readsubreg4
MRC p15,0, R0, c6, c3
B done
readsubreg4
CMP R1, #4
BNE readsubreg5
MRC p15,0, R0, c6, c4
B done
readsubreg5
CMP R1, #5
BNE readsubreg6
MRC p15,0, R0, c6, c5
B done
readsubreg6
CMP R1, #6
BNE readsubreg7
MRC p15,0, R0, c6, c6
B done
readsubreg7
CMP R1, #7
BNE readsubdone
MRC p15,0, R0, c6, c7
readsubdone
B done
done
IF :DEF: __THUMB__
BX LR
ELSE
MOV PC,LR
ENDIF
IF :DEF: __THUMB__
CODE32
; The following function is used to call a THUMB function from ARM mode
; R0 contains the address of the 'C' subroutine to call.
thumb_call
STMDB SP!,{R0-IP,LR} ; Store all of the registers
LDR R3,=l3 ; Set up our return address into the LR
MOV LR,R3
BX R12 ; Call the THUMB function
CODE16
l3
LDR R3,=l1 ; This is where we will return to from the THUMB routine
; Setup our jump address to switch back into ARM mode
BX R3 ; Do the jump to ARM mode
CODE32
l1
LDMIA SP!,{R0-IP,PC} ; restore the registers and return
ENDIF
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -