📄 init.s
字号:
;#line 1 "<stdin>"; $Id: ; ;#line 1 "C:\Triscend\SDK_3.0\Triscend\a7hal\include\hal_conf.h" ;#line 11 "<stdin>"Mode_USR EQU 0x10Mode_IRQ EQU 0x12Mode_SVC EQU 0x13Mode_ABT EQU 0x17Mode_FIQ EQU 0x11I_Bit EQU 0x80F_Bit EQU 0x40REMAP_ALIAS_ENABLE_REG EQU 0xd1010440MSS_SDR_CTRL_REG EQU 0xd101000cSYS_POWER_CTRL_REG EQU 0xd1010110SYS_CLOCK_CTRL_REG EQU 0xd1010100SYS_PLL_STATUS_REG EQU 0xd1010104SYS_PLL_STATUS_CLEAR_REG EQU 0xd1010108SYS_PLL_CONTROL_REG EQU 0xd1010114RMAP_PAUSE_REG EQU 0xd1010400 IMPORT |Image$$.text$$Limit| ; End of ROM code (=start of ROM data) IMPORT |Image$$RW$$Base| ; Base of RAM to initialise IMPORT |Image$$RW$$ZI$$Base| ; Base and limit of area IMPORT |Image$$RW$$ZI$$Limit| ; to zero initialise IMPORT __use_no_semihosting_swi IMPORT a7hal_icu_IRQExit IMPORT a7hal_icu_IRQEnter IMPORT __IMAGE_DEST_ADDRESS IMPORT __PHYSICAL_EXEC_ADDRESS IMPORT __ALIAS_SETTING IMPORT __STACK_TOP IMPORT __STACK_SIZE AREA vectors, CODE EXPORT __begin EXPORT _main EXPORT __vectorend EXPORT Hardware_Vector0 ENTRY_main__begin LDR PC,Start_AddrUdef B UdefSWI LDR PC, SWI_Wrapper_AddrPrefetch B PrefetchAbort LDR PC, Abort_Wrapper_AddrRes NOPIRQ LDR PC, IRQ_Wrapper_AddrFIQ LDR PC, FIQ_Wrapper_Addr; Hardware_Vector0 DCD 0Hardware_Vector1 DCD 0Hardware_Vector2 DCD 0Hardware_Vector3 DCD 0Hardware_Vector4 DCD 0Hardware_Vector5 DCD 0Hardware_Vector6 DCD 0Hardware_Vector7 DCD 0SWI_Wrapper_Addr DCD SWI_WrapperAbort_Wrapper_Addr DCD Abort_WrapperIRQ_Wrapper_Addr DCD IRQ_WrapperFIQ_Wrapper_Addr DCD FIQ_WrapperStart_Addr DCD Start ; ; Registers used by this function: ; v1 = interrupt status ; v2 = SDRAM_CTRL_REG ; v3 = CLOCK_CTRL_REG ; v4 = PLL_CONTROL_REG ; EXPORT _a7hal_power_lowPower_a7hal_power_lowPower STMDB SP!,{v1-v4} ; Save the registers we need to use ; ; Save the current interrupt status ; MRS v1,CPSR ; ; Disable interurpts, if this is not done, when we get the ; wakeup interrupt we will jump off to the IRQ vector instead of ; powering up the device. ; ORR R0,v1,#I_Bit | F_Bit MSR CPSR_c,R0 ; ; Save the value of the SDRAM control register. Then check ; to see if the SDRAM controller is enabled, if it is not ; enabled, there is no need to put the SDRAM into self-refresh. ; LDR R0,SDRAM_CTRL_REG LDR v2,[R0,#0] TST v2,#0x07 BEQ noSDRAMPowerDown ; ; Put the SDRAM into self refresh ; mode. ; BIC R1,v2,#0x07 ORR R1,R1,#0x00000004 STR R1,[R0,#0]noSDRAMPowerDown ; ; Save the value of the clock ; control register. ; LDR R0,CLOCK_CTRL_REG LDR v3,[R0,#0] ; ; Switch the clock to the ; internal ring oscillator ; MOV R1,#0 STR R1,[R0,#0] ; Power down LDR R0,POWER_DOWN_CTRL_REG MOV R1,#0x2f STR R1,[R0,#0] ORR R1,R1,#0x10 STR R1,[R0,#0] ; ; The CPU will continue from this ; point after it wakes up ; ; Check to see if we need to use the PLL ; if not branch over the PLL init code. ; TST v3,#0x01 BEQ noPLL ; ; Clear the PLL status register ; LDR R0,PLL_STATUS_CLEAR_REG MOV R1,#0x03 STR R1,[R0,#0] ; ; Restore the clock control reg. ; but do not use the PLL yet ; LDR R0,CLOCK_CTRL_REG BIC R1,v3,#0x01 STR R1,[R0,#0] ; ; Wait for the PLL Locked bit ; LDR R0,PLL_STATUS_REGlocked LDR R1,[R0,#0] ANDS R1,R1,#0x02 BEQ lockednoPLL ; ; Restore the clock control reg. ; LDR R0,CLOCK_CTRL_REG STR v3,[R0,#0] ; ; Restore the SDRAM control reg. ; TST v2,#0x07 BEQ noSDRAMDelay LDR R0,SDRAM_CTRL_REG STR v2,[R0,#0] ; ; Give the SDRAM time to enter normal mode ; before we change to the ring oscillator. ; LDR R1,SDRAM_DELAYsdram_delay_loop SUBS R1,R1,#1 BNE sdram_delay_loopnoSDRAMDelay ; ; Restore the interrupt status ; MSR CPSR_c,v1 LDMIA SP!,{v1-v4} ; restore the registers MOV PC,LR;; The addresses of the A7 registers are stored here; to prevent the linker from putting them into SDRAM; which we put into self refresh.;SDRAM_DELAY DCD 500000SDRAM_CTRL_REG DCD MSS_SDR_CTRL_REGPOWER_DOWN_CTRL_REG DCD SYS_POWER_CTRL_REGCLOCK_CTRL_REG DCD SYS_CLOCK_CTRL_REGPAUSE_REG DCD RMAP_PAUSE_REGPLL_STATUS_REG DCD SYS_PLL_STATUS_REGPLL_STATUS_CLEAR_REG DCD SYS_PLL_STATUS_CLEAR_REG__vectorend AREA |.text|, CODE, READONLY DCB "Copyright (C) 2001-2004, Triscend Corporation. All Rights Reserved." ; ; Abort Wrapper saves all of the registers and ; branches to the 'C' routine to handle the ; abort passing the address of the instruction ; that cause the abort in R0. ; CODE32 IMPORT a7hal_icu_abortMainAbort_Wrapper SUB LR,LR,#4 STMDB SP!,{R0-IP,LR} ; Store all of the registers SUB R0, LR, #4 ; Address of instruction that caused abort BL a7hal_icu_abortMain ; call the C handler 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_swiMainSWI_Wrapper STMFD SP!,{R0-R12,LR} ; Store all of the registers MRS v1,SPSR STMFD SP!,{v1} LDR R12,[LR] BIC R12,R12,#0xff000000 STR R12,[sp,#-8]! LDR R12,=a7hal_icu_swiMain LDR R12,[R12] CMP R12,#0 MOVNE LR,PC MOVNE PC,R1 ADD SP,SP,#8 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_fiqMainIRQ_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 BL a7hal_icu_isrMain ; call the C ISR 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 registersFIQ_Wrapper SUB LR,LR,#4 STMFD SP!,{R0-R7, LR} ; Store all of the registers MRS v1,SPSR STMFD SP!,{v1} BL a7hal_icu_fiqMain ; call the C ISR LDMFD SP!,{v1} MSR SPSR_cxfs,v1 LDMFD SP!,{R0-R7,PC}^ ; restore the registersStart ; ; 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 BL a7hal_sdram_init 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 lSkipCopy ; Copy 16K (32K) 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 (32K) 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,=0x4000l2 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, =LoAddressLoAddress ; 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 L1L0 CMP r1, r3 ; Copy init data LDRCC r2, [r0], #4 STRCC r2, [r1], #4 BCC L0L1 LDR r1, =|Image$$RW$$ZI$$Limit| ; Top of zero init segment MOV r2, #0L2 CMP r3, r1 ; Zero init STRCC r2, [r3], #4 BCC L2 ; ; Initialize any configured devices ; IMPORT a7hal_driverInit BL a7hal_driverInit ; ; 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. ; IMPORT __rt_entry B __rt_entry EXPORT __writeCPR__writeCPR CMP R0, #0 BNE reg1 MCR p15,0, R1, c0, c0 B donereg1 CMP R0, #1 BNE reg2 MCR p15,0, R1, c1, c0 B donereg2 CMP R0, #2 BNE reg3 MCR p15,0, R1, c2, c0 B donereg3 CMP R0, #3 BNE reg4 MCR p15,0, R1, c3, c0 B donereg4 CMP R0, #4 BNE reg5 MCR p15,0, R1, c4, c0 B donereg5 CMP R0, #5 BNE reg6 MCR p15,0, R1, c5, c0 B donereg6 CMP R0, #6 BNE reg7 MCR p15,0, R1, c6, c0 B donereg7 CMP R0, #7 BNE done MCR p15,0, R1, c7, c0 B done EXPORT __readCPR__readCPR CMP R0, #0 BNE readreg1 MRC p15,0, R0, c0, c0 MOV PC,LRreadreg1 CMP R0, #1 BNE readreg2 MRC p15,0, R0, c1, c0 B donereadreg2 CMP R0, #2 BNE readreg3 MRC p15,0, R0, c2, c0 B donereadreg3 CMP R0, #3 BNE readreg4 MRC p15,0, R0, c3, c0 B donereadreg4 CMP R0, #4 BNE readreg5 MRC p15,0, R0, c4, c0 B donereadreg5 CMP R0, #5 BNE readreg6 MRC p15,0, R0, c5, c0 B donereadreg6 CMP R0, #6 BNE readreg7 MRC p15,0, R0, c6, c0 B donereadreg7 CMP R0, #7 BNE readregdone MRC p15,0, R0, c7, c0readregdone B done EXPORT __writeCPRSub__writeCPRSub CMP R1, #0 BNE writesubreg1 MCR p15,0, R2, c6, c0 B donewritesubreg1 CMP R1, #1 BNE writesubreg2 MCR p15,0, R2, c6, c1 B donewritesubreg2 CMP R1, #2 BNE writesubreg3 MCR p15,0, R2, c6, c2 B donewritesubreg3 CMP R1, #3 BNE writesubreg4 MCR p15,0, R2, c6, c3 B donewritesubreg4 CMP R1, #4 BNE writesubreg5 MCR p15,0, R2, c6, c4 B donewritesubreg5 CMP R1, #5 BNE writesubreg6 MCR p15,0, R2, c6, c5 B donewritesubreg6 CMP R1, #6 BNE writesubreg7 MCR p15,0, R2, c6, c6 B donewritesubreg7 CMP R1, #7 BNE writesubdone MCR p15,0, R2, c6, c7writesubdone B done EXPORT __readCPRSub__readCPRSub CMP R1, #0 BNE readsubreg1 MRC p15,0, R0, c6, c0 B donereadsubreg1 CMP R1, #1 BNE readsubreg2 MRC p15,0, R0, c6, c1 B donereadsubreg2 CMP R1, #2 BNE readsubreg3 MRC p15,0, R0, c6, c2 B donereadsubreg3 CMP R1, #3 BNE readsubreg4 MRC p15,0, R0, c6, c3 B donereadsubreg4 CMP R1, #4 BNE readsubreg5 MRC p15,0, R0, c6, c4 B donereadsubreg5 CMP R1, #5 BNE readsubreg6 MRC p15,0, R0, c6, c5 B donereadsubreg6 CMP R1, #6 BNE readsubreg7 MRC p15,0, R0, c6, c6 B donereadsubreg7 CMP R1, #7 BNE readsubdone MRC p15,0, R0, c6, c7readsubdone B donedone MOV PC,LR END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -