rt-thread-official/libcpu/arm/sep4020/start_rvds.S

386 lines
12 KiB
ArmAsm
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;==============================================================================================
; star_rvds.s for Keil MDK 4.10
;
; SEP4020 start up code
;
; Change Logs:
; Date Author Notes
; 2010-03-17 zchong
;=============================================================================================
PMU_PLTR EQU 0x10001000 ; PLL的稳定过渡时间
PMU_PMCR EQU 0x10001004 ; 系统主时钟PLL的控制寄存器
PMU_PUCR EQU 0x10001008 ; USB时钟PLL的控制寄存器
PMU_PCSR EQU 0x1000100C ; 内部模块时钟源供给的控制寄存器
PMU_PDSLOW EQU 0x10001010 ; SLOW状态下时钟的分频因子
PMU_PMDR EQU 0x10001014 ; 芯片工作模式寄存器
PMU_RCTR EQU 0x10001018 ; Reset控制寄存器
PMU_CLRWAKUP EQU 0x1000101C ; WakeUp清除寄存器
RTC_CTR EQU 0x1000200C ; RTC控制寄存器
INTC_IER EQU 0x10000000 ; IRQ中断允许寄存器
INTC_IMR EQU 0x10000008 ; IRQ中断屏蔽寄存器
INTC_IFSR EQU 0x10000030 ; IRQ中断最终状态寄存器
INTC_FIER EQU 0x100000C0 ; FIQ中断允许寄存器
INTC_FIMR EQU 0x100000C4 ; FIQ中断屏蔽寄存器
EMI_CSACONF EQU 0x11000000 ; CSA参数配置寄存器
EMI_CSECONF EQU 0x11000010 ; CSE参数配置寄存器
EMI_CSFCONF EQU 0x11000014 ; CSF参数配置寄存器
EMI_SDCONF1 EQU 0x11000018 ; SDRAM时序配置寄存器1
EMI_SDCONF2 EQU 0x1100001C ; SDRAM时序配置寄存器2, SDRAM初始化用到的配置信息
EMI_REMAPCONF EQU 0x11000020 ; 片选空间及地址映射REMAP配置寄存器
Mode_USR EQU 0x10
Mode_FIQ EQU 0x11
Mode_IRQ EQU 0x12
Mode_SVC EQU 0x13
Mode_ABT EQU 0x17
Mode_UND EQU 0x1B
Mode_SYS EQU 0x1F
I_Bit EQU 0x80 ; when I bit is set, IRQ is disabled
F_Bit EQU 0x40 ; when F bit is set, FIQ is disabled
NOINT EQU 0xc0
MASK_MODE EQU 0x0000003F
MODE_SVC32 EQU 0x00000013
; Internal Memory Base Addresses
FLASH_BASE EQU 0x20000000
RAM_BASE EQU 0x04000000
SDRAM_BASE EQU 0x30000000
; Stack
Unused_Stack_Size EQU 0x00000100
Svc_Stack_Size EQU 0x00001000
Abt_Stack_Size EQU 0x00000000
Fiq_Stack_Size EQU 0x00000000
Irq_Stack_Size EQU 0x00001000
Usr_Stack_Size EQU 0x00000000
;SVC STACK
AREA STACK, NOINIT, READWRITE, ALIGN=3
Svc_Stack SPACE Svc_Stack_Size
__initial_sp
Svc_Stack_Top
;IRQ STACK
AREA STACK, NOINIT, READWRITE, ALIGN=3
Irq_Stack SPACE Irq_Stack_Size
Irq_Stack_Top
;UNUSED STACK
AREA STACK, NOINIT, READWRITE, ALIGN=3
Unused_Stack SPACE Unused_Stack_Size
Unused_Stack_Top
; Heap
Heap_Size EQU 0x0000100
AREA HEAP, NOINIT, READWRITE, ALIGN=3
EXPORT Heap_Mem
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
PRESERVE8
; Area Definition and Entry Point
; Startup Code must be linked first at Address at which it expects to run.
AREA RESET, CODE, READONLY
ARM
; Exception Vectors
; Mapped to Address 0.
; Absolute addressing mode must be used.
; Dummy Handlers are implemented as infinite loops which can be modified.
EXPORT Entry_Point
Entry_Point
Vectors LDR PC,Reset_Addr
LDR PC,Undef_Addr
LDR PC,SWI_Addr
LDR PC,PAbt_Addr
LDR PC,DAbt_Addr
NOP ; Reserved Vector
LDR PC,IRQ_Addr
LDR PC,FIQ_Addr
Reset_Addr DCD Reset_Handler
Undef_Addr DCD Undef_Handler
SWI_Addr DCD SWI_Handler
PAbt_Addr DCD PAbt_Handler
DAbt_Addr DCD DAbt_Handler
DCD 0 ; Reserved Address
IRQ_Addr DCD IRQ_Handler
FIQ_Addr DCD FIQ_Handler
Undef_Handler B Undef_Handler
SWI_Handler B SWI_Handler
PAbt_Handler B Abort_Handler
DAbt_Handler B Abort_Handler
FIQ_Handler B FIQ_Handler
Abort_Handler PROC
ARM
EXPORT Abort_Handler
DeadLoop BHI DeadLoop ; Abort happened in irq mode, halt system.
ENDP
; Reset Handler
;IMPORT __user_initial_stackheap
EXPORT Reset_Handler
Reset_Handler
;****************************************************************
;* Shutdown watchdog
;****************************************************************
LDR R0,=RTC_CTR
LDR R1,=0x0
STR R1,[R0]
;****************************************************************
;* shutdown interrupts
;****************************************************************
MRS R0, CPSR
BIC R0, R0, #MASK_MODE
ORR R0, R0, #MODE_SVC32
ORR R0, R0, #I_Bit
ORR R0, R0, #F_Bit
MSR CPSR_c, r0
LDR R0,=INTC_IER
LDR R1,=0x0
STR R1,[R0]
LDR R0,=INTC_IMR
LDR R1,=0xFFFFFFFF
STR R1,[R0]
LDR R0,=INTC_FIER
LDR R1,=0x0
STR R1,[R0]
LDR R0,=INTC_FIMR
LDR R1,=0x0F
STR R1,[R0]
;****************************************************************
;* Initialize Stack Pointer
;****************************************************************
LDR SP, =Svc_Stack_Top ;init SP_svc
MOV R4, #0xD2 ;chmod to irq and init SP_irq
MSR cpsr_c, R4
LDR SP, =Irq_Stack_Top
MOV R4, #0XD1 ;chomod to fiq and init SP_fiq
MSR cpsr_c, R4
LDR SP, =Unused_Stack_Top
MOV R4, #0XD7 ;chomod to abt and init SP_ABT
MSR cpsr_c, R4
LDR SP, =Unused_Stack_Top
MOV R4, #0XDB ;chomod to undf and init SP_UNDF
MSR cpsr_c, R4
LDR SP, =Unused_Stack_Top
;chomod to abt and init SP_sys
MOV R4, #0xDF ;all interrupts disabled
MSR cpsr_c, R4 ;SYSTEM mode, @32-bit code mode
LDR SP, =Unused_Stack_Top
MOV R4, #0XD3 ;chmod to svc modle, CPSR IRQ bit is disable
MSR cpsr_c, R4
;****************************************************************
;* Initialize PMU & System Clock
;****************************************************************
LDR R4, =PMU_PCSR ; 打所有模块时钟
LDR R5, =0x0001ffff
STR R5, [ R4 ]
LDR R4, =PMU_PLTR ; 配置PLL稳定过度时间为保守值50us*100M.
LDR R5, =0x00fa00fa
STR R5, [ R4 ]
LDR R4, =PMU_PMDR ; 由SLOW模式进入NORMAL模式
LDR R5, =0x00000001
STR R5, [ R4 ]
LDR R4, =PMU_PMCR ; 配置系统时钟为80MHz
LDR R5, =0x00004009 ; 400b -- 88M
STR R5, [ R4 ]
;PMU_PMCR寄存器第15位需要有从低到高的翻转才能触发PLL的时钟配置
LDR R4, =PMU_PMCR
LDR R5, =0x0000c009
STR R5, [ R4 ]
;****************************************************************
;* 初始化EMI
;****************************************************************
IF :DEF:INIT_EMI
LDR R4, =EMI_CSACONF ; CSA片选时序参数配置
LDR R5, =0x08a6a6a1
STR R5, [ R4 ]
LDR R4, =EMI_CSECONF ; CSE片选时序参数配置,最保守配置
LDR R5, =0x8cfffff1
STR R5, [ R4 ]
LDR R4, =EMI_SDCONF1 ; SDRAM参数配置1
LDR R5, =0x1E104177
STR R5, [ R4 ]
LDR R4, =EMI_SDCONF2 ; SDRAM参数配置2
LDR R5, =0x80001860
STR R5, [ R4 ]
ENDIF
; Copy Exception Vectors to Internal RAM
IF :DEF:RAM_INTVEC
ADR R8, Vectors ; Source
LDR R9, =RAM_BASE ; Destination
LDMIA R8!, {R0-R7} ; Load Vectors
STMIA R9!, {R0-R7} ; Store Vectors
LDMIA R8!, {R0-R7} ; Load Handler Addresses
STMIA R9!, {R0-R7} ; Store Handler Addresses
ENDIF
; Remap on-chip RAM to address 0
IF :DEF:REMAP
LDR R0, =EMI_REMAPCONF
IF :DEF:RAM_INTVEC
MOV R1, #0x80000000
ELSE
MOV R1, #0x0000000b
ENDIF
STR R1, [R0, #0] ; Remap
ENDIF
;***************************************************************
;* Open irq interrupt
;***************************************************************
MRS R4, cpsr
BIC R4, R4, #0x80 ; set bit7 to zero
MSR cpsr_c, R4
; Enter the C code
IMPORT __main
LDR R0,=__main
BX R0
IMPORT rt_interrupt_enter
IMPORT rt_interrupt_leave
IMPORT rt_thread_switch_interrupt_flag
IMPORT rt_interrupt_from_thread
IMPORT rt_interrupt_to_thread
IMPORT rt_hw_trap_irq
IRQ_Handler PROC
EXPORT IRQ_Handler
STMFD sp!, {r0-r12,lr}
BL rt_interrupt_enter
BL rt_hw_trap_irq
BL rt_interrupt_leave
; if rt_thread_switch_interrupt_flag set, jump to
; rt_hw_context_switch_interrupt_do and don't return
LDR r0, =rt_thread_switch_interrupt_flag
LDR r1, [r0]
CMP r1, #1
BEQ rt_hw_context_switch_interrupt_do
LDMFD sp!, {r0-r12,lr}
SUBS pc, lr, #4
ENDP
; /*
; * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
; */
rt_hw_context_switch_interrupt_do PROC
EXPORT rt_hw_context_switch_interrupt_do
MOV r1, #0 ; clear flag
STR r1, [r0]
LDMFD sp!, {r0-r12,lr}; reload saved registers
STMFD sp!, {r0-r3} ; save r0-r3
MOV r1, sp
ADD sp, sp, #16 ; restore sp
SUB r2, lr, #4 ; save old task's pc to r2
MRS r3, spsr ; get cpsr of interrupt thread
; switch to SVC mode and no interrupt
MSR cpsr_c, #I_Bit :OR F_Bit :OR Mode_SVC
STMFD sp!, {r2} ; push old task's pc
STMFD sp!, {r4-r12,lr}; push old task's lr,r12-r4
MOV r4, r1 ; Special optimised code below
MOV r5, r3
LDMFD r4!, {r0-r3}
STMFD sp!, {r0-r3} ; push old task's r3-r0
STMFD sp!, {r5} ; push old task's cpsr
MRS r4, spsr
STMFD sp!, {r4} ; push old task's spsr
LDR r4, =rt_interrupt_from_thread
LDR r5, [r4]
STR sp, [r5] ; store sp in preempted tasks's TCB
LDR r6, =rt_interrupt_to_thread
LDR r6, [r6]
LDR sp, [r6] ; get new task's stack pointer
LDMFD sp!, {r4} ; pop new task's spsr
MSR spsr_cxsf, r4
LDMFD sp!, {r4} ; pop new task's psr
MSR cpsr_cxsf, r4
LDMFD sp!, {r0-r12,lr,pc} ; pop new task's r0-r12,lr & pc
ENDP
ALIGN
IF :DEF:__MICROLIB
EXPORT __heap_base
EXPORT __heap_limit
EXPORT __initial_sp
ELSE ;__MICROLIB
; User Initial Stack & Heap
AREA |.text|, CODE, READONLY
IMPORT __use_two_region_memory
EXPORT __user_initial_stackheap
__user_initial_stackheap
LDR R0, = Heap_Mem
LDR R1, = (Svc_Stack + Svc_Stack_Size)
LDR R2, = (Heap_Mem + Heap_Size)
LDR R3, = Svc_Stack
BX LR
ALIGN
ENDIF
END