patch-2.4.22 linux-2.4.22/arch/mips64/kernel/r4k_switch.S
Next file: linux-2.4.22/arch/mips64/kernel/scall_64.S
Previous file: linux-2.4.22/arch/mips64/kernel/r4k_genex.S
Back to the patch index
Back to the overall index
- Lines: 160
- Date:
2003-08-25 04:44:40.000000000 -0700
- Orig file:
linux-2.4.21/arch/mips64/kernel/r4k_switch.S
- Orig date:
2002-11-28 15:53:10.000000000 -0800
diff -urN linux-2.4.21/arch/mips64/kernel/r4k_switch.S linux-2.4.22/arch/mips64/kernel/r4k_switch.S
@@ -23,6 +23,19 @@
.set mips3
+#define PF_USEDFPU 0x00100000 /* task used FPU this quantum (SMP) */
+#define ST_OFF (KERNEL_STACK_SIZE - 32 - PT_SIZE + PT_STATUS)
+
+/*
+ * [jsun] FPU context is saved if and only if the process has used FPU in
+ * the current run (PF_USEDFPU). In any case, the CU1 bit for user space
+ * STATUS register should be 0, so that a process *always* starts its
+ * userland with FPU disabled after each context switch.
+ *
+ * FPU will be enabled as soon as the process accesses FPU again, through
+ * do_cpu() trap.
+ */
+
/*
* task_struct *resume(task_struct *prev, task_struct *next)
*/
@@ -35,6 +48,38 @@
sd ra, THREAD_REG31(a0)
/*
+ * check if we need to save FPU registers
+ */
+ ld t0, TASK_FLAGS(a0)
+ li t1, PF_USEDFPU
+ and t2, t0, t1
+ beqz t2, 1f
+ nor t1, zero, t1
+
+ /*
+ * clear PF_USEDFPU bit in task flags
+ */
+ and t0, t0, t1
+ sd t0, TASK_FLAGS(a0)
+
+ /*
+ * clear saved user stack CU1 bit
+ */
+ ld t0, ST_OFF(a0)
+ li t1, ~ST0_CU1
+ and t0, t0, t1
+ sd t0, ST_OFF(a0)
+
+
+ sll t2, t0, 5
+ bgez t2, 2f
+ sdc1 $f0, (THREAD_FPU + 0x00)(a0)
+ fpu_save_16odd a0
+2:
+ fpu_save_16even a0 t1 # clobbers t1
+1:
+
+ /*
* The order of restoring the registers takes care of the race
* updating $28, $29 and kernelsp without disabling ints.
*/
@@ -42,7 +87,7 @@
cpu_restore_nonscratch $28
daddiu a1, $28, KERNEL_STACK_SIZE-32
- set_saved_sp a1 t0
+ set_saved_sp a1, t0, t1
mfc0 t1, CP0_STATUS /* Do we really need this? */
li a3, 0xff00
@@ -57,51 +102,10 @@
END(resume)
/*
- * Do lazy fpu context switch. Saves FPU context to the process in a0
- * and loads the new context of the current process.
- */
-
-#define ST_OFF (KERNEL_STACK_SIZE - 32 - PT_SIZE + PT_STATUS)
-
-LEAF(lazy_fpu_switch)
- mfc0 t0, CP0_STATUS # enable cp1
- li t3, ST0_CU1
- or t0, t3
- mtc0 t0, CP0_STATUS
- FPU_ENABLE_HAZARD
-
- beqz a0, 2f # Save floating point state
- nor t3, zero, t3
-
- ld t1, ST_OFF(a0) # last thread looses fpu
- and t1, t3
- sd t1, ST_OFF(a0)
- sll t2, t1, 5
- bgez t2, 1f
- sdc1 $f0, (THREAD_FPU + 0x00)(a0)
- fpu_save_16odd a0
-1:
- fpu_save_16even a0 t1 # clobbers t1
-2:
-
- beqz a1, 3f
-
- sll t0, t0, 5 # load new fp state
- bgez t0, 1f
- ldc1 $f0, (THREAD_FPU + 0x00)(a1)
- fpu_restore_16odd a1
-1:
- .set reorder
- fpu_restore_16even a1, t0 # clobbers t0
-3:
- jr ra
- END(lazy_fpu_switch)
-
-/*
* Save a thread's fp context.
*/
.set noreorder
-LEAF(save_fp)
+LEAF(_save_fp)
mfc0 t0, CP0_STATUS
sll t1, t0, 5
bgez t1, 1f # 16 register mode?
@@ -111,12 +115,12 @@
fpu_save_16even a0 t1 # clobbers t1
jr ra
sdc1 $f0, (THREAD_FPU + 0x00)(a0)
- END(save_fp)
+ END(_save_fp)
/*
* Restore a thread's fp context.
*/
-LEAF(restore_fp)
+LEAF(_restore_fp)
mfc0 t0, CP0_STATUS
sll t1, t0, 5
bgez t1, 1f # 16 register mode?
@@ -128,7 +132,7 @@
jr ra
ldc1 $f0, (THREAD_FPU + 0x00)(a0)
- END(restore_fp)
+ END(_restore_fp)
/*
* Load the FPU with signalling NANS. This bit pattern we're using has
@@ -140,7 +144,7 @@
#define FPU_DEFAULT 0x00000000
-LEAF(init_fpu)
+LEAF(_init_fpu)
mfc0 t0, CP0_STATUS
li t1, ST0_CU1
or t0, t1
@@ -188,4 +192,4 @@
dmtc1 t0, $f28
jr ra
dmtc1 t0, $f30
- END(init_fpu)
+ END(_init_fpu)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)