Blame view

arch/mips/kernel/r2300_switch.S 3.32 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
  /*
   * r2300_switch.S: R2300 specific task switching code.
   *
   * Copyright (C) 1994, 1995, 1996, 1999 by Ralf Baechle
   * Copyright (C) 1994, 1995, 1996 by Andreas Busse
   *
   * Multi-cpu abstraction and macros for easier reading:
79add6277   Justin P. Mattock   update David Mill...
8
   * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
9
10
11
12
   *
   * Further modifications to make this work:
   * Copyright (c) 1998-2000 Harald Koerfgen
   */
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
35
36
  #include <asm/page.h>
  #include <asm/regdef.h>
  #include <asm/stackframe.h>
  #include <asm/thread_info.h>
  
  #include <asm/asmmacro.h>
  
  	.set	mips1
  	.align	5
  
  /*
   * 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...
37
   * space STATUS register should be 0, so that a process *always* starts its
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
38
39
40
41
42
43
44
45
46
47
48
   * 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) )
   */
  LEAF(resume)
5323180db   Atsushi Nemoto   [MIPS] Disallow C...
49
50
  	mfc0	t1, CP0_STATUS
  	sw	t1, THREAD_STATUS(a0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
51
52
  	cpu_save_nonscratch a0
  	sw	ra, THREAD_REG31(a0)
42a3b4f25   Ralf Baechle   [PATCH] mips: nuk...
53
  	/*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54
55
56
57
58
  	 * check if we need to save FPU registers
  	 */
  	lw	t3, TASK_THREAD_INFO(a0)
  	lw	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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
  	nor	t1, zero, t1
  
  	and	t0, t0, t1
  	sw	t0, TI_FLAGS(t3)
  
  	/*
  	 * clear saved user stack CU1 bit
  	 */
  	lw	t0, ST_OFF(t3)
  	li	t1, ~ST0_CU1
  	and	t0, t0, t1
  	sw	t0, ST_OFF(t3)
  
  	fpu_save_single a0, t0			# clobbers t0
  
  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
  
  	addiu	t1, $28, _THREAD_SIZE - 32
  	sw	t1, kernelsp
  
  	mfc0	t1, CP0_STATUS		/* Do we really need this? */
  	li	a3, 0xff01
  	and	t1, a3
  	lw	a2, THREAD_STATUS(a1)
  	nor	a3, $0, a3
  	and	a2, a3
  	or	a2, t1
  	mtc0	a2, CP0_STATUS
  	move	v0, a0
  	jr	ra
  	END(resume)
  
  /*
   * Save a thread's fp context.
   */
  LEAF(_save_fp)
  	fpu_save_single a0, t1			# clobbers t1
  	jr	ra
  	END(_save_fp)
  
  /*
   * Restore a thread's fp context.
   */
  LEAF(_restore_fp)
  	fpu_restore_single a0, t1		# clobbers t1
  	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)
  	mfc0	t0, CP0_STATUS
  	li	t1, ST0_CU1
  	or	t0, t1
  	mtc0	t0, CP0_STATUS
  
  	li	t1, FPU_DEFAULT
  	ctc1	t1, fcr31
  
  	li	t0, -1
  
  	mtc1	t0, $f0
  	mtc1	t0, $f1
  	mtc1	t0, $f2
  	mtc1	t0, $f3
  	mtc1	t0, $f4
  	mtc1	t0, $f5
  	mtc1	t0, $f6
  	mtc1	t0, $f7
  	mtc1	t0, $f8
  	mtc1	t0, $f9
  	mtc1	t0, $f10
  	mtc1	t0, $f11
  	mtc1	t0, $f12
  	mtc1	t0, $f13
  	mtc1	t0, $f14
  	mtc1	t0, $f15
  	mtc1	t0, $f16
  	mtc1	t0, $f17
  	mtc1	t0, $f18
  	mtc1	t0, $f19
  	mtc1	t0, $f20
  	mtc1	t0, $f21
  	mtc1	t0, $f22
  	mtc1	t0, $f23
  	mtc1	t0, $f24
  	mtc1	t0, $f25
  	mtc1	t0, $f26
  	mtc1	t0, $f27
  	mtc1	t0, $f28
  	mtc1	t0, $f29
  	mtc1	t0, $f30
  	mtc1	t0, $f31
  	jr	ra
  	END(_init_fpu)