summaryrefslogtreecommitdiffstats
path: root/c
diff options
context:
space:
mode:
authorTill Straumann <strauman@slac.stanford.edu>2006-06-19 19:59:59 +0000
committerTill Straumann <strauman@slac.stanford.edu>2006-06-19 19:59:59 +0000
commit368894feef1b54628d186b5355619cd283a74230 (patch)
tree9d6d0ca1e39c73ce5f90392c227c5b1b2b8a3f01 /c
parent Never allow the FPU to be switched on for integer-only tasks (diff)
downloadrtems-368894feef1b54628d186b5355619cd283a74230.tar.bz2
FP context switch may be called from environment with no
FPU available (ISR, int-only task) - switch FPU on for the switch and restore MSR_FP after it's done.
Diffstat (limited to 'c')
-rw-r--r--c/src/lib/libcpu/powerpc/ChangeLog8
-rw-r--r--c/src/lib/libcpu/powerpc/new-exceptions/cpu_asm.S29
2 files changed, 35 insertions, 2 deletions
diff --git a/c/src/lib/libcpu/powerpc/ChangeLog b/c/src/lib/libcpu/powerpc/ChangeLog
index 48066f35ae..0df4583fca 100644
--- a/c/src/lib/libcpu/powerpc/ChangeLog
+++ b/c/src/lib/libcpu/powerpc/ChangeLog
@@ -1,7 +1,11 @@
2006-06-19 Till Straumann <strauman@slac.stanford.edu>
- * new-exceptions/cpu.c: Never allow the FPU to be switched
- on for integer-only tasks (new gcc may use FP regs implicitely).
+ * new-exceptions/cpu.c, new-exceptions/cpu_asm.S: Never
+ allow the FPU to be switched on for integer-only tasks
+ (new gcc may use FP regs implicitely).
+ FP context switch may be called from environment with no
+ FPU available (ISR, int-only task) - switch FPU on
+ for the switch and restore MSR_FP after it's done.
2006-05-16 Ralf Corsepius <ralf.corsepius@rtems.org>
diff --git a/c/src/lib/libcpu/powerpc/new-exceptions/cpu_asm.S b/c/src/lib/libcpu/powerpc/new-exceptions/cpu_asm.S
index b1bc2b9648..95e5d65c63 100644
--- a/c/src/lib/libcpu/powerpc/new-exceptions/cpu_asm.S
+++ b/c/src/lib/libcpu/powerpc/new-exceptions/cpu_asm.S
@@ -33,6 +33,7 @@
#include <rtems/asm.h>
#include <rtems/powerpc/powerpc.h>
+#include <rtems/powerpc/registers.h>
/*
* Offsets for various Contexts
@@ -161,6 +162,16 @@
PUBLIC_PROC (_CPU_Context_save_fp)
PROC (_CPU_Context_save_fp):
#if (PPC_HAS_FPU == 1)
+/* A FP context switch may occur in an ISR or exception handler when the FPU is not
+ * available. Therefore, we must explicitely enable it here!
+ */
+ mfmsr r4
+ andi. r5,r4,MSR_FP
+ bne 1f
+ ori r5,r4,MSR_FP
+ mtmsr r5
+ isync
+1:
lwz r3, 0(r3)
STF f0, FP_0(r3)
STF f1, FP_1(r3)
@@ -196,6 +207,10 @@ PROC (_CPU_Context_save_fp):
STF f31, FP_31(r3)
mffs f2
STF f2, FP_FPSCR(r3)
+ bne 1f
+ mtmsr r4
+ isync
+1:
#endif
blr
@@ -217,6 +232,16 @@ PROC (_CPU_Context_save_fp):
PROC (_CPU_Context_restore_fp):
#if (PPC_HAS_FPU == 1)
lwz r3, 0(r3)
+/* A FP context switch may occur in an ISR or exception handler when the FPU is not
+ * available. Therefore, we must explicitely enable it here!
+ */
+ mfmsr r4
+ andi. r5,r4,MSR_FP
+ bne 1f
+ ori r5,r4,MSR_FP
+ mtmsr r5
+ isync
+1:
LDF f2, FP_FPSCR(r3)
mtfsf 255, f2
LDF f0, FP_0(r3)
@@ -251,6 +276,10 @@ PROC (_CPU_Context_restore_fp):
LDF f29, FP_29(r3)
LDF f30, FP_30(r3)
LDF f31, FP_31(r3)
+ bne 1f
+ mtmsr r4
+ isync
+1:
#endif
blr