1/* break.S: Break interrupt handling (kept separate from entry.S)
2 *
3 * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/linkage.h>
13#include <asm/setup.h>
14#include <asm/segment.h>
15#include <asm/ptrace.h>
16#include <asm/thread_info.h>
17#include <asm/spr-regs.h>
18
19#include <asm/errno.h>
20
21#
22# the break handler has its own stack
23#
24	.section	.bss.stack
25	.globl		__break_user_context
26	.balign		THREAD_SIZE
27__break_stack:
28	.space		THREAD_SIZE - FRV_FRAME0_SIZE
29__break_frame_0:
30	.space		FRV_FRAME0_SIZE
31
32#
33# miscellaneous variables
34#
35	.section	.bss
36#ifdef CONFIG_MMU
37	.globl		__break_tlb_miss_real_return_info
38__break_tlb_miss_real_return_info:
39	.balign		8
40	.space		2*4			/* saved PCSR, PSR for TLB-miss handler fixup */
41#endif
42
43__break_trace_through_exceptions:
44	.space		4
45
46#define CS2_ECS1	0xe1200000
47#define CS2_USERLED	0x4
48
49.macro LEDS val,reg
50#	sethi.p		%hi(CS2_ECS1+CS2_USERLED),gr30
51#	setlo		%lo(CS2_ECS1+CS2_USERLED),gr30
52#	setlos		#~\val,\reg
53#	st		\reg,@(gr30,gr0)
54#	setlos		#0x5555,\reg
55#	sethi.p		%hi(0xffc00100),gr30
56#	setlo		%lo(0xffc00100),gr30
57#	sth		\reg,@(gr30,gr0)
58#	membar
59.endm
60
61###############################################################################
62#
63# entry point for Break Exceptions/Interrupts
64#
65###############################################################################
66	.text
67	.balign		4
68	.globl		__entry_break
69__entry_break:
70#ifdef CONFIG_MMU
71	movgs		gr31,scr3
72#endif
73	LEDS		0x1001,gr31
74
75	sethi.p		%hi(__break_frame_0),gr31
76	setlo		%lo(__break_frame_0),gr31
77
78	stdi		gr2,@(gr31,#REG_GR(2))
79	movsg		ccr,gr3
80	sti		gr3,@(gr31,#REG_CCR)
81
82	# catch the return from a TLB-miss handler that had single-step disabled
83	# traps will be enabled, so we have to do this now
84#ifdef CONFIG_MMU
85	movsg		bpcsr,gr3
86	sethi.p		%hi(__break_tlb_miss_return_breaks_here),gr2
87	setlo		%lo(__break_tlb_miss_return_breaks_here),gr2
88	subcc		gr2,gr3,gr0,icc0
89	beq		icc0,#2,__break_return_singlestep_tlbmiss
90#endif
91
92	# determine whether we have stepped through into an exception
93	# - we need to take special action to suspend h/w single stepping if we've done
94	#   that, so that the gdbstub doesn't get bogged down endlessly stepping through
95	#   external interrupt handling
96	movsg		bpsr,gr3
97	andicc		gr3,#BPSR_BET,gr0,icc0
98	bne		icc0,#2,__break_maybe_userspace	/* jump if PSR.ET was 1 */
99
100	LEDS		0x1003,gr2
101
102	movsg		brr,gr3
103	andicc		gr3,#BRR_ST,gr0,icc0
104	andicc.p	gr3,#BRR_SB,gr0,icc1
105	bne		icc0,#2,__break_step		/* jump if single-step caused break */
106	beq		icc1,#2,__break_continue	/* jump if BREAK didn't cause break */
107
108	LEDS		0x1007,gr2
109
110	# handle special breaks
111	movsg		bpcsr,gr3
112
113	sethi.p		%hi(__entry_return_singlestep_breaks_here),gr2
114	setlo		%lo(__entry_return_singlestep_breaks_here),gr2
115	subcc		gr2,gr3,gr0,icc0
116	beq		icc0,#2,__break_return_singlestep
117
118	bra		__break_continue
119
120
121###############################################################################
122#
123# handle BREAK instruction in kernel-mode exception epilogue
124#
125###############################################################################
126__break_return_singlestep:
127	LEDS		0x100f,gr2
128
129	# special break insn requests single-stepping to be turned back on
130	#		HERE		RETT
131	# PSR.ET	0		0
132	# PSR.PS	old PSR.S	?
133	# PSR.S		1		1
134	# BPSR.ET	0		1 (can't have caused orig excep otherwise)
135	# BPSR.BS	1		old PSR.S
136	movsg		dcr,gr2
137	sethi.p		%hi(DCR_SE),gr3
138	setlo		%lo(DCR_SE),gr3
139	or		gr2,gr3,gr2
140	movgs		gr2,dcr
141
142	movsg		psr,gr2
143	andi		gr2,#PSR_PS,gr2
144	slli		gr2,#11,gr2			/* PSR.PS -> BPSR.BS */
145	ori		gr2,#BPSR_BET,gr2		/* 1 -> BPSR.BET */
146	movgs		gr2,bpsr
147
148	# return to the invoker of the original kernel exception
149	movsg		pcsr,gr2
150	movgs		gr2,bpcsr
151
152	LEDS		0x101f,gr2
153
154	ldi		@(gr31,#REG_CCR),gr3
155	movgs		gr3,ccr
156	lddi.p		@(gr31,#REG_GR(2)),gr2
157	xor		gr31,gr31,gr31
158	movgs		gr0,brr
159#ifdef CONFIG_MMU
160	movsg		scr3,gr31
161#endif
162	rett		#1
163
164###############################################################################
165#
166# handle BREAK instruction in TLB-miss handler return path
167#
168###############################################################################
169#ifdef CONFIG_MMU
170__break_return_singlestep_tlbmiss:
171	LEDS		0x1100,gr2
172
173	sethi.p		%hi(__break_tlb_miss_real_return_info),gr3
174	setlo		%lo(__break_tlb_miss_real_return_info),gr3
175	lddi		@(gr3,#0),gr2
176	movgs		gr2,pcsr
177	movgs		gr3,psr
178
179	bra		__break_return_singlestep
180#endif
181
182
183###############################################################################
184#
185# handle single stepping into an exception prologue from kernel mode
186# - we try and catch it whilst it is still in the main vector table
187# - if we catch it there, we have to jump to the fixup handler
188#   - there is a fixup table that has a pointer for every 16b slot in the trap
189#     table
190#
191###############################################################################
192__break_step:
193	LEDS		0x2003,gr2
194
195	# external interrupts seem to escape from the trap table before single
196	# step catches up with them
197	movsg		bpcsr,gr2
198	sethi.p		%hi(__entry_kernel_external_interrupt),gr3
199	setlo		%lo(__entry_kernel_external_interrupt),gr3
200	subcc.p		gr2,gr3,gr0,icc0
201	sethi		%hi(__entry_uspace_external_interrupt),gr3
202	setlo.p		%lo(__entry_uspace_external_interrupt),gr3
203	beq		icc0,#2,__break_step_kernel_external_interrupt
204	subcc.p		gr2,gr3,gr0,icc0
205	sethi		%hi(__entry_kernel_external_interrupt_virtually_disabled),gr3
206	setlo.p		%lo(__entry_kernel_external_interrupt_virtually_disabled),gr3
207	beq		icc0,#2,__break_step_uspace_external_interrupt
208	subcc.p		gr2,gr3,gr0,icc0
209	sethi		%hi(__entry_kernel_external_interrupt_virtual_reenable),gr3
210	setlo.p		%lo(__entry_kernel_external_interrupt_virtual_reenable),gr3
211	beq		icc0,#2,__break_step_kernel_external_interrupt_virtually_disabled
212	subcc		gr2,gr3,gr0,icc0
213	beq		icc0,#2,__break_step_kernel_external_interrupt_virtual_reenable
214
215	LEDS		0x2007,gr2
216
217	# the two main vector tables are adjacent on one 8Kb slab
218	movsg		bpcsr,gr2
219	setlos		#0xffffe000,gr3
220	and		gr2,gr3,gr2
221	sethi.p		%hi(__trap_tables),gr3
222	setlo		%lo(__trap_tables),gr3
223	subcc		gr2,gr3,gr0,icc0
224	bne		icc0,#2,__break_continue
225
226	LEDS		0x200f,gr2
227
228	# skip workaround if so requested by GDB
229	sethi.p		%hi(__break_trace_through_exceptions),gr3
230	setlo		%lo(__break_trace_through_exceptions),gr3
231	ld		@(gr3,gr0),gr3
232	subcc		gr3,gr0,gr0,icc0
233	bne		icc0,#0,__break_continue
234
235	LEDS		0x201f,gr2
236
237	# access the fixup table - there's a 1:1 mapping between the slots in the trap tables and
238	# the slots in the trap fixup tables allowing us to simply divide the offset into the
239	# former by 4 to access the latter
240	sethi.p		%hi(__trap_tables),gr3
241	setlo		%lo(__trap_tables),gr3
242	movsg		bpcsr,gr2
243	sub		gr2,gr3,gr2
244	srli.p		gr2,#2,gr2
245
246	sethi		%hi(__trap_fixup_tables),gr3
247	setlo.p		%lo(__trap_fixup_tables),gr3
248	andi		gr2,#~3,gr2
249	ld		@(gr2,gr3),gr2
250	jmpil		@(gr2,#0)
251
252# step through an internal exception from kernel mode
253	.globl		__break_step_kernel_softprog_interrupt
254__break_step_kernel_softprog_interrupt:
255	sethi.p		%hi(__entry_kernel_softprog_interrupt_reentry),gr3
256	setlo		%lo(__entry_kernel_softprog_interrupt_reentry),gr3
257	bra		__break_return_as_kernel_prologue
258
259# step through an external interrupt from kernel mode
260	.globl		__break_step_kernel_external_interrupt
261__break_step_kernel_external_interrupt:
262	# deal with virtual interrupt disablement
263	beq		icc2,#0,__break_step_kernel_external_interrupt_virtually_disabled
264
265	sethi.p		%hi(__entry_kernel_external_interrupt_reentry),gr3
266	setlo		%lo(__entry_kernel_external_interrupt_reentry),gr3
267
268__break_return_as_kernel_prologue:
269	LEDS		0x203f,gr2
270
271	movgs		gr3,bpcsr
272
273	# do the bit we had to skip
274#ifdef CONFIG_MMU
275	movsg		ear0,gr2		/* EAR0 can get clobbered by gdb-stub (ICI/ICEI) */
276	movgs		gr2,scr2
277#endif
278
279	or.p		sp,gr0,gr2		/* set up the stack pointer */
280	subi		sp,#REG__END,sp
281	sti.p		gr2,@(sp,#REG_SP)
282
283	setlos		#REG__STATUS_STEP,gr2
284	sti		gr2,@(sp,#REG__STATUS)		/* record single step status */
285
286	# cancel single-stepping mode
287	movsg		dcr,gr2
288	sethi.p		%hi(~DCR_SE),gr3
289	setlo		%lo(~DCR_SE),gr3
290	and		gr2,gr3,gr2
291	movgs		gr2,dcr
292
293	LEDS		0x207f,gr2
294
295	ldi		@(gr31,#REG_CCR),gr3
296	movgs		gr3,ccr
297	lddi.p		@(gr31,#REG_GR(2)),gr2
298	xor		gr31,gr31,gr31
299	movgs		gr0,brr
300#ifdef CONFIG_MMU
301	movsg		scr3,gr31
302#endif
303	rett		#1
304
305# we single-stepped into an interrupt handler whilst interrupts were merely virtually disabled
306# need to really disable interrupts, set flag, fix up and return
307__break_step_kernel_external_interrupt_virtually_disabled:
308	movsg		psr,gr2
309	andi		gr2,#~PSR_PIL,gr2
310	ori		gr2,#PSR_PIL_14,gr2	/* debugging interrupts only */
311	movgs		gr2,psr
312
313	ldi		@(gr31,#REG_CCR),gr3
314	movgs		gr3,ccr
315	subcc.p		gr0,gr0,gr0,icc2	/* leave Z set, clear C */
316
317	# exceptions must've been enabled and we must've been in supervisor mode
318	setlos		BPSR_BET|BPSR_BS,gr3
319	movgs		gr3,bpsr
320
321	# return to where the interrupt happened
322	movsg		pcsr,gr2
323	movgs		gr2,bpcsr
324
325	lddi.p		@(gr31,#REG_GR(2)),gr2
326
327	xor		gr31,gr31,gr31
328	movgs		gr0,brr
329#ifdef CONFIG_MMU
330	movsg		scr3,gr31
331#endif
332	rett		#1
333
334# we stepped through into the virtual interrupt reenablement trap
335#
336# we also want to single step anyway, but after fixing up so that we get an event on the
337# instruction after the broken-into exception returns
338	.globl		__break_step_kernel_external_interrupt_virtual_reenable
339__break_step_kernel_external_interrupt_virtual_reenable:
340	movsg		psr,gr2
341	andi		gr2,#~PSR_PIL,gr2
342	movgs		gr2,psr
343
344	ldi		@(gr31,#REG_CCR),gr3
345	movgs		gr3,ccr
346	subicc		gr0,#1,gr0,icc2		/* clear Z, set C */
347
348	# save the adjusted ICC2
349	movsg		ccr,gr3
350	sti		gr3,@(gr31,#REG_CCR)
351
352	# exceptions must've been enabled and we must've been in supervisor mode
353	setlos		BPSR_BET|BPSR_BS,gr3
354	movgs		gr3,bpsr
355
356	# return to where the trap happened
357	movsg		pcsr,gr2
358	movgs		gr2,bpcsr
359
360	# and then process the single step
361	bra		__break_continue
362
363# step through an internal exception from uspace mode
364	.globl		__break_step_uspace_softprog_interrupt
365__break_step_uspace_softprog_interrupt:
366	sethi.p		%hi(__entry_uspace_softprog_interrupt_reentry),gr3
367	setlo		%lo(__entry_uspace_softprog_interrupt_reentry),gr3
368	bra		__break_return_as_uspace_prologue
369
370# step through an external interrupt from kernel mode
371	.globl		__break_step_uspace_external_interrupt
372__break_step_uspace_external_interrupt:
373	sethi.p		%hi(__entry_uspace_external_interrupt_reentry),gr3
374	setlo		%lo(__entry_uspace_external_interrupt_reentry),gr3
375
376__break_return_as_uspace_prologue:
377	LEDS		0x20ff,gr2
378
379	movgs		gr3,bpcsr
380
381	# do the bit we had to skip
382	sethi.p		%hi(__kernel_frame0_ptr),gr28
383	setlo		%lo(__kernel_frame0_ptr),gr28
384	ldi.p		@(gr28,#0),gr28
385
386	setlos		#REG__STATUS_STEP,gr2
387	sti		gr2,@(gr28,#REG__STATUS)	/* record single step status */
388
389	# cancel single-stepping mode
390	movsg		dcr,gr2
391	sethi.p		%hi(~DCR_SE),gr3
392	setlo		%lo(~DCR_SE),gr3
393	and		gr2,gr3,gr2
394	movgs		gr2,dcr
395
396	LEDS		0x20fe,gr2
397
398	ldi		@(gr31,#REG_CCR),gr3
399	movgs		gr3,ccr
400	lddi.p		@(gr31,#REG_GR(2)),gr2
401	xor		gr31,gr31,gr31
402	movgs		gr0,brr
403#ifdef CONFIG_MMU
404	movsg		scr3,gr31
405#endif
406	rett		#1
407
408#ifdef CONFIG_MMU
409# step through an ITLB-miss handler from user mode
410	.globl		__break_user_insn_tlb_miss
411__break_user_insn_tlb_miss:
412	# we'll want to try the trap stub again
413	sethi.p		%hi(__trap_user_insn_tlb_miss),gr2
414	setlo		%lo(__trap_user_insn_tlb_miss),gr2
415	movgs		gr2,bpcsr
416
417__break_tlb_miss_common:
418	LEDS		0x2101,gr2
419
420	# cancel single-stepping mode
421	movsg		dcr,gr2
422	sethi.p		%hi(~DCR_SE),gr3
423	setlo		%lo(~DCR_SE),gr3
424	and		gr2,gr3,gr2
425	movgs		gr2,dcr
426
427	# we'll swap the real return address for one with a BREAK insn so that we can re-enable
428	# single stepping on return
429	movsg		pcsr,gr2
430	sethi.p		%hi(__break_tlb_miss_real_return_info),gr3
431	setlo		%lo(__break_tlb_miss_real_return_info),gr3
432	sti		gr2,@(gr3,#0)
433
434	sethi.p		%hi(__break_tlb_miss_return_break),gr2
435	setlo		%lo(__break_tlb_miss_return_break),gr2
436	movgs		gr2,pcsr
437
438	# we also have to fudge PSR because the return BREAK is in kernel space and we want
439	# to get a BREAK fault not an access violation should the return be to userspace
440	movsg		psr,gr2
441	sti.p		gr2,@(gr3,#4)
442	ori		gr2,#PSR_PS,gr2
443	movgs		gr2,psr
444
445	LEDS		0x2102,gr2
446
447	ldi		@(gr31,#REG_CCR),gr3
448	movgs		gr3,ccr
449	lddi		@(gr31,#REG_GR(2)),gr2
450	movsg		scr3,gr31
451	movgs		gr0,brr
452	rett		#1
453
454# step through a DTLB-miss handler from user mode
455	.globl		__break_user_data_tlb_miss
456__break_user_data_tlb_miss:
457	# we'll want to try the trap stub again
458	sethi.p		%hi(__trap_user_data_tlb_miss),gr2
459	setlo		%lo(__trap_user_data_tlb_miss),gr2
460	movgs		gr2,bpcsr
461	bra		__break_tlb_miss_common
462
463# step through an ITLB-miss handler from kernel mode
464	.globl		__break_kernel_insn_tlb_miss
465__break_kernel_insn_tlb_miss:
466	# we'll want to try the trap stub again
467	sethi.p		%hi(__trap_kernel_insn_tlb_miss),gr2
468	setlo		%lo(__trap_kernel_insn_tlb_miss),gr2
469	movgs		gr2,bpcsr
470	bra		__break_tlb_miss_common
471
472# step through a DTLB-miss handler from kernel mode
473	.globl		__break_kernel_data_tlb_miss
474__break_kernel_data_tlb_miss:
475	# we'll want to try the trap stub again
476	sethi.p		%hi(__trap_kernel_data_tlb_miss),gr2
477	setlo		%lo(__trap_kernel_data_tlb_miss),gr2
478	movgs		gr2,bpcsr
479	bra		__break_tlb_miss_common
480#endif
481
482###############################################################################
483#
484# handle debug events originating with userspace
485#
486###############################################################################
487__break_maybe_userspace:
488	LEDS		0x3003,gr2
489
490	setlos		#BPSR_BS,gr2
491	andcc		gr3,gr2,gr0,icc0
492	bne		icc0,#0,__break_continue	/* skip if PSR.S was 1 */
493
494	movsg		brr,gr2
495	andicc		gr2,#BRR_ST|BRR_SB,gr0,icc0
496	beq		icc0,#0,__break_continue	/* jump if not BREAK or single-step */
497
498	LEDS		0x3007,gr2
499
500	# do the first part of the exception prologue here
501	sethi.p		%hi(__kernel_frame0_ptr),gr28
502	setlo		%lo(__kernel_frame0_ptr),gr28
503	ldi		@(gr28,#0),gr28
504	andi		gr28,#~7,gr28
505
506	# set up the kernel stack pointer
507	sti		sp  ,@(gr28,#REG_SP)
508	ori		gr28,0,sp
509	sti		gr0 ,@(gr28,#REG_GR(28))
510
511	stdi		gr20,@(gr28,#REG_GR(20))
512	stdi		gr22,@(gr28,#REG_GR(22))
513
514	movsg		tbr,gr20
515	movsg		bpcsr,gr21
516	movsg		psr,gr22
517
518	# determine the exception type and cancel single-stepping mode
519	or		gr0,gr0,gr23
520
521	movsg		dcr,gr2
522	sethi.p		%hi(DCR_SE),gr3
523	setlo		%lo(DCR_SE),gr3
524	andcc		gr2,gr3,gr0,icc0
525	beq		icc0,#0,__break_no_user_sstep	/* must have been a BREAK insn */
526
527	not		gr3,gr3
528	and		gr2,gr3,gr2
529	movgs		gr2,dcr
530	ori		gr23,#REG__STATUS_STEP,gr23
531
532__break_no_user_sstep:
533	LEDS		0x300f,gr2
534
535	movsg		brr,gr2
536	andi		gr2,#BRR_ST|BRR_SB,gr2
537	slli		gr2,#1,gr2
538	or		gr23,gr2,gr23
539	sti.p		gr23,@(gr28,#REG__STATUS)	/* record single step status */
540
541	# adjust the value acquired from TBR - this indicates the exception
542	setlos		#~TBR_TT,gr2
543	and.p		gr20,gr2,gr20
544	setlos		#TBR_TT_BREAK,gr2
545	or.p		gr20,gr2,gr20
546
547	# fudge PSR.PS and BPSR.BS to return to kernel mode through the trap
548	# table as trap 126
549	andi		gr22,#~PSR_PS,gr22		/* PSR.PS should be 0 */
550	movgs		gr22,psr
551
552	setlos		#BPSR_BS,gr2			/* BPSR.BS should be 1 and BPSR.BET 0 */
553	movgs		gr2,bpsr
554
555	# return through remainder of the exception prologue
556	# - need to load gr23 with return handler address
557	sethi.p		%hi(__entry_return_from_user_exception),gr23
558	setlo		%lo(__entry_return_from_user_exception),gr23
559	sethi.p		%hi(__entry_common),gr3
560	setlo		%lo(__entry_common),gr3
561	movgs		gr3,bpcsr
562
563	LEDS		0x301f,gr2
564
565	ldi		@(gr31,#REG_CCR),gr3
566	movgs		gr3,ccr
567	lddi.p		@(gr31,#REG_GR(2)),gr2
568	xor		gr31,gr31,gr31
569	movgs		gr0,brr
570#ifdef CONFIG_MMU
571	movsg		scr3,gr31
572#endif
573	rett		#1
574
575###############################################################################
576#
577# resume normal debug-mode entry
578#
579###############################################################################
580__break_continue:
581	LEDS		0x4003,gr2
582
583	# set up the kernel stack pointer
584	sti		sp,@(gr31,#REG_SP)
585
586	sethi.p		%hi(__break_frame_0),sp
587	setlo		%lo(__break_frame_0),sp
588
589	# finish building the exception frame
590	stdi		gr4 ,@(gr31,#REG_GR(4))
591	stdi		gr6 ,@(gr31,#REG_GR(6))
592	stdi		gr8 ,@(gr31,#REG_GR(8))
593	stdi		gr10,@(gr31,#REG_GR(10))
594	stdi		gr12,@(gr31,#REG_GR(12))
595	stdi		gr14,@(gr31,#REG_GR(14))
596	stdi		gr16,@(gr31,#REG_GR(16))
597	stdi		gr18,@(gr31,#REG_GR(18))
598	stdi		gr20,@(gr31,#REG_GR(20))
599	stdi		gr22,@(gr31,#REG_GR(22))
600	stdi		gr24,@(gr31,#REG_GR(24))
601	stdi		gr26,@(gr31,#REG_GR(26))
602	sti		gr0 ,@(gr31,#REG_GR(28))	/* NULL frame pointer */
603	sti		gr29,@(gr31,#REG_GR(29))
604	sti		gr30,@(gr31,#REG_GR(30))
605	sti		gr8 ,@(gr31,#REG_ORIG_GR8)
606
607#ifdef CONFIG_MMU
608	movsg		scr3,gr19
609	sti		gr19,@(gr31,#REG_GR(31))
610#endif
611
612	movsg		bpsr ,gr19
613	movsg		tbr  ,gr20
614	movsg		bpcsr,gr21
615	movsg		psr  ,gr22
616	movsg		isr  ,gr23
617	movsg		cccr ,gr25
618	movsg		lr   ,gr26
619	movsg		lcr  ,gr27
620
621	andi.p		gr22,#~(PSR_S|PSR_ET),gr5	/* rebuild PSR */
622	andi		gr19,#PSR_ET,gr4
623	or.p		gr4,gr5,gr5
624	srli		gr19,#10,gr4
625	andi		gr4,#PSR_S,gr4
626	or.p		gr4,gr5,gr5
627
628	setlos		#-1,gr6
629	sti		gr20,@(gr31,#REG_TBR)
630	sti		gr21,@(gr31,#REG_PC)
631	sti		gr5 ,@(gr31,#REG_PSR)
632	sti		gr23,@(gr31,#REG_ISR)
633	sti		gr25,@(gr31,#REG_CCCR)
634	stdi		gr26,@(gr31,#REG_LR)
635	sti		gr6 ,@(gr31,#REG_SYSCALLNO)
636
637	# store CPU-specific regs
638	movsg		iacc0h,gr4
639	movsg		iacc0l,gr5
640	stdi		gr4,@(gr31,#REG_IACC0)
641
642	movsg		gner0,gr4
643	movsg		gner1,gr5
644	stdi		gr4,@(gr31,#REG_GNER0)
645
646	# build the debug register frame
647	movsg		brr,gr4
648	movgs		gr0,brr
649	movsg		nmar,gr5
650	movsg		dcr,gr6
651
652	sethi.p		%hi(__debug_status),gr7
653	setlo		%lo(__debug_status),gr7
654
655	stdi		gr4 ,@(gr7,#DEBUG_BRR)
656	sti		gr19,@(gr7,#DEBUG_BPSR)
657	sti.p		gr6 ,@(gr7,#DEBUG_DCR)
658
659	# trap exceptions during break handling and disable h/w breakpoints/watchpoints
660	sethi		%hi(DCR_EBE),gr5
661	setlo.p		%lo(DCR_EBE),gr5
662	sethi		%hi(__entry_breaktrap_table),gr4
663	setlo		%lo(__entry_breaktrap_table),gr4
664	movgs		gr5,dcr
665	movgs		gr4,tbr
666
667	# set up kernel global registers
668	sethi.p		%hi(__kernel_current_task),gr5
669	setlo		%lo(__kernel_current_task),gr5
670	ld		@(gr5,gr0),gr29
671	ldi.p		@(gr29,#4),gr15		; __current_thread_info = current->thread_info
672
673	sethi		%hi(_gp),gr16
674	setlo.p		%lo(_gp),gr16
675
676	# make sure we (the kernel) get div-zero and misalignment exceptions
677	setlos		#ISR_EDE|ISR_DTT_DIVBYZERO|ISR_EMAM_EXCEPTION,gr5
678	movgs		gr5,isr
679
680	# enter the GDB stub
681	LEDS		0x4007,gr2
682
683	or.p		gr0,gr0,fp
684	call		debug_stub
685
686	LEDS		0x403f,gr2
687
688	# return from break
689	lddi		@(gr31,#REG_IACC0),gr4
690	movgs		gr4,iacc0h
691	movgs		gr5,iacc0l
692
693	lddi		@(gr31,#REG_GNER0),gr4
694	movgs		gr4,gner0
695	movgs		gr5,gner1
696
697	lddi		@(gr31,#REG_LR)  ,gr26
698	lddi		@(gr31,#REG_CCR) ,gr24
699	lddi		@(gr31,#REG_PSR) ,gr22
700	ldi		@(gr31,#REG_PC)  ,gr21
701	ldi		@(gr31,#REG_TBR) ,gr20
702
703	sethi.p		%hi(__debug_status),gr6
704	setlo		%lo(__debug_status),gr6
705	ldi.p		@(gr6,#DEBUG_DCR) ,gr6
706
707	andi		gr22,#PSR_S,gr19		/* rebuild BPSR */
708	andi.p		gr22,#PSR_ET,gr5
709	slli		gr19,#10,gr19
710	or		gr5,gr19,gr19
711
712	movgs		gr6 ,dcr
713	movgs		gr19,bpsr
714	movgs		gr20,tbr
715	movgs		gr21,bpcsr
716	movgs		gr23,isr
717	movgs		gr24,ccr
718	movgs		gr25,cccr
719	movgs		gr26,lr
720	movgs		gr27,lcr
721
722	LEDS		0x407f,gr2
723
724#ifdef CONFIG_MMU
725	ldi		@(gr31,#REG_GR(31)),gr2
726	movgs		gr2,scr3
727#endif
728
729	ldi		@(gr31,#REG_GR(30)),gr30
730	ldi		@(gr31,#REG_GR(29)),gr29
731	lddi		@(gr31,#REG_GR(26)),gr26
732	lddi		@(gr31,#REG_GR(24)),gr24
733	lddi		@(gr31,#REG_GR(22)),gr22
734	lddi		@(gr31,#REG_GR(20)),gr20
735	lddi		@(gr31,#REG_GR(18)),gr18
736	lddi		@(gr31,#REG_GR(16)),gr16
737	lddi		@(gr31,#REG_GR(14)),gr14
738	lddi		@(gr31,#REG_GR(12)),gr12
739	lddi		@(gr31,#REG_GR(10)),gr10
740	lddi		@(gr31,#REG_GR(8)) ,gr8
741	lddi		@(gr31,#REG_GR(6)) ,gr6
742	lddi		@(gr31,#REG_GR(4)) ,gr4
743	lddi		@(gr31,#REG_GR(2)) ,gr2
744	ldi.p		@(gr31,#REG_SP)    ,sp
745
746	xor		gr31,gr31,gr31
747	movgs		gr0,brr
748#ifdef CONFIG_MMU
749	movsg		scr3,gr31
750#endif
751	rett		#1
752
753###################################################################################################
754#
755# GDB stub "system calls"
756#
757###################################################################################################
758
759#ifdef CONFIG_GDBSTUB
760	# void gdbstub_console_write(struct console *con, const char *p, unsigned n)
761	.globl		gdbstub_console_write
762gdbstub_console_write:
763	break
764	bralr
765#endif
766
767	# GDB stub BUG() trap
768	# GR8 is the proposed signal number
769	.globl		__debug_bug_trap
770__debug_bug_trap:
771	break
772	bralr
773
774	# transfer kernel exeception to GDB for handling
775	.globl		__break_hijack_kernel_event
776__break_hijack_kernel_event:
777	break
778	.globl		__break_hijack_kernel_event_breaks_here
779__break_hijack_kernel_event_breaks_here:
780	nop
781
782#ifdef CONFIG_MMU
783	# handle a return from TLB-miss that requires single-step reactivation
784	.globl		__break_tlb_miss_return_break
785__break_tlb_miss_return_break:
786	break
787__break_tlb_miss_return_breaks_here:
788	nop
789#endif
790
791	# guard the first .text label in the next file from confusion
792	nop
793