more changes on original files
[linux-2.4.git] / include / asm-mips / stackframe.h
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  *  Copyright (C) 1994, 1995, 1996, 2001 Ralf Baechle
7  *  Copyright (C) 1994, 1995, 1996 Paul M. Antoine.
8  */
9 #ifndef __ASM_STACKFRAME_H
10 #define __ASM_STACKFRAME_H
11
12 #include <linux/config.h>
13 #include <asm/addrspace.h>
14 #include <asm/mipsregs.h>
15 #include <asm/processor.h>
16 #include <asm/asm.h>
17 #include <asm/offset.h>
18
19 #define SAVE_AT                                          \
20                 .set    push;                            \
21                 .set    noat;                            \
22                 sw      $1, PT_R1(sp);                   \
23                 .set    pop
24
25 #define SAVE_TEMP                                        \
26                 mfhi    v1;                              \
27                 sw      $8, PT_R8(sp);                   \
28                 sw      $9, PT_R9(sp);                   \
29                 sw      v1, PT_HI(sp);                   \
30                 mflo    v1;                              \
31                 sw      $10,PT_R10(sp);                  \
32                 sw      $11, PT_R11(sp);                 \
33                 sw      v1,  PT_LO(sp);                  \
34                 sw      $12, PT_R12(sp);                 \
35                 sw      $13, PT_R13(sp);                 \
36                 sw      $14, PT_R14(sp);                 \
37                 sw      $15, PT_R15(sp);                 \
38                 sw      $24, PT_R24(sp)
39
40 #define SAVE_STATIC                                      \
41                 sw      $16, PT_R16(sp);                 \
42                 sw      $17, PT_R17(sp);                 \
43                 sw      $18, PT_R18(sp);                 \
44                 sw      $19, PT_R19(sp);                 \
45                 sw      $20, PT_R20(sp);                 \
46                 sw      $21, PT_R21(sp);                 \
47                 sw      $22, PT_R22(sp);                 \
48                 sw      $23, PT_R23(sp);                 \
49                 sw      $30, PT_R30(sp)
50
51 #ifdef CONFIG_SMP
52 #  define GET_SAVED_SP                                   \
53                 mfc0    k0, CP0_CONTEXT;                 \
54                 lui     k1, %hi(kernelsp);               \
55                 srl     k0, k0, 23;                      \
56                 sll     k0, k0, 2;                       \
57                 addu    k1, k0;                          \
58                 lw      k1, %lo(kernelsp)(k1);
59
60 #else
61 #  define GET_SAVED_SP                                   \
62                 lui     k1, %hi(kernelsp);               \
63                 lw      k1, %lo(kernelsp)(k1);
64 #endif
65
66 #define SAVE_SOME                                        \
67                 .set    push;                            \
68                 .set    reorder;                         \
69                 mfc0    k0, CP0_STATUS;                  \
70                 sll     k0, 3;     /* extract cu0 bit */ \
71                 .set    noreorder;                       \
72                 bltz    k0, 8f;                          \
73                  move   k1, sp;                          \
74                 .set    reorder;                         \
75                 /* Called from user mode, new stack. */  \
76                 GET_SAVED_SP                             \
77 8:                                                       \
78                 move    k0, sp;                          \
79                 subu    sp, k1, PT_SIZE;                 \
80                 sw      k0, PT_R29(sp);                  \
81                 sw      $3, PT_R3(sp);                   \
82                 sw      $0, PT_R0(sp);                   \
83                 mfc0    v1, CP0_STATUS;                  \
84                 sw      $2, PT_R2(sp);                   \
85                 sw      v1, PT_STATUS(sp);               \
86                 sw      $4, PT_R4(sp);                   \
87                 mfc0    v1, CP0_CAUSE;                   \
88                 sw      $5, PT_R5(sp);                   \
89                 sw      v1, PT_CAUSE(sp);                \
90                 sw      $6, PT_R6(sp);                   \
91                 mfc0    v1, CP0_EPC;                     \
92                 sw      $7, PT_R7(sp);                   \
93                 sw      v1, PT_EPC(sp);                  \
94                 sw      $25, PT_R25(sp);                 \
95                 sw      $28, PT_R28(sp);                 \
96                 sw      $31, PT_R31(sp);                 \
97                 ori     $28, sp, 0x1fff;                 \
98                 xori    $28, 0x1fff;                     \
99                 .set    pop
100
101 #define SAVE_ALL                                         \
102                 SAVE_SOME;                               \
103                 SAVE_AT;                                 \
104                 SAVE_TEMP;                               \
105                 SAVE_STATIC
106
107 #define RESTORE_AT                                       \
108                 .set    push;                            \
109                 .set    noat;                            \
110                 lw      $1,  PT_R1(sp);                  \
111                 .set    pop;
112
113 #define RESTORE_TEMP                                     \
114                 lw      $24, PT_LO(sp);                  \
115                 lw      $8, PT_R8(sp);                   \
116                 lw      $9, PT_R9(sp);                   \
117                 mtlo    $24;                             \
118                 lw      $24, PT_HI(sp);                  \
119                 lw      $10,PT_R10(sp);                  \
120                 lw      $11, PT_R11(sp);                 \
121                 mthi    $24;                             \
122                 lw      $12, PT_R12(sp);                 \
123                 lw      $13, PT_R13(sp);                 \
124                 lw      $14, PT_R14(sp);                 \
125                 lw      $15, PT_R15(sp);                 \
126                 lw      $24, PT_R24(sp)
127
128 #define RESTORE_STATIC                                   \
129                 lw      $16, PT_R16(sp);                 \
130                 lw      $17, PT_R17(sp);                 \
131                 lw      $18, PT_R18(sp);                 \
132                 lw      $19, PT_R19(sp);                 \
133                 lw      $20, PT_R20(sp);                 \
134                 lw      $21, PT_R21(sp);                 \
135                 lw      $22, PT_R22(sp);                 \
136                 lw      $23, PT_R23(sp);                 \
137                 lw      $30, PT_R30(sp)
138
139 #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
140
141 #define RESTORE_SOME                                     \
142                 .set    push;                            \
143                 .set    reorder;                         \
144                 mfc0    t0, CP0_STATUS;                  \
145                 .set    pop;                             \
146                 ori     t0, 0x1f;                        \
147                 xori    t0, 0x1f;                        \
148                 mtc0    t0, CP0_STATUS;                  \
149                 li      v1, 0xff00;                      \
150                 and     t0, v1;                          \
151                 lw      v0, PT_STATUS(sp);               \
152                 nor     v1, $0, v1;                      \
153                 and     v0, v1;                          \
154                 or      v0, t0;                          \
155                 mtc0    v0, CP0_STATUS;                  \
156                 lw      $31, PT_R31(sp);                 \
157                 lw      $28, PT_R28(sp);                 \
158                 lw      $25, PT_R25(sp);                 \
159                 lw      $7,  PT_R7(sp);                  \
160                 lw      $6,  PT_R6(sp);                  \
161                 lw      $5,  PT_R5(sp);                  \
162                 lw      $4,  PT_R4(sp);                  \
163                 lw      $3,  PT_R3(sp);                  \
164                 lw      $2,  PT_R2(sp)
165
166 #define RESTORE_SP_AND_RET                               \
167                 .set    push;                            \
168                 .set    noreorder;                       \
169                 lw      k0, PT_EPC(sp);                  \
170                 lw      sp,  PT_R29(sp);                 \
171                 jr      k0;                              \
172                  rfe;                                    \
173                 .set    pop
174
175 #else
176
177 #define RESTORE_SOME                                     \
178                 .set    push;                            \
179                 .set    reorder;                         \
180                 mfc0    t0, CP0_STATUS;                  \
181                 .set    pop;                             \
182                 ori     t0, 0x1f;                        \
183                 xori    t0, 0x1f;                        \
184                 mtc0    t0, CP0_STATUS;                  \
185                 li      v1, 0xff00;                      \
186                 and     t0, v1;                          \
187                 lw      v0, PT_STATUS(sp);               \
188                 nor     v1, $0, v1;                      \
189                 and     v0, v1;                          \
190                 or      v0, t0;                          \
191                 mtc0    v0, CP0_STATUS;                  \
192                 lw      v1, PT_EPC(sp);                  \
193                 mtc0    v1, CP0_EPC;                     \
194                 lw      $31, PT_R31(sp);                 \
195                 lw      $28, PT_R28(sp);                 \
196                 lw      $25, PT_R25(sp);                 \
197                 lw      $7,  PT_R7(sp);                  \
198                 lw      $6,  PT_R6(sp);                  \
199                 lw      $5,  PT_R5(sp);                  \
200                 lw      $4,  PT_R4(sp);                  \
201                 lw      $3,  PT_R3(sp);                  \
202                 lw      $2,  PT_R2(sp)
203
204 #define RESTORE_SP_AND_RET                               \
205                 lw      sp,  PT_R29(sp);                 \
206                 .set    mips3;                           \
207                 eret;                                    \
208                 .set    mips0
209
210 #endif
211
212 #define RESTORE_SP                                       \
213                 lw      sp,  PT_R29(sp);                 \
214
215 #define RESTORE_ALL                                      \
216                 RESTORE_SOME;                            \
217                 RESTORE_AT;                              \
218                 RESTORE_TEMP;                            \
219                 RESTORE_STATIC;                          \
220                 RESTORE_SP
221
222 #define RESTORE_ALL_AND_RET                              \
223                 RESTORE_SOME;                            \
224                 RESTORE_AT;                              \
225                 RESTORE_TEMP;                            \
226                 RESTORE_STATIC;                          \
227                 RESTORE_SP_AND_RET
228
229
230 /*
231  * Move to kernel mode and disable interrupts.
232  * Set cp0 enable bit as sign that we're running on the kernel stack
233  */
234 #define CLI                                             \
235                 mfc0    t0,CP0_STATUS;                  \
236                 li      t1,ST0_CU0|0x1f;                \
237                 or      t0,t1;                          \
238                 xori    t0,0x1f;                        \
239                 mtc0    t0,CP0_STATUS
240
241 /*
242  * Move to kernel mode and enable interrupts.
243  * Set cp0 enable bit as sign that we're running on the kernel stack
244  */
245 #define STI                                             \
246                 mfc0    t0,CP0_STATUS;                  \
247                 li      t1,ST0_CU0|0x1f;                \
248                 or      t0,t1;                          \
249                 xori    t0,0x1e;                        \
250                 mtc0    t0,CP0_STATUS
251
252 /*
253  * Just move to kernel mode and leave interrupts as they are.
254  * Set cp0 enable bit as sign that we're running on the kernel stack
255  */
256 #define KMODE                                           \
257                 mfc0    t0,CP0_STATUS;                  \
258                 li      t1,ST0_CU0|0x1e;                \
259                 or      t0,t1;                          \
260                 xori    t0,0x1e;                        \
261                 mtc0    t0,CP0_STATUS
262
263 #endif /* __ASM_STACKFRAME_H */