Blame view

arch/mips/kernel/r4k_switch.S 5.05 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
  /*
   * This file is subject to the terms and conditions of the GNU General Public
   * License.  See the file "COPYING" in the main directory of this archive
   * for more details.
   *
   * Copyright (C) 1994, 1995, 1996, 1998, 1999, 2002, 2003 Ralf Baechle
79add6277   Justin P. Mattock   update David Mill...
7
   * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
8
9
10
11
12
   * Copyright (C) 1994, 1995, 1996, by Andreas Busse
   * Copyright (C) 1999 Silicon Graphics, Inc.
   * Copyright (C) 2000 MIPS Technologies, Inc.
   *    written by Carsten Langgaard, carstenl@mips.com
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
13
14
15
16
  #include <asm/asm.h>
  #include <asm/cachectl.h>
  #include <asm/fpregdef.h>
  #include <asm/mipsregs.h>
048eb582f   Sam Ravnborg   kbuild: mips use ...
17
  #include <asm/asm-offsets.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
  #include <asm/page.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)
  
  /*
   * 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
42a3b4f25   Ralf Baechle   [PATCH] mips: nuk...
35
   * space STATUS register should be 0, so that a process *always* starts its
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
36
37
38
39
40
41
42
43
44
45
46
47
   * 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,
   *                     struct thread_info *next_ti)
   */
  	.align	5
  	LEAF(resume)
5323180db   Atsushi Nemoto   [MIPS] Disallow C...
48
49
  	mfc0	t1, CP0_STATUS
  	LONG_S	t1, THREAD_STATUS(a0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50
51
52
53
54
55
56
57
58
  	cpu_save_nonscratch 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
5323180db   Atsushi Nemoto   [MIPS] Disallow C...
59
60
  	and	t2, t0, t1
  	beqz	t2, 1f
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
62
63
64
65
66
67
68
69
70
71
72
  	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)
c138e12f3   Atsushi Nemoto   [MIPS] Fix fpu_sa...
73
74
  	fpu_save_double a0 t0 t1		# c0_status passed in t0
  						# clobbers t1
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
75
76
77
78
79
80
81
82
  1:
  
  	/*
  	 * The order of restoring the registers takes care of the race
  	 * updating $28, $29 and kernelsp without disabling ints.
  	 */
  	move	$28, a2
  	cpu_restore_nonscratch a1
3bd396644   Ralf Baechle   [MIPS] Fix resume...
83
  	PTR_ADDU	t0, $28, _THREAD_SIZE - 32
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
84
  	set_saved_sp	t0, t1, t2
41c594ab6   Ralf Baechle   [MIPS] MT: Improv...
85
86
87
88
89
90
  #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
4277ff5ee   Ralf Baechle   [MIPS] Fix use of...
91
  	_ehb
41c594ab6   Ralf Baechle   [MIPS] MT: Improv...
92
93
94
95
96
  	DMT	8				# dmt	t0
  	move	t1,ra
  	jal	mips_ihb
  	move	ra,t1
  #endif /* CONFIG_MIPS_MT_SMTC */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
97
98
99
100
101
102
103
104
  	mfc0	t1, CP0_STATUS		/* Do we really need this? */
  	li	a3, 0xff01
  	and	t1, a3
  	LONG_L	a2, THREAD_STATUS(a1)
  	nor	a3, $0, a3
  	and	a2, a3
  	or	a2, t1
  	mtc0	a2, CP0_STATUS
41c594ab6   Ralf Baechle   [MIPS] MT: Improv...
105
  #ifdef CONFIG_MIPS_MT_SMTC
4277ff5ee   Ralf Baechle   [MIPS] Fix use of...
106
  	_ehb
41c594ab6   Ralf Baechle   [MIPS] MT: Improv...
107
108
109
110
111
112
113
114
  	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
4277ff5ee   Ralf Baechle   [MIPS] Fix use of...
115
  	_ehb
41c594ab6   Ralf Baechle   [MIPS] MT: Improv...
116
  #endif /* CONFIG_MIPS_MT_SMTC */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
117
118
119
120
121
122
123
124
  	move	v0, a0
  	jr	ra
  	END(resume)
  
  /*
   * Save a thread's fp context.
   */
  LEAF(_save_fp)
875d43e72   Ralf Baechle   [PATCH] mips: cle...
125
  #ifdef CONFIG_64BIT
c138e12f3   Atsushi Nemoto   [MIPS] Fix fpu_sa...
126
  	mfc0	t0, CP0_STATUS
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
127
  #endif
