fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / arch / mips / kernel / r4k_switch.S
index 9eb885d..cc566cf 100644 (file)
  * Copyright (C) 2000 MIPS Technologies, Inc.
  *    written by Carsten Langgaard, carstenl@mips.com
  */
-#include <linux/config.h>
 #include <asm/asm.h>
 #include <asm/cachectl.h>
 #include <asm/fpregdef.h>
 #include <asm/mipsregs.h>
-#include <asm/offset.h>
+#include <asm/asm-offsets.h>
 #include <asm/page.h>
 #include <asm/pgtable-bits.h>
 #include <asm/regdef.h>
@@ -33,7 +32,7 @@
 /*
  * FPU context is saved iff the process has used it's FPU in the current
  * time slice as indicated by _TIF_USEDFPU.  In any case, the CU1 bit for user
- * space STATUS register should be 0, so that a process *always* starts its 
+ * 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
        and     t0, t0, t1
        LONG_S  t0, ST_OFF(t3)
 
-#ifdef CONFIG_MIPS32
-       fpu_save_double a0 t0                   # clobbers t0
-#endif
-#ifdef CONFIG_MIPS64
-       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
-#endif
+       fpu_save_double a0 t0 t1                # c0_status passed in t0
+                                               # clobbers t1
 1:
 
        /*
        move    $28, a2
        cpu_restore_nonscratch a1
 
+#if (_THREAD_SIZE - 32) < 0x10000
        PTR_ADDIU       t0, $28, _THREAD_SIZE - 32
+#else
+       PTR_LI          t0, _THREAD_SIZE - 32
+       PTR_ADDU        t0, $28
+#endif
        set_saved_sp    t0, t1, t2
-
+#ifdef CONFIG_MIPS_MT_SMTC
+       /* Read-modify-writes of Status must be atomic on a VPE */
+       mfc0    t2, CP0_TCSTATUS
+       ori     t1, t2, TCSTATUS_IXMT
+       mtc0    t1, CP0_TCSTATUS
+       andi    t2, t2, TCSTATUS_IXMT
+       _ehb
+       DMT     8                               # dmt   t0
+       move    t1,ra
+       jal     mips_ihb
+       move    ra,t1
+#endif /* CONFIG_MIPS_MT_SMTC */
        mfc0    t1, CP0_STATUS          /* Do we really need this? */
        li      a3, 0xff01
        and     t1, a3
        and     a2, a3
        or      a2, t1
        mtc0    a2, CP0_STATUS
+#ifdef CONFIG_MIPS_MT_SMTC
+       _ehb
+       andi    t0, t0, VPECONTROL_TE
+       beqz    t0, 1f
+       emt
+1:
+       mfc0    t1, CP0_TCSTATUS
+       xori    t1, t1, TCSTATUS_IXMT
+       or      t1, t1, t2
+       mtc0    t1, CP0_TCSTATUS
+       _ehb
+#endif /* CONFIG_MIPS_MT_SMTC */
        move    v0, a0
        jr      ra
        END(resume)
  * Save a thread's fp context.
  */
 LEAF(_save_fp)
-#ifdef CONFIG_MIPS32
-       fpu_save_double a0 t1                   # clobbers t1
-#endif
-#ifdef CONFIG_MIPS64
+#ifdef CONFIG_64BIT
        mfc0    t0, CP0_STATUS
-       sll     t1, t0, 5
-       bgez    t1, 1f                          # 16 register mode?
-       fpu_save_16odd a0
-1:
-       fpu_save_16even a0 t1                   # clobbers t1
-       sdc1    $f0, (THREAD_FPU + 0x00)(a0)
 #endif
+       fpu_save_double a0 t0 t1                # clobbers t1
        jr      ra
        END(_save_fp)
 
@@ -133,19 +143,10 @@ LEAF(_save_fp)
  * Restore a thread's fp context.
  */
 LEAF(_restore_fp)
-#ifdef CONFIG_MIPS32
-       fpu_restore_double a0, t1               # clobbers t1
-#endif
-#ifdef CONFIG_MIPS64
+#ifdef CONFIG_64BIT
        mfc0    t0, CP0_STATUS
-       sll     t1, t0, 5
-       bgez    t1, 1f                          # 16 register mode?
-
-       fpu_restore_16odd a0
-1:     fpu_restore_16even a0, t0               # clobbers t0
-        ldc1   $f0, (THREAD_FPU + 0x00)(a0)
 #endif
-
+       fpu_restore_double a0 t0 t1             # clobbers t1
        jr      ra
        END(_restore_fp)
 
@@ -160,10 +161,19 @@ LEAF(_restore_fp)
 #define FPU_DEFAULT  0x00000000
 
 LEAF(_init_fpu)
+#ifdef CONFIG_MIPS_MT_SMTC
+       /* Rather than manipulate per-VPE Status, set per-TC bit in TCStatus */
+       mfc0    t0, CP0_TCSTATUS
+       /* Bit position is the same for Status, TCStatus */
+       li      t1, ST0_CU1
+       or      t0, t1
+       mtc0    t0, CP0_TCSTATUS
+#else /* Normal MIPS CU1 enable */
        mfc0    t0, CP0_STATUS
        li      t1, ST0_CU1
        or      t0, t1
        mtc0    t0, CP0_STATUS
+#endif /* CONFIG_MIPS_MT_SMTC */
        fpu_enable_hazard
 
        li      t1, FPU_DEFAULT
@@ -171,7 +181,7 @@ LEAF(_init_fpu)
 
        li      t1, -1                          # SNaN
 
-#ifdef CONFIG_MIPS64
+#ifdef CONFIG_64BIT
        sll     t0, t0, 5
        bgez    t0, 1f                          # 16 / 32 register mode?
 
@@ -193,7 +203,7 @@ LEAF(_init_fpu)
        dmtc1   t1, $f31
 1:
 #endif
-       
+
 #ifdef CONFIG_CPU_MIPS32
        mtc1    t1, $f0
        mtc1    t1, $f1