rm48: move some asm file to libcpu

This commit is contained in:
Grissiom
2013-10-20 18:51:46 +08:00
parent 9568669109
commit 81ab083ae5
5 changed files with 255 additions and 0 deletions
+255
View File
@@ -0,0 +1,255 @@
/*
* File : context_ccs.asm
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2009-01-20 Bernard first version
* 2011-07-22 Bernard added thumb mode porting
* 2013-05-24 Grissiom port to CCS
* 2013-05-26 Grissiom optimize for ARMv7
* 2013-10-20 Grissiom port to GCC
*/
#include <rtconfig.h>
.text
.arm
.globl rt_thread_switch_interrupt_flag
.globl rt_interrupt_from_thread
.globl rt_interrupt_to_thread
.globl rt_interrupt_enter
.globl rt_interrupt_leave
.globl rt_hw_trap_irq
/*
* rt_base_t rt_hw_interrupt_disable()
*/
.globl rt_hw_interrupt_disable
rt_hw_interrupt_disable:
MRS r0, cpsr
CPSID IF
BX lr
/*
* void rt_hw_interrupt_enable(rt_base_t level)
*/
.globl rt_hw_interrupt_enable
rt_hw_interrupt_enable:
MSR cpsr_c, r0
BX lr
/*
* void rt_hw_context_switch(rt_uint32 from, rt_uint32 to)
* r0 --> from
* r1 --> to
*/
.globl rt_hw_context_switch
rt_hw_context_switch:
STMDB sp!, {lr} @ push pc (lr should be pushed in place of PC)
STMDB sp!, {r0-r12, lr} @ push lr & register file
MRS r4, cpsr
TST lr, #0x01
ORRNE r4, r4, #0x20 @ it's thumb code
STMDB sp!, {r4} @ push cpsr
#if defined (__VFP_FP__) && !defined(__SOFTFP__) && defined(RT_VFP_LAZY_STACKING)
VMRS r4, fpexc
TST r4, #0x40000000
BEQ __no_vfp_frame1
VSTMDB sp!, {d0-d15}
VMRS r5, fpscr
@ TODO: add support for Common VFPv3.
@ Save registers like FPINST, FPINST2
STMDB sp!, {r5}
__no_vfp_frame1:
STMDB sp!, {r4}
#endif
STR sp, [r0] @ store sp in preempted tasks TCB
LDR sp, [r1] @ get new task stack pointer
#if defined (__VFP_FP__) && !defined(__SOFTFP__) && defined(RT_VFP_LAZY_STACKING)
LDMIA sp!, {r0} @ get fpexc
VMSR fpexc, r0 @ restore fpexc
TST r0, #0x40000000
BEQ __no_vfp_frame2
LDMIA sp!, {r1} @ get fpscr
VMSR fpscr, r1
VLDMIA sp!, {d0-d15}
__no_vfp_frame2:
#endif
LDMIA sp!, {r4} @ pop new task cpsr to spsr
MSR spsr_cxsf, r4
LDMIA sp!, {r0-r12, lr, pc}^ @ pop new task r0-r12, lr & pc, copy spsr to cpsr
/*
* void rt_hw_context_switch_to(rt_uint32 to)
* r0 --> to
*/
.globl rt_hw_context_switch_to
rt_hw_context_switch_to:
LDR sp, [r0] @ get new task stack pointer
#if defined (__VFP_FP__) && !defined(__SOFTFP__) && defined(RT_VFP_LAZY_STACKING)
LDMIA sp!, {r0} @ get fpexc
VMSR fpexc, r0
TST r0, #0x40000000
BEQ __no_vfp_frame_to
LDMIA sp!, {r1} @ get fpscr
VMSR fpscr, r1
VLDMIA sp!, {d0-d15}
__no_vfp_frame_to:
#endif
LDMIA sp!, {r4} @ pop new task cpsr to spsr
MSR spsr_cxsf, r4
LDMIA sp!, {r0-r12, lr, pc}^ @ pop new task r0-r12, lr & pc, copy spsr to cpsr
/*
* void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)@
*/
.globl rt_hw_context_switch_interrupt
rt_hw_context_switch_interrupt:
LDR r2, =rt_thread_switch_interrupt_flag
LDR r3, [r2]
CMP r3, #1
BEQ _reswitch
MOV r3, #1 @ set rt_thread_switch_interrupt_flag to 1
STR r3, [r2]
LDR r2, =rt_interrupt_from_thread @ set rt_interrupt_from_thread
STR r0, [r2]
_reswitch:
LDR r2, =rt_interrupt_to_thread @ set rt_interrupt_to_thread
STR r1, [r2]
BX lr
.globl IRQ_Handler
IRQ_Handler:
STMDB sp!, {r0-r12,lr}
#if defined (__VFP_FP__) && !defined(__SOFTFP__) && defined(RT_VFP_LAZY_STACKING)
VMRS r0, fpexc
TST r0, #0x40000000
BEQ __no_vfp_frame_str_irq
VSTMDB sp!, {d0-d15}
VMRS r1, fpscr
@ TODO: add support for Common VFPv3.
@ Save registers like FPINST, FPINST2
STMDB sp!, {r1}
__no_vfp_frame_str_irq:
STMDB sp!, {r0}
#endif
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
#if defined (__VFP_FP__) && !defined(__SOFTFP__) && defined(RT_VFP_LAZY_STACKING)
LDMIA sp!, {r0} @ get fpexc
VMSR fpexc, r0
TST r0, #0x40000000
BEQ __no_vfp_frame_ldr_irq
LDMIA sp!, {r1} @ get fpscr
VMSR fpscr, r1
VLDMIA sp!, {d0-d15}
__no_vfp_frame_ldr_irq:
#endif
LDMIA sp!, {r0-r12,lr}
SUBS pc, lr, #4
/*
* void rt_hw_context_switch_interrupt_do(rt_base_t flag)
*/
.globl rt_hw_context_switch_interrupt_do
rt_hw_context_switch_interrupt_do:
MOV r1, #0 @ clear flag
STR r1, [r0]
#if defined (__VFP_FP__) && !defined(__SOFTFP__) && defined(RT_VFP_LAZY_STACKING)
LDMIA sp!, {r0} @ get fpexc
VMSR fpexc, r0
TST r0, #0x40000000
BEQ __no_vfp_frame_do1
LDMIA sp!, {r1} @ get fpscr
VMSR fpscr, r1
VLDMIA sp!, {d0-d15}
__no_vfp_frame_do1:
#endif
LDMIA sp!, {r0-r12,lr} @ reload saved registers
STMDB sp, {r0-r3} @ save r0-r3. We will restore r0-r3 in the SVC
@ mode so there is no need to update SP.
SUB r1, sp, #16 @ save the right SP value in r1, so we could restore r0-r3.
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
CPSID IF, #0x13
STMDB sp!, {r2} @ push old task's pc
STMDB sp!, {r4-r12,lr} @ push old task's lr,r12-r4
LDMIA r1!, {r4-r7} @ restore r0-r3 of the interrupted thread
STMDB sp!, {r4-r7} @ push old task's r3-r0. We don't need to push/pop them to
@ r0-r3 because we just want to transfer the data and don't
@ use them here.
STMDB sp!, {r3} @ push old task's cpsr
#if defined (__VFP_FP__) && !defined(__SOFTFP__) && defined(RT_VFP_LAZY_STACKING)
VMRS r0, fpexc
TST r0, #0x40000000
BEQ __no_vfp_frame_do2
VSTMDB sp!, {d0-d15}
VMRS r1, fpscr
@ TODO: add support for Common VFPv3.
@ Save registers like FPINST, FPINST2
STMDB sp!, {r1}
__no_vfp_frame_do2:
STMDB sp!, {r0}
#endif
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
#if defined (__VFP_FP__) && !defined(__SOFTFP__) && defined(RT_VFP_LAZY_STACKING)
LDMIA sp!, {r0} @ get fpexc
VMSR fpexc, r0
TST r0, #0x40000000
BEQ __no_vfp_frame_do3
LDMIA sp!, {r1} @ get fpscr
VMSR fpscr, r1
VLDMIA sp!, {d0-d15}
__no_vfp_frame_do3:
#endif
LDMIA sp!, {r4} @ pop new task's cpsr to spsr
MSR spsr_cxsf, r4
LDMIA sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr
File diff suppressed because it is too large Load Diff
+452
View File
@@ -0,0 +1,452 @@
@-------------------------------------------------------------------------------
@ sys_core.asm
@
@ (c) Texas Instruments 2009-2013, All rights reserved.
@
#include <rtconfig.h>
.equ Mode_USR, 0x10
.equ Mode_FIQ, 0x11
.equ Mode_IRQ, 0x12
.equ Mode_SVC, 0x13
.equ Mode_ABT, 0x17
.equ Mode_UND, 0x1B
.equ Mode_SYS, 0x1F
.equ I_Bit, 0x80 @ when I bit is set, IRQ is disabled
.equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled
.equ UND_Stack_Size, 0x00000000
.equ SVC_Stack_Size, 0x00000100
.equ ABT_Stack_Size, 0x00000000
.equ FIQ_Stack_Size, 0x00000000
.equ IRQ_Stack_Size, 0x00000100
.equ USR_Stack_Size, 0x00000100
.section .bss.noinit
/* stack */
.globl stack_start
.globl stack_top
stack_start:
.rept (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + FIQ_Stack_Size + IRQ_Stack_Size)
.long 0
.endr
stack_top:
.section .text, "ax"
.text
.arm
.globl _c_int00
.globl _reset
_reset:
@-------------------------------------------------------------------------------
@ Initialize CPU Registers
@ After reset, the CPU is in the Supervisor mode (M = 10011)
cpsid if, #19
#if defined (__VFP_FP__) && !defined(__SOFTFP__) && defined(RT_VFP_LAZY_STACKING)
@ Turn on FPV coprocessor
mrc p15, #0x00, r2, c1, c0, #0x02
orr r2, r2, #0xF00000
mcr p15, #0x00, r2, c1, c0, #0x02
fmrx r2, fpexc
orr r2, r2, #0x40000000
fmxr fpexc, r2
#endif
@-------------------------------------------------------------------------------
@ Initialize Stack Pointers
ldr r0, =stack_top
@ Enter Undefined Instruction Mode and set its Stack Pointer
msr cpsr_c, #Mode_UND|I_Bit|F_Bit
mov sp, r0
sub r0, r0, #UND_Stack_Size
@ Enter Abort Mode and set its Stack Pointer
msr cpsr_c, #Mode_ABT|I_Bit|F_Bit
mov sp, r0
sub r0, r0, #ABT_Stack_Size
@ Enter FIQ Mode and set its Stack Pointer
msr cpsr_c, #Mode_FIQ|I_Bit|F_Bit
mov sp, r0
sub r0, r0, #FIQ_Stack_Size
@ Enter IRQ Mode and set its Stack Pointer
msr cpsr_c, #Mode_IRQ|I_Bit|F_Bit
mov sp, r0
sub r0, r0, #IRQ_Stack_Size
@ Enter Supervisor Mode and set its Stack Pointer
msr cpsr_c, #Mode_SVC|I_Bit|F_Bit
mov sp, r0
sub r0, r0, #SVC_Stack_Size
@ Enter User Mode and set its Stack Pointer
mov sp, r0
sub sl, sp, #USR_Stack_Size
bl next1
next1:
bl next2
next2:
bl next3
next3:
bl next4
next4:
ldr lr, =_c_int00
bx lr
.globl data_init
data_init:
/* copy .data to SRAM */
ldr r1, =_sidata /* .data start in image */
ldr r2, =_edata /* .data end in image */
ldr r3, =_sdata /* sram data start */
data_loop:
ldr r0, [r1, #0]
str r0, [r3]
add r1, r1, #4
add r3, r3, #4
cmp r3, r2 /* check if data to clear */
blo data_loop /* loop until done */
/* clear .bss */
mov r0,#0 /* get a zero */
ldr r1,=__bss_start /* bss start */
ldr r2,=__bss_end /* bss end */
bss_loop:
cmp r1,r2 /* check if data to clear */
strlo r0,[r1],#4 /* clear 4 bytes */
blo bss_loop /* loop until done */
/* call C++ constructors of global objects */
ldr r0, =__ctors_start__
ldr r1, =__ctors_end__
ctor_loop:
cmp r0, r1
beq ctor_end
ldr r2, [r0], #4
stmfd sp!, {r0-r3, ip, lr}
mov lr, pc
bx r2
ldmfd sp!, {r0-r3, ip, lr}
b ctor_loop
ctor_end:
bx lr
@-------------------------------------------------------------------------------
@ Enable RAM ECC Support
.globl _coreEnableRamEcc_
_coreEnableRamEcc_:
stmfd sp!, {r0}
mrc p15, #0x00, r0, c1, c0, #0x01
orr r0, r0, #0x0C000000
mcr p15, #0x00, r0, c1, c0, #0x01
ldmfd sp!, {r0}
bx lr
@-------------------------------------------------------------------------------
@ Disable RAM ECC Support
.globl _coreDisableRamEcc_
_coreDisableRamEcc_:
stmfd sp!, {r0}
mrc p15, #0x00, r0, c1, c0, #0x01
bic r0, r0, #0x0C000000
mcr p15, #0x00, r0, c1, c0, #0x01
ldmfd sp!, {r0}
bx lr
@-------------------------------------------------------------------------------
@ Enable Flash ECC Support
.globl _coreEnableFlashEcc_
_coreEnableFlashEcc_:
stmfd sp!, {r0}
mrc p15, #0x00, r0, c1, c0, #0x01
orr r0, r0, #0x02000000
dmb
mcr p15, #0x00, r0, c1, c0, #0x01
ldmfd sp!, {r0}
bx lr
@-------------------------------------------------------------------------------
@ Disable Flash ECC Support
.globl _coreDisableFlashEcc_
_coreDisableFlashEcc_:
stmfd sp!, {r0}
mrc p15, #0x00, r0, c1, c0, #0x01
bic r0, r0, #0x02000000
mcr p15, #0x00, r0, c1, c0, #0x01
ldmfd sp!, {r0}
bx lr
@-------------------------------------------------------------------------------
@ Get data fault status register
.globl _coreGetDataFault_
_coreGetDataFault_:
mrc p15, #0, r0, c5, c0, #0
bx lr
@-------------------------------------------------------------------------------
@ Clear data fault status register
.globl _coreClearDataFault_
_coreClearDataFault_:
stmfd sp!, {r0}
mov r0, #0
mcr p15, #0, r0, c5, c0, #0
ldmfd sp!, {r0}
bx lr
@-------------------------------------------------------------------------------
@ Get instruction fault status register
.globl _coreGetInstructionFault_
_coreGetInstructionFault_:
mrc p15, #0, r0, c5, c0, #1
bx lr
@-------------------------------------------------------------------------------
@ Clear instruction fault status register
.globl _coreClearInstructionFault_
_coreClearInstructionFault_:
stmfd sp!, {r0}
mov r0, #0
mcr p15, #0, r0, c5, c0, #1
ldmfd sp!, {r0}
bx lr
@-------------------------------------------------------------------------------
@ Get data fault address register
.globl _coreGetDataFaultAddress_
_coreGetDataFaultAddress_:
mrc p15, #0, r0, c6, c0, #0
bx lr
@-------------------------------------------------------------------------------
@ Clear data fault address register
.globl _coreClearDataFaultAddress_
_coreClearDataFaultAddress_:
stmfd sp!, {r0}
mov r0, #0
mcr p15, #0, r0, c6, c0, #0
ldmfd sp!, {r0}
bx lr
@-------------------------------------------------------------------------------
@ Get instruction fault address register
.globl _coreGetInstructionFaultAddress_
_coreGetInstructionFaultAddress_:
mrc p15, #0, r0, c6, c0, #2
bx lr
@-------------------------------------------------------------------------------
@ Clear instruction fault address register
.globl _coreClearInstructionFaultAddress_
_coreClearInstructionFaultAddress_:
stmfd sp!, {r0}
mov r0, #0
mcr p15, #0, r0, c6, c0, #2
ldmfd sp!, {r0}
bx lr
@-------------------------------------------------------------------------------
@ Get auxiliary data fault status register
.globl _coreGetAuxiliaryDataFault_
_coreGetAuxiliaryDataFault_:
mrc p15, #0, r0, c5, c1, #0
bx lr
@-------------------------------------------------------------------------------
@ Clear auxiliary data fault status register
.globl _coreClearAuxiliaryDataFault_
_coreClearAuxiliaryDataFault_:
stmfd sp!, {r0}
mov r0, #0
mcr p15, #0, r0, c5, c1, #0
ldmfd sp!, {r0}
bx lr
@-------------------------------------------------------------------------------
@ Get auxiliary instruction fault status register
.globl _coreGetAuxiliaryInstructionFault_
_coreGetAuxiliaryInstructionFault_:
mrc p15, #0, r0, c5, c1, #1
bx lr
@-------------------------------------------------------------------------------
@ Clear auxiliary instruction fault status register
.globl _coreClearAuxiliaryInstructionFault_
_coreClearAuxiliaryInstructionFault_:
stmfd sp!, {r0}
mov r0, #0
mrc p15, #0, r0, c5, c1, #1
ldmfd sp!, {r0}
bx lr
@-------------------------------------------------------------------------------
@ Clear ESM CCM errorss
.globl _esmCcmErrorsClear_
_esmCcmErrorsClear_:
stmfd sp!, {r0-r2}
ldr r0, ESMSR1_REG @ load the ESMSR1 status register address
ldr r2, ESMSR1_ERR_CLR
str r2, [r0] @ clear the ESMSR1 register
ldr r0, ESMSR2_REG @ load the ESMSR2 status register address
ldr r2, ESMSR2_ERR_CLR
str r2, [r0] @ clear the ESMSR2 register
ldr r0, ESMSSR2_REG @ load the ESMSSR2 status register address
ldr r2, ESMSSR2_ERR_CLR
str r2, [r0] @ clear the ESMSSR2 register
ldr r0, ESMKEY_REG @ load the ESMKEY register address
mov r2, #0x5 @ load R2 with 0x5
str r2, [r0] @ clear the ESMKEY register
ldr r0, VIM_INTREQ @ load the INTREQ register address
ldr r2, VIM_INT_CLR
str r2, [r0] @ clear the INTREQ register
ldr r0, CCMR4_STAT_REG @ load the CCMR4 status register address
ldr r2, CCMR4_ERR_CLR
str r2, [r0] @ clear the CCMR4 status register
ldmfd sp!, {r0-r2}
bx lr
ESMSR1_REG: .word 0xFFFFF518
ESMSR2_REG: .word 0xFFFFF51C
ESMSR3_REG: .word 0xFFFFF520
ESMKEY_REG: .word 0xFFFFF538
ESMSSR2_REG: .word 0xFFFFF53C
CCMR4_STAT_REG: .word 0xFFFFF600
ERR_CLR_WRD: .word 0xFFFFFFFF
CCMR4_ERR_CLR: .word 0x00010000
ESMSR1_ERR_CLR: .word 0x80000000
ESMSR2_ERR_CLR: .word 0x00000004
ESMSSR2_ERR_CLR: .word 0x00000004
VIM_INT_CLR: .word 0x00000001
VIM_INTREQ: .word 0xFFFFFE20
@-------------------------------------------------------------------------------
@ Work Around for Errata CORTEX-R4#57:
@
@ Errata Description:
@ Conditional VMRS APSR_Nzcv, FPSCR May Evaluate With Incorrect Flags
@ Workaround:
@ Disable out-of-order single-precision floating point
@ multiply-accumulate instruction completion
.globl _errata_CORTEXR4_57_
_errata_CORTEXR4_57_:
push {r0}
mrc p15, #0, r0, c15, c0, #0 @ Read Secondary Auxiliary Control Register
orr r0, r0, #0x10000 @ Set BIT 16 (Set DOOFMACS)
mcr p15, #0, r0, c15, c0, #0 @ Write Secondary Auxiliary Control Register
pop {r0}
bx lr
@-------------------------------------------------------------------------------
@ Work Around for Errata CORTEX-R4#66:
@
@ Errata Description:
@ Register Corruption During A Load-Multiple Instruction At
@ an Exception Vector
@ Workaround:
@ Disable out-of-order completion for divide instructions in
@ Auxiliary Control register
.globl _errata_CORTEXR4_66_
_errata_CORTEXR4_66_:
push {r0}
mrc p15, #0, r0, c1, c0, #1 @ Read Auxiliary Control register
orr r0, r0, #0x80 @ Set BIT 7 (Disable out-of-order completion
@ for divide instructions.)
mcr p15, #0, r0, c1, c0, #1 @ Write Auxiliary Control register
pop {r0}
bx lr
.globl turnon_VFP
turnon_VFP:
@ Enable FPV
STMDB sp!, {r0}
fmrx r0, fpexc
orr r0, r0, #0x40000000
fmxr fpexc, r0
LDMIA sp!, {r0}
subs pc, lr, #4
.globl _dabort
_dabort:
stmfd r13!, {r0 - r12, lr}
ldmfd r13!, {r0 - r12, lr}
subs pc, lr, #8
+36
View File
@@ -0,0 +1,36 @@
;-------------------------------------------------------------------------------
; sys_intvecs.asm
;
; (c) Texas Instruments 2009-2013, All rights reserved.
;
.sect ".intvecs"
.arm
;-------------------------------------------------------------------------------
; import reference for interrupt routines
.ref _reset
.ref _dabort
.ref turnon_VFP
.ref IRQ_Handler
.def resetEntry
;-------------------------------------------------------------------------------
; interrupt vectors
resetEntry
b _reset
b turnon_VFP
svcEntry
b svcEntry
prefetchEntry
b prefetchEntry
b _dabort
reservedEntry
b reservedEntry
b IRQ_Handler
ldr pc,[pc,#-0x1b0]
;-------------------------------------------------------------------------------
+31
View File
@@ -0,0 +1,31 @@
@-------------------------------------------------------------------------------
@ sys_intvecs.asm
@
@ (c) Texas Instruments 2009-2013, All rights reserved.
@
.section .vectors, "ax"
.code 32
@-------------------------------------------------------------------------------
@ import reference for interrupt routines
.globl _reset
.globl _dabort
.globl turnon_VFP
.globl IRQ_Handler
.globl system_vectors
system_vectors:
b _reset
b turnon_VFP
svcEntry:
b svcEntry
prefetchEntry:
b prefetchEntry
b _dabort
reservedEntry:
b reservedEntry
b IRQ_Handler
ldr pc,[pc,#-0x1b0]