summaryrefslogtreecommitdiff
path: root/libcpu
diff options
context:
space:
mode:
authorGrissiom <[email protected]>2013-05-31 20:25:44 +0800
committerGrissiom <[email protected]>2013-05-31 20:58:08 +0800
commit24fc6e6ebbb5769941845e4549382be6d6f76ced (patch)
tree3242febd63cc487a0b65229999c1a5d5db8d9fa0 /libcpu
parent8bbfd45ce3bd78d01e8c03bd5877825f1bb4d610 (diff)
rm48x50: VFP lazy stacking
You need to turn on RT_VFP_LAZY_STACKING in rtconfig.h. By default, RTT will turn on VFP for all threads and stack all the VFP registers. When doing lazy stacking, VFP will only be turned on for the thread who issued VFP instructions. Currently, if a thread turned on VFP, it cannot be turned off. RTT will never know what time the thread doesn't need VFP any more. The thread might could turn off the VFP for it self in proper time.
Diffstat (limited to 'libcpu')
-rw-r--r--libcpu/arm/rm48x50/context_ccs.asm12
-rw-r--r--libcpu/arm/rm48x50/stack.c9
2 files changed, 13 insertions, 8 deletions
diff --git a/libcpu/arm/rm48x50/context_ccs.asm b/libcpu/arm/rm48x50/context_ccs.asm
index 695844e300..dc4113f5e4 100644
--- a/libcpu/arm/rm48x50/context_ccs.asm
+++ b/libcpu/arm/rm48x50/context_ccs.asm
@@ -75,13 +75,13 @@ __no_vfp_frame1
.if (__TI_VFP_SUPPORT__)
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
- VMSR fpexc, r0
.endif
LDMIA sp!, {r4} ; pop new task cpsr to spsr
@@ -99,13 +99,13 @@ rt_hw_context_switch_to
.if (__TI_VFP_SUPPORT__)
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
- VMSR fpexc, r0
.endif
LDMIA sp!, {r4} ; pop new task cpsr to spsr
@@ -162,13 +162,13 @@ __no_vfp_frame_str_irq
.if (__TI_VFP_SUPPORT__)
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
- VMSR fpexc, r0
.endif
LDMIA sp!, {r0-r12,lr}
@@ -184,13 +184,13 @@ rt_hw_context_switch_interrupt_do
.if (__TI_VFP_SUPPORT__)
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
- VMSR fpexc, r0
.endif
LDMIA sp!, {r0-r12,lr} ; reload saved registers
@@ -216,7 +216,7 @@ __no_vfp_frame_do1
VMRS r0, fpexc
TST r0, #0x40000000
BEQ __no_vfp_frame_do2
- VSTMDB sp!, {d0-d15}
+ VSTMDB sp!, {d0-d15}
VMRS r1, fpscr
; TODO: add support for Common VFPv3.
; Save registers like FPINST, FPINST2
@@ -235,13 +235,13 @@ __no_vfp_frame_do2
.if (__TI_VFP_SUPPORT__)
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
- VMSR fpexc, r0
.endif
LDMIA sp!, {r4} ; pop new task's cpsr to spsr
diff --git a/libcpu/arm/rm48x50/stack.c b/libcpu/arm/rm48x50/stack.c
index a11d8896f9..02dc84e6f1 100644
--- a/libcpu/arm/rm48x50/stack.c
+++ b/libcpu/arm/rm48x50/stack.c
@@ -58,8 +58,9 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
*(--stk) = SVCMODE; /* arm mode */
#ifdef __TI_VFP_SUPPORT__
- #define VFP_DATA_NR 32
+#ifndef RT_VFP_LAZY_STACKING
{
+ #define VFP_DATA_NR 32
int i;
for (i = 0; i < VFP_DATA_NR; i++)
@@ -68,9 +69,13 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
}
/* FPSCR TODO: do we need to set the values other than 0? */
*(--stk) = 0;
- /* FPEXC. Enable the FVP by default. */
+ /* FPEXC. Enable the FVP if no lazy stacking. */
*(--stk) = 0x40000000;
}
+#else
+ /* FPEXC. Disable the FVP by default. */
+ *(--stk) = 0x00000000;
+#endif
#endif
/* return task's current stack address */