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, 1999 Ralf Baechle
7 * Copyright (C) 1994, 1995, 1996 Paul M. Antoine.
8 * Copyright (C) 1999 Silicon Graphics, Inc.
9 */
10#ifndef _ASM_STACKFRAME_H
11#define _ASM_STACKFRAME_H
12
13#include <linux/config.h>
14
15#include <asm/asm.h>
16#include <asm/offset.h>
17#include <asm/processor.h>
18#include <asm/addrspace.h>
19
20#ifndef __ASSEMBLY__
21
22#define __str2(x) #x
23#define __str(x) __str2(x)
24
25#define save_static(frame)                               \
26	__asm__ __volatile__(                            \
27		"sd\t$16,"__str(PT_R16)"(%0)\n\t"        \
28		"sd\t$17,"__str(PT_R17)"(%0)\n\t"        \
29		"sd\t$18,"__str(PT_R18)"(%0)\n\t"        \
30		"sd\t$19,"__str(PT_R19)"(%0)\n\t"        \
31		"sd\t$20,"__str(PT_R20)"(%0)\n\t"        \
32		"sd\t$21,"__str(PT_R21)"(%0)\n\t"        \
33		"sd\t$22,"__str(PT_R22)"(%0)\n\t"        \
34		"sd\t$23,"__str(PT_R23)"(%0)\n\t"        \
35		"sd\t$30,"__str(PT_R30)"(%0)\n\t"        \
36		: /* No outputs */                       \
37		: "r" (frame))
38
39#endif /* !__ASSEMBLY__ */
40
41#ifdef __ASSEMBLY__
42
43		.macro	SAVE_AT
44		.set	push
45		.set	noat
46		sd	$1, PT_R1(sp)
47		.set	pop
48		.endm
49
50		.macro	SAVE_TEMP
51		mfhi	v1
52		sd	$8, PT_R8(sp)
53		sd	$9, PT_R9(sp)
54		sd	v1, PT_HI(sp)
55		mflo	v1
56		sd	$10, PT_R10(sp)
57		sd	$11, PT_R11(sp)
58		sd	v1,  PT_LO(sp)
59		sd	$12, PT_R12(sp)
60		sd	$13, PT_R13(sp)
61		sd	$14, PT_R14(sp)
62		sd	$15, PT_R15(sp)
63		sd	$24, PT_R24(sp)
64		.endm
65
66		.macro	SAVE_STATIC
67		sd	$16, PT_R16(sp)
68		sd	$17, PT_R17(sp)
69		sd	$18, PT_R18(sp)
70		sd	$19, PT_R19(sp)
71		sd	$20, PT_R20(sp)
72		sd	$21, PT_R21(sp)
73		sd	$22, PT_R22(sp)
74		sd	$23, PT_R23(sp)
75		sd	$30, PT_R30(sp)
76		.endm
77
78#ifdef CONFIG_SMP
79		.macro	get_saved_sp	/* R10000 variation */
80#ifdef CONFIG_CPU_SB1
81		dmfc0	k1, CP0_WATCHLO
82#else
83		mfc0	k0, CP0_WATCHLO
84		mfc0	k1, CP0_WATCHHI
85		dsll32	k0, k0, 0	/* Get rid of sign extension */
86		dsrl32	k0, k0, 0	/* Get rid of sign extension */
87		dsll32	k1, k1, 0
88		or	k1, k1, k0
89		li	k0, K0BASE
90		or	k1, k1, k0
91#endif
92		.endm
93
94		.macro	set_saved_sp	stackp temp
95#ifdef CONFIG_CPU_SB1
96		dmtc0	\stackp, CP0_WATCHLO
97#else
98		mtc0	\stackp, CP0_WATCHLO
99		dsrl32	\temp, \stackp, 0
100		mtc0	\temp, CP0_WATCHHI
101#endif
102		.endm
103
104		.macro	declare_saved_sp
105		# empty, stackpointer stored in a register
106		.endm
107#else
108		.macro	get_saved_sp	/* Uniprocessor variation */
109		lui	k1, %hi(kernelsp)
110		ld	k1, %lo(kernelsp)(k1)
111		.endm
112
113		.macro	set_saved_sp	stackp temp
114		sd	\stackp, kernelsp
115		.endm
116
117		.macro	declare_saved_sp
118		.comm	kernelsp, 8, 8			# current stackpointer
119		.endm
120#endif
121
122		.macro	SAVE_SOME
123		.set	push
124		.set	reorder
125		mfc0	k0, CP0_STATUS
126		sll	k0, 3		/* extract cu0 bit */
127		.set	noreorder
128		bltz	k0, 8f
129		 move	k1, sp
130		.set	reorder
131		/* Called from user mode, new stack. */
132		get_saved_sp
1338:		move	k0, sp
134		dsubu	sp, k1, PT_SIZE
135		sd	k0, PT_R29(sp)
136		sd	$3, PT_R3(sp)
137		sd	$0, PT_R0(sp)
138		mfc0	v1, CP0_STATUS
139		sd	$2, PT_R2(sp)
140		sd	v1, PT_STATUS(sp)
141		sd	$4, PT_R4(sp)
142		mfc0	v1, CP0_CAUSE
143		sd	$5, PT_R5(sp)
144		sd	v1, PT_CAUSE(sp)
145		sd	$6, PT_R6(sp)
146		dmfc0	v1, CP0_EPC
147		sd	$7, PT_R7(sp)
148		sd	v1, PT_EPC(sp)
149		sd	$25, PT_R25(sp)
150		sd	$28, PT_R28(sp)
151		sd	$31, PT_R31(sp)
152		ori	$28, sp, 0x3fff
153		xori	$28, 0x3fff
154		.set	pop
155		.endm
156
157		.macro	SAVE_ALL
158		SAVE_SOME
159		SAVE_AT
160		SAVE_TEMP
161		SAVE_STATIC
162		.endm
163
164		.macro	RESTORE_AT
165		.set	push
166		.set	noat
167		ld	$1,  PT_R1(sp)
168		.set	pop
169		.endm
170
171		.macro	RESTORE_SP
172		ld	sp,  PT_R29(sp)
173		.endm
174
175		.macro	RESTORE_TEMP
176		ld	$24, PT_LO(sp)
177		ld	$8, PT_R8(sp)
178		ld	$9, PT_R9(sp)
179		mtlo	$24
180		ld	$24, PT_HI(sp)
181		ld	$10, PT_R10(sp)
182		ld	$11, PT_R11(sp)
183		mthi	$24
184		ld	$12, PT_R12(sp)
185		ld	$13, PT_R13(sp)
186		ld	$14, PT_R14(sp)
187		ld	$15, PT_R15(sp)
188		ld	$24, PT_R24(sp)
189		.endm
190
191		.macro	RESTORE_STATIC
192		ld	$16, PT_R16(sp)
193		ld	$17, PT_R17(sp)
194		ld	$18, PT_R18(sp)
195		ld	$19, PT_R19(sp)
196		ld	$20, PT_R20(sp)
197		ld	$21, PT_R21(sp)
198		ld	$22, PT_R22(sp)
199		ld	$23, PT_R23(sp)
200		ld	$30, PT_R30(sp)
201		.endm
202
203		.macro	RESTORE_SOME
204		.set	push
205		.set	reorder
206		mfc0	t0, CP0_STATUS
207		.set	pop
208		ori	t0, 0x1f
209		xori	t0, 0x1f
210		mtc0	t0, CP0_STATUS
211		li	v1, 0xff00
212		and	t0, v1
213		ld	v0, PT_STATUS(sp)
214		nor	v1, $0, v1
215		and	v0, v1
216		or	v0, t0
217		mtc0	v0, CP0_STATUS
218		ld	v1, PT_EPC(sp)
219		dmtc0	v1, CP0_EPC
220		ld	$31, PT_R31(sp)
221		ld	$28, PT_R28(sp)
222		ld	$25, PT_R25(sp)
223		ld	$7,  PT_R7(sp)
224		ld	$6,  PT_R6(sp)
225		ld	$5,  PT_R5(sp)
226		ld	$4,  PT_R4(sp)
227		ld	$3,  PT_R3(sp)
228		ld	$2,  PT_R2(sp)
229		.endm
230
231		.macro	RESTORE_ALL
232		RESTORE_SOME
233		RESTORE_AT
234		RESTORE_TEMP
235		RESTORE_STATIC
236		RESTORE_SP
237		.endm
238
239/*
240 * Move to kernel mode and disable interrupts.
241 * Set cp0 enable bit as sign that we're running on the kernel stack
242 */
243		.macro	CLI
244		mfc0	t0, CP0_STATUS
245		li	t1, ST0_CU0|0x1f
246		or	t0, t1
247		xori	t0, 0x1f
248		mtc0	t0, CP0_STATUS
249		.endm
250
251/*
252 * Move to kernel mode and enable interrupts.
253 * Set cp0 enable bit as sign that we're running on the kernel stack
254 */
255		.macro	STI
256		mfc0	t0, CP0_STATUS
257		li	t1, ST0_CU0 | 0x1f
258		or	t0, t1
259		xori	t0, 0x1e
260		mtc0	t0, CP0_STATUS
261		.endm
262
263/*
264 * Just move to kernel mode and leave interrupts as they are.
265 * Set cp0 enable bit as sign that we're running on the kernel stack
266 */
267		.macro	KMODE
268		mfc0	t0, CP0_STATUS
269		li	t1, ST0_CU0 | 0x1e
270		or	t0, t1
271		xori	t0, 0x1e
272		mtc0	t0, CP0_STATUS
273		.endm
274
275#endif /* __ASSEMBLY__ */
276
277#endif /* _ASM_STACKFRAME_H */
278