1/*
2 * gdb-low.S contains the low-level trap handler for the GDB stub.
3 *
4 * Copyright (C) 1995 Andreas Busse
5 */
6#include <linux/sys.h>
7
8#include <asm/asm.h>
9#include <asm/errno.h>
10#include <asm/irqflags.h>
11#include <asm/mipsregs.h>
12#include <asm/regdef.h>
13#include <asm/stackframe.h>
14#include <asm/gdb-stub.h>
15
16#ifdef CONFIG_32BIT
17#define DMFC0	mfc0
18#define DMTC0	mtc0
19#define LDC1	lwc1
20#define SDC1	lwc1
21#endif
22#ifdef CONFIG_64BIT
23#define DMFC0	dmfc0
24#define DMTC0	dmtc0
25#define LDC1	ldc1
26#define SDC1	ldc1
27#endif
28
29/*
30 * [jsun] We reserves about 2x GDB_FR_SIZE in stack.  The lower (addressed)
31 * part is used to store registers and passed to exception handler.
32 * The upper part is reserved for "call func" feature where gdb client
33 * saves some of the regs, setups call frame and passes args.
34 *
35 * A trace shows about 200 bytes are used to store about half of all regs.
36 * The rest should be big enough for frame setup and passing args.
37 */
38
39/*
40 * The low level trap handler
41 */
42		.align 	5
43		NESTED(trap_low, GDB_FR_SIZE, sp)
44		.set	noat
45		.set 	noreorder
46
47		mfc0	k0, CP0_STATUS
48		sll	k0, 3     		/* extract cu0 bit */
49		bltz	k0, 1f
50		move	k1, sp
51
52		/*
53		 * Called from user mode, go somewhere else.
54		 */
55		mfc0	k0, CP0_CAUSE
56		andi	k0, k0, 0x7c
57#ifdef CONFIG_64BIT
58		dsll	k0, k0, 1
59#endif
60		PTR_L	k1, saved_vectors(k0)
61		jr	k1
62		nop
631:
64		move	k0, sp
65		PTR_SUBU sp, k1, GDB_FR_SIZE*2	# see comment above
66		LONG_S	k0, GDB_FR_REG29(sp)
67		LONG_S	$2, GDB_FR_REG2(sp)
68
69/*
70 * First save the CP0 and special registers
71 */
72
73		mfc0	v0, CP0_STATUS
74		LONG_S	v0, GDB_FR_STATUS(sp)
75		mfc0	v0, CP0_CAUSE
76		LONG_S	v0, GDB_FR_CAUSE(sp)
77		DMFC0	v0, CP0_EPC
78		LONG_S	v0, GDB_FR_EPC(sp)
79		DMFC0	v0, CP0_BADVADDR
80		LONG_S	v0, GDB_FR_BADVADDR(sp)
81		mfhi	v0
82		LONG_S	v0, GDB_FR_HI(sp)
83		mflo	v0
84		LONG_S	v0, GDB_FR_LO(sp)
85
86/*
87 * Now the integer registers
88 */
89
90		LONG_S	zero, GDB_FR_REG0(sp)		/* I know... */
91		LONG_S	$1, GDB_FR_REG1(sp)
92		/* v0 already saved */
93		LONG_S	$3, GDB_FR_REG3(sp)
94		LONG_S	$4, GDB_FR_REG4(sp)
95		LONG_S	$5, GDB_FR_REG5(sp)
96		LONG_S	$6, GDB_FR_REG6(sp)
97		LONG_S	$7, GDB_FR_REG7(sp)
98		LONG_S	$8, GDB_FR_REG8(sp)
99		LONG_S	$9, GDB_FR_REG9(sp)
100		LONG_S	$10, GDB_FR_REG10(sp)
101		LONG_S	$11, GDB_FR_REG11(sp)
102		LONG_S	$12, GDB_FR_REG12(sp)
103		LONG_S	$13, GDB_FR_REG13(sp)
104		LONG_S	$14, GDB_FR_REG14(sp)
105		LONG_S	$15, GDB_FR_REG15(sp)
106		LONG_S	$16, GDB_FR_REG16(sp)
107		LONG_S	$17, GDB_FR_REG17(sp)
108		LONG_S	$18, GDB_FR_REG18(sp)
109		LONG_S	$19, GDB_FR_REG19(sp)
110		LONG_S	$20, GDB_FR_REG20(sp)
111		LONG_S	$21, GDB_FR_REG21(sp)
112		LONG_S	$22, GDB_FR_REG22(sp)
113		LONG_S	$23, GDB_FR_REG23(sp)
114		LONG_S	$24, GDB_FR_REG24(sp)
115		LONG_S	$25, GDB_FR_REG25(sp)
116		LONG_S	$26, GDB_FR_REG26(sp)
117		LONG_S	$27, GDB_FR_REG27(sp)
118		LONG_S	$28, GDB_FR_REG28(sp)
119		/* sp already saved */
120		LONG_S	$30, GDB_FR_REG30(sp)
121		LONG_S	$31, GDB_FR_REG31(sp)
122
123		CLI				/* disable interrupts */
124		TRACE_IRQS_OFF
125
126/*
127 * Followed by the floating point registers
128 */
129		mfc0	v0, CP0_STATUS		/* FPU enabled? */
130		srl	v0, v0, 16
131		andi	v0, v0, (ST0_CU1 >> 16)
132
133		beqz	v0,2f			/* disabled, skip */
134		 nop
135
136		SDC1	$0, GDB_FR_FPR0(sp)
137		SDC1	$1, GDB_FR_FPR1(sp)
138		SDC1	$2, GDB_FR_FPR2(sp)
139		SDC1	$3, GDB_FR_FPR3(sp)
140		SDC1	$4, GDB_FR_FPR4(sp)
141		SDC1	$5, GDB_FR_FPR5(sp)
142		SDC1	$6, GDB_FR_FPR6(sp)
143		SDC1	$7, GDB_FR_FPR7(sp)
144		SDC1	$8, GDB_FR_FPR8(sp)
145		SDC1	$9, GDB_FR_FPR9(sp)
146		SDC1	$10, GDB_FR_FPR10(sp)
147		SDC1	$11, GDB_FR_FPR11(sp)
148		SDC1	$12, GDB_FR_FPR12(sp)
149		SDC1	$13, GDB_FR_FPR13(sp)
150		SDC1	$14, GDB_FR_FPR14(sp)
151		SDC1	$15, GDB_FR_FPR15(sp)
152		SDC1	$16, GDB_FR_FPR16(sp)
153		SDC1	$17, GDB_FR_FPR17(sp)
154		SDC1	$18, GDB_FR_FPR18(sp)
155		SDC1	$19, GDB_FR_FPR19(sp)
156		SDC1	$20, GDB_FR_FPR20(sp)
157		SDC1	$21, GDB_FR_FPR21(sp)
158		SDC1	$22, GDB_FR_FPR22(sp)
159		SDC1	$23, GDB_FR_FPR23(sp)
160		SDC1	$24, GDB_FR_FPR24(sp)
161		SDC1	$25, GDB_FR_FPR25(sp)
162		SDC1	$26, GDB_FR_FPR26(sp)
163		SDC1	$27, GDB_FR_FPR27(sp)
164		SDC1	$28, GDB_FR_FPR28(sp)
165		SDC1	$29, GDB_FR_FPR29(sp)
166		SDC1	$30, GDB_FR_FPR30(sp)
167		SDC1	$31, GDB_FR_FPR31(sp)
168
169/*
170 * FPU control registers
171 */
172
173		cfc1	v0, CP1_STATUS
174		LONG_S	v0, GDB_FR_FSR(sp)
175		cfc1	v0, CP1_REVISION
176		LONG_S	v0, GDB_FR_FIR(sp)
177
178/*
179 * Current stack frame ptr
180 */
181
1822:
183		LONG_S	sp, GDB_FR_FRP(sp)
184
185/*
186 * CP0 registers (R4000/R4400 unused registers skipped)
187 */
188
189		mfc0	v0, CP0_INDEX
190		LONG_S	v0, GDB_FR_CP0_INDEX(sp)
191		mfc0	v0, CP0_RANDOM
192		LONG_S	v0, GDB_FR_CP0_RANDOM(sp)
193		DMFC0	v0, CP0_ENTRYLO0
194		LONG_S	v0, GDB_FR_CP0_ENTRYLO0(sp)
195		DMFC0	v0, CP0_ENTRYLO1
196		LONG_S	v0, GDB_FR_CP0_ENTRYLO1(sp)
197		DMFC0	v0, CP0_CONTEXT
198		LONG_S	v0, GDB_FR_CP0_CONTEXT(sp)
199		mfc0	v0, CP0_PAGEMASK
200		LONG_S	v0, GDB_FR_CP0_PAGEMASK(sp)
201		mfc0	v0, CP0_WIRED
202		LONG_S	v0, GDB_FR_CP0_WIRED(sp)
203		DMFC0	v0, CP0_ENTRYHI
204		LONG_S	v0, GDB_FR_CP0_ENTRYHI(sp)
205		mfc0	v0, CP0_PRID
206		LONG_S	v0, GDB_FR_CP0_PRID(sp)
207
208		.set	at
209
210/*
211 * Continue with the higher level handler
212 */
213
214		move	a0,sp
215
216		jal	handle_exception
217		 nop
218
219/*
220 * Restore all writable registers, in reverse order
221 */
222
223		.set	noat
224
225		LONG_L	v0, GDB_FR_CP0_ENTRYHI(sp)
226		LONG_L	v1, GDB_FR_CP0_WIRED(sp)
227		DMTC0	v0, CP0_ENTRYHI
228		mtc0	v1, CP0_WIRED
229		LONG_L	v0, GDB_FR_CP0_PAGEMASK(sp)
230		LONG_L	v1, GDB_FR_CP0_ENTRYLO1(sp)
231		mtc0	v0, CP0_PAGEMASK
232		DMTC0	v1, CP0_ENTRYLO1
233		LONG_L	v0, GDB_FR_CP0_ENTRYLO0(sp)
234		LONG_L	v1, GDB_FR_CP0_INDEX(sp)
235		DMTC0	v0, CP0_ENTRYLO0
236		LONG_L	v0, GDB_FR_CP0_CONTEXT(sp)
237		mtc0	v1, CP0_INDEX
238		DMTC0	v0, CP0_CONTEXT
239
240
241/*
242 * Next, the floating point registers
243 */
244		mfc0	v0, CP0_STATUS		/* check if the FPU is enabled */
245		srl	v0, v0, 16
246		andi	v0, v0, (ST0_CU1 >> 16)
247
248		beqz	v0, 3f			/* disabled, skip */
249		 nop
250
251		LDC1	$31, GDB_FR_FPR31(sp)
252		LDC1	$30, GDB_FR_FPR30(sp)
253		LDC1	$29, GDB_FR_FPR29(sp)
254		LDC1	$28, GDB_FR_FPR28(sp)
255		LDC1	$27, GDB_FR_FPR27(sp)
256		LDC1	$26, GDB_FR_FPR26(sp)
257		LDC1	$25, GDB_FR_FPR25(sp)
258		LDC1	$24, GDB_FR_FPR24(sp)
259		LDC1	$23, GDB_FR_FPR23(sp)
260		LDC1	$22, GDB_FR_FPR22(sp)
261		LDC1	$21, GDB_FR_FPR21(sp)
262		LDC1	$20, GDB_FR_FPR20(sp)
263		LDC1	$19, GDB_FR_FPR19(sp)
264		LDC1	$18, GDB_FR_FPR18(sp)
265		LDC1	$17, GDB_FR_FPR17(sp)
266		LDC1	$16, GDB_FR_FPR16(sp)
267		LDC1	$15, GDB_FR_FPR15(sp)
268		LDC1	$14, GDB_FR_FPR14(sp)
269		LDC1	$13, GDB_FR_FPR13(sp)
270		LDC1	$12, GDB_FR_FPR12(sp)
271		LDC1	$11, GDB_FR_FPR11(sp)
272		LDC1	$10, GDB_FR_FPR10(sp)
273		LDC1	$9, GDB_FR_FPR9(sp)
274		LDC1	$8, GDB_FR_FPR8(sp)
275		LDC1	$7, GDB_FR_FPR7(sp)
276		LDC1	$6, GDB_FR_FPR6(sp)
277		LDC1	$5, GDB_FR_FPR5(sp)
278		LDC1	$4, GDB_FR_FPR4(sp)
279		LDC1	$3, GDB_FR_FPR3(sp)
280		LDC1	$2, GDB_FR_FPR2(sp)
281		LDC1	$1, GDB_FR_FPR1(sp)
282		LDC1	$0, GDB_FR_FPR0(sp)
283
284/*
285 * Now the CP0 and integer registers
286 */
287
2883:
289#ifdef CONFIG_MIPS_MT_SMTC
290		/* Read-modify write of Status must be atomic */
291		mfc0	t2, CP0_TCSTATUS
292		ori	t1, t2, TCSTATUS_IXMT
293		mtc0	t1, CP0_TCSTATUS
294		andi	t2, t2, TCSTATUS_IXMT
295		_ehb
296		DMT	9				# dmt	t1
297		jal	mips_ihb
298		nop
299#endif /* CONFIG_MIPS_MT_SMTC */
300		mfc0	t0, CP0_STATUS
301		ori	t0, 0x1f
302		xori	t0, 0x1f
303		mtc0	t0, CP0_STATUS
304#ifdef CONFIG_MIPS_MT_SMTC
305        	andi    t1, t1, VPECONTROL_TE
306        	beqz    t1, 9f
307		nop
308        	EMT					# emt
3099:
310		mfc0	t1, CP0_TCSTATUS
311		xori	t1, t1, TCSTATUS_IXMT
312		or	t1, t1, t2
313		mtc0	t1, CP0_TCSTATUS
314		_ehb
315#endif /* CONFIG_MIPS_MT_SMTC */
316		LONG_L	v0, GDB_FR_STATUS(sp)
317		LONG_L	v1, GDB_FR_EPC(sp)
318		mtc0	v0, CP0_STATUS
319		DMTC0	v1, CP0_EPC
320		LONG_L	v0, GDB_FR_HI(sp)
321		LONG_L	v1, GDB_FR_LO(sp)
322		mthi	v0
323		mtlo	v1
324		LONG_L	$31, GDB_FR_REG31(sp)
325		LONG_L	$30, GDB_FR_REG30(sp)
326		LONG_L	$28, GDB_FR_REG28(sp)
327		LONG_L	$27, GDB_FR_REG27(sp)
328		LONG_L	$26, GDB_FR_REG26(sp)
329		LONG_L	$25, GDB_FR_REG25(sp)
330		LONG_L	$24, GDB_FR_REG24(sp)
331		LONG_L	$23, GDB_FR_REG23(sp)
332		LONG_L	$22, GDB_FR_REG22(sp)
333		LONG_L	$21, GDB_FR_REG21(sp)
334		LONG_L	$20, GDB_FR_REG20(sp)
335		LONG_L	$19, GDB_FR_REG19(sp)
336		LONG_L	$18, GDB_FR_REG18(sp)
337		LONG_L	$17, GDB_FR_REG17(sp)
338		LONG_L	$16, GDB_FR_REG16(sp)
339		LONG_L	$15, GDB_FR_REG15(sp)
340		LONG_L	$14, GDB_FR_REG14(sp)
341		LONG_L	$13, GDB_FR_REG13(sp)
342		LONG_L	$12, GDB_FR_REG12(sp)
343		LONG_L	$11, GDB_FR_REG11(sp)
344		LONG_L	$10, GDB_FR_REG10(sp)
345		LONG_L	$9, GDB_FR_REG9(sp)
346		LONG_L	$8, GDB_FR_REG8(sp)
347		LONG_L	$7, GDB_FR_REG7(sp)
348		LONG_L	$6, GDB_FR_REG6(sp)
349		LONG_L	$5, GDB_FR_REG5(sp)
350		LONG_L	$4, GDB_FR_REG4(sp)
351		LONG_L	$3, GDB_FR_REG3(sp)
352		LONG_L	$2, GDB_FR_REG2(sp)
353		LONG_L	$1, GDB_FR_REG1(sp)
354#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
355		LONG_L	k0, GDB_FR_EPC(sp)
356		LONG_L	$29, GDB_FR_REG29(sp)		/* Deallocate stack */
357		jr	k0
358		rfe
359#else
360		LONG_L	sp, GDB_FR_REG29(sp)		/* Deallocate stack */
361
362		.set	mips3
363		eret
364		.set	mips0
365#endif
366		.set	at
367		.set	reorder
368		END(trap_low)
369
370LEAF(kgdb_read_byte)
3714:		lb	t0, (a0)
372		sb	t0, (a1)
373		li	v0, 0
374		jr	ra
375		.section __ex_table,"a"
376		PTR	4b, kgdbfault
377		.previous
378		END(kgdb_read_byte)
379
380LEAF(kgdb_write_byte)
3815:		sb	a0, (a1)
382		li	v0, 0
383		jr	ra
384		.section __ex_table,"a"
385		PTR	5b, kgdbfault
386		.previous
387		END(kgdb_write_byte)
388
389		.type	kgdbfault@function
390		.ent	kgdbfault
391
392kgdbfault:	li	v0, -EFAULT
393		jr	ra
394		.end	kgdbfault
395