1/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * Copyright (C) 1994 - 2000, 2001, 2003 Ralf Baechle
4 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
5 * Copyright (C) 2002, 2007  Maciej W. Rozycki
6 * Copyright (C) 2001, 2012 MIPS Technologies, Inc.  All rights reserved.
7 */
8
9#include <asm/asm.h>
10#include <asm/regdef.h>
11#include <asm/mipsregs.h>
12#include <asm/asm-offsets.h>
13
14#define STATMASK 0x1f
15
16	.set	noreorder
17
18	/*
19	 * Macros copied and adapted from Linux MIPS
20	 */
21	.macro	SAVE_AT
22	.set	push
23	.set	noat
24	LONG_S	$1, PT_R1(sp)
25	.set	pop
26	.endm
27
28	.macro	SAVE_TEMP
29#if __mips_isa_rev < 6
30	mfhi	v1
31#endif
32#ifdef CONFIG_32BIT
33	LONG_S	$8, PT_R8(sp)
34	LONG_S	$9, PT_R9(sp)
35#endif
36	LONG_S	$10, PT_R10(sp)
37	LONG_S	$11, PT_R11(sp)
38	LONG_S	$12, PT_R12(sp)
39#if __mips_isa_rev < 6
40	LONG_S	v1, PT_HI(sp)
41	mflo	v1
42#endif
43	LONG_S	$13, PT_R13(sp)
44	LONG_S	$14, PT_R14(sp)
45	LONG_S	$15, PT_R15(sp)
46	LONG_S	$24, PT_R24(sp)
47#if __mips_isa_rev < 6
48	LONG_S	v1, PT_LO(sp)
49#endif
50	.endm
51
52	.macro	SAVE_STATIC
53	LONG_S	$16, PT_R16(sp)
54	LONG_S	$17, PT_R17(sp)
55	LONG_S	$18, PT_R18(sp)
56	LONG_S	$19, PT_R19(sp)
57	LONG_S	$20, PT_R20(sp)
58	LONG_S	$21, PT_R21(sp)
59	LONG_S	$22, PT_R22(sp)
60	LONG_S	$23, PT_R23(sp)
61	LONG_S	$30, PT_R30(sp)
62	.endm
63
64	.macro	SAVE_SOME
65	.set	push
66	.set	noat
67	PTR_SUBU k1, sp, PT_SIZE
68	LONG_S	sp, PT_R29(k1)
69	move	sp, k1
70
71	LONG_S	$3, PT_R3(sp)
72	LONG_S	$0, PT_R0(sp)
73	mfc0	v1, CP0_STATUS
74	LONG_S	$2, PT_R2(sp)
75	LONG_S	v1, PT_STATUS(sp)
76	LONG_S	$4, PT_R4(sp)
77	mfc0	v1, CP0_CAUSE
78	LONG_S	$5, PT_R5(sp)
79	LONG_S	v1, PT_CAUSE(sp)
80	LONG_S	$6, PT_R6(sp)
81	MFC0	v1, CP0_EPC
82	LONG_S	$7, PT_R7(sp)
83#ifdef CONFIG_64BIT
84	LONG_S	$8, PT_R8(sp)
85	LONG_S	$9, PT_R9(sp)
86#endif
87	LONG_S	v1, PT_EPC(sp)
88	LONG_S	$25, PT_R25(sp)
89	LONG_S	$28, PT_R28(sp)
90	LONG_S	$31, PT_R31(sp)
91	.set	pop
92	.endm
93
94	.macro	RESTORE_AT
95	.set	push
96	.set	noat
97	LONG_L	$1,  PT_R1(sp)
98	.set	pop
99	.endm
100
101	.macro	RESTORE_TEMP
102#if __mips_isa_rev < 6
103	LONG_L	$24, PT_LO(sp)
104	mtlo	$24
105	LONG_L	$24, PT_HI(sp)
106	mthi	$24
107#endif
108#ifdef CONFIG_32BIT
109	LONG_L	$8, PT_R8(sp)
110	LONG_L	$9, PT_R9(sp)
111#endif
112	LONG_L	$10, PT_R10(sp)
113	LONG_L	$11, PT_R11(sp)
114	LONG_L	$12, PT_R12(sp)
115	LONG_L	$13, PT_R13(sp)
116	LONG_L	$14, PT_R14(sp)
117	LONG_L	$15, PT_R15(sp)
118	LONG_L	$24, PT_R24(sp)
119	.endm
120
121	.macro	RESTORE_STATIC
122	LONG_L	$16, PT_R16(sp)
123	LONG_L	$17, PT_R17(sp)
124	LONG_L	$18, PT_R18(sp)
125	LONG_L	$19, PT_R19(sp)
126	LONG_L	$20, PT_R20(sp)
127	LONG_L	$21, PT_R21(sp)
128	LONG_L	$22, PT_R22(sp)
129	LONG_L	$23, PT_R23(sp)
130	LONG_L	$30, PT_R30(sp)
131	.endm
132
133	.macro	RESTORE_SOME
134	.set	push
135	.set	reorder
136	.set	noat
137	mfc0	a0, CP0_STATUS
138	ori	a0, STATMASK
139	xori	a0, STATMASK
140	mtc0	a0, CP0_STATUS
141	li	v1, ST0_CU1 | ST0_FR | ST0_IM
142	and	a0, v1
143	LONG_L	v0, PT_STATUS(sp)
144	nor	v1, $0, v1
145	and	v0, v1
146	or	v0, a0
147	mtc0	v0, CP0_STATUS
148	LONG_L	v1, PT_EPC(sp)
149	MTC0	v1, CP0_EPC
150	LONG_L	$31, PT_R31(sp)
151	LONG_L	$28, PT_R28(sp)
152	LONG_L	$25, PT_R25(sp)
153#ifdef CONFIG_64BIT
154	LONG_L	$8, PT_R8(sp)
155	LONG_L	$9, PT_R9(sp)
156#endif
157	LONG_L	$7,  PT_R7(sp)
158	LONG_L	$6,  PT_R6(sp)
159	LONG_L	$5,  PT_R5(sp)
160	LONG_L	$4,  PT_R4(sp)
161	LONG_L	$3,  PT_R3(sp)
162	LONG_L	$2,  PT_R2(sp)
163	.set	pop
164	.endm
165
166	.macro	RESTORE_SP
167	LONG_L	sp, PT_R29(sp)
168	.endm
169
170NESTED(except_vec3_generic, 0, sp)
171	PTR_LA	k1, handle_reserved
172	jr	k1
173	 nop
174	END(except_vec3_generic)
175
176NESTED(except_vec_ejtag_debug, 0, sp)
177	PTR_LA	k1, handle_ejtag_debug
178	jr	k1
179	 nop
180	END(except_vec_ejtag_debug)
181
182NESTED(handle_reserved, PT_SIZE, sp)
183	SAVE_SOME
184	SAVE_AT
185	SAVE_TEMP
186	SAVE_STATIC
187
188	PTR_LA	t9, do_reserved
189	jr	t9
190	 move	a0, sp
191	END(handle_reserved)
192
193NESTED(handle_ejtag_debug, PT_SIZE, sp)
194	.set	push
195	.set	noat
196	MTC0	k1, CP0_DESAVE
197
198	/* Check for SDBBP */
199	MFC0	k1, CP0_DEBUG
200	sll	k1, k1, 30
201	bgez	k1, ejtag_return
202	 nop
203
204	SAVE_SOME
205	SAVE_AT
206	SAVE_TEMP
207	SAVE_STATIC
208
209	PTR_LA	t9, do_ejtag_debug
210	jalr	t9
211	 move	a0, sp
212
213	RESTORE_TEMP
214	RESTORE_STATIC
215	RESTORE_AT
216	RESTORE_SOME
217	RESTORE_SP
218
219ejtag_return:
220	MFC0	k1, CP0_DESAVE
221	deret
222	.set pop
223	END(handle_ejtag_debug)
224