summaryrefslogtreecommitdiffstats
path: root/include/asm-mips64/stackframe.h
blob: a9e62c232db167618d75fd5d3c9824c69b6dd8be (plain)
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
/* $Id$
 *
 * 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 <asm/asm.h>
#include <asm/offset.h>

#ifdef _LANGUAGE_C

#define __str2(x) #x
#define __str(x) __str2(x)

#define save_static(frame)                               \
	__asm__ __volatile__(                            \
		"sw\t$16,"__str(PT_R16)"(%0)\n\t"        \
		"sw\t$17,"__str(PT_R17)"(%0)\n\t"        \
		"sw\t$18,"__str(PT_R18)"(%0)\n\t"        \
		"sw\t$19,"__str(PT_R19)"(%0)\n\t"        \
		"sw\t$20,"__str(PT_R20)"(%0)\n\t"        \
		"sw\t$21,"__str(PT_R21)"(%0)\n\t"        \
		"sw\t$22,"__str(PT_R22)"(%0)\n\t"        \
		"sw\t$23,"__str(PT_R23)"(%0)\n\t"        \
		"sw\t$30,"__str(PT_R30)"(%0)\n\t"        \
		: /* No outputs */                       \
		: "r" (frame))

#endif /* _LANGUAGE_C */

#ifdef _LANGUAGE_ASSEMBLY

		.macro	SAVE_AT
		sw	$1, PT_R1(sp)
		.endm

		.macro	SAVE_TEMP
		mfhi	v1
		sw	$8, PT_R8(sp)
		sw	$9, PT_R9(sp)
		sw	v1, PT_HI(sp)
		mflo	v1
		sw	$10,PT_R10(sp)
		sw	$11, PT_R11(sp)
		sw	v1,  PT_LO(sp)
		sw	$12, PT_R12(sp)
		sw	$13, PT_R13(sp)
		sw	$14, PT_R14(sp)
		sw	$15, PT_R15(sp)
		sw	$24, PT_R24(sp)
		.endm

		.macro	SAVE_STATIC
		sw	$16, PT_R16(sp)
		sw	$17, PT_R17(sp)
		sw	$18, PT_R18(sp)
		sw	$19, PT_R19(sp)
		sw	$20, PT_R20(sp)
		sw	$21, PT_R21(sp)
		sw	$22, PT_R22(sp)
		sw	$23, PT_R23(sp)
		sw	$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. */
		lui	k1, %hi(kernelsp)
		lw	k1, %lo(kernelsp)(k1)
8:		move	k0, sp
		subu	sp, k1, PT_SIZE
		sw	k0, PT_R29(sp)
		sw	$3, PT_R3(sp)
		sw	$0, PT_R0(sp)
		mfc0	v1, CP0_STATUS
		sw	$2, PT_R2(sp)
		sw	v1, PT_STATUS(sp)
		sw	$4, PT_R4(sp)
		mfc0	v1, CP0_CAUSE
		sw	$5, PT_R5(sp)
		sw	v1, PT_CAUSE(sp)
		sw	$6, PT_R6(sp)
		mfc0	v1, CP0_EPC
		sw	$7, PT_R7(sp)
		sw	v1, PT_EPC(sp)
		sw	$25, PT_R25(sp)
		sw	$28, PT_R28(sp)
		sw	$31, PT_R31(sp)
		ori	$28, sp, 0x1fff
		xori	$28, 0x1fff
		.set	pop
		.endm

		.macro	SAVE_ALL
		SAVE_SOME
		SAVE_AT
		SAVE_TEMP
		SAVE_STATIC
		.endm

		.macro	RESTORE_AT
		lw	$1,  PT_R1(sp)
		.endm

		.macro	RESTORE_SP
		lw	sp,  PT_R29(sp)
		.endm

		.macro	RESTORE_TEMP
		lw	$24, PT_LO(sp)
		lw	$8, PT_R8(sp)
		lw	$9, PT_R9(sp)
		mtlo	$24
		lw	$24, PT_HI(sp)
		lw	$10,PT_R10(sp)
		lw	$11, PT_R11(sp)
		mthi	$24
		lw	$12, PT_R12(sp)
		lw	$13, PT_R13(sp)
		lw	$14, PT_R14(sp)
		lw	$15, PT_R15(sp)
		lw	$24, PT_R24(sp)
		.endm

		.macro	RESTORE_STATIC
		lw	$16, PT_R16(sp)
		lw	$17, PT_R17(sp)
		lw	$18, PT_R18(sp)
		lw	$19, PT_R19(sp)
		lw	$20, PT_R20(sp)
		lw	$21, PT_R21(sp)
		lw	$22, PT_R22(sp)
		lw	$23, PT_R23(sp)
		lw	$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
		lw	v0, PT_STATUS(sp)
		nor	v1, $0, v1
		and	v0, v1
		or	v0, t0
		mtc0	v0, CP0_STATUS
		lw	v1, PT_EPC(sp)
		mtc0	v1, CP0_EPC
		lw	$31, PT_R31(sp)
		lw	$28, PT_R28(sp)
		lw	$25, PT_R25(sp)
		lw	$7,  PT_R7(sp)
		lw	$6,  PT_R6(sp)
		lw	$5,  PT_R5(sp)
		lw	$4,  PT_R4(sp)
		lw	$3,  PT_R3(sp)
		lw	$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 */