1 /* break.S: Break interrupt handling (kept separate from entry.S)
3 * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
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.
12 #include <linux/sys.h>
13 #include <linux/linkage.h>
14 #include <asm/setup.h>
15 #include <asm/segment.h>
16 #include <asm/ptrace.h>
17 #include <asm/spr-regs.h>
19 #include <asm/errno.h>
22 # the break handler has its own stack
25 .globl __break_user_context
28 .space (8192 - (USER_CONTEXT_SIZE + REG__DEBUG_XTRA)) & ~7
30 .space REG__DEBUG_XTRA
32 .space USER_CONTEXT_SIZE
35 # miscellaneous variables
39 .globl __break_tlb_miss_real_return_info
40 __break_tlb_miss_real_return_info:
42 .space 2*4 /* saved PCSR, PSR for TLB-miss handler fixup */
45 __break_trace_through_exceptions:
48 #define CS2_ECS1 0xe1200000
49 #define CS2_USERLED 0x4
52 # sethi.p %hi(CS2_ECS1+CS2_USERLED),gr30
53 # setlo %lo(CS2_ECS1+CS2_USERLED),gr30
57 # sethi.p %hi(0xffc00100),gr30
58 # setlo %lo(0xffc00100),gr30
59 # sth \reg,@(gr30,gr0)
63 ###############################################################################
65 # entry point for Break Exceptions/Interrupts
67 ###############################################################################
77 sethi.p %hi(__break_user_context),gr31
78 setlo %lo(__break_user_context),gr31
80 stdi gr2,@(gr31,#REG_GR(2))
82 sti gr3,@(gr31,#REG_CCR)
84 # catch the return from a TLB-miss handler that had single-step disabled
85 # traps will be enabled, so we have to do this now
88 sethi.p %hi(__break_tlb_miss_return_breaks_here),gr2
89 setlo %lo(__break_tlb_miss_return_breaks_here),gr2
90 subcc gr2,gr3,gr0,icc0
91 beq icc0,#2,__break_return_singlestep_tlbmiss
94 # determine whether we have stepped through into an exception
95 # - we need to take special action to suspend h/w single stepping if we've done
96 # that, so that the gdbstub doesn't get bogged down endlessly stepping through
97 # external interrupt handling
99 andicc gr3,#BPSR_BET,gr0,icc0
100 bne icc0,#2,__break_maybe_userspace /* jump if PSR.ET was 1 */
105 andicc gr3,#BRR_ST,gr0,icc0
106 andicc.p gr3,#BRR_SB,gr0,icc1
107 bne icc0,#2,__break_step /* jump if single-step caused break */
108 beq icc1,#2,__break_continue /* jump if BREAK didn't cause break */
112 # handle special breaks
115 sethi.p %hi(__entry_return_singlestep_breaks_here),gr2
116 setlo %lo(__entry_return_singlestep_breaks_here),gr2
117 subcc gr2,gr3,gr0,icc0
118 beq icc0,#2,__break_return_singlestep
123 ###############################################################################
125 # handle BREAK instruction in kernel-mode exception epilogue
127 ###############################################################################
128 __break_return_singlestep:
131 # special break insn requests single-stepping to be turned back on
136 # BPSR.ET 0 1 (can't have caused orig excep otherwise)
137 # BPSR.BS 1 old PSR.S
139 sethi.p %hi(DCR_SE),gr3
140 setlo %lo(DCR_SE),gr3
146 slli gr2,#11,gr2 /* PSR.PS -> BPSR.BS */
147 ori gr2,#BPSR_BET,gr2 /* 1 -> BPSR.BET */
150 # return to the invoker of the original kernel exception
156 ldi @(gr31,#REG_CCR),gr3
158 lddi.p @(gr31,#REG_GR(2)),gr2
166 ###############################################################################
168 # handle BREAK instruction in TLB-miss handler return path
170 ###############################################################################
172 __break_return_singlestep_tlbmiss:
175 sethi.p %hi(__break_tlb_miss_real_return_info),gr3
176 setlo %lo(__break_tlb_miss_real_return_info),gr3
181 bra __break_return_singlestep
185 ###############################################################################
187 # handle single stepping into an exception prologue from kernel mode
188 # - we try and catch it whilst it is still in the main vector table
189 # - if we catch it there, we have to jump to the fixup handler
190 # - there is a fixup table that has a pointer for every 16b slot in the trap
193 ###############################################################################
197 # external interrupts seem to escape from the trap table before single
198 # step catches up with them
200 sethi.p %hi(__entry_kernel_external_interrupt),gr3
201 setlo %lo(__entry_kernel_external_interrupt),gr3
202 subcc.p gr2,gr3,gr0,icc0
203 sethi %hi(__entry_uspace_external_interrupt),gr3
204 setlo.p %lo(__entry_uspace_external_interrupt),gr3
205 beq icc0,#2,__break_step_kernel_external_interrupt
206 subcc.p gr2,gr3,gr0,icc0
207 sethi %hi(__entry_kernel_external_interrupt_virtually_disabled),gr3
208 setlo.p %lo(__entry_kernel_external_interrupt_virtually_disabled),gr3
209 beq icc0,#2,__break_step_uspace_external_interrupt
210 subcc.p gr2,gr3,gr0,icc0
211 sethi %hi(__entry_kernel_external_interrupt_virtual_reenable),gr3
212 setlo.p %lo(__entry_kernel_external_interrupt_virtual_reenable),gr3
213 beq icc0,#2,__break_step_kernel_external_interrupt_virtually_disabled
214 subcc gr2,gr3,gr0,icc0
215 beq icc0,#2,__break_step_kernel_external_interrupt_virtual_reenable
219 # the two main vector tables are adjacent on one 8Kb slab
221 setlos #0xffffe000,gr3
223 sethi.p %hi(__trap_tables),gr3
224 setlo %lo(__trap_tables),gr3
225 subcc gr2,gr3,gr0,icc0
226 bne icc0,#2,__break_continue
230 # skip workaround if so requested by GDB
231 sethi.p %hi(__break_trace_through_exceptions),gr3
232 setlo %lo(__break_trace_through_exceptions),gr3
234 subcc gr3,gr0,gr0,icc0
235 bne icc0,#0,__break_continue
239 # access the fixup table - there's a 1:1 mapping between the slots in the trap tables and
240 # the slots in the trap fixup tables allowing us to simply divide the offset into the
241 # former by 4 to access the latter
242 sethi.p %hi(__trap_tables),gr3
243 setlo %lo(__trap_tables),gr3
248 sethi %hi(__trap_fixup_tables),gr3
249 setlo.p %lo(__trap_fixup_tables),gr3
254 # step through an internal exception from kernel mode
255 .globl __break_step_kernel_softprog_interrupt
256 __break_step_kernel_softprog_interrupt:
257 sethi.p %hi(__entry_kernel_softprog_interrupt_reentry),gr3
258 setlo %lo(__entry_kernel_softprog_interrupt_reentry),gr3
259 bra __break_return_as_kernel_prologue
261 # step through an external interrupt from kernel mode
262 .globl __break_step_kernel_external_interrupt
263 __break_step_kernel_external_interrupt:
264 # deal with virtual interrupt disablement
265 beq icc2,#0,__break_step_kernel_external_interrupt_virtually_disabled
267 sethi.p %hi(__entry_kernel_external_interrupt_reentry),gr3
268 setlo %lo(__entry_kernel_external_interrupt_reentry),gr3
270 __break_return_as_kernel_prologue:
275 # do the bit we had to skip
277 movsg ear0,gr2 /* EAR0 can get clobbered by gdb-stub (ICI/ICEI) */
281 or.p sp,gr0,gr2 /* set up the stack pointer */
283 sti.p gr2,@(sp,#REG_SP)
285 setlos #REG__STATUS_STEP,gr2
286 sti gr2,@(sp,#REG__STATUS) /* record single step status */
288 # cancel single-stepping mode
290 sethi.p %hi(~DCR_SE),gr3
291 setlo %lo(~DCR_SE),gr3
297 ldi @(gr31,#REG_CCR),gr3
299 lddi.p @(gr31,#REG_GR(2)),gr2
307 # we single-stepped into an interrupt handler whilst interrupts were merely virtually disabled
308 # need to really disable interrupts, set flag, fix up and return
309 __break_step_kernel_external_interrupt_virtually_disabled:
311 andi gr2,#~PSR_PIL,gr2
312 ori gr2,#PSR_PIL_14,gr2 /* debugging interrupts only */
315 ldi @(gr31,#REG_CCR),gr3
317 subcc.p gr0,gr0,gr0,icc2 /* leave Z set, clear C */
319 # exceptions must've been enabled and we must've been in supervisor mode
320 setlos BPSR_BET|BPSR_BS,gr3
323 # return to where the interrupt happened
327 lddi.p @(gr31,#REG_GR(2)),gr2
336 # we stepped through into the virtual interrupt reenablement trap
338 # we also want to single step anyway, but after fixing up so that we get an event on the
339 # instruction after the broken-into exception returns
340 .globl __break_step_kernel_external_interrupt_virtual_reenable
341 __break_step_kernel_external_interrupt_virtual_reenable:
343 andi gr2,#~PSR_PIL,gr2
346 ldi @(gr31,#REG_CCR),gr3
348 subicc gr0,#1,gr0,icc2 /* clear Z, set C */
350 # save the adjusted ICC2
352 sti gr3,@(gr31,#REG_CCR)
354 # exceptions must've been enabled and we must've been in supervisor mode
355 setlos BPSR_BET|BPSR_BS,gr3
358 # return to where the trap happened
362 # and then process the single step
365 # step through an internal exception from uspace mode
366 .globl __break_step_uspace_softprog_interrupt
367 __break_step_uspace_softprog_interrupt:
368 sethi.p %hi(__entry_uspace_softprog_interrupt_reentry),gr3
369 setlo %lo(__entry_uspace_softprog_interrupt_reentry),gr3
370 bra __break_return_as_uspace_prologue
372 # step through an external interrupt from kernel mode
373 .globl __break_step_uspace_external_interrupt
374 __break_step_uspace_external_interrupt:
375 sethi.p %hi(__entry_uspace_external_interrupt_reentry),gr3
376 setlo %lo(__entry_uspace_external_interrupt_reentry),gr3
378 __break_return_as_uspace_prologue:
383 # do the bit we had to skip
384 sethi.p %hi(__kernel_frame0_ptr),gr28
385 setlo %lo(__kernel_frame0_ptr),gr28
386 ldi.p @(gr28,#0),gr28
388 setlos #REG__STATUS_STEP,gr2
389 sti gr2,@(gr28,#REG__STATUS) /* record single step status */
391 # cancel single-stepping mode
393 sethi.p %hi(~DCR_SE),gr3
394 setlo %lo(~DCR_SE),gr3
400 ldi @(gr31,#REG_CCR),gr3
402 lddi.p @(gr31,#REG_GR(2)),gr2
411 # step through an ITLB-miss handler from user mode
412 .globl __break_user_insn_tlb_miss
413 __break_user_insn_tlb_miss:
414 # we'll want to try the trap stub again
415 sethi.p %hi(__trap_user_insn_tlb_miss),gr2
416 setlo %lo(__trap_user_insn_tlb_miss),gr2
419 __break_tlb_miss_common:
422 # cancel single-stepping mode
424 sethi.p %hi(~DCR_SE),gr3
425 setlo %lo(~DCR_SE),gr3
429 # we'll swap the real return address for one with a BREAK insn so that we can re-enable
430 # single stepping on return
432 sethi.p %hi(__break_tlb_miss_real_return_info),gr3
433 setlo %lo(__break_tlb_miss_real_return_info),gr3
436 sethi.p %hi(__break_tlb_miss_return_break),gr2
437 setlo %lo(__break_tlb_miss_return_break),gr2
440 # we also have to fudge PSR because the return BREAK is in kernel space and we want
441 # to get a BREAK fault not an access violation should the return be to userspace
449 ldi @(gr31,#REG_CCR),gr3
451 lddi @(gr31,#REG_GR(2)),gr2
456 # step through a DTLB-miss handler from user mode
457 .globl __break_user_data_tlb_miss
458 __break_user_data_tlb_miss:
459 # we'll want to try the trap stub again
460 sethi.p %hi(__trap_user_data_tlb_miss),gr2
461 setlo %lo(__trap_user_data_tlb_miss),gr2
463 bra __break_tlb_miss_common
465 # step through an ITLB-miss handler from kernel mode
466 .globl __break_kernel_insn_tlb_miss
467 __break_kernel_insn_tlb_miss:
468 # we'll want to try the trap stub again
469 sethi.p %hi(__trap_kernel_insn_tlb_miss),gr2
470 setlo %lo(__trap_kernel_insn_tlb_miss),gr2
472 bra __break_tlb_miss_common
474 # step through a DTLB-miss handler from kernel mode
475 .globl __break_kernel_data_tlb_miss
476 __break_kernel_data_tlb_miss:
477 # we'll want to try the trap stub again
478 sethi.p %hi(__trap_kernel_data_tlb_miss),gr2
479 setlo %lo(__trap_kernel_data_tlb_miss),gr2
481 bra __break_tlb_miss_common
484 ###############################################################################
486 # handle debug events originating with userspace
488 ###############################################################################
489 __break_maybe_userspace:
493 andcc gr3,gr2,gr0,icc0
494 bne icc0,#0,__break_continue /* skip if PSR.S was 1 */
497 andicc gr2,#BRR_ST|BRR_SB,gr0,icc0
498 beq icc0,#0,__break_continue /* jump if not BREAK or single-step */
502 # do the first part of the exception prologue here
503 sethi.p %hi(__kernel_frame0_ptr),gr28
504 setlo %lo(__kernel_frame0_ptr),gr28
508 # set up the kernel stack pointer
509 sti sp ,@(gr28,#REG_SP)
511 sti gr0 ,@(gr28,#REG_GR(28))
513 stdi gr20,@(gr28,#REG_GR(20))
514 stdi gr22,@(gr28,#REG_GR(22))
520 # determine the exception type and cancel single-stepping mode
524 sethi.p %hi(DCR_SE),gr3
525 setlo %lo(DCR_SE),gr3
526 andcc gr2,gr3,gr0,icc0
527 beq icc0,#0,__break_no_user_sstep /* must have been a BREAK insn */
532 ori gr23,#REG__STATUS_STEP,gr23
534 __break_no_user_sstep:
538 andi gr2,#BRR_ST|BRR_SB,gr2
541 sti.p gr23,@(gr28,#REG__STATUS) /* record single step status */
543 # adjust the value acquired from TBR - this indicates the exception
546 setlos #TBR_TT_BREAK,gr2
549 # fudge PSR.PS and BPSR.BS to return to kernel mode through the trap
551 andi gr22,#~PSR_PS,gr22 /* PSR.PS should be 0 */
554 setlos #BPSR_BS,gr2 /* BPSR.BS should be 1 and BPSR.BET 0 */
557 # return through remainder of the exception prologue
558 # - need to load gr23 with return handler address
559 sethi.p %hi(__entry_return_from_user_exception),gr23
560 setlo %lo(__entry_return_from_user_exception),gr23
561 sethi.p %hi(__entry_common),gr3
562 setlo %lo(__entry_common),gr3
567 ldi @(gr31,#REG_CCR),gr3
569 lddi.p @(gr31,#REG_GR(2)),gr2
577 ###############################################################################
579 # resume normal debug-mode entry
581 ###############################################################################
585 # set up the kernel stack pointer
586 sti sp,@(gr31,#REG_SP)
588 sethi.p %hi(__break_stack_tos),sp
589 setlo %lo(__break_stack_tos),sp
591 # finish building the exception frame
592 stdi gr4 ,@(gr31,#REG_GR(4))
593 stdi gr6 ,@(gr31,#REG_GR(6))
594 stdi gr8 ,@(gr31,#REG_GR(8))
595 stdi gr10,@(gr31,#REG_GR(10))
596 stdi gr12,@(gr31,#REG_GR(12))
597 stdi gr14,@(gr31,#REG_GR(14))
598 stdi gr16,@(gr31,#REG_GR(16))
599 stdi gr18,@(gr31,#REG_GR(18))
600 stdi gr20,@(gr31,#REG_GR(20))
601 stdi gr22,@(gr31,#REG_GR(22))
602 stdi gr24,@(gr31,#REG_GR(24))
603 stdi gr26,@(gr31,#REG_GR(26))
604 sti gr0 ,@(gr31,#REG_GR(28)) /* NULL frame pointer */
605 sti gr29,@(gr31,#REG_GR(29))
606 sti gr30,@(gr31,#REG_GR(30))
607 sti gr8 ,@(gr31,#REG_ORIG_GR8)
611 sti gr19,@(gr31,#REG_GR(31))
623 andi.p gr22,#~(PSR_S|PSR_ET),gr5 /* rebuild PSR */
624 andi gr19,#PSR_ET,gr4
631 sti gr20,@(gr31,#REG_TBR)
632 sti gr21,@(gr31,#REG_PC)
633 sti gr5 ,@(gr31,#REG_PSR)
634 sti gr23,@(gr31,#REG_ISR)
635 sti gr25,@(gr31,#REG_CCCR)
636 stdi gr26,@(gr31,#REG_LR)
637 sti gr6 ,@(gr31,#REG_SYSCALLNO)
639 # store CPU-specific regs
642 stdi gr4,@(gr31,#REG_IACC0)
646 stdi gr4,@(gr31,#REG_GNER0)
648 # build the debug register frame
654 stdi gr4 ,@(gr31,#REG_BRR)
655 sti gr19,@(gr31,#REG_BPSR)
656 sti.p gr6 ,@(gr31,#REG_DCR)
658 # trap exceptions during break handling and disable h/w breakpoints/watchpoints
659 sethi %hi(DCR_EBE),gr5
660 setlo.p %lo(DCR_EBE),gr5
661 sethi %hi(__entry_breaktrap_table),gr4
662 setlo %lo(__entry_breaktrap_table),gr4
666 # set up kernel global registers
667 sethi.p %hi(__kernel_current_task),gr5
668 setlo %lo(__kernel_current_task),gr5
670 ldi.p @(gr29,#4),gr15 ; __current_thread_info = current->thread_info
673 setlo.p %lo(_gp),gr16
675 # make sure we (the kernel) get div-zero and misalignment exceptions
676 setlos #ISR_EDE|ISR_DTT_DIVBYZERO|ISR_EMAM_EXCEPTION,gr5
688 lddi @(gr31,#REG_IACC0),gr4
692 lddi @(gr31,#REG_GNER0),gr4
696 lddi @(gr31,#REG_LR) ,gr26
697 lddi @(gr31,#REG_CCR) ,gr24
698 lddi @(gr31,#REG_PSR) ,gr22
699 ldi @(gr31,#REG_PC) ,gr21
700 ldi @(gr31,#REG_TBR) ,gr20
701 ldi.p @(gr31,#REG_DCR) ,gr6
703 andi gr22,#PSR_S,gr19 /* rebuild BPSR */
704 andi.p gr22,#PSR_ET,gr5
721 ldi @(gr31,#REG_GR(31)),gr2
725 ldi @(gr31,#REG_GR(30)),gr30
726 ldi @(gr31,#REG_GR(29)),gr29
727 lddi @(gr31,#REG_GR(26)),gr26
728 lddi @(gr31,#REG_GR(24)),gr24
729 lddi @(gr31,#REG_GR(22)),gr22
730 lddi @(gr31,#REG_GR(20)),gr20
731 lddi @(gr31,#REG_GR(18)),gr18
732 lddi @(gr31,#REG_GR(16)),gr16
733 lddi @(gr31,#REG_GR(14)),gr14
734 lddi @(gr31,#REG_GR(12)),gr12
735 lddi @(gr31,#REG_GR(10)),gr10
736 lddi @(gr31,#REG_GR(8)) ,gr8
737 lddi @(gr31,#REG_GR(6)) ,gr6
738 lddi @(gr31,#REG_GR(4)) ,gr4
739 lddi @(gr31,#REG_GR(2)) ,gr2
740 ldi.p @(gr31,#REG_SP) ,sp
749 ###################################################################################################
751 # GDB stub "system calls"
753 ###################################################################################################
755 #ifdef CONFIG_GDBSTUB
756 # void gdbstub_console_write(struct console *con, const char *p, unsigned n)
757 .globl gdbstub_console_write
758 gdbstub_console_write:
763 # GDB stub BUG() trap
764 # GR8 is the proposed signal number
765 .globl __debug_bug_trap
770 # transfer kernel exeception to GDB for handling
771 .globl __break_hijack_kernel_event
772 __break_hijack_kernel_event:
774 .globl __break_hijack_kernel_event_breaks_here
775 __break_hijack_kernel_event_breaks_here:
779 # handle a return from TLB-miss that requires single-step reactivation
780 .globl __break_tlb_miss_return_break
781 __break_tlb_miss_return_break:
783 __break_tlb_miss_return_breaks_here:
787 # guard the first .text label in the next file from confusion