|
@@ -10,24 +10,12 @@
|
|
* Copyright (C) 2000 MIPS Technologies, Inc.
|
|
* Copyright (C) 2000 MIPS Technologies, Inc.
|
|
* written by Carsten Langgaard, carstenl@mips.com
|
|
* written by Carsten Langgaard, carstenl@mips.com
|
|
*/
|
|
*/
|
|
-#include <asm/asm.h>
|
|
|
|
-#include <asm/cachectl.h>
|
|
|
|
-#include <asm/fpregdef.h>
|
|
|
|
-#include <asm/mipsregs.h>
|
|
|
|
-#include <asm/asm-offsets.h>
|
|
|
|
-#include <asm/pgtable-bits.h>
|
|
|
|
-#include <asm/regdef.h>
|
|
|
|
-#include <asm/stackframe.h>
|
|
|
|
-#include <asm/thread_info.h>
|
|
|
|
-
|
|
|
|
-#include <asm/asmmacro.h>
|
|
|
|
-
|
|
|
|
-/*
|
|
|
|
- * Offset to the current process status flags, the first 32 bytes of the
|
|
|
|
- * stack are not used.
|
|
|
|
- */
|
|
|
|
-#define ST_OFF (_THREAD_SIZE - 32 - PT_SIZE + PT_STATUS)
|
|
|
|
|
|
|
|
|
|
+#define USE_ALTERNATE_RESUME_IMPL 1
|
|
|
|
+ .set push
|
|
|
|
+ .set arch=mips64r2
|
|
|
|
+#include "r4k_switch.S"
|
|
|
|
+ .set pop
|
|
/*
|
|
/*
|
|
* task_struct *resume(task_struct *prev, task_struct *next,
|
|
* task_struct *resume(task_struct *prev, task_struct *next,
|
|
* struct thread_info *next_ti, int usedfpu)
|
|
* struct thread_info *next_ti, int usedfpu)
|
|
@@ -40,6 +28,61 @@
|
|
cpu_save_nonscratch a0
|
|
cpu_save_nonscratch a0
|
|
LONG_S ra, THREAD_REG31(a0)
|
|
LONG_S ra, THREAD_REG31(a0)
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * check if we need to save FPU registers
|
|
|
|
+ */
|
|
|
|
+ PTR_L t3, TASK_THREAD_INFO(a0)
|
|
|
|
+ LONG_L t0, TI_FLAGS(t3)
|
|
|
|
+ li t1, _TIF_USEDFPU
|
|
|
|
+ and t2, t0, t1
|
|
|
|
+ beqz t2, 1f
|
|
|
|
+ nor t1, zero, t1
|
|
|
|
+
|
|
|
|
+ and t0, t0, t1
|
|
|
|
+ LONG_S t0, TI_FLAGS(t3)
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * clear saved user stack CU1 bit
|
|
|
|
+ */
|
|
|
|
+ LONG_L t0, ST_OFF(t3)
|
|
|
|
+ li t1, ~ST0_CU1
|
|
|
|
+ and t0, t0, t1
|
|
|
|
+ LONG_S t0, ST_OFF(t3)
|
|
|
|
+
|
|
|
|
+ .set push
|
|
|
|
+ .set arch=mips64r2
|
|
|
|
+ fpu_save_double a0 t0 t1 # c0_status passed in t0
|
|
|
|
+ # clobbers t1
|
|
|
|
+ .set pop
|
|
|
|
+1:
|
|
|
|
+
|
|
|
|
+ /* check if we need to save COP2 registers */
|
|
|
|
+ PTR_L t2, TASK_THREAD_INFO(a0)
|
|
|
|
+ LONG_L t0, ST_OFF(t2)
|
|
|
|
+ bbit0 t0, 30, 1f
|
|
|
|
+
|
|
|
|
+ /* Disable COP2 in the stored process state */
|
|
|
|
+ li t1, ST0_CU2
|
|
|
|
+ xor t0, t1
|
|
|
|
+ LONG_S t0, ST_OFF(t2)
|
|
|
|
+
|
|
|
|
+ /* Enable COP2 so we can save it */
|
|
|
|
+ mfc0 t0, CP0_STATUS
|
|
|
|
+ or t0, t1
|
|
|
|
+ mtc0 t0, CP0_STATUS
|
|
|
|
+
|
|
|
|
+ /* Save COP2 */
|
|
|
|
+ daddu a0, THREAD_CP2
|
|
|
|
+ jal octeon_cop2_save
|
|
|
|
+ dsubu a0, THREAD_CP2
|
|
|
|
+
|
|
|
|
+ /* Disable COP2 now that we are done */
|
|
|
|
+ mfc0 t0, CP0_STATUS
|
|
|
|
+ li t1, ST0_CU2
|
|
|
|
+ xor t0, t1
|
|
|
|
+ mtc0 t0, CP0_STATUS
|
|
|
|
+
|
|
|
|
+1:
|
|
#if CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0
|
|
#if CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0
|
|
/* Check if we need to store CVMSEG state */
|
|
/* Check if we need to store CVMSEG state */
|
|
mfc0 t0, $11,7 /* CvmMemCtl */
|
|
mfc0 t0, $11,7 /* CvmMemCtl */
|
|
@@ -85,12 +128,7 @@
|
|
move $28, a2
|
|
move $28, a2
|
|
cpu_restore_nonscratch a1
|
|
cpu_restore_nonscratch a1
|
|
|
|
|
|
-#if (_THREAD_SIZE - 32) < 0x8000
|
|
|
|
- PTR_ADDIU t0, $28, _THREAD_SIZE - 32
|
|
|
|
-#else
|
|
|
|
- PTR_LI t0, _THREAD_SIZE - 32
|
|
|
|
- PTR_ADDU t0, $28
|
|
|
|
-#endif
|
|
|
|
|
|
+ PTR_ADDU t0, $28, _THREAD_SIZE - 32
|
|
set_saved_sp t0, t1, t2
|
|
set_saved_sp t0, t1, t2
|
|
|
|
|
|
mfc0 t1, CP0_STATUS /* Do we really need this? */
|
|
mfc0 t1, CP0_STATUS /* Do we really need this? */
|