c138e12f3   Atsushi Nemoto   [MIPS] Fix fpu_sa...
128
  	fpu_save_double a0 t0 t1		# clobbers t1
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
129
130
131
132
133
134
135
  	jr	ra
  	END(_save_fp)
  
  /*
   * Restore a thread's fp context.
   */
  LEAF(_restore_fp)
c138e12f3   Atsushi Nemoto   [MIPS] Fix fpu_sa...
136
137
138
139
  #ifdef CONFIG_64BIT
  	mfc0	t0, CP0_STATUS
  #endif
  	fpu_restore_double a0 t0 t1		# clobbers t1
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
140
141
142
143
144
145
146
147
148
149
150
151
152
153
  	jr	ra
  	END(_restore_fp)
  
  /*
   * Load the FPU with signalling NANS.  This bit pattern we're using has
   * the property that no matter whether considered as single or as double
   * precision represents signaling NANS.
   *
   * We initialize fcr31 to rounding to nearest, no exceptions.
   */
  
  #define FPU_DEFAULT  0x00000000
  
  LEAF(_init_fpu)
41c594ab6   Ralf Baechle   [MIPS] MT: Improv...
154
155
156
157
158
159
160
161
  #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 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
162
163
164
165
  	mfc0	t0, CP0_STATUS
  	li	t1, ST0_CU1
  	or	t0, t1
  	mtc0	t0, CP0_STATUS
41c594ab6   Ralf Baechle   [MIPS] MT: Improv...
166
  #endif /* CONFIG_MIPS_MT_SMTC */
f9509c84d   Chris Dearman   [MIPS] Remove dup...
167
  	enable_fpu_hazard
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
168
169
170
171
172
  
  	li	t1, FPU_DEFAULT
  	ctc1	t1, fcr31
  
  	li	t1, -1				# SNaN
875d43e72   Ralf Baechle   [PATCH] mips: cle...
173
  #ifdef CONFIG_64BIT
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
  	sll	t0, t0, 5
  	bgez	t0, 1f				# 16 / 32 register mode?
  
  	dmtc1	t1, $f1
  	dmtc1	t1, $f3
  	dmtc1	t1, $f5
  	dmtc1	t1, $f7
  	dmtc1	t1, $f9
  	dmtc1	t1, $f11
  	dmtc1	t1, $f13
  	dmtc1	t1, $f15
  	dmtc1	t1, $f17
  	dmtc1	t1, $f19
  	dmtc1	t1, $f21
  	dmtc1	t1, $f23
  	dmtc1	t1, $f25
  	dmtc1	t1, $f27
  	dmtc1	t1, $f29
  	dmtc1	t1, $f31
  1:
  #endif
42a3b4f25   Ralf Baechle   [PATCH] mips: nuk...
195

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
  #ifdef CONFIG_CPU_MIPS32
  	mtc1	t1, $f0
  	mtc1	t1, $f1
  	mtc1	t1, $f2
  	mtc1	t1, $f3
  	mtc1	t1, $f4
  	mtc1	t1, $f5
  	mtc1	t1, $f6
  	mtc1	t1, $f7
  	mtc1	t1, $f8
  	mtc1	t1, $f9
  	mtc1	t1, $f10
  	mtc1	t1, $f11
  	mtc1	t1, $f12
  	mtc1	t1, $f13
  	mtc1	t1, $f14
  	mtc1	t1, $f15
  	mtc1	t1, $f16
  	mtc1	t1, $f17
  	mtc1	t1, $f18
  	mtc1	t1, $f19
  	mtc1	t1, $f20
  	mtc1	t1, $f21
  	mtc1	t1, $f22
  	mtc1	t1, $f23
  	mtc1	t1, $f24
  	mtc1	t1, $f25
  	mtc1	t1, $f26
  	mtc1	t1, $f27
  	mtc1	t1, $f28
  	mtc1	t1, $f29
  	mtc1	t1, $f30
  	mtc1	t1, $f31
  #else
  	.set	mips3
  	dmtc1	t1, $f0
  	dmtc1	t1, $f2
  	dmtc1	t1, $f4
  	dmtc1	t1, $f6
  	dmtc1	t1, $f8
  	dmtc1	t1, $f10
  	dmtc1	t1, $f12
  	dmtc1	t1, $f14
  	dmtc1	t1, $f16
  	dmtc1	t1, $f18
  	dmtc1	t1, $f20
  	dmtc1	t1, $f22
  	dmtc1	t1, $f24
  	dmtc1	t1, $f26
  	dmtc1	t1, $f28
  	dmtc1	t1, $f30
  #endif
  	jr	ra
  	END(_init_fpu)