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