123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793 |
- /* 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/linkage.h>
- #include <asm/setup.h>
- #include <asm/segment.h>
- #include <asm/ptrace.h>
- #include <asm/thread_info.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 THREAD_SIZE
- __break_stack:
- .space THREAD_SIZE - FRV_FRAME0_SIZE
- __break_frame_0:
- .space FRV_FRAME0_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
- #
- ###############################################################################
- .section .text..break
- .balign 4
- .globl __entry_break
- __entry_break:
- #ifdef CONFIG_MMU
- movgs gr31,scr3
- #endif
- LEDS 0x1001,gr31
- sethi.p %hi(__break_frame_0),gr31
- setlo %lo(__break_frame_0),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.p gr2,gr3,gr0,icc0
- sethi %hi(__entry_uspace_external_interrupt),gr3
- setlo.p %lo(__entry_uspace_external_interrupt),gr3
- beq icc0,#2,__break_step_kernel_external_interrupt
- subcc.p gr2,gr3,gr0,icc0
- sethi %hi(__entry_kernel_external_interrupt_virtually_disabled),gr3
- setlo.p %lo(__entry_kernel_external_interrupt_virtually_disabled),gr3
- beq icc0,#2,__break_step_uspace_external_interrupt
- subcc.p gr2,gr3,gr0,icc0
- sethi %hi(__entry_kernel_external_interrupt_virtual_reenable),gr3
- setlo.p %lo(__entry_kernel_external_interrupt_virtual_reenable),gr3
- beq icc0,#2,__break_step_kernel_external_interrupt_virtually_disabled
- subcc gr2,gr3,gr0,icc0
- beq icc0,#2,__break_step_kernel_external_interrupt_virtual_reenable
- 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:
- # deal with virtual interrupt disablement
- beq icc2,#0,__break_step_kernel_external_interrupt_virtually_disabled
- 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
- # we single-stepped into an interrupt handler whilst interrupts were merely virtually disabled
- # need to really disable interrupts, set flag, fix up and return
- __break_step_kernel_external_interrupt_virtually_disabled:
- movsg psr,gr2
- andi gr2,#~PSR_PIL,gr2
- ori gr2,#PSR_PIL_14,gr2 /* debugging interrupts only */
- movgs gr2,psr
- ldi @(gr31,#REG_CCR),gr3
- movgs gr3,ccr
- subcc.p gr0,gr0,gr0,icc2 /* leave Z set, clear C */
- # exceptions must've been enabled and we must've been in supervisor mode
- setlos BPSR_BET|BPSR_BS,gr3
- movgs gr3,bpsr
- # return to where the interrupt happened
- movsg pcsr,gr2
- movgs gr2,bpcsr
- lddi.p @(gr31,#REG_GR(2)),gr2
- xor gr31,gr31,gr31
- movgs gr0,brr
- #ifdef CONFIG_MMU
- movsg scr3,gr31
- #endif
- rett #1
- # we stepped through into the virtual interrupt reenablement trap
- #
- # we also want to single step anyway, but after fixing up so that we get an event on the
- # instruction after the broken-into exception returns
- .globl __break_step_kernel_external_interrupt_virtual_reenable
- __break_step_kernel_external_interrupt_virtual_reenable:
- movsg psr,gr2
- andi gr2,#~PSR_PIL,gr2
- movgs gr2,psr
- ldi @(gr31,#REG_CCR),gr3
- movgs gr3,ccr
- subicc gr0,#1,gr0,icc2 /* clear Z, set C */
- # save the adjusted ICC2
- movsg ccr,gr3
- sti gr3,@(gr31,#REG_CCR)
- # exceptions must've been enabled and we must've been in supervisor mode
- setlos BPSR_BET|BPSR_BS,gr3
- movgs gr3,bpsr
- # return to where the trap happened
- movsg pcsr,gr2
- movgs gr2,bpcsr
- # and then process the single step
- bra __break_continue
- # 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_frame_0),sp
- setlo %lo(__break_frame_0),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
- sethi.p %hi(__debug_status),gr7
- setlo %lo(__debug_status),gr7
- stdi gr4 ,@(gr7,#DEBUG_BRR)
- sti gr19,@(gr7,#DEBUG_BPSR)
- sti.p gr6 ,@(gr7,#DEBUG_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
- sethi.p %hi(__debug_status),gr6
- setlo %lo(__debug_status),gr6
- ldi.p @(gr6,#DEBUG_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
|