1 | This patch (against rtems-ss-20020301) fixes saving / restoring |
---|
2 | floating point context. |
---|
3 | The fpsave / fprestore routines are only used in a executing |
---|
4 | context which _is_ fp and hence has the FPU enabled. The current |
---|
5 | behavior required the FPU always to be on which is very dangerous |
---|
6 | if lazy context switching is used. |
---|
7 | |
---|
8 | The patch also makes sure (on powerpc only) that the FPU is disabled |
---|
9 | for integer tasks. Note that this is crucial if deferred fp context |
---|
10 | switching is used. Otherwise, fp context corruption may go undetected! |
---|
11 | Also note that even tasks which merely push/pop FP registers to/from the stack |
---|
12 | without modifying them still MUST be FP tasks - otherwise (if lazy FP |
---|
13 | context switching is used), FP register corruption (of other, FP, tasks |
---|
14 | may occur)! |
---|
15 | |
---|
16 | Furthermore, (on PPC) by default, lazy FP context save/restore is _disabled_ |
---|
17 | |
---|
18 | |
---|
19 | Author: Till Straumann <strauman@slac.stanford.edu>, 4/2002 |
---|
20 | |
---|
21 | Index: c/src/exec/score/src/threaddispatch.c |
---|
22 | =================================================================== |
---|
23 | RCS file: /afs/slac/g/spear/cvsrep/rtems/src/c/src/exec/score/src/threaddispatch.c,v |
---|
24 | retrieving revision 1.1.1.1 |
---|
25 | retrieving revision 1.4 |
---|
26 | diff -c -r1.1.1.1 -r1.4 |
---|
27 | *** c/src/exec/score/src/threaddispatch.c 2001/12/14 22:49:52 1.1.1.1 |
---|
28 | --- c/src/exec/score/src/threaddispatch.c 2002/04/24 22:50:28 1.4 |
---|
29 | *************** |
---|
30 | *** 93,115 **** |
---|
31 | */ |
---|
32 | |
---|
33 | #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) |
---|
34 | #if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE ) |
---|
35 | ! if ( (heir->fp_context != NULL) && !_Thread_Is_allocated_fp( heir ) ) { |
---|
36 | if ( _Thread_Allocated_fp != NULL ) |
---|
37 | _Context_Save_fp( &_Thread_Allocated_fp->fp_context ); |
---|
38 | ! _Context_Restore_fp( &heir->fp_context ); |
---|
39 | ! _Thread_Allocated_fp = heir; |
---|
40 | } |
---|
41 | #else |
---|
42 | if ( executing->fp_context != NULL ) |
---|
43 | ! _Context_Save_fp( &executing->fp_context ); |
---|
44 | ! |
---|
45 | ! if ( heir->fp_context != NULL ) |
---|
46 | ! _Context_Restore_fp( &heir->fp_context ); |
---|
47 | #endif |
---|
48 | #endif |
---|
49 | - |
---|
50 | - _Context_Switch( &executing->Registers, &heir->Registers ); |
---|
51 | |
---|
52 | executing = _Thread_Executing; |
---|
53 | |
---|
54 | --- 93,119 ---- |
---|
55 | */ |
---|
56 | |
---|
57 | #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) |
---|
58 | + #if ( CPU_USE_DEFERRED_FP_SWITCH != TRUE ) |
---|
59 | + if ( executing->fp_context != NULL ) |
---|
60 | + _Context_Save_fp( &executing->fp_context ); |
---|
61 | + #endif |
---|
62 | + #endif |
---|
63 | + |
---|
64 | + _Context_Switch( &executing->Registers, &heir->Registers ); |
---|
65 | + |
---|
66 | + #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) |
---|
67 | #if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE ) |
---|
68 | ! if ( (executing->fp_context != NULL) && !_Thread_Is_allocated_fp( executing ) ) { |
---|
69 | if ( _Thread_Allocated_fp != NULL ) |
---|
70 | _Context_Save_fp( &_Thread_Allocated_fp->fp_context ); |
---|
71 | ! _Context_Restore_fp( &executing->fp_context ); |
---|
72 | ! _Thread_Allocated_fp = executing; |
---|
73 | } |
---|
74 | #else |
---|
75 | if ( executing->fp_context != NULL ) |
---|
76 | ! _Context_Restore_fp( &executing->fp_context ); |
---|
77 | #endif |
---|
78 | #endif |
---|
79 | |
---|
80 | executing = _Thread_Executing; |
---|
81 | |
---|
82 | Index: c/src/exec/score/src/threadhandler.c |
---|
83 | =================================================================== |
---|
84 | RCS file: /afs/slac/g/spear/cvsrep/rtems/src/c/src/exec/score/src/threadhandler.c,v |
---|
85 | retrieving revision 1.1.1.2 |
---|
86 | retrieving revision 1.3 |
---|
87 | diff -c -r1.1.1.2 -r1.3 |
---|
88 | *** c/src/exec/score/src/threadhandler.c 2001/12/15 00:08:12 1.1.1.2 |
---|
89 | --- c/src/exec/score/src/threadhandler.c 2002/05/05 18:14:53 1.3 |
---|
90 | *************** |
---|
91 | *** 78,83 **** |
---|
92 | --- 78,94 ---- |
---|
93 | doneConstructors = 1; |
---|
94 | #endif |
---|
95 | |
---|
96 | + #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) |
---|
97 | + #if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE ) |
---|
98 | + if ( (executing->fp_context != NULL) && !_Thread_Is_allocated_fp( executing ) ) { |
---|
99 | + if ( _Thread_Allocated_fp != NULL ) |
---|
100 | + _Context_Save_fp( &_Thread_Allocated_fp->fp_context ); |
---|
101 | + _Thread_Allocated_fp = executing; |
---|
102 | + } |
---|
103 | + #endif |
---|
104 | + #endif |
---|
105 | + |
---|
106 | + |
---|
107 | /* |
---|
108 | * Take care that 'begin' extensions get to complete before |
---|
109 | * 'switch' extensions can run. This means must keep dispatch |
---|
110 | Index: c/src/lib/libbsp/powerpc/support/new_exception_processing/cpu.c |
---|
111 | =================================================================== |
---|
112 | RCS file: /afs/slac/g/spear/cvsrep/rtems/src/c/src/lib/libbsp/powerpc/support/new_exception_processing/cpu.c,v |
---|
113 | retrieving revision 1.1.1.1 |
---|
114 | retrieving revision 1.2 |
---|
115 | diff -c -r1.1.1.1 -r1.2 |
---|
116 | *** c/src/lib/libbsp/powerpc/support/new_exception_processing/cpu.c 2001/12/15 00:14:11 1.1.1.1 |
---|
117 | --- c/src/lib/libbsp/powerpc/support/new_exception_processing/cpu.c 2002/04/21 00:17:39 1.2 |
---|
118 | *************** |
---|
119 | *** 93,100 **** |
---|
120 | * time (7 July 1997), this restructuring is not being done. |
---|
121 | */ |
---|
122 | |
---|
123 | ! /*if ( is_fp ) */ |
---|
124 | the_context->msr |= PPC_MSR_FP; |
---|
125 | |
---|
126 | the_context->pc = (unsigned32)entry_point; |
---|
127 | } |
---|
128 | --- 93,112 ---- |
---|
129 | * time (7 July 1997), this restructuring is not being done. |
---|
130 | */ |
---|
131 | |
---|
132 | ! /* Till Straumann: For deferred FPContext save/restore, make sure integer |
---|
133 | ! * tasks have no FPU access in order to catch violations. |
---|
134 | ! * Otherwise, the FP registers may be corrupted. |
---|
135 | ! * Since we set the_contex->msr using our current MSR, |
---|
136 | ! * we must make sure MSR_FP is off if (!is_fp)... |
---|
137 | ! */ |
---|
138 | ! #if defined(CPU_USE_DEFERRED_FP_SWITCH) && (CPU_USE_DEFERRED_FP_SWITCH==TRUE) |
---|
139 | ! if ( is_fp ) |
---|
140 | ! #endif |
---|
141 | the_context->msr |= PPC_MSR_FP; |
---|
142 | + #if defined(CPU_USE_DEFERRED_FP_SWITCH) && (CPU_USE_DEFERRED_FP_SWITCH==TRUE) |
---|
143 | + else |
---|
144 | + the_context->msr &= ~PPC_MSR_FP; |
---|
145 | + #endif |
---|
146 | |
---|
147 | the_context->pc = (unsigned32)entry_point; |
---|
148 | } |
---|
149 | Index: c/src/lib/libbsp/powerpc/support/new_exception_processing/rtems/score/cpu.h |
---|
150 | =================================================================== |
---|
151 | RCS file: /afs/slac/g/spear/cvsrep/rtems/src/c/src/lib/libbsp/powerpc/support/new_exception_processing/rtems/score/cpu.h,v |
---|
152 | retrieving revision 1.1.1.1 |
---|
153 | retrieving revision 1.3 |
---|
154 | diff -c -r1.1.1.1 -r1.3 |
---|
155 | *** c/src/lib/libbsp/powerpc/support/new_exception_processing/rtems/score/cpu.h 2001/12/15 00:14:11 1.1.1.1 |
---|
156 | --- c/src/lib/libbsp/powerpc/support/new_exception_processing/rtems/score/cpu.h 2002/04/24 22:50:29 1.3 |
---|
157 | *************** |
---|
158 | *** 229,240 **** |
---|
159 | * until a context switch is made to another, different FP task. |
---|
160 | * Thus in a system with only one FP task, the FP context will never |
---|
161 | * be saved or restored. |
---|
162 | */ |
---|
163 | /* |
---|
164 | * ACB Note: This could make debugging tricky.. |
---|
165 | */ |
---|
166 | |
---|
167 | ! #define CPU_USE_DEFERRED_FP_SWITCH TRUE |
---|
168 | |
---|
169 | /* |
---|
170 | * Does this port provide a CPU dependent IDLE task implementation? |
---|
171 | --- 229,247 ---- |
---|
172 | * until a context switch is made to another, different FP task. |
---|
173 | * Thus in a system with only one FP task, the FP context will never |
---|
174 | * be saved or restored. |
---|
175 | + * |
---|
176 | + * Note, however that compilers may use floating point registers/ |
---|
177 | + * instructions for optimization or they may save/restore FP registers |
---|
178 | + * on the stack. You must not use deferred switching in these cases |
---|
179 | + * and on the PowerPC attempting to do so will raise a "FP unavailable" |
---|
180 | + * exception. |
---|
181 | */ |
---|
182 | /* |
---|
183 | * ACB Note: This could make debugging tricky.. |
---|
184 | */ |
---|
185 | |
---|
186 | ! /* conservative setting (FALSE); probably doesn't affect performance too much */ |
---|
187 | ! #define CPU_USE_DEFERRED_FP_SWITCH FALSE |
---|
188 | |
---|
189 | /* |
---|
190 | * Does this port provide a CPU dependent IDLE task implementation? |
---|