summaryrefslogtreecommitdiff
path: root/libcpu/arm
diff options
context:
space:
mode:
authorGrissiom <[email protected]>2013-10-20 18:27:06 +0800
committerGrissiom <[email protected]>2013-10-20 18:51:46 +0800
commit81ab083ae52ee3d1be3804ffe11685802e881bfe (patch)
treeb5d1d922bc8316962b2c0beb9a39e5d9a969e360 /libcpu/arm
parent9568669109ffcb3aa6de8d07959795de71d505ae (diff)
rm48: move some asm file to libcpu
Diffstat (limited to 'libcpu/arm')
-rw-r--r--libcpu/arm/cortex-r4/context_gcc.S255
-rw-r--r--libcpu/arm/cortex-r4/start_ccs.asm515
-rw-r--r--libcpu/arm/cortex-r4/start_gcc.S452
-rw-r--r--libcpu/arm/cortex-r4/vector_ccs.asm36
-rw-r--r--libcpu/arm/cortex-r4/vector_gcc.S31
5 files changed, 1289 insertions, 0 deletions
diff --git a/libcpu/arm/cortex-r4/context_gcc.S b/libcpu/arm/cortex-r4/context_gcc.S
new file mode 100644
index 0000000000..5256645ab8
--- /dev/null
+++ b/libcpu/arm/cortex-r4/context_gcc.S
@@ -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
+
diff --git a/libcpu/arm/cortex-r4/start_ccs.asm b/libcpu/arm/cortex-r4/start_ccs.asm
new file mode 100644
index 0000000000..186d4f28ab
--- /dev/null
+++ b/libcpu/arm/cortex-r4/start_ccs.asm
@@ -0,0 +1,515 @@
+;-------------------------------------------------------------------------------
+; sys_core.asm
+;
+; (c) Texas Instruments 2009-2013, All rights reserved.
+;
+
+ .text
+ .arm
+
+ .ref _c_int00
+
+ .def _reset
+ .asmfunc
+_reset
+;-------------------------------------------------------------------------------
+; Initialize CPU Registers
+; After reset, the CPU is in the Supervisor mode (M = 10011)
+ mov r0, lr
+ mov r1, #0x0000
+ mov r2, #0x0000
+ mov r3, #0x0000
+ mov r4, #0x0000
+ mov r5, #0x0000
+ mov r6, #0x0000
+ mov r7, #0x0000
+ mov r8, #0x0000
+ mov r9, #0x0000
+ mov r10, #0x0000
+ mov r11, #0x0000
+ mov r12, #0x0000
+ mov r13, #0x0000
+ mrs r1, cpsr
+ msr spsr_cxsf, r1
+ ; Switch to FIQ mode (M = 10001)
+ cps #17
+ mov lr, r0
+ mov r8, #0x0000
+ mov r9, #0x0000
+ mov r10, #0x0000
+ mov r11, #0x0000
+ mov r12, #0x0000
+ mrs r1, cpsr
+ msr spsr_cxsf, r1
+ ; Switch to IRQ mode (M = 10010)
+ cps #18
+ mov lr, r0
+ mrs r1,cpsr
+ msr spsr_cxsf, r1
+ ; Switch to Abort mode (M = 10111)
+ cps #23
+ mov lr, r0
+ mrs r1,cpsr
+ msr spsr_cxsf, r1
+ ; Switch to Undefined Instruction Mode (M = 11011)
+ cps #27
+ mov lr, r0
+ mrs r1,cpsr
+ msr spsr_cxsf, r1
+ ; Switch to System Mode ( Shares User Mode registers ) (M = 11111)
+ cps #31
+ mov lr, r0
+ mrs r1,cpsr
+ msr spsr_cxsf, r1
+ ; Switch back to Supervisor Mode (M = 10011)
+ cps #19
+
+ ; Turn on FPV coprocessor
+ mrc p15, #0x00, r2, c1, c0, #0x02
+ orr r2, r2, #0xF00000
+ mcr p15, #0x00, r2, c1, c0, #0x02
+
+ .if (RT_VFP_LAZY_STACKING) = 0
+ fmrx r2, fpexc
+ orr r2, r2, #0x40000000
+ fmxr fpexc, r2
+
+ fmdrr d0, r1, r1
+ fmdrr d1, r1, r1
+ fmdrr d2, r1, r1
+ fmdrr d3, r1, r1
+ fmdrr d4, r1, r1
+ fmdrr d5, r1, r1
+ fmdrr d6, r1, r1
+ fmdrr d7, r1, r1
+ fmdrr d8, r1, r1
+ fmdrr d9, r1, r1
+ fmdrr d10, r1, r1
+ fmdrr d11, r1, r1
+ fmdrr d12, r1, r1
+ fmdrr d13, r1, r1
+ fmdrr d14, r1, r1
+ fmdrr d15, r1, r1
+ .endif
+
+;-------------------------------------------------------------------------------
+; Initialize Stack Pointers
+ cps #17
+ ldr sp, fiqSp
+ cps #18
+ ldr sp, irqSp
+ cps #23
+ ldr sp, abortSp
+ cps #27
+ ldr sp, undefSp
+ cps #31
+ ldr sp, userSp
+ cps #19
+ ldr sp, svcSp
+
+ bl next1
+next1
+ bl next2
+next2
+ bl next3
+next3
+ bl next4
+next4
+ ldr lr, int00ad
+ bx lr
+
+int00ad .word _c_int00
+userSp .word 0x08000000+0x00001000
+svcSp .word 0x08000000+0x00001000+0x00000100
+fiqSp .word 0x08000000+0x00001000+0x00000100+0x00000100
+irqSp .word 0x08000000+0x00001000+0x00000100+0x00000100+0x00000100
+abortSp .word 0x08000000+0x00001000+0x00000100+0x00000100+0x00000100+0x00000100
+undefSp .word 0x08000000+0x00001000+0x00000100+0x00000100+0x00000100+0x00000100+0x00000100
+
+ .endasmfunc
+
+;-------------------------------------------------------------------------------
+; Enable RAM ECC Support
+
+ .def _coreEnableRamEcc_
+ .asmfunc
+
+_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
+
+ .endasmfunc
+
+
+;-------------------------------------------------------------------------------
+; Disable RAM ECC Support
+
+ .def _coreDisableRamEcc_
+ .asmfunc
+
+_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
+
+ .endasmfunc
+
+
+;-------------------------------------------------------------------------------
+; Enable Flash ECC Support
+
+ .def _coreEnableFlashEcc_
+ .asmfunc
+
+_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
+
+ .endasmfunc
+
+
+;-------------------------------------------------------------------------------
+; Disable Flash ECC Support
+
+ .def _coreDisableFlashEcc_
+ .asmfunc
+
+_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
+
+ .endasmfunc
+
+;-------------------------------------------------------------------------------
+; Get data fault status register
+
+ .def _coreGetDataFault_
+ .asmfunc
+
+_coreGetDataFault_
+
+ mrc p15, #0, r0, c5, c0, #0
+ bx lr
+
+ .endasmfunc
+
+
+;-------------------------------------------------------------------------------
+; Clear data fault status register
+
+ .def _coreClearDataFault_
+ .asmfunc
+
+_coreClearDataFault_
+
+ stmfd sp!, {r0}
+ mov r0, #0
+ mcr p15, #0, r0, c5, c0, #0
+ ldmfd sp!, {r0}
+ bx lr
+
+ .endasmfunc
+
+
+;-------------------------------------------------------------------------------
+; Get instruction fault status register
+
+ .def _coreGetInstructionFault_
+ .asmfunc
+
+_coreGetInstructionFault_
+
+ mrc p15, #0, r0, c5, c0, #1
+ bx lr
+
+ .endasmfunc
+
+
+;-------------------------------------------------------------------------------
+; Clear instruction fault status register
+
+ .def _coreClearInstructionFault_
+ .asmfunc
+
+_coreClearInstructionFault_
+
+ stmfd sp!, {r0}
+ mov r0, #0
+ mcr p15, #0, r0, c5, c0, #1
+ ldmfd sp!, {r0}
+ bx lr
+
+ .endasmfunc
+
+
+;-------------------------------------------------------------------------------
+; Get data fault address register
+
+ .def _coreGetDataFaultAddress_
+ .asmfunc
+
+_coreGetDataFaultAddress_
+
+ mrc p15, #0, r0, c6, c0, #0
+ bx lr
+
+ .endasmfunc
+
+
+;-------------------------------------------------------------------------------
+; Clear data fault address register
+
+ .def _coreClearDataFaultAddress_
+ .asmfunc
+
+_coreClearDataFaultAddress_
+
+ stmfd sp!, {r0}
+ mov r0, #0
+ mcr p15, #0, r0, c6, c0, #0
+ ldmfd sp!, {r0}
+ bx lr
+
+ .endasmfunc
+
+
+;-------------------------------------------------------------------------------
+; Get instruction fault address register
+
+ .def _coreGetInstructionFaultAddress_
+ .asmfunc
+
+_coreGetInstructionFaultAddress_
+
+ mrc p15, #0, r0, c6, c0, #2
+ bx lr
+
+ .endasmfunc
+
+
+;-------------------------------------------------------------------------------
+; Clear instruction fault address register
+
+ .def _coreClearInstructionFaultAddress_
+ .asmfunc
+
+_coreClearInstructionFaultAddress_
+
+ stmfd sp!, {r0}
+ mov r0, #0
+ mcr p15, #0, r0, c6, c0, #2
+ ldmfd sp!, {r0}
+ bx lr
+
+ .endasmfunc
+
+
+;-------------------------------------------------------------------------------
+; Get auxiliary data fault status register
+
+ .def _coreGetAuxiliaryDataFault_
+ .asmfunc
+
+_coreGetAuxiliaryDataFault_
+
+ mrc p15, #0, r0, c5, c1, #0
+ bx lr
+
+ .endasmfunc
+
+
+;-------------------------------------------------------------------------------
+; Clear auxiliary data fault status register
+
+ .def _coreClearAuxiliaryDataFault_
+ .asmfunc
+
+_coreClearAuxiliaryDataFault_
+
+ stmfd sp!, {r0}
+ mov r0, #0
+ mcr p15, #0, r0, c5, c1, #0
+ ldmfd sp!, {r0}
+ bx lr
+
+ .endasmfunc
+
+
+;-------------------------------------------------------------------------------
+; Get auxiliary instruction fault status register
+
+ .def _coreGetAuxiliaryInstructionFault_
+ .asmfunc
+
+_coreGetAuxiliaryInstructionFault_
+
+ mrc p15, #0, r0, c5, c1, #1
+ bx lr
+
+ .endasmfunc
+
+;-------------------------------------------------------------------------------
+; Clear auxiliary instruction fault status register
+
+ .def _coreClearAuxiliaryInstructionFault_
+ .asmfunc
+
+_coreClearAuxiliaryInstructionFault_
+
+ stmfd sp!, {r0}
+ mov r0, #0
+ mrc p15, #0, r0, c5, c1, #1
+ ldmfd sp!, {r0}
+ bx lr
+
+ .endasmfunc
+
+;-------------------------------------------------------------------------------
+; Clear ESM CCM errorss
+
+ .def _esmCcmErrorsClear_
+ .asmfunc
+
+_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
+
+ .endasmfunc
+
+;-------------------------------------------------------------------------------
+; 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
+
+ .def _errata_CORTEXR4_57_
+ .asmfunc
+
+_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
+ .endasmfunc
+
+;-------------------------------------------------------------------------------
+; 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
+
+ .def _errata_CORTEXR4_66_
+ .asmfunc
+
+_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
+ .endasmfunc
+
+ .def turnon_VFP
+ .asmfunc
+turnon_VFP
+ ; Enable FPV
+ STMDB sp!, {r0}
+ fmrx r0, fpexc
+ orr r0, r0, #0x40000000
+ fmxr fpexc, r0
+ LDMIA sp!, {r0}
+ subs pc, lr, #4
+ .endasmfunc
+
+ .def _dabort
+ .asmfunc
+
+_dabort
+ stmfd r13!, {r0 - r12, lr}
+ ldmfd r13!, {r0 - r12, lr}
+ subs pc, lr, #8
+ .endasmfunc
+;-------------------------------------------------------------------------------
+; C++ construct table pointers
+
+ .def __TI_PINIT_Base, __TI_PINIT_Limit
+ .weak SHT$$INIT_ARRAY$$Base, SHT$$INIT_ARRAY$$Limit
+
+__TI_PINIT_Base .long SHT$$INIT_ARRAY$$Base
+__TI_PINIT_Limit .long SHT$$INIT_ARRAY$$Limit
+
+
+
+;-------------------------------------------------------------------------------
+
diff --git a/libcpu/arm/cortex-r4/start_gcc.S b/libcpu/arm/cortex-r4/start_gcc.S
new file mode 100644
index 0000000000..00d459dd34
--- /dev/null
+++ b/libcpu/arm/cortex-r4/start_gcc.S
@@ -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
diff --git a/libcpu/arm/cortex-r4/vector_ccs.asm b/libcpu/arm/cortex-r4/vector_ccs.asm
new file mode 100644
index 0000000000..0ac6647266
--- /dev/null
+++ b/libcpu/arm/cortex-r4/vector_ccs.asm
@@ -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]
+
+;-------------------------------------------------------------------------------
diff --git a/libcpu/arm/cortex-r4/vector_gcc.S b/libcpu/arm/cortex-r4/vector_gcc.S
new file mode 100644
index 0000000000..b21d5d4910
--- /dev/null
+++ b/libcpu/arm/cortex-r4/vector_gcc.S
@@ -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]