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/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>
20 #include <asm/errno.h>
23 # the break handler has its own stack
26 .globl __break_user_context
29 .space (8192 - (USER_CONTEXT_SIZE + REG__DEBUG_XTRA)) & ~7
31 .space REG__DEBUG_XTRA
33 .space USER_CONTEXT_SIZE
36 # miscellaneous variables
40 .globl __break_tlb_miss_real_return_info
41 __break_tlb_miss_real_return_info:
43 .space 2*4 /* saved PCSR, PSR for TLB-miss handler fixup */
46 __break_trace_through_exceptions:
49 #define CS2_ECS1 0xe1200000
50 #define CS2_USERLED 0x4
53 # sethi.p %hi(CS2_ECS1+CS2_USERLED),gr30
54 # setlo %lo(CS2_ECS1+CS2_USERLED),gr30
58 # sethi.p %hi(0xffc00100),gr30
59 # setlo %lo(0xffc00100),gr30
60 # sth \reg,@(gr30,gr0)
64 ###############################################################################
66 # entry point for Break Exceptions/Interrupts
68 ###############################################################################
78 sethi.p %hi(__break_user_context),gr31
79 setlo %lo(__break_user_context),gr31
81 stdi gr2,@(gr31,#REG_GR(2))
83 sti gr3,@(gr31,#REG_CCR)
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
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
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
100 andicc gr3,#BPSR_BET,gr0,icc0
101 bne icc0,#2,__break_maybe_userspace /* jump if PSR.ET was 1 */
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 */
113 # handle special breaks
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
124 ###############################################################################
126 # handle BREAK instruction in kernel-mode exception epilogue
128 ###############################################################################
129 __break_return_singlestep:
132 # special break insn requests single-stepping to be turned back on
137 # BPSR.ET 0 1 (can't have caused orig excep otherwise)
138 # BPSR.BS 1 old PSR.S
140 sethi.p %hi(DCR_SE),gr3
141 setlo %lo(DCR_SE),gr3
147 slli gr2,#11,gr2 /* PSR.PS -> BPSR.BS */
148 ori gr2,#BPSR_BET,gr2 /* 1 -> BPSR.BET */
151 # return to the invoker of the original kernel exception
157 ldi @(gr31,#REG_CCR),gr3
159 lddi.p @(gr31,#REG_GR(2)),gr2
167 ###############################################################################
169 # handle BREAK instruction in TLB-miss handler return path
171 ###############################################################################
173 __break_return_singlestep_tlbmiss:
176 sethi.p %hi(__break_tlb_miss_real_return_info),gr3
177 setlo %lo(__break_tlb_miss_real_return_info),gr3
182 bra __break_return_singlestep
186 ###############################################################################
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
194 ###############################################################################
198 # external interrupts seem to escape from the trap table before single
199 # step catches up with them
201 sethi.p %hi(__entry_kernel_external_interrupt),gr3
202 setlo %lo(__entry_kernel_external_interrupt),gr3
203 subcc.p gr2,gr3,gr0,icc0
204 sethi %hi(__entry_uspace_external_interrupt),gr3
205 setlo.p %lo(__entry_uspace_external_interrupt),gr3
206 beq icc0,#2,__break_step_kernel_external_interrupt
207 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
210 beq icc0,#2,__break_step_uspace_external_interrupt
211 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
220 # the two main vector tables are adjacent on one 8Kb slab
222 setlos #0xffffe000,gr3
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
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
235 subcc gr3,gr0,gr0,icc0
236 bne icc0,#0,__break_continue
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
249 sethi %hi(__trap_fixup_tables),gr3
250 setlo.p %lo(__trap_fixup_tables),gr3
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
262 # step through an external interrupt from kernel mode
263 .globl __break_step_kernel_external_interrupt
264 __break_step_kernel_external_interrupt:
265 # deal with virtual interrupt disablement
266 beq icc2,#0,__break_step_kernel_external_interrupt_virtually_disabled
268 sethi.p %hi(__entry_kernel_external_interrupt_reentry),gr3
269 setlo %lo(__entry_kernel_external_interrupt_reentry),gr3
271 __break_return_as_kernel_prologue:
276 # do the bit we had to skip
278 movsg ear0,gr2 /* EAR0 can get clobbered by gdb-stub (ICI/ICEI) */
282 or.p sp,gr0,gr2 /* set up the stack pointer */
284 sti.p gr2,@(sp,#REG_SP)
286 setlos #REG__STATUS_STEP,gr2
287 sti gr2,@(sp,#REG__STATUS) /* record single step status */
289 # cancel single-stepping mode
291 sethi.p %hi(~DCR_SE),gr3
292 setlo %lo(~DCR_SE),gr3
298 ldi @(gr31,#REG_CCR),gr3
300 lddi.p @(gr31,#REG_GR(2)),gr2
308 # 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:
312 andi gr2,#~PSR_PIL,gr2
313 ori gr2,#PSR_PIL_14,gr2 /* debugging interrupts only */
316 ldi @(gr31,#REG_CCR),gr3
318 subcc.p gr0,gr0,gr0,icc2 /* leave Z set, clear C */
320 # exceptions must've been enabled and we must've been in supervisor mode
321 setlos BPSR_BET|BPSR_BS,gr3
324 # return to where the interrupt happened
328 lddi.p @(gr31,#REG_GR(2)),gr2
337 # we stepped through into the virtual interrupt reenablement trap
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:
344 andi gr2,#~PSR_PIL,gr2
347 ldi @(gr31,#REG_CCR),gr3
349 subicc gr0,#1,gr0,icc2 /* clear Z, set C */
351 # save the adjusted ICC2
353 sti gr3,@(gr31,#REG_CCR)
355 # exceptions must've been enabled and we must've been in supervisor mode
356 setlos BPSR_BET|BPSR_BS,gr3
359 # return to where the trap happened
363 # and then process the single step
366 # 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
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
379 __break_return_as_uspace_prologue:
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
389 setlos #REG__STATUS_STEP,gr2
390 sti gr2,@(gr28,#REG__STATUS) /* record single step status */
392 # cancel single-stepping mode
394 sethi.p %hi(~DCR_SE),gr3
395 setlo %lo(~DCR_SE),gr3
401 ldi @(gr31,#REG_CCR),gr3
403 lddi.p @(gr31,#REG_GR(2)),gr2
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
420 __break_tlb_miss_common:
423 # cancel single-stepping mode
425 sethi.p %hi(~DCR_SE),gr3
426 setlo %lo(~DCR_SE),gr3
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
433 sethi.p %hi(__break_tlb_miss_real_return_info),gr3
434 setlo %lo(__break_tlb_miss_real_return_info),gr3
437 sethi.p %hi(__break_tlb_miss_return_break),gr2
438 setlo %lo(__break_tlb_miss_return_break),gr2
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
450 ldi @(gr31,#REG_CCR),gr3
452 lddi @(gr31,#REG_GR(2)),gr2
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
464 bra __break_tlb_miss_common
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
473 bra __break_tlb_miss_common
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
482 bra __break_tlb_miss_common
485 ###############################################################################
487 # handle debug events originating with userspace
489 ###############################################################################
490 __break_maybe_userspace:
494 andcc gr3,gr2,gr0,icc0
495 bne icc0,#0,__break_continue /* skip if PSR.S was 1 */
498 andicc gr2,#BRR_ST|BRR_SB,gr0,icc0
499 beq icc0,#0,__break_continue /* jump if not BREAK or single-step */
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
509 # set up the kernel stack pointer
510 sti sp ,@(gr28,#REG_SP)
512 sti gr0 ,@(gr28,#REG_GR(28))
514 stdi gr20,@(gr28,#REG_GR(20))
515 stdi gr22,@(gr28,#REG_GR(22))
521 # determine the exception type and cancel single-stepping mode
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 */
533 ori gr23,#REG__STATUS_STEP,gr23
535 __break_no_user_sstep:
539 andi gr2,#BRR_ST|BRR_SB,gr2
542 sti.p gr23,@(gr28,#REG__STATUS) /* record single step status */
544 # adjust the value acquired from TBR - this indicates the exception
547 setlos #TBR_TT_BREAK,gr2
550 # fudge PSR.PS and BPSR.BS to return to kernel mode through the trap
552 andi gr22,#~PSR_PS,gr22 /* PSR.PS should be 0 */
555 setlos #BPSR_BS,gr2 /* BPSR.BS should be 1 and BPSR.BET 0 */
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
568 ldi @(gr31,#REG_CCR),gr3
570 lddi.p @(gr31,#REG_GR(2)),gr2
578 ###############################################################################
580 # resume normal debug-mode entry
582 ###############################################################################
586 # set up the kernel stack pointer
587 sti sp,@(gr31,#REG_SP)
589 sethi.p %hi(__break_stack_tos),sp
590 setlo %lo(__break_stack_tos),sp
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)
612 sti gr19,@(gr31,#REG_GR(31))
624 andi.p gr22,#~(PSR_S|PSR_ET),gr5 /* rebuild PSR */
625 andi gr19,#PSR_ET,gr4
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)
640 # store CPU-specific regs
643 stdi gr4,@(gr31,#REG_IACC0)
647 stdi gr4,@(gr31,#REG_GNER0)
649 # build the debug register frame
655 stdi gr4 ,@(gr31,#REG_BRR)
656 sti gr19,@(gr31,#REG_BPSR)
657 sti.p gr6 ,@(gr31,#REG_DCR)
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
667 # set up kernel global registers
668 sethi.p %hi(__kernel_current_task),gr5
669 setlo %lo(__kernel_current_task),gr5
671 ldi.p @(gr29,#4),gr15 ; __current_thread_info = current->thread_info
674 setlo.p %lo(_gp),gr16
676 # make sure we (the kernel) get div-zero and misalignment exceptions
677 setlos #ISR_EDE|ISR_DTT_DIVBYZERO|ISR_EMAM_EXCEPTION,gr5
689 lddi @(gr31,#REG_IACC0),gr4
693 lddi @(gr31,#REG_GNER0),gr4
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
704 andi gr22,#PSR_S,gr19 /* rebuild BPSR */
705 andi.p gr22,#PSR_ET,gr5
722 ldi @(gr31,#REG_GR(31)),gr2
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
750 ###################################################################################################
752 # GDB stub "system calls"
754 ###################################################################################################
756 #ifdef CONFIG_GDBSTUB
757 # void gdbstub_console_write(struct console *con, const char *p, unsigned n)
758 .globl gdbstub_console_write
759 gdbstub_console_write:
764 # GDB stub BUG() trap
765 # GR8 is the proposed signal number
766 .globl __debug_bug_trap
771 # transfer kernel exeception to GDB for handling
772 .globl __break_hijack_kernel_event
773 __break_hijack_kernel_event:
775 .globl __break_hijack_kernel_event_breaks_here
776 __break_hijack_kernel_event_breaks_here:
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:
784 __break_tlb_miss_return_breaks_here:
788 # guard the first .text label in the next file from confusion