summaryrefslogtreecommitdiff
path: root/libcpu
diff options
context:
space:
mode:
authorBernard Xiong <[email protected]>2013-10-22 16:22:02 -0700
committerBernard Xiong <[email protected]>2013-10-22 16:22:02 -0700
commita3bf5e2d9b12482a0552bb96bfa091e4b80c79df (patch)
treecabdeec3ebd073b044c86a55658069312772954d /libcpu
parentac5da68db79fb98071463da28ac88bb2981c8a53 (diff)
parent377c6e6cc9b415793d4787c86d0e9dea5e47e914 (diff)
Merge pull request #181 from grissiom/rm48x50-next
Rm48x50 next
Diffstat (limited to 'libcpu')
-rw-r--r--libcpu/arm/cortex-r4/RM48x50.h39
-rw-r--r--libcpu/arm/cortex-r4/armv7.h48
-rw-r--r--libcpu/arm/cortex-r4/context_gcc.S255
-rw-r--r--libcpu/arm/cortex-r4/cpu.c7
-rw-r--r--libcpu/arm/cortex-r4/interrupt.c6
-rw-r--r--libcpu/arm/cortex-r4/stack.c6
-rw-r--r--libcpu/arm/cortex-r4/start_ccs.asm552
-rw-r--r--libcpu/arm/cortex-r4/start_gcc.S482
-rw-r--r--libcpu/arm/cortex-r4/trap.c46
-rw-r--r--libcpu/arm/cortex-r4/vector_ccs.asm34
-rw-r--r--libcpu/arm/cortex-r4/vector_gcc.S31
11 files changed, 1440 insertions, 66 deletions
diff --git a/libcpu/arm/cortex-r4/RM48x50.h b/libcpu/arm/cortex-r4/RM48x50.h
deleted file mode 100644
index 9f4bcc976f..0000000000
--- a/libcpu/arm/cortex-r4/RM48x50.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef RM48X50_H
-#define RM48X50_H
-
-#include <system.h>
-#include <sys_vim.h>
-
-#define USERMODE 0x10
-#define FIQMODE 0x11
-#define IRQMODE 0x12
-#define SVCMODE 0x13
-#define ABORTMODE 0x17
-#define UNDEFMODE 0x1b
-#define MODEMASK 0x1f
-#define NOINT 0xc0
-
-struct rt_hw_register
-{
- unsigned long r0;
- unsigned long r1;
- unsigned long r2;
- unsigned long r3;
- unsigned long r4;
- unsigned long r5;
- unsigned long r6;
- unsigned long r7;
- unsigned long r8;
- unsigned long r9;
- unsigned long r10;
- unsigned long fp;
- unsigned long ip;
- unsigned long sp;
- unsigned long lr;
- unsigned long pc;
- unsigned long cpsr;
- unsigned long ORIG_r0;
-};
-
-#endif /* end of include guard: RM48X50_H */
-
diff --git a/libcpu/arm/cortex-r4/armv7.h b/libcpu/arm/cortex-r4/armv7.h
new file mode 100644
index 0000000000..7dc3471c70
--- /dev/null
+++ b/libcpu/arm/cortex-r4/armv7.h
@@ -0,0 +1,48 @@
+#ifndef __ARMV7_H__
+#define __ARMV7_H__
+
+#ifndef VFP_DATA_NR
+#define VFP_DATA_NR 32
+#endif
+
+/* the exception stack without VFP registers */
+struct rt_hw_exp_stack
+{
+ unsigned long r0;
+ unsigned long r1;
+ unsigned long r2;
+ unsigned long r3;
+ unsigned long r4;
+ unsigned long r5;
+ unsigned long r6;
+ unsigned long r7;
+ unsigned long r8;
+ unsigned long r9;
+ unsigned long r10;
+ unsigned long fp;
+ unsigned long ip;
+ unsigned long sp;
+ unsigned long lr;
+ unsigned long pc;
+ unsigned long cpsr;
+};
+
+#define USERMODE 0x10
+#define FIQMODE 0x11
+#define IRQMODE 0x12
+#define SVCMODE 0x13
+#define MONITORMODE 0x16
+#define ABORTMODE 0x17
+#define HYPMODE 0x1b
+#define UNDEFMODE 0x1b
+#define MODEMASK 0x1f
+#define NOINT 0xc0
+
+#define T_Bit (1<<5)
+#define F_Bit (1<<6)
+#define I_Bit (1<<7)
+#define A_Bit (1<<8)
+#define E_Bit (1<<9)
+#define J_Bit (1<<24)
+
+#endif
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/cpu.c b/libcpu/arm/cortex-r4/cpu.c
index d1b5c9df54..89369d5209 100644
--- a/libcpu/arm/cortex-r4/cpu.c
+++ b/libcpu/arm/cortex-r4/cpu.c
@@ -39,6 +39,7 @@ void rt_hw_cpu_shutdown()
while (1);
}
+#ifdef __TI_COMPILER_VERSION__
#ifdef RT_USING_CPU_FFS
int __rt_ffs(int value)
{
@@ -52,7 +53,6 @@ int __rt_ffs(int value)
}
#endif
-#ifdef __TI_COMPILER_VERSION__
void rt_hw_cpu_icache_enable()
{
__asm(" MRC p15, #0, r1, c1, c0, #0 ; Read SCTLR configuration data");
@@ -90,5 +90,10 @@ void rt_hw_cpu_dcache_disable()
__asm(" MCR p15, #0, r1, c1, c0, #0 ; disabled data cache");
}
+#elif __GNUC__
+int __rt_ffs(int value)
+{
+ return __builtin_ffs(value);
+}
#endif
/*@}*/
diff --git a/libcpu/arm/cortex-r4/interrupt.c b/libcpu/arm/cortex-r4/interrupt.c
index d001b509ee..ba2d99e998 100644
--- a/libcpu/arm/cortex-r4/interrupt.c
+++ b/libcpu/arm/cortex-r4/interrupt.c
@@ -15,7 +15,11 @@
#include <rtthread.h>
#include <rthw.h>
-#include "RM48x50.h"
+
+#include <sys_vim.h>
+#include <system.h>
+
+#include "armv7.h"
#define MAX_HANDLERS 96
diff --git a/libcpu/arm/cortex-r4/stack.c b/libcpu/arm/cortex-r4/stack.c
index 02dc84e6f1..3c8e89444c 100644
--- a/libcpu/arm/cortex-r4/stack.c
+++ b/libcpu/arm/cortex-r4/stack.c
@@ -13,7 +13,8 @@
* 2013-05-24 Grissiom port to RM48x50
*/
#include <rtthread.h>
-#include "RM48x50.h"
+
+#include "armv7.h"
/**
* @addtogroup RM48x50
*/
@@ -57,10 +58,9 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
else
*(--stk) = SVCMODE; /* arm mode */
-#ifdef __TI_VFP_SUPPORT__
+#if defined(__TI_VFP_SUPPORT__) || (defined (__VFP_FP__) && !defined(__SOFTFP__))
#ifndef RT_VFP_LAZY_STACKING
{
- #define VFP_DATA_NR 32
int i;
for (i = 0; i < VFP_DATA_NR; i++)
diff --git a/libcpu/arm/cortex-r4/start_ccs.asm b/libcpu/arm/cortex-r4/start_ccs.asm
new file mode 100644
index 0000000000..4334fa9b0f
--- /dev/null
+++ b/libcpu/arm/cortex-r4/start_ccs.asm
@@ -0,0 +1,552 @@
+;-------------------------------------------------------------------------------
+; 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
+
+_push_svc_reg .macro
+ sub sp, sp, #17 * 4 ;/* Sizeof(struct rt_hw_exp_stack) */
+ stmia sp, {r0 - r12} ;/* Calling r0-r12 */
+ mov r0, sp
+ mrs r6, spsr ;/* Save CPSR */
+ str lr, [r0, #15*4] ;/* Push PC */
+ str r6, [r0, #16*4] ;/* Push CPSR */
+ cps #0x13
+ str sp, [r0, #13*4] ;/* Save calling SP */
+ str lr, [r0, #14*4] ;/* Save calling PC */
+ .endm
+
+ .ref rt_hw_trap_svc
+ .def vector_svc
+ .asmfunc
+vector_svc:
+ _push_svc_reg
+ bl rt_hw_trap_svc
+ sub pc, pc, #-4
+ .endasmfunc
+
+ .ref rt_hw_trap_pabt
+ .def vector_pabort
+ .asmfunc
+vector_pabort:
+ _push_svc_reg
+ bl rt_hw_trap_pabt
+ sub pc, pc, #-4
+ .endasmfunc
+
+ .ref rt_hw_trap_dabt
+ .def vector_dabort
+ .asmfunc
+vector_dabort:
+ _push_svc_reg
+ bl rt_hw_trap_dabt
+ sub pc, pc, #-4
+ .endasmfunc
+
+ .ref rt_hw_trap_resv
+ .def vector_resv
+ .asmfunc
+vector_resv:
+ _push_svc_reg
+ bl rt_hw_trap_resv
+ sub pc, pc, #-4
+ .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..20a1ccfc0f
--- /dev/null
+++ b/libcpu/arm/cortex-r4/start_gcc.S
@@ -0,0 +1,482 @@
+@-------------------------------------------------------------------------------
+@ 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
+
+ .macro push_svc_reg
+ sub sp, sp, #17 * 4 @/* Sizeof(struct rt_hw_exp_stack) */
+ stmia sp, {r0 - r12} @/* Calling r0-r12 */
+ mov r0, sp
+ mrs r6, spsr @/* Save CPSR */
+ str lr, [r0, #15*4] @/* Push PC */
+ str r6, [r0, #16*4] @/* Push CPSR */
+ cps #Mode_SVC
+ str sp, [r0, #13*4] @/* Save calling SP */
+ str lr, [r0, #14*4] @/* Save calling PC */
+ .endm
+
+ .globl vector_svc
+vector_svc:
+ push_svc_reg
+ bl rt_hw_trap_svc
+ b .
+
+ .globl vector_pabort
+vector_pabort:
+ push_svc_reg
+ bl rt_hw_trap_pabt
+ b .
+
+ .globl vector_dabort
+vector_dabort:
+ push_svc_reg
+ bl rt_hw_trap_dabt
+ b .
+
+ .globl vector_resv
+vector_resv:
+ push_svc_reg
+ bl rt_hw_trap_resv
+ b .
diff --git a/libcpu/arm/cortex-r4/trap.c b/libcpu/arm/cortex-r4/trap.c
index d77f9734da..b72237dac2 100644
--- a/libcpu/arm/cortex-r4/trap.c
+++ b/libcpu/arm/cortex-r4/trap.c
@@ -15,8 +15,10 @@
#include <rtthread.h>
#include <rthw.h>
-#include "RM48x50.h"
-//#define BSP_INT_DEBUG
+
+#include <sys_vim.h>
+
+#include "armv7.h"
/**
* @addtogroup RM48x50
@@ -28,7 +30,7 @@
*
* @param regs the registers point
*/
-void rt_hw_show_register (struct rt_hw_register *regs)
+void rt_hw_show_register (struct rt_hw_exp_stack *regs)
{
rt_kprintf("Execption:\n");
rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3);
@@ -40,14 +42,14 @@ void rt_hw_show_register (struct rt_hw_register *regs)
}
/**
- * When ARM7TDMI comes across an instruction which it cannot handle,
+ * When comes across an instruction which it cannot handle,
* it takes the undefined instruction trap.
*
* @param regs system registers
*
* @note never invoke this function in application
*/
-void rt_hw_trap_udef(struct rt_hw_register *regs)
+void rt_hw_trap_udef(struct rt_hw_exp_stack *regs)
{
rt_kprintf("undefined instruction\n");
rt_hw_show_register(regs);
@@ -65,12 +67,13 @@ void rt_hw_trap_udef(struct rt_hw_register *regs)
*
* @note never invoke this function in application
*/
-void rt_hw_trap_swi(struct rt_hw_register *regs)
+void rt_hw_trap_svc(struct rt_hw_exp_stack *regs)
{
rt_kprintf("software interrupt\n");
rt_hw_show_register(regs);
- if (rt_thread_self() != RT_NULL)
- rt_kprintf("Current Thread: %s\n", rt_thread_self()->name);
+#ifdef RT_USING_FINSH
+ list_thread();
+#endif
rt_hw_cpu_shutdown();
}
@@ -82,12 +85,13 @@ void rt_hw_trap_swi(struct rt_hw_register *regs)
*
* @note never invoke this function in application
*/
-void rt_hw_trap_pabt(struct rt_hw_register *regs)
+void rt_hw_trap_pabt(struct rt_hw_exp_stack *regs)
{
rt_kprintf("prefetch abort\n");
rt_hw_show_register(regs);
- if (rt_thread_self() != RT_NULL)
- rt_kprintf("Current Thread: %s\n", rt_thread_self()->name);
+#ifdef RT_USING_FINSH
+ list_thread();
+#endif
rt_hw_cpu_shutdown();
}
@@ -99,12 +103,13 @@ void rt_hw_trap_pabt(struct rt_hw_register *regs)
*
* @note never invoke this function in application
*/
-void rt_hw_trap_dabt(struct rt_hw_register *regs)
+void rt_hw_trap_dabt(struct rt_hw_exp_stack *regs)
{
rt_kprintf("Data Abort ");
rt_hw_show_register(regs);
- if (rt_thread_self() != RT_NULL)
- rt_kprintf("Current Thread: %s\n", rt_thread_self()->name);
+#ifdef RT_USING_FINSH
+ list_thread();
+#endif
rt_hw_cpu_shutdown();
}
@@ -115,19 +120,16 @@ void rt_hw_trap_dabt(struct rt_hw_register *regs)
*
* @note never invoke this function in application
*/
-void rt_hw_trap_resv(struct rt_hw_register *regs)
+void rt_hw_trap_resv(struct rt_hw_exp_stack *regs)
{
- rt_kprintf("not used\n");
+ rt_kprintf("Reserved trap\n");
rt_hw_show_register(regs);
- if (rt_thread_self() != RT_NULL)
- rt_kprintf("Current Thread: %s\n", rt_thread_self()->name);
+#ifdef RT_USING_FINSH
+ list_thread();
+#endif
rt_hw_cpu_shutdown();
}
-/*
- *#pragma CODE_STATE(rt_hw_trap_irq, 32)
- *#pragma INTERRUPT(rt_hw_trap_irq, IRQ)
- */
extern rt_isr_handler_t isr_table[];
void rt_hw_trap_irq(void)
{
diff --git a/libcpu/arm/cortex-r4/vector_ccs.asm b/libcpu/arm/cortex-r4/vector_ccs.asm
new file mode 100644
index 0000000000..df2bcec925
--- /dev/null
+++ b/libcpu/arm/cortex-r4/vector_ccs.asm
@@ -0,0 +1,34 @@
+;-------------------------------------------------------------------------------
+; sys_intvecs.asm
+;
+; (c) Texas Instruments 2009-2013, All rights reserved.
+;
+
+ .sect ".intvecs"
+ .arm
+
+;-------------------------------------------------------------------------------
+; import reference for interrupt routines
+
+ .ref _reset
+ .ref turnon_VFP
+ .ref vector_svc
+ .ref vector_pabort
+ .ref vector_dabort
+ .ref vector_resv
+ .ref IRQ_Handler
+
+;-------------------------------------------------------------------------------
+; interrupt vectors
+ .def resetEntry
+resetEntry
+ b _reset
+ b turnon_VFP
+ b vector_svc
+ b vector_pabort
+ b vector_dabort
+ b vector_resv
+ 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..da91421f43
--- /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 turnon_VFP
+ .globl vector_svc
+ .globl vector_pabort
+ .globl vector_dabort
+ .globl vector_resv
+ .globl IRQ_Handler
+
+
+.globl system_vectors
+system_vectors:
+ b _reset
+ b turnon_VFP
+ b vector_svc
+ b vector_pabort
+ b vector_dabort
+ b vector_resv
+ b IRQ_Handler
+ ldr pc,[pc,#-0x1b0]