Import 2.3.9pre4
[davej-history.git] / arch / mips / kernel / r4k_switch.S
blob8868c5beede2cff2a74ab9fd8845bf50b43ce9c7
1 /* $Id: r4k_switch.S,v 1.4 1998/07/14 09:15:33 ralf Exp $
2  *
3  * This file is subject to the terms and conditions of the GNU General Public
4  * License.  See the file "COPYING" in the main directory of this archive
5  * for more details.
6  *
7  * Copyright (C) 1994, 1995, 1996, 1998 by Ralf Baechle
8  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
9  * Copyright (C) 1994, 1995, 1996, by Andreas Busse
10  */
11 #include <asm/asm.h>
12 #include <asm/bootinfo.h>
13 #include <asm/cachectl.h>
14 #include <asm/current.h>
15 #include <asm/fpregdef.h>
16 #include <asm/mipsconfig.h>
17 #include <asm/mipsregs.h>
18 #include <asm/offset.h>
19 #include <asm/page.h>
20 #include <asm/pgtable.h>
21 #include <asm/processor.h>
22 #include <asm/regdef.h>
23 #include <asm/stackframe.h>
25 #include <asm/asmmacro.h>
27         .set    noreorder
28         .set    mips3
29         .align  5
30         LEAF(r4xx0_resume)
31         mfc0    t1, CP0_STATUS
32         sw      t1, THREAD_STATUS($28)
33         CPU_SAVE_NONSCRATCH($28)
34         sw      ra, THREAD_REG31($28)
36         /*
37          * The order of restoring the registers takes care of the race
38          * updating $28, $29 and kernelsp without disabling ints.
39          */
40         move    $28, a0
41         CPU_RESTORE_NONSCRATCH($28)
42         addiu   t0, $28, KERNEL_STACK_SIZE-32
43         sw      t0, kernelsp
44         lw      a3, TASK_MM($28)
45         lw      a2, THREAD_STATUS($28)
46         lw      a3, MM_CONTEXT(a3)
47         mtc0    a2, CP0_STATUS
48         andi    a3, a3, 0xff
49         jr      ra
50          mtc0   a3, CP0_ENTRYHI
51         END(r4xx0_resume)
54  * Do lazy fpu context switch.  Saves FPU context to the process in a0
55  * and loads the new context of the current process.
56  */
58 #define ST_OFF (KERNEL_STACK_SIZE - 32 - PT_SIZE + PT_STATUS)
60 LEAF(r4xx0_lazy_fpu_switch)
61         mfc0    t0, CP0_STATUS                  # enable cp1
62         li      t3, 0x20000000
63         or      t0, t3
64         mtc0    t0, CP0_STATUS
66         beqz    a0, 2f                          # Save floating point state
67          nor    t3, zero, t3
68         lw      t1, ST_OFF(a0)                  # last thread looses fpu
69         and     t1, t3
70         sw      t1, ST_OFF(a0)
71         sll     t2, t1, 5
72         bgez    t2, 1f
73          sdc1   $f0, (THREAD_FPU + 0x00)(a0)
74         FPU_SAVE_16ODD(a0)
76         FPU_SAVE_16EVEN(a0, t1)                 # clobbers t1
79         sll     t0, t0, 5                       # load new fp state
80         bgez    t0, 1f
81          ldc1   $f0, (THREAD_FPU + 0x00)($28)
82         FPU_RESTORE_16ODD($28)
84         .set    reorder
85         FPU_RESTORE_16EVEN($28, t0)             # clobbers t0
86         jr      ra
87         END(r4xx0_lazy_fpu_switch)
90  * Save a thread's fp context.
91  */
92         .set    noreorder
93 LEAF(r4xx0_save_fp)
94         mfc0    t0, CP0_STATUS
95         sll     t1, t0, 5
96         bgez    t1, 1f                          # 16 register mode?
97          nop
98         FPU_SAVE_16ODD(a0)
100         FPU_SAVE_16EVEN(a0, t1)                 # clobbers t1
101         jr      ra
102          sdc1   $f0, (THREAD_FPU + 0x00)(a0)
103         END(r4xx0_save_fp)
106  * Load the FPU with signalling NANS.  This bit pattern we're using has
107  * the property that no matter wether considered as single or as double
108  * precission represents signaling NANS.
110  * We initialize fcr31 to rounding to nearest, no exceptions.
111  */
113 #define FPU_DEFAULT  0x00000000
115 LEAF(r4xx0_init_fpu)
116         mfc0    t0, CP0_STATUS
117         li      t1, 0x20000000
118         or      t0, t1
119         mtc0    t0, CP0_STATUS
120         sll     t0, t0, 5
122         li      t1, FPU_DEFAULT
123         ctc1    t1, fcr31
125         bgez    t0, 1f                  # 16 / 32 register mode?
126          li     t0, -1
128         dmtc1   t0, $f1
129         dmtc1   t0, $f3
130         dmtc1   t0, $f5
131         dmtc1   t0, $f7
132         dmtc1   t0, $f9
133         dmtc1   t0, $f11
134         dmtc1   t0, $f13
135         dmtc1   t0, $f15
136         dmtc1   t0, $f17
137         dmtc1   t0, $f19
138         dmtc1   t0, $f21
139         dmtc1   t0, $f23
140         dmtc1   t0, $f25
141         dmtc1   t0, $f27
142         dmtc1   t0, $f29
143         dmtc1   t0, $f31
145 1:      dmtc1   t0, $f0
146         dmtc1   t0, $f2
147         dmtc1   t0, $f4
148         dmtc1   t0, $f6
149         dmtc1   t0, $f8
150         dmtc1   t0, $f10
151         dmtc1   t0, $f12
152         dmtc1   t0, $f14
153         dmtc1   t0, $f16
154         dmtc1   t0, $f18
155         dmtc1   t0, $f20
156         dmtc1   t0, $f22
157         dmtc1   t0, $f24
158         dmtc1   t0, $f26
159         dmtc1   t0, $f28
160         jr      ra
161          dmtc1  t0, $f30
162         END(r4xx0_init_fpu)