summaryrefslogtreecommitdiff
path: root/libcpu
diff options
context:
space:
mode:
Diffstat (limited to 'libcpu')
-rw-r--r--libcpu/arm/cortex-r4/context_ccs.asm10
-rw-r--r--libcpu/arm/cortex-r4/cpu.c52
-rw-r--r--libcpu/arm/cortex-r4/interrupt.c2
3 files changed, 63 insertions, 1 deletions
diff --git a/libcpu/arm/cortex-r4/context_ccs.asm b/libcpu/arm/cortex-r4/context_ccs.asm
index dc4113f5e4..2b459f8238 100644
--- a/libcpu/arm/cortex-r4/context_ccs.asm
+++ b/libcpu/arm/cortex-r4/context_ccs.asm
@@ -28,18 +28,22 @@
; * rt_base_t rt_hw_interrupt_disable();
; */
.def rt_hw_interrupt_disable
+ .asmfunc
rt_hw_interrupt_disable
MRS r0, cpsr
CPSID IF
BX lr
+ .endasmfunc
;/*
; * void rt_hw_interrupt_enable(rt_base_t level);
; */
.def rt_hw_interrupt_enable
+ .asmfunc
rt_hw_interrupt_enable
MSR cpsr_c, r0
BX lr
+ .endasmfunc
;/*
; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
@@ -47,6 +51,7 @@ rt_hw_interrupt_enable
; * r1 --> to
; */
.def rt_hw_context_switch
+ .asmfunc
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
@@ -88,12 +93,14 @@ __no_vfp_frame2
MSR spsr_cxsf, r4
LDMIA sp!, {r0-r12, lr, pc}^ ; pop new task r0-r12, lr & pc, copy spsr to cpsr
+ .endasmfunc
;/*
; * void rt_hw_context_switch_to(rt_uint32 to);
; * r0 --> to
; */
.def rt_hw_context_switch_to
+ .asmfunc
rt_hw_context_switch_to
LDR sp, [r0] ; get new task stack pointer
@@ -112,12 +119,14 @@ __no_vfp_frame_to
MSR spsr_cxsf, r4
LDMIA sp!, {r0-r12, lr, pc}^ ; pop new task r0-r12, lr & pc, copy spsr to cpsr
+ .endasmfunc
;/*
; * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
; */
.def rt_hw_context_switch_interrupt
+ .asmfunc
rt_hw_context_switch_interrupt
LDR r2, pintflag
LDR r3, [r2]
@@ -131,6 +140,7 @@ _reswitch
LDR r2, ptothread ; set rt_interrupt_to_thread
STR r1, [r2]
BX lr
+ .endasmfunc
.def IRQ_Handler
IRQ_Handler
diff --git a/libcpu/arm/cortex-r4/cpu.c b/libcpu/arm/cortex-r4/cpu.c
index 569f7d0c29..d1b5c9df54 100644
--- a/libcpu/arm/cortex-r4/cpu.c
+++ b/libcpu/arm/cortex-r4/cpu.c
@@ -39,4 +39,56 @@ void rt_hw_cpu_shutdown()
while (1);
}
+#ifdef RT_USING_CPU_FFS
+int __rt_ffs(int value)
+{
+ if (value == 0)
+ return value;
+
+ __asm(" rsb r1, r0, #0");
+ __asm(" and r1, r1, r0");
+ __asm(" clz r1, r1");
+ __asm(" rsb r0, r1, #32");
+}
+#endif
+
+#ifdef __TI_COMPILER_VERSION__
+void rt_hw_cpu_icache_enable()
+{
+ __asm(" MRC p15, #0, r1, c1, c0, #0 ; Read SCTLR configuration data");
+ __asm(" ORR r1, r1, #0x1 <<12 ; instruction cache enable");
+ __asm(" MCR p15, #0, r0, c7, c5, #0 ; Invalidate entire instruction cache, r0 is ignored");
+ __asm(" MCR p15, #0, r1, c1, c0, #0 ; enabled instruction cache");
+ __asm(" ISB");
+}
+
+void rt_hw_cpu_icache_disable()
+{
+ __asm(" MRC p15, #0, r1, c1, c0, #0 ; Read SCTLR configuration data");
+ __asm(" BIC r1, r1, #0x1 <<12 ; instruction cache enable");
+ __asm(" MCR p15, #0, r1, c1, c0, #0 ; disabled instruction cache");
+ __asm(" ISB");
+}
+
+void rt_hw_cpu_dcache_enable()
+{
+ __asm(" MRC p15, #0, R1, c1, c0, #0 ; Read SCTLR configuration data");
+ __asm(" ORR R1, R1, #0x1 <<2");
+ __asm(" DSB");
+ __asm(" MCR p15, #0, r0, c15, c5, #0 ; Invalidate entire data cache");
+ __asm(" MCR p15, #0, R1, c1, c0, #0 ; enabled data cache");
+}
+
+void rt_hw_cpu_dcache_disable()
+{
+ /* FIXME: Clean entire data cache. This routine depends on the data cache
+ * size. It can be omitted if it is known that the data cache has no dirty
+ * data. */
+ __asm(" MRC p15, #0, r1, c1, c0, #0 ; Read SCTLR configuration data");
+ __asm(" BIC r1, r1, #0x1 <<2");
+ __asm(" DSB");
+ __asm(" MCR p15, #0, r1, c1, c0, #0 ; disabled data cache");
+}
+
+#endif
/*@}*/
diff --git a/libcpu/arm/cortex-r4/interrupt.c b/libcpu/arm/cortex-r4/interrupt.c
index 8d0a977db9..d001b509ee 100644
--- a/libcpu/arm/cortex-r4/interrupt.c
+++ b/libcpu/arm/cortex-r4/interrupt.c
@@ -22,7 +22,7 @@
/* exception and interrupt handler table */
struct rt_irq_desc irq_desc[MAX_HANDLERS];
-extern rt_uint32_t rt_interrupt_nest;
+extern volatile rt_uint8_t rt_interrupt_nest;
/* exception and interrupt handler table */
rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;