This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / arch / frv / kernel / break.S
diff --git a/arch/frv/kernel/break.S b/arch/frv/kernel/break.S
new file mode 100644 (file)
index 0000000..33233dc
--- /dev/null
@@ -0,0 +1,720 @@
+/* break.S: Break interrupt handling (kept separate from entry.S)
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/sys.h>
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/ptrace.h>
+#include <asm/spr-regs.h>
+
+#include <asm/errno.h>
+
+#
+# the break handler has its own stack
+#
+       .section        .bss.stack
+       .globl          __break_user_context
+       .balign         8192
+__break_stack:
+       .space          (8192 - (USER_CONTEXT_SIZE + REG__DEBUG_XTRA)) & ~7
+__break_stack_tos:
+       .space          REG__DEBUG_XTRA
+__break_user_context:
+       .space          USER_CONTEXT_SIZE
+
+#
+# miscellaneous variables
+#
+       .section        .bss
+#ifdef CONFIG_MMU
+       .globl          __break_tlb_miss_real_return_info
+__break_tlb_miss_real_return_info:
+       .balign         8
+       .space          2*4                     /* saved PCSR, PSR for TLB-miss handler fixup */
+#endif
+
+__break_trace_through_exceptions:
+       .space          4
+
+#define CS2_ECS1       0xe1200000
+#define CS2_USERLED    0x4
+
+.macro LEDS val,reg
+#      sethi.p         %hi(CS2_ECS1+CS2_USERLED),gr30
+#      setlo           %lo(CS2_ECS1+CS2_USERLED),gr30
+#      setlos          #~\val,\reg
+#      st              \reg,@(gr30,gr0)
+#      setlos          #0x5555,\reg
+#      sethi.p         %hi(0xffc00100),gr30
+#      setlo           %lo(0xffc00100),gr30
+#      sth             \reg,@(gr30,gr0)
+#      membar
+.endm
+
+###############################################################################
+#
+# entry point for Break Exceptions/Interrupts
+#
+###############################################################################
+       .text
+       .balign         4
+       .globl          __entry_break
+__entry_break:
+#ifdef CONFIG_MMU
+       movgs           gr31,scr3
+#endif
+       LEDS            0x1001,gr31
+
+       sethi.p         %hi(__break_user_context),gr31
+       setlo           %lo(__break_user_context),gr31
+
+       stdi            gr2,@(gr31,#REG_GR(2))
+       movsg           ccr,gr3
+       sti             gr3,@(gr31,#REG_CCR)
+
+       # catch the return from a TLB-miss handler that had single-step disabled
+       # traps will be enabled, so we have to do this now
+#ifdef CONFIG_MMU
+       movsg           bpcsr,gr3
+       sethi.p         %hi(__break_tlb_miss_return_breaks_here),gr2
+       setlo           %lo(__break_tlb_miss_return_breaks_here),gr2
+       subcc           gr2,gr3,gr0,icc0
+       beq             icc0,#2,__break_return_singlestep_tlbmiss
+#endif
+
+       # determine whether we have stepped through into an exception
+       # - we need to take special action to suspend h/w single stepping if we've done
+       #   that, so that the gdbstub doesn't get bogged down endlessly stepping through
+       #   external interrupt handling
+       movsg           bpsr,gr3
+       andicc          gr3,#BPSR_BET,gr0,icc0
+       bne             icc0,#2,__break_maybe_userspace /* jump if PSR.ET was 1 */
+
+       LEDS            0x1003,gr2
+
+       movsg           brr,gr3
+       andicc          gr3,#BRR_ST,gr0,icc0
+       andicc.p        gr3,#BRR_SB,gr0,icc1
+       bne             icc0,#2,__break_step            /* jump if single-step caused break */
+       beq             icc1,#2,__break_continue        /* jump if BREAK didn't cause break */
+
+       LEDS            0x1007,gr2
+
+       # handle special breaks
+       movsg           bpcsr,gr3
+
+       sethi.p         %hi(__entry_return_singlestep_breaks_here),gr2
+       setlo           %lo(__entry_return_singlestep_breaks_here),gr2
+       subcc           gr2,gr3,gr0,icc0
+       beq             icc0,#2,__break_return_singlestep
+
+       bra             __break_continue
+
+
+###############################################################################
+#
+# handle BREAK instruction in kernel-mode exception epilogue
+#
+###############################################################################
+__break_return_singlestep:
+       LEDS            0x100f,gr2
+
+       # special break insn requests single-stepping to be turned back on
+       #               HERE            RETT
+       # PSR.ET        0               0
+       # PSR.PS        old PSR.S       ?
+       # PSR.S         1               1
+       # BPSR.ET       0               1 (can't have caused orig excep otherwise)
+       # BPSR.BS       1               old PSR.S
+       movsg           dcr,gr2
+       sethi.p         %hi(DCR_SE),gr3
+       setlo           %lo(DCR_SE),gr3
+       or              gr2,gr3,gr2
+       movgs           gr2,dcr
+
+       movsg           psr,gr2
+       andi            gr2,#PSR_PS,gr2
+       slli            gr2,#11,gr2                     /* PSR.PS -> BPSR.BS */
+       ori             gr2,#BPSR_BET,gr2               /* 1 -> BPSR.BET */
+       movgs           gr2,bpsr
+
+       # return to the invoker of the original kernel exception
+       movsg           pcsr,gr2
+       movgs           gr2,bpcsr
+
+       LEDS            0x101f,gr2
+
+       ldi             @(gr31,#REG_CCR),gr3
+       movgs           gr3,ccr
+       lddi.p          @(gr31,#REG_GR(2)),gr2
+       xor             gr31,gr31,gr31
+       movgs           gr0,brr
+#ifdef CONFIG_MMU
+       movsg           scr3,gr31
+#endif
+       rett            #1
+
+###############################################################################
+#
+# handle BREAK instruction in TLB-miss handler return path
+#
+###############################################################################
+#ifdef CONFIG_MMU
+__break_return_singlestep_tlbmiss:
+       LEDS            0x1100,gr2
+
+       sethi.p         %hi(__break_tlb_miss_real_return_info),gr3
+       setlo           %lo(__break_tlb_miss_real_return_info),gr3
+       lddi            @(gr3,#0),gr2
+       movgs           gr2,pcsr
+       movgs           gr3,psr
+
+       bra             __break_return_singlestep
+#endif
+
+
+###############################################################################
+#
+# handle single stepping into an exception prologue from kernel mode
+# - we try and catch it whilst it is still in the main vector table
+# - if we catch it there, we have to jump to the fixup handler
+#   - there is a fixup table that has a pointer for every 16b slot in the trap
+#     table
+#
+###############################################################################
+__break_step:
+       LEDS            0x2003,gr2
+
+       # external interrupts seem to escape from the trap table before single
+       # step catches up with them
+       movsg           bpcsr,gr2
+       sethi.p         %hi(__entry_kernel_external_interrupt),gr3
+       setlo           %lo(__entry_kernel_external_interrupt),gr3
+       subcc           gr2,gr3,gr0,icc0
+       beq             icc0,#2,__break_step_kernel_external_interrupt
+       sethi.p         %hi(__entry_uspace_external_interrupt),gr3
+       setlo           %lo(__entry_uspace_external_interrupt),gr3
+       subcc           gr2,gr3,gr0,icc0
+       beq             icc0,#2,__break_step_uspace_external_interrupt
+
+       LEDS            0x2007,gr2
+
+       # the two main vector tables are adjacent on one 8Kb slab
+       movsg           bpcsr,gr2
+       setlos          #0xffffe000,gr3
+       and             gr2,gr3,gr2
+       sethi.p         %hi(__trap_tables),gr3
+       setlo           %lo(__trap_tables),gr3
+       subcc           gr2,gr3,gr0,icc0
+       bne             icc0,#2,__break_continue
+
+       LEDS            0x200f,gr2
+
+       # skip workaround if so requested by GDB
+       sethi.p         %hi(__break_trace_through_exceptions),gr3
+       setlo           %lo(__break_trace_through_exceptions),gr3
+       ld              @(gr3,gr0),gr3
+       subcc           gr3,gr0,gr0,icc0
+       bne             icc0,#0,__break_continue
+
+       LEDS            0x201f,gr2
+
+       # access the fixup table - there's a 1:1 mapping between the slots in the trap tables and
+       # the slots in the trap fixup tables allowing us to simply divide the offset into the
+       # former by 4 to access the latter
+       sethi.p         %hi(__trap_tables),gr3
+       setlo           %lo(__trap_tables),gr3
+       movsg           bpcsr,gr2
+       sub             gr2,gr3,gr2
+       srli.p          gr2,#2,gr2
+
+       sethi           %hi(__trap_fixup_tables),gr3
+       setlo.p         %lo(__trap_fixup_tables),gr3
+       andi            gr2,#~3,gr2
+       ld              @(gr2,gr3),gr2
+       jmpil           @(gr2,#0)
+
+# step through an internal exception from kernel mode
+       .globl          __break_step_kernel_softprog_interrupt
+__break_step_kernel_softprog_interrupt:
+       sethi.p         %hi(__entry_kernel_softprog_interrupt_reentry),gr3
+       setlo           %lo(__entry_kernel_softprog_interrupt_reentry),gr3
+       bra             __break_return_as_kernel_prologue
+
+# step through an external interrupt from kernel mode
+       .globl          __break_step_kernel_external_interrupt
+__break_step_kernel_external_interrupt:
+       sethi.p         %hi(__entry_kernel_external_interrupt_reentry),gr3
+       setlo           %lo(__entry_kernel_external_interrupt_reentry),gr3
+
+__break_return_as_kernel_prologue:
+       LEDS            0x203f,gr2
+
+       movgs           gr3,bpcsr
+
+       # do the bit we had to skip
+#ifdef CONFIG_MMU
+       movsg           ear0,gr2                /* EAR0 can get clobbered by gdb-stub (ICI/ICEI) */
+       movgs           gr2,scr2
+#endif
+
+       or.p            sp,gr0,gr2              /* set up the stack pointer */
+       subi            sp,#REG__END,sp
+       sti.p           gr2,@(sp,#REG_SP)
+
+       setlos          #REG__STATUS_STEP,gr2
+       sti             gr2,@(sp,#REG__STATUS)          /* record single step status */
+
+       # cancel single-stepping mode
+       movsg           dcr,gr2
+       sethi.p         %hi(~DCR_SE),gr3
+       setlo           %lo(~DCR_SE),gr3
+       and             gr2,gr3,gr2
+       movgs           gr2,dcr
+
+       LEDS            0x207f,gr2
+
+       ldi             @(gr31,#REG_CCR),gr3
+       movgs           gr3,ccr
+       lddi.p          @(gr31,#REG_GR(2)),gr2
+       xor             gr31,gr31,gr31
+       movgs           gr0,brr
+#ifdef CONFIG_MMU
+       movsg           scr3,gr31
+#endif
+       rett            #1
+
+# step through an internal exception from uspace mode
+       .globl          __break_step_uspace_softprog_interrupt
+__break_step_uspace_softprog_interrupt:
+       sethi.p         %hi(__entry_uspace_softprog_interrupt_reentry),gr3
+       setlo           %lo(__entry_uspace_softprog_interrupt_reentry),gr3
+       bra             __break_return_as_uspace_prologue
+
+# step through an external interrupt from kernel mode
+       .globl          __break_step_uspace_external_interrupt
+__break_step_uspace_external_interrupt:
+       sethi.p         %hi(__entry_uspace_external_interrupt_reentry),gr3
+       setlo           %lo(__entry_uspace_external_interrupt_reentry),gr3
+
+__break_return_as_uspace_prologue:
+       LEDS            0x20ff,gr2
+
+       movgs           gr3,bpcsr
+
+       # do the bit we had to skip
+       sethi.p         %hi(__kernel_frame0_ptr),gr28
+       setlo           %lo(__kernel_frame0_ptr),gr28
+       ldi.p           @(gr28,#0),gr28
+
+       setlos          #REG__STATUS_STEP,gr2
+       sti             gr2,@(gr28,#REG__STATUS)        /* record single step status */
+
+       # cancel single-stepping mode
+       movsg           dcr,gr2
+       sethi.p         %hi(~DCR_SE),gr3
+       setlo           %lo(~DCR_SE),gr3
+       and             gr2,gr3,gr2
+       movgs           gr2,dcr
+
+       LEDS            0x20fe,gr2
+
+       ldi             @(gr31,#REG_CCR),gr3
+       movgs           gr3,ccr
+       lddi.p          @(gr31,#REG_GR(2)),gr2
+       xor             gr31,gr31,gr31
+       movgs           gr0,brr
+#ifdef CONFIG_MMU
+       movsg           scr3,gr31
+#endif
+       rett            #1
+
+#ifdef CONFIG_MMU
+# step through an ITLB-miss handler from user mode
+       .globl          __break_user_insn_tlb_miss
+__break_user_insn_tlb_miss:
+       # we'll want to try the trap stub again
+       sethi.p         %hi(__trap_user_insn_tlb_miss),gr2
+       setlo           %lo(__trap_user_insn_tlb_miss),gr2
+       movgs           gr2,bpcsr
+
+__break_tlb_miss_common:
+       LEDS            0x2101,gr2
+
+       # cancel single-stepping mode
+       movsg           dcr,gr2
+       sethi.p         %hi(~DCR_SE),gr3
+       setlo           %lo(~DCR_SE),gr3
+       and             gr2,gr3,gr2
+       movgs           gr2,dcr
+
+       # we'll swap the real return address for one with a BREAK insn so that we can re-enable
+       # single stepping on return
+       movsg           pcsr,gr2
+       sethi.p         %hi(__break_tlb_miss_real_return_info),gr3
+       setlo           %lo(__break_tlb_miss_real_return_info),gr3
+       sti             gr2,@(gr3,#0)
+
+       sethi.p         %hi(__break_tlb_miss_return_break),gr2
+       setlo           %lo(__break_tlb_miss_return_break),gr2
+       movgs           gr2,pcsr
+
+       # we also have to fudge PSR because the return BREAK is in kernel space and we want
+       # to get a BREAK fault not an access violation should the return be to userspace
+       movsg           psr,gr2
+       sti.p           gr2,@(gr3,#4)
+       ori             gr2,#PSR_PS,gr2
+       movgs           gr2,psr
+
+       LEDS            0x2102,gr2
+
+       ldi             @(gr31,#REG_CCR),gr3
+       movgs           gr3,ccr
+       lddi            @(gr31,#REG_GR(2)),gr2
+       movsg           scr3,gr31
+       movgs           gr0,brr
+       rett            #1
+
+# step through a DTLB-miss handler from user mode
+       .globl          __break_user_data_tlb_miss
+__break_user_data_tlb_miss:
+       # we'll want to try the trap stub again
+       sethi.p         %hi(__trap_user_data_tlb_miss),gr2
+       setlo           %lo(__trap_user_data_tlb_miss),gr2
+       movgs           gr2,bpcsr
+       bra             __break_tlb_miss_common
+
+# step through an ITLB-miss handler from kernel mode
+       .globl          __break_kernel_insn_tlb_miss
+__break_kernel_insn_tlb_miss:
+       # we'll want to try the trap stub again
+       sethi.p         %hi(__trap_kernel_insn_tlb_miss),gr2
+       setlo           %lo(__trap_kernel_insn_tlb_miss),gr2
+       movgs           gr2,bpcsr
+       bra             __break_tlb_miss_common
+
+# step through a DTLB-miss handler from kernel mode
+       .globl          __break_kernel_data_tlb_miss
+__break_kernel_data_tlb_miss:
+       # we'll want to try the trap stub again
+       sethi.p         %hi(__trap_kernel_data_tlb_miss),gr2
+       setlo           %lo(__trap_kernel_data_tlb_miss),gr2
+       movgs           gr2,bpcsr
+       bra             __break_tlb_miss_common
+#endif
+
+###############################################################################
+#
+# handle debug events originating with userspace
+#
+###############################################################################
+__break_maybe_userspace:
+       LEDS            0x3003,gr2
+
+       setlos          #BPSR_BS,gr2
+       andcc           gr3,gr2,gr0,icc0
+       bne             icc0,#0,__break_continue        /* skip if PSR.S was 1 */
+
+       movsg           brr,gr2
+       andicc          gr2,#BRR_ST|BRR_SB,gr0,icc0
+       beq             icc0,#0,__break_continue        /* jump if not BREAK or single-step */
+
+       LEDS            0x3007,gr2
+
+       # do the first part of the exception prologue here
+       sethi.p         %hi(__kernel_frame0_ptr),gr28
+       setlo           %lo(__kernel_frame0_ptr),gr28
+       ldi             @(gr28,#0),gr28
+       andi            gr28,#~7,gr28
+
+       # set up the kernel stack pointer
+       sti             sp  ,@(gr28,#REG_SP)
+       ori             gr28,0,sp
+       sti             gr0 ,@(gr28,#REG_GR(28))
+
+       stdi            gr20,@(gr28,#REG_GR(20))
+       stdi            gr22,@(gr28,#REG_GR(22))
+
+       movsg           tbr,gr20
+       movsg           bpcsr,gr21
+       movsg           psr,gr22
+
+       # determine the exception type and cancel single-stepping mode
+       or              gr0,gr0,gr23
+
+       movsg           dcr,gr2
+       sethi.p         %hi(DCR_SE),gr3
+       setlo           %lo(DCR_SE),gr3
+       andcc           gr2,gr3,gr0,icc0
+       beq             icc0,#0,__break_no_user_sstep   /* must have been a BREAK insn */
+
+       not             gr3,gr3
+       and             gr2,gr3,gr2
+       movgs           gr2,dcr
+       ori             gr23,#REG__STATUS_STEP,gr23
+
+__break_no_user_sstep:
+       LEDS            0x300f,gr2
+
+       movsg           brr,gr2
+       andi            gr2,#BRR_ST|BRR_SB,gr2
+       slli            gr2,#1,gr2
+       or              gr23,gr2,gr23
+       sti.p           gr23,@(gr28,#REG__STATUS)       /* record single step status */
+
+       # adjust the value acquired from TBR - this indicates the exception
+       setlos          #~TBR_TT,gr2
+       and.p           gr20,gr2,gr20
+       setlos          #TBR_TT_BREAK,gr2
+       or.p            gr20,gr2,gr20
+
+       # fudge PSR.PS and BPSR.BS to return to kernel mode through the trap
+       # table as trap 126
+       andi            gr22,#~PSR_PS,gr22              /* PSR.PS should be 0 */
+       movgs           gr22,psr
+
+       setlos          #BPSR_BS,gr2                    /* BPSR.BS should be 1 and BPSR.BET 0 */
+       movgs           gr2,bpsr
+
+       # return through remainder of the exception prologue
+       # - need to load gr23 with return handler address
+       sethi.p         %hi(__entry_return_from_user_exception),gr23
+       setlo           %lo(__entry_return_from_user_exception),gr23
+       sethi.p         %hi(__entry_common),gr3
+       setlo           %lo(__entry_common),gr3
+       movgs           gr3,bpcsr
+
+       LEDS            0x301f,gr2
+
+       ldi             @(gr31,#REG_CCR),gr3
+       movgs           gr3,ccr
+       lddi.p          @(gr31,#REG_GR(2)),gr2
+       xor             gr31,gr31,gr31
+       movgs           gr0,brr
+#ifdef CONFIG_MMU
+       movsg           scr3,gr31
+#endif
+       rett            #1
+
+###############################################################################
+#
+# resume normal debug-mode entry
+#
+###############################################################################
+__break_continue:
+       LEDS            0x4003,gr2
+
+       # set up the kernel stack pointer
+       sti             sp,@(gr31,#REG_SP)
+
+       sethi.p         %hi(__break_stack_tos),sp
+       setlo           %lo(__break_stack_tos),sp
+
+       # finish building the exception frame
+       stdi            gr4 ,@(gr31,#REG_GR(4))
+       stdi            gr6 ,@(gr31,#REG_GR(6))
+       stdi            gr8 ,@(gr31,#REG_GR(8))
+       stdi            gr10,@(gr31,#REG_GR(10))
+       stdi            gr12,@(gr31,#REG_GR(12))
+       stdi            gr14,@(gr31,#REG_GR(14))
+       stdi            gr16,@(gr31,#REG_GR(16))
+       stdi            gr18,@(gr31,#REG_GR(18))
+       stdi            gr20,@(gr31,#REG_GR(20))
+       stdi            gr22,@(gr31,#REG_GR(22))
+       stdi            gr24,@(gr31,#REG_GR(24))
+       stdi            gr26,@(gr31,#REG_GR(26))
+       sti             gr0 ,@(gr31,#REG_GR(28))        /* NULL frame pointer */
+       sti             gr29,@(gr31,#REG_GR(29))
+       sti             gr30,@(gr31,#REG_GR(30))
+       sti             gr8 ,@(gr31,#REG_ORIG_GR8)
+
+#ifdef CONFIG_MMU
+       movsg           scr3,gr19
+       sti             gr19,@(gr31,#REG_GR(31))
+#endif
+
+       movsg           bpsr ,gr19
+       movsg           tbr  ,gr20
+       movsg           bpcsr,gr21
+       movsg           psr  ,gr22
+       movsg           isr  ,gr23
+       movsg           cccr ,gr25
+       movsg           lr   ,gr26
+       movsg           lcr  ,gr27
+
+       andi.p          gr22,#~(PSR_S|PSR_ET),gr5       /* rebuild PSR */
+       andi            gr19,#PSR_ET,gr4
+       or.p            gr4,gr5,gr5
+       srli            gr19,#10,gr4
+       andi            gr4,#PSR_S,gr4
+       or.p            gr4,gr5,gr5
+
+       setlos          #-1,gr6
+       sti             gr20,@(gr31,#REG_TBR)
+       sti             gr21,@(gr31,#REG_PC)
+       sti             gr5 ,@(gr31,#REG_PSR)
+       sti             gr23,@(gr31,#REG_ISR)
+       sti             gr25,@(gr31,#REG_CCCR)
+       stdi            gr26,@(gr31,#REG_LR)
+       sti             gr6 ,@(gr31,#REG_SYSCALLNO)
+
+       # store CPU-specific regs
+       movsg           iacc0h,gr4
+       movsg           iacc0l,gr5
+       stdi            gr4,@(gr31,#REG_IACC0)
+
+       movsg           gner0,gr4
+       movsg           gner1,gr5
+       stdi            gr4,@(gr31,#REG_GNER0)
+
+       # build the debug register frame
+       movsg           brr,gr4
+       movgs           gr0,brr
+       movsg           nmar,gr5
+       movsg           dcr,gr6
+
+       stdi            gr4 ,@(gr31,#REG_BRR)
+       sti             gr19,@(gr31,#REG_BPSR)
+       sti.p           gr6 ,@(gr31,#REG_DCR)
+
+       # trap exceptions during break handling and disable h/w breakpoints/watchpoints
+       sethi           %hi(DCR_EBE),gr5
+       setlo.p         %lo(DCR_EBE),gr5
+       sethi           %hi(__entry_breaktrap_table),gr4
+       setlo           %lo(__entry_breaktrap_table),gr4
+       movgs           gr5,dcr
+       movgs           gr4,tbr
+
+       # set up kernel global registers
+       sethi.p         %hi(__kernel_current_task),gr5
+       setlo           %lo(__kernel_current_task),gr5
+       ld              @(gr5,gr0),gr29
+       ldi.p           @(gr29,#4),gr15         ; __current_thread_info = current->thread_info
+
+       sethi           %hi(_gp),gr16
+       setlo.p         %lo(_gp),gr16
+
+       # make sure we (the kernel) get div-zero and misalignment exceptions
+       setlos          #ISR_EDE|ISR_DTT_DIVBYZERO|ISR_EMAM_EXCEPTION,gr5
+       movgs           gr5,isr
+
+       # enter the GDB stub
+       LEDS            0x4007,gr2
+
+       or.p            gr0,gr0,fp
+       call            debug_stub
+
+       LEDS            0x403f,gr2
+
+       # return from break
+       lddi            @(gr31,#REG_IACC0),gr4
+       movgs           gr4,iacc0h
+       movgs           gr5,iacc0l
+
+       lddi            @(gr31,#REG_GNER0),gr4
+       movgs           gr4,gner0
+       movgs           gr5,gner1
+
+       lddi            @(gr31,#REG_LR)  ,gr26
+       lddi            @(gr31,#REG_CCR) ,gr24
+       lddi            @(gr31,#REG_PSR) ,gr22
+       ldi             @(gr31,#REG_PC)  ,gr21
+       ldi             @(gr31,#REG_TBR) ,gr20
+       ldi.p           @(gr31,#REG_DCR) ,gr6
+
+       andi            gr22,#PSR_S,gr19                /* rebuild BPSR */
+       andi.p          gr22,#PSR_ET,gr5
+       slli            gr19,#10,gr19
+       or              gr5,gr19,gr19
+
+       movgs           gr6 ,dcr
+       movgs           gr19,bpsr
+       movgs           gr20,tbr
+       movgs           gr21,bpcsr
+       movgs           gr23,isr
+       movgs           gr24,ccr
+       movgs           gr25,cccr
+       movgs           gr26,lr
+       movgs           gr27,lcr
+
+       LEDS            0x407f,gr2
+
+#ifdef CONFIG_MMU
+       ldi             @(gr31,#REG_GR(31)),gr2
+       movgs           gr2,scr3
+#endif
+
+       ldi             @(gr31,#REG_GR(30)),gr30
+       ldi             @(gr31,#REG_GR(29)),gr29
+       lddi            @(gr31,#REG_GR(26)),gr26
+       lddi            @(gr31,#REG_GR(24)),gr24
+       lddi            @(gr31,#REG_GR(22)),gr22
+       lddi            @(gr31,#REG_GR(20)),gr20
+       lddi            @(gr31,#REG_GR(18)),gr18
+       lddi            @(gr31,#REG_GR(16)),gr16
+       lddi            @(gr31,#REG_GR(14)),gr14
+       lddi            @(gr31,#REG_GR(12)),gr12
+       lddi            @(gr31,#REG_GR(10)),gr10
+       lddi            @(gr31,#REG_GR(8)) ,gr8
+       lddi            @(gr31,#REG_GR(6)) ,gr6
+       lddi            @(gr31,#REG_GR(4)) ,gr4
+       lddi            @(gr31,#REG_GR(2)) ,gr2
+       ldi.p           @(gr31,#REG_SP)    ,sp
+
+       xor             gr31,gr31,gr31
+       movgs           gr0,brr
+#ifdef CONFIG_MMU
+       movsg           scr3,gr31
+#endif
+       rett            #1
+
+###################################################################################################
+#
+# GDB stub "system calls"
+#
+###################################################################################################
+
+#ifdef CONFIG_GDBSTUB
+       # void gdbstub_console_write(struct console *con, const char *p, unsigned n)
+       .globl          gdbstub_console_write
+gdbstub_console_write:
+       break
+       bralr
+#endif
+
+       # GDB stub BUG() trap
+       # GR8 is the proposed signal number
+       .globl          __debug_bug_trap
+__debug_bug_trap:
+       break
+       bralr
+
+       # transfer kernel exeception to GDB for handling
+       .globl          __break_hijack_kernel_event
+__break_hijack_kernel_event:
+       break
+       .globl          __break_hijack_kernel_event_breaks_here
+__break_hijack_kernel_event_breaks_here:
+       nop
+
+#ifdef CONFIG_MMU
+       # handle a return from TLB-miss that requires single-step reactivation
+       .globl          __break_tlb_miss_return_break
+__break_tlb_miss_return_break:
+       break
+__break_tlb_miss_return_breaks_here:
+       nop
+#endif
+
+       # guard the first .text label in the next file from confusion
+       nop