summaryrefslogtreecommitdiff
path: root/arch/frv/kernel/break.S
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 15:20:36 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 15:20:36 -0700
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/frv/kernel/break.S
Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'arch/frv/kernel/break.S')
-rw-r--r--arch/frv/kernel/break.S720
1 files changed, 720 insertions, 0 deletions
diff --git a/arch/frv/kernel/break.S b/arch/frv/kernel/break.S
new file mode 100644
index 000000000000..33233dc23e29
--- /dev/null
+++ b/arch/frv/kernel/break.S
@@ -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