1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
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
|
/* $Id: stackframe.h,v 1.3 1999/12/04 03:59:12 ralf Exp $
*
* 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, 1999 Ralf Baechle
* Copyright (C) 1994, 1995, 1996 Paul M. Antoine.
* Copyright (C) 1999 Silicon Graphics, Inc.
*/
#ifndef _ASM_STACKFRAME_H
#define _ASM_STACKFRAME_H
#include <linux/config.h>
#include <asm/asm.h>
#include <asm/offset.h>
#include <asm/processor.h>
#include <asm/addrspace.h>
#ifdef _LANGUAGE_C
#define __str2(x) #x
#define __str(x) __str2(x)
#define save_static(frame) \
__asm__ __volatile__( \
"sd\t$16,"__str(PT_R16)"(%0)\n\t" \
"sd\t$17,"__str(PT_R17)"(%0)\n\t" \
"sd\t$18,"__str(PT_R18)"(%0)\n\t" \
"sd\t$19,"__str(PT_R19)"(%0)\n\t" \
"sd\t$20,"__str(PT_R20)"(%0)\n\t" \
"sd\t$21,"__str(PT_R21)"(%0)\n\t" \
"sd\t$22,"__str(PT_R22)"(%0)\n\t" \
"sd\t$23,"__str(PT_R23)"(%0)\n\t" \
"sd\t$30,"__str(PT_R30)"(%0)\n\t" \
: /* No outputs */ \
: "r" (frame))
#endif /* _LANGUAGE_C */
#ifdef _LANGUAGE_ASSEMBLY
.macro SAVE_AT
.set push
.set noat
sd $1, PT_R1(sp)
.set pop
.endm
.macro SAVE_TEMP
mfhi v1
sd $8, PT_R8(sp)
sd $9, PT_R9(sp)
sd v1, PT_HI(sp)
mflo v1
sd $10, PT_R10(sp)
sd $11, PT_R11(sp)
sd v1, PT_LO(sp)
sd $12, PT_R12(sp)
sd $13, PT_R13(sp)
sd $14, PT_R14(sp)
sd $15, PT_R15(sp)
sd $24, PT_R24(sp)
.endm
.macro SAVE_STATIC
sd $16, PT_R16(sp)
sd $17, PT_R17(sp)
sd $18, PT_R18(sp)
sd $19, PT_R19(sp)
sd $20, PT_R20(sp)
sd $21, PT_R21(sp)
sd $22, PT_R22(sp)
sd $23, PT_R23(sp)
sd $30, PT_R30(sp)
.endm
.macro SAVE_SOME
.set push
.set reorder
mfc0 k0, CP0_STATUS
sll k0, 3 /* extract cu0 bit */
.set noreorder
bltz k0, 8f
move k1, sp
.set reorder
/* Called from user mode, new stack. */
#ifndef CONFIG_SMP
lui k1, %hi(kernelsp)
ld k1, %lo(kernelsp)(k1)
#else
mfc0 k0, CP0_WATCHLO
mfc0 k1, CP0_WATCHHI
dsll32 k0, k0, 0 /* Get rid of sign extension */
dsrl32 k0, k0, 0 /* Get rid of sign extension */
dsll32 k1, k1, 0
or k1, k1, k0
li k0, K0BASE
or k1, k1, k0
daddiu k1, k1, KERNEL_STACK_SIZE-32
#endif
8: move k0, sp
dsubu sp, k1, PT_SIZE
sd k0, PT_R29(sp)
sd $3, PT_R3(sp)
sd $0, PT_R0(sp)
dmfc0 v1, CP0_STATUS
sd $2, PT_R2(sp)
sd v1, PT_STATUS(sp)
sd $4, PT_R4(sp)
dmfc0 v1, CP0_CAUSE
sd $5, PT_R5(sp)
sd v1, PT_CAUSE(sp)
sd $6, PT_R6(sp)
dmfc0 v1, CP0_EPC
sd $7, PT_R7(sp)
sd v1, PT_EPC(sp)
sd $25, PT_R25(sp)
sd $28, PT_R28(sp)
sd $31, PT_R31(sp)
ori $28, sp, 0x3fff
xori $28, 0x3fff
.set pop
.endm
.macro SAVE_ALL
SAVE_SOME
SAVE_AT
SAVE_TEMP
SAVE_STATIC
.endm
.macro RESTORE_AT
.set push
.set noat
ld $1, PT_R1(sp)
.set pop
.endm
.macro RESTORE_SP
ld sp, PT_R29(sp)
.endm
.macro RESTORE_TEMP
ld $24, PT_LO(sp)
ld $8, PT_R8(sp)
ld $9, PT_R9(sp)
mtlo $24
ld $24, PT_HI(sp)
ld $10, PT_R10(sp)
ld $11, PT_R11(sp)
mthi $24
ld $12, PT_R12(sp)
ld $13, PT_R13(sp)
ld $14, PT_R14(sp)
ld $15, PT_R15(sp)
ld $24, PT_R24(sp)
.endm
.macro RESTORE_STATIC
ld $16, PT_R16(sp)
ld $17, PT_R17(sp)
ld $18, PT_R18(sp)
ld $19, PT_R19(sp)
ld $20, PT_R20(sp)
ld $21, PT_R21(sp)
ld $22, PT_R22(sp)
ld $23, PT_R23(sp)
ld $30, PT_R30(sp)
.endm
.macro RESTORE_SOME
.set push
.set reorder
mfc0 t0, CP0_STATUS
.set pop
ori t0, 0x1f
xori t0, 0x1f
mtc0 t0, CP0_STATUS
li v1, 0xff00
and t0, v1
ld v0, PT_STATUS(sp)
nor v1, $0, v1
and v0, v1
or v0, t0
dmtc0 v0, CP0_STATUS
ld v1, PT_EPC(sp)
dmtc0 v1, CP0_EPC
ld $31, PT_R31(sp)
ld $28, PT_R28(sp)
ld $25, PT_R25(sp)
ld $7, PT_R7(sp)
ld $6, PT_R6(sp)
ld $5, PT_R5(sp)
ld $4, PT_R4(sp)
ld $3, PT_R3(sp)
ld $2, PT_R2(sp)
.endm
.macro RESTORE_ALL
RESTORE_SOME
RESTORE_AT
RESTORE_TEMP
RESTORE_STATIC
RESTORE_SP
.endm
/*
* Move to kernel mode and disable interrupts.
* Set cp0 enable bit as sign that we're running on the kernel stack
*/
.macro CLI
mfc0 t0, CP0_STATUS
li t1, ST0_CU0|0x1f
or t0, t1
xori t0, 0x1f
mtc0 t0, CP0_STATUS
.endm
/*
* Move to kernel mode and enable interrupts.
* Set cp0 enable bit as sign that we're running on the kernel stack
*/
.macro STI
mfc0 t0, CP0_STATUS
li t1, ST0_CU0 | 0x1f
or t0, t1
xori t0, 0x1e
mtc0 t0, CP0_STATUS
.endm
/*
* Just move to kernel mode and leave interrupts as they are.
* Set cp0 enable bit as sign that we're running on the kernel stack
*/
.macro KMODE
mfc0 t0, CP0_STATUS
li t1, ST0_CU0 | 0x1e
or t0, t1
xori t0, 0x1e
mtc0 t0, CP0_STATUS
.endm
#endif /* _LANGUAGE_ASSEMBLY */
#endif /* _ASM_STACKFRAME_H */
|