Back to home page

LXR

 
 

    


0001 /* break.S: Break interrupt handling (kept separate from entry.S)
0002  *
0003  * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
0004  * Written by David Howells (dhowells@redhat.com)
0005  *
0006  * This program is free software; you can redistribute it and/or
0007  * modify it under the terms of the GNU General Public License
0008  * as published by the Free Software Foundation; either version
0009  * 2 of the License, or (at your option) any later version.
0010  */
0011 
0012 #include <linux/linkage.h>
0013 #include <asm/setup.h>
0014 #include <asm/segment.h>
0015 #include <asm/ptrace.h>
0016 #include <asm/thread_info.h>
0017 #include <asm/spr-regs.h>
0018 
0019 #include <asm/errno.h>
0020 
0021 #
0022 # the break handler has its own stack
0023 #
0024     .section    .bss..stack
0025     .globl      __break_user_context
0026     .balign     THREAD_SIZE
0027 __break_stack:
0028     .space      THREAD_SIZE - FRV_FRAME0_SIZE
0029 __break_frame_0:
0030     .space      FRV_FRAME0_SIZE
0031 
0032 #
0033 # miscellaneous variables
0034 #
0035     .section    .bss
0036 #ifdef CONFIG_MMU
0037     .globl      __break_tlb_miss_real_return_info
0038 __break_tlb_miss_real_return_info:
0039     .balign     8
0040     .space      2*4         /* saved PCSR, PSR for TLB-miss handler fixup */
0041 #endif
0042 
0043 __break_trace_through_exceptions:
0044     .space      4
0045 
0046 #define CS2_ECS1    0xe1200000
0047 #define CS2_USERLED 0x4
0048 
0049 .macro LEDS val,reg
0050 #   sethi.p     %hi(CS2_ECS1+CS2_USERLED),gr30
0051 #   setlo       %lo(CS2_ECS1+CS2_USERLED),gr30
0052 #   setlos      #~\val,\reg
0053 #   st      \reg,@(gr30,gr0)
0054 #   setlos      #0x5555,\reg
0055 #   sethi.p     %hi(0xffc00100),gr30
0056 #   setlo       %lo(0xffc00100),gr30
0057 #   sth     \reg,@(gr30,gr0)
0058 #   membar
0059 .endm
0060 
0061 ###############################################################################
0062 #
0063 # entry point for Break Exceptions/Interrupts
0064 #
0065 ###############################################################################
0066     .section    .text..break
0067     .balign     4
0068     .globl      __entry_break
0069 __entry_break:
0070 #ifdef CONFIG_MMU
0071     movgs       gr31,scr3
0072 #endif
0073     LEDS        0x1001,gr31
0074 
0075     sethi.p     %hi(__break_frame_0),gr31
0076     setlo       %lo(__break_frame_0),gr31
0077 
0078     stdi        gr2,@(gr31,#REG_GR(2))
0079     movsg       ccr,gr3
0080     sti     gr3,@(gr31,#REG_CCR)
0081 
0082     # catch the return from a TLB-miss handler that had single-step disabled
0083     # traps will be enabled, so we have to do this now
0084 #ifdef CONFIG_MMU
0085     movsg       bpcsr,gr3
0086     sethi.p     %hi(__break_tlb_miss_return_breaks_here),gr2
0087     setlo       %lo(__break_tlb_miss_return_breaks_here),gr2
0088     subcc       gr2,gr3,gr0,icc0
0089     beq     icc0,#2,__break_return_singlestep_tlbmiss
0090 #endif
0091 
0092     # determine whether we have stepped through into an exception
0093     # - we need to take special action to suspend h/w single stepping if we've done
0094     #   that, so that the gdbstub doesn't get bogged down endlessly stepping through
0095     #   external interrupt handling
0096     movsg       bpsr,gr3
0097     andicc      gr3,#BPSR_BET,gr0,icc0
0098     bne     icc0,#2,__break_maybe_userspace /* jump if PSR.ET was 1 */
0099 
0100     LEDS        0x1003,gr2
0101 
0102     movsg       brr,gr3
0103     andicc      gr3,#BRR_ST,gr0,icc0
0104     andicc.p    gr3,#BRR_SB,gr0,icc1
0105     bne     icc0,#2,__break_step        /* jump if single-step caused break */
0106     beq     icc1,#2,__break_continue    /* jump if BREAK didn't cause break */
0107 
0108     LEDS        0x1007,gr2
0109 
0110     # handle special breaks
0111     movsg       bpcsr,gr3
0112 
0113     sethi.p     %hi(__entry_return_singlestep_breaks_here),gr2
0114     setlo       %lo(__entry_return_singlestep_breaks_here),gr2
0115     subcc       gr2,gr3,gr0,icc0
0116     beq     icc0,#2,__break_return_singlestep
0117 
0118     bra     __break_continue
0119 
0120 
0121 ###############################################################################
0122 #
0123 # handle BREAK instruction in kernel-mode exception epilogue
0124 #
0125 ###############################################################################
0126 __break_return_singlestep:
0127     LEDS        0x100f,gr2
0128 
0129     # special break insn requests single-stepping to be turned back on
0130     #       HERE        RETT
0131     # PSR.ET    0       0
0132     # PSR.PS    old PSR.S   ?
0133     # PSR.S     1       1
0134     # BPSR.ET   0       1 (can't have caused orig excep otherwise)
0135     # BPSR.BS   1       old PSR.S
0136     movsg       dcr,gr2
0137     sethi.p     %hi(DCR_SE),gr3
0138     setlo       %lo(DCR_SE),gr3
0139     or      gr2,gr3,gr2
0140     movgs       gr2,dcr
0141 
0142     movsg       psr,gr2
0143     andi        gr2,#PSR_PS,gr2
0144     slli        gr2,#11,gr2         /* PSR.PS -> BPSR.BS */
0145     ori     gr2,#BPSR_BET,gr2       /* 1 -> BPSR.BET */
0146     movgs       gr2,bpsr
0147 
0148     # return to the invoker of the original kernel exception
0149     movsg       pcsr,gr2
0150     movgs       gr2,bpcsr
0151 
0152     LEDS        0x101f,gr2
0153 
0154     ldi     @(gr31,#REG_CCR),gr3
0155     movgs       gr3,ccr
0156     lddi.p      @(gr31,#REG_GR(2)),gr2
0157     xor     gr31,gr31,gr31
0158     movgs       gr0,brr
0159 #ifdef CONFIG_MMU
0160     movsg       scr3,gr31
0161 #endif
0162     rett        #1
0163 
0164 ###############################################################################
0165 #
0166 # handle BREAK instruction in TLB-miss handler return path
0167 #
0168 ###############################################################################
0169 #ifdef CONFIG_MMU
0170 __break_return_singlestep_tlbmiss:
0171     LEDS        0x1100,gr2
0172 
0173     sethi.p     %hi(__break_tlb_miss_real_return_info),gr3
0174     setlo       %lo(__break_tlb_miss_real_return_info),gr3
0175     lddi        @(gr3,#0),gr2
0176     movgs       gr2,pcsr
0177     movgs       gr3,psr
0178 
0179     bra     __break_return_singlestep
0180 #endif
0181 
0182 
0183 ###############################################################################
0184 #
0185 # handle single stepping into an exception prologue from kernel mode
0186 # - we try and catch it whilst it is still in the main vector table
0187 # - if we catch it there, we have to jump to the fixup handler
0188 #   - there is a fixup table that has a pointer for every 16b slot in the trap
0189 #     table
0190 #
0191 ###############################################################################
0192 __break_step:
0193     LEDS        0x2003,gr2
0194 
0195     # external interrupts seem to escape from the trap table before single
0196     # step catches up with them
0197     movsg       bpcsr,gr2
0198     sethi.p     %hi(__entry_kernel_external_interrupt),gr3
0199     setlo       %lo(__entry_kernel_external_interrupt),gr3
0200     subcc.p     gr2,gr3,gr0,icc0
0201     sethi       %hi(__entry_uspace_external_interrupt),gr3
0202     setlo.p     %lo(__entry_uspace_external_interrupt),gr3
0203     beq     icc0,#2,__break_step_kernel_external_interrupt
0204     subcc.p     gr2,gr3,gr0,icc0
0205     sethi       %hi(__entry_kernel_external_interrupt_virtually_disabled),gr3
0206     setlo.p     %lo(__entry_kernel_external_interrupt_virtually_disabled),gr3
0207     beq     icc0,#2,__break_step_uspace_external_interrupt
0208     subcc.p     gr2,gr3,gr0,icc0
0209     sethi       %hi(__entry_kernel_external_interrupt_virtual_reenable),gr3
0210     setlo.p     %lo(__entry_kernel_external_interrupt_virtual_reenable),gr3
0211     beq     icc0,#2,__break_step_kernel_external_interrupt_virtually_disabled
0212     subcc       gr2,gr3,gr0,icc0
0213     beq     icc0,#2,__break_step_kernel_external_interrupt_virtual_reenable
0214 
0215     LEDS        0x2007,gr2
0216 
0217     # the two main vector tables are adjacent on one 8Kb slab
0218     movsg       bpcsr,gr2
0219     setlos      #0xffffe000,gr3
0220     and     gr2,gr3,gr2
0221     sethi.p     %hi(__trap_tables),gr3
0222     setlo       %lo(__trap_tables),gr3
0223     subcc       gr2,gr3,gr0,icc0
0224     bne     icc0,#2,__break_continue
0225 
0226     LEDS        0x200f,gr2
0227 
0228     # skip workaround if so requested by GDB
0229     sethi.p     %hi(__break_trace_through_exceptions),gr3
0230     setlo       %lo(__break_trace_through_exceptions),gr3
0231     ld      @(gr3,gr0),gr3
0232     subcc       gr3,gr0,gr0,icc0
0233     bne     icc0,#0,__break_continue
0234 
0235     LEDS        0x201f,gr2
0236 
0237     # access the fixup table - there's a 1:1 mapping between the slots in the trap tables and
0238     # the slots in the trap fixup tables allowing us to simply divide the offset into the
0239     # former by 4 to access the latter
0240     sethi.p     %hi(__trap_tables),gr3
0241     setlo       %lo(__trap_tables),gr3
0242     movsg       bpcsr,gr2
0243     sub     gr2,gr3,gr2
0244     srli.p      gr2,#2,gr2
0245 
0246     sethi       %hi(__trap_fixup_tables),gr3
0247     setlo.p     %lo(__trap_fixup_tables),gr3
0248     andi        gr2,#~3,gr2
0249     ld      @(gr2,gr3),gr2
0250     jmpil       @(gr2,#0)
0251 
0252 # step through an internal exception from kernel mode
0253     .globl      __break_step_kernel_softprog_interrupt
0254 __break_step_kernel_softprog_interrupt:
0255     sethi.p     %hi(__entry_kernel_softprog_interrupt_reentry),gr3
0256     setlo       %lo(__entry_kernel_softprog_interrupt_reentry),gr3
0257     bra     __break_return_as_kernel_prologue
0258 
0259 # step through an external interrupt from kernel mode
0260     .globl      __break_step_kernel_external_interrupt
0261 __break_step_kernel_external_interrupt:
0262     # deal with virtual interrupt disablement
0263     beq     icc2,#0,__break_step_kernel_external_interrupt_virtually_disabled
0264 
0265     sethi.p     %hi(__entry_kernel_external_interrupt_reentry),gr3
0266     setlo       %lo(__entry_kernel_external_interrupt_reentry),gr3
0267 
0268 __break_return_as_kernel_prologue:
0269     LEDS        0x203f,gr2
0270 
0271     movgs       gr3,bpcsr
0272 
0273     # do the bit we had to skip
0274 #ifdef CONFIG_MMU
0275     movsg       ear0,gr2        /* EAR0 can get clobbered by gdb-stub (ICI/ICEI) */
0276     movgs       gr2,scr2
0277 #endif
0278 
0279     or.p        sp,gr0,gr2      /* set up the stack pointer */
0280     subi        sp,#REG__END,sp
0281     sti.p       gr2,@(sp,#REG_SP)
0282 
0283     setlos      #REG__STATUS_STEP,gr2
0284     sti     gr2,@(sp,#REG__STATUS)      /* record single step status */
0285 
0286     # cancel single-stepping mode
0287     movsg       dcr,gr2
0288     sethi.p     %hi(~DCR_SE),gr3
0289     setlo       %lo(~DCR_SE),gr3
0290     and     gr2,gr3,gr2
0291     movgs       gr2,dcr
0292 
0293     LEDS        0x207f,gr2
0294 
0295     ldi     @(gr31,#REG_CCR),gr3
0296     movgs       gr3,ccr
0297     lddi.p      @(gr31,#REG_GR(2)),gr2
0298     xor     gr31,gr31,gr31
0299     movgs       gr0,brr
0300 #ifdef CONFIG_MMU
0301     movsg       scr3,gr31
0302 #endif
0303     rett        #1
0304 
0305 # we single-stepped into an interrupt handler whilst interrupts were merely virtually disabled
0306 # need to really disable interrupts, set flag, fix up and return
0307 __break_step_kernel_external_interrupt_virtually_disabled:
0308     movsg       psr,gr2
0309     andi        gr2,#~PSR_PIL,gr2
0310     ori     gr2,#PSR_PIL_14,gr2 /* debugging interrupts only */
0311     movgs       gr2,psr
0312 
0313     ldi     @(gr31,#REG_CCR),gr3
0314     movgs       gr3,ccr
0315     subcc.p     gr0,gr0,gr0,icc2    /* leave Z set, clear C */
0316 
0317     # exceptions must've been enabled and we must've been in supervisor mode
0318     setlos      BPSR_BET|BPSR_BS,gr3
0319     movgs       gr3,bpsr
0320 
0321     # return to where the interrupt happened
0322     movsg       pcsr,gr2
0323     movgs       gr2,bpcsr
0324 
0325     lddi.p      @(gr31,#REG_GR(2)),gr2
0326 
0327     xor     gr31,gr31,gr31
0328     movgs       gr0,brr
0329 #ifdef CONFIG_MMU
0330     movsg       scr3,gr31
0331 #endif
0332     rett        #1
0333 
0334 # we stepped through into the virtual interrupt reenablement trap
0335 #
0336 # we also want to single step anyway, but after fixing up so that we get an event on the
0337 # instruction after the broken-into exception returns
0338     .globl      __break_step_kernel_external_interrupt_virtual_reenable
0339 __break_step_kernel_external_interrupt_virtual_reenable:
0340     movsg       psr,gr2
0341     andi        gr2,#~PSR_PIL,gr2
0342     movgs       gr2,psr
0343 
0344     ldi     @(gr31,#REG_CCR),gr3
0345     movgs       gr3,ccr
0346     subicc      gr0,#1,gr0,icc2     /* clear Z, set C */
0347 
0348     # save the adjusted ICC2
0349     movsg       ccr,gr3
0350     sti     gr3,@(gr31,#REG_CCR)
0351 
0352     # exceptions must've been enabled and we must've been in supervisor mode
0353     setlos      BPSR_BET|BPSR_BS,gr3
0354     movgs       gr3,bpsr
0355 
0356     # return to where the trap happened
0357     movsg       pcsr,gr2
0358     movgs       gr2,bpcsr
0359 
0360     # and then process the single step
0361     bra     __break_continue
0362 
0363 # step through an internal exception from uspace mode
0364     .globl      __break_step_uspace_softprog_interrupt
0365 __break_step_uspace_softprog_interrupt:
0366     sethi.p     %hi(__entry_uspace_softprog_interrupt_reentry),gr3
0367     setlo       %lo(__entry_uspace_softprog_interrupt_reentry),gr3
0368     bra     __break_return_as_uspace_prologue
0369 
0370 # step through an external interrupt from kernel mode
0371     .globl      __break_step_uspace_external_interrupt
0372 __break_step_uspace_external_interrupt:
0373     sethi.p     %hi(__entry_uspace_external_interrupt_reentry),gr3
0374     setlo       %lo(__entry_uspace_external_interrupt_reentry),gr3
0375 
0376 __break_return_as_uspace_prologue:
0377     LEDS        0x20ff,gr2
0378 
0379     movgs       gr3,bpcsr
0380 
0381     # do the bit we had to skip
0382     sethi.p     %hi(__kernel_frame0_ptr),gr28
0383     setlo       %lo(__kernel_frame0_ptr),gr28
0384     ldi.p       @(gr28,#0),gr28
0385 
0386     setlos      #REG__STATUS_STEP,gr2
0387     sti     gr2,@(gr28,#REG__STATUS)    /* record single step status */
0388 
0389     # cancel single-stepping mode
0390     movsg       dcr,gr2
0391     sethi.p     %hi(~DCR_SE),gr3
0392     setlo       %lo(~DCR_SE),gr3
0393     and     gr2,gr3,gr2
0394     movgs       gr2,dcr
0395 
0396     LEDS        0x20fe,gr2
0397 
0398     ldi     @(gr31,#REG_CCR),gr3
0399     movgs       gr3,ccr
0400     lddi.p      @(gr31,#REG_GR(2)),gr2
0401     xor     gr31,gr31,gr31
0402     movgs       gr0,brr
0403 #ifdef CONFIG_MMU
0404     movsg       scr3,gr31
0405 #endif
0406     rett        #1
0407 
0408 #ifdef CONFIG_MMU
0409 # step through an ITLB-miss handler from user mode
0410     .globl      __break_user_insn_tlb_miss
0411 __break_user_insn_tlb_miss:
0412     # we'll want to try the trap stub again
0413     sethi.p     %hi(__trap_user_insn_tlb_miss),gr2
0414     setlo       %lo(__trap_user_insn_tlb_miss),gr2
0415     movgs       gr2,bpcsr
0416 
0417 __break_tlb_miss_common:
0418     LEDS        0x2101,gr2
0419 
0420     # cancel single-stepping mode
0421     movsg       dcr,gr2
0422     sethi.p     %hi(~DCR_SE),gr3
0423     setlo       %lo(~DCR_SE),gr3
0424     and     gr2,gr3,gr2
0425     movgs       gr2,dcr
0426 
0427     # we'll swap the real return address for one with a BREAK insn so that we can re-enable
0428     # single stepping on return
0429     movsg       pcsr,gr2
0430     sethi.p     %hi(__break_tlb_miss_real_return_info),gr3
0431     setlo       %lo(__break_tlb_miss_real_return_info),gr3
0432     sti     gr2,@(gr3,#0)
0433 
0434     sethi.p     %hi(__break_tlb_miss_return_break),gr2
0435     setlo       %lo(__break_tlb_miss_return_break),gr2
0436     movgs       gr2,pcsr
0437 
0438     # we also have to fudge PSR because the return BREAK is in kernel space and we want
0439     # to get a BREAK fault not an access violation should the return be to userspace
0440     movsg       psr,gr2
0441     sti.p       gr2,@(gr3,#4)
0442     ori     gr2,#PSR_PS,gr2
0443     movgs       gr2,psr
0444 
0445     LEDS        0x2102,gr2
0446 
0447     ldi     @(gr31,#REG_CCR),gr3
0448     movgs       gr3,ccr
0449     lddi        @(gr31,#REG_GR(2)),gr2
0450     movsg       scr3,gr31
0451     movgs       gr0,brr
0452     rett        #1
0453 
0454 # step through a DTLB-miss handler from user mode
0455     .globl      __break_user_data_tlb_miss
0456 __break_user_data_tlb_miss:
0457     # we'll want to try the trap stub again
0458     sethi.p     %hi(__trap_user_data_tlb_miss),gr2
0459     setlo       %lo(__trap_user_data_tlb_miss),gr2
0460     movgs       gr2,bpcsr
0461     bra     __break_tlb_miss_common
0462 
0463 # step through an ITLB-miss handler from kernel mode
0464     .globl      __break_kernel_insn_tlb_miss
0465 __break_kernel_insn_tlb_miss:
0466     # we'll want to try the trap stub again
0467     sethi.p     %hi(__trap_kernel_insn_tlb_miss),gr2
0468     setlo       %lo(__trap_kernel_insn_tlb_miss),gr2
0469     movgs       gr2,bpcsr
0470     bra     __break_tlb_miss_common
0471 
0472 # step through a DTLB-miss handler from kernel mode
0473     .globl      __break_kernel_data_tlb_miss
0474 __break_kernel_data_tlb_miss:
0475     # we'll want to try the trap stub again
0476     sethi.p     %hi(__trap_kernel_data_tlb_miss),gr2
0477     setlo       %lo(__trap_kernel_data_tlb_miss),gr2
0478     movgs       gr2,bpcsr
0479     bra     __break_tlb_miss_common
0480 #endif
0481 
0482 ###############################################################################
0483 #
0484 # handle debug events originating with userspace
0485 #
0486 ###############################################################################
0487 __break_maybe_userspace:
0488     LEDS        0x3003,gr2
0489 
0490     setlos      #BPSR_BS,gr2
0491     andcc       gr3,gr2,gr0,icc0
0492     bne     icc0,#0,__break_continue    /* skip if PSR.S was 1 */
0493 
0494     movsg       brr,gr2
0495     andicc      gr2,#BRR_ST|BRR_SB,gr0,icc0
0496     beq     icc0,#0,__break_continue    /* jump if not BREAK or single-step */
0497 
0498     LEDS        0x3007,gr2
0499 
0500     # do the first part of the exception prologue here
0501     sethi.p     %hi(__kernel_frame0_ptr),gr28
0502     setlo       %lo(__kernel_frame0_ptr),gr28
0503     ldi     @(gr28,#0),gr28
0504     andi        gr28,#~7,gr28
0505 
0506     # set up the kernel stack pointer
0507     sti     sp  ,@(gr28,#REG_SP)
0508     ori     gr28,0,sp
0509     sti     gr0 ,@(gr28,#REG_GR(28))
0510 
0511     stdi        gr20,@(gr28,#REG_GR(20))
0512     stdi        gr22,@(gr28,#REG_GR(22))
0513 
0514     movsg       tbr,gr20
0515     movsg       bpcsr,gr21
0516     movsg       psr,gr22
0517 
0518     # determine the exception type and cancel single-stepping mode
0519     or      gr0,gr0,gr23
0520 
0521     movsg       dcr,gr2
0522     sethi.p     %hi(DCR_SE),gr3
0523     setlo       %lo(DCR_SE),gr3
0524     andcc       gr2,gr3,gr0,icc0
0525     beq     icc0,#0,__break_no_user_sstep   /* must have been a BREAK insn */
0526 
0527     not     gr3,gr3
0528     and     gr2,gr3,gr2
0529     movgs       gr2,dcr
0530     ori     gr23,#REG__STATUS_STEP,gr23
0531 
0532 __break_no_user_sstep:
0533     LEDS        0x300f,gr2
0534 
0535     movsg       brr,gr2
0536     andi        gr2,#BRR_ST|BRR_SB,gr2
0537     slli        gr2,#1,gr2
0538     or      gr23,gr2,gr23
0539     sti.p       gr23,@(gr28,#REG__STATUS)   /* record single step status */
0540 
0541     # adjust the value acquired from TBR - this indicates the exception
0542     setlos      #~TBR_TT,gr2
0543     and.p       gr20,gr2,gr20
0544     setlos      #TBR_TT_BREAK,gr2
0545     or.p        gr20,gr2,gr20
0546 
0547     # fudge PSR.PS and BPSR.BS to return to kernel mode through the trap
0548     # table as trap 126
0549     andi        gr22,#~PSR_PS,gr22      /* PSR.PS should be 0 */
0550     movgs       gr22,psr
0551 
0552     setlos      #BPSR_BS,gr2            /* BPSR.BS should be 1 and BPSR.BET 0 */
0553     movgs       gr2,bpsr
0554 
0555     # return through remainder of the exception prologue
0556     # - need to load gr23 with return handler address
0557     sethi.p     %hi(__entry_return_from_user_exception),gr23
0558     setlo       %lo(__entry_return_from_user_exception),gr23
0559     sethi.p     %hi(__entry_common),gr3
0560     setlo       %lo(__entry_common),gr3
0561     movgs       gr3,bpcsr
0562 
0563     LEDS        0x301f,gr2
0564 
0565     ldi     @(gr31,#REG_CCR),gr3
0566     movgs       gr3,ccr
0567     lddi.p      @(gr31,#REG_GR(2)),gr2
0568     xor     gr31,gr31,gr31
0569     movgs       gr0,brr
0570 #ifdef CONFIG_MMU
0571     movsg       scr3,gr31
0572 #endif
0573     rett        #1
0574 
0575 ###############################################################################
0576 #
0577 # resume normal debug-mode entry
0578 #
0579 ###############################################################################
0580 __break_continue:
0581     LEDS        0x4003,gr2
0582 
0583     # set up the kernel stack pointer
0584     sti     sp,@(gr31,#REG_SP)
0585 
0586     sethi.p     %hi(__break_frame_0),sp
0587     setlo       %lo(__break_frame_0),sp
0588 
0589     # finish building the exception frame
0590     stdi        gr4 ,@(gr31,#REG_GR(4))
0591     stdi        gr6 ,@(gr31,#REG_GR(6))
0592     stdi        gr8 ,@(gr31,#REG_GR(8))
0593     stdi        gr10,@(gr31,#REG_GR(10))
0594     stdi        gr12,@(gr31,#REG_GR(12))
0595     stdi        gr14,@(gr31,#REG_GR(14))
0596     stdi        gr16,@(gr31,#REG_GR(16))
0597     stdi        gr18,@(gr31,#REG_GR(18))
0598     stdi        gr20,@(gr31,#REG_GR(20))
0599     stdi        gr22,@(gr31,#REG_GR(22))
0600     stdi        gr24,@(gr31,#REG_GR(24))
0601     stdi        gr26,@(gr31,#REG_GR(26))
0602     sti     gr0 ,@(gr31,#REG_GR(28))    /* NULL frame pointer */
0603     sti     gr29,@(gr31,#REG_GR(29))
0604     sti     gr30,@(gr31,#REG_GR(30))
0605     sti     gr8 ,@(gr31,#REG_ORIG_GR8)
0606 
0607 #ifdef CONFIG_MMU
0608     movsg       scr3,gr19
0609     sti     gr19,@(gr31,#REG_GR(31))
0610 #endif
0611 
0612     movsg       bpsr ,gr19
0613     movsg       tbr  ,gr20
0614     movsg       bpcsr,gr21
0615     movsg       psr  ,gr22
0616     movsg       isr  ,gr23
0617     movsg       cccr ,gr25
0618     movsg       lr   ,gr26
0619     movsg       lcr  ,gr27
0620 
0621     andi.p      gr22,#~(PSR_S|PSR_ET),gr5   /* rebuild PSR */
0622     andi        gr19,#PSR_ET,gr4
0623     or.p        gr4,gr5,gr5
0624     srli        gr19,#10,gr4
0625     andi        gr4,#PSR_S,gr4
0626     or.p        gr4,gr5,gr5
0627 
0628     setlos      #-1,gr6
0629     sti     gr20,@(gr31,#REG_TBR)
0630     sti     gr21,@(gr31,#REG_PC)
0631     sti     gr5 ,@(gr31,#REG_PSR)
0632     sti     gr23,@(gr31,#REG_ISR)
0633     sti     gr25,@(gr31,#REG_CCCR)
0634     stdi        gr26,@(gr31,#REG_LR)
0635     sti     gr6 ,@(gr31,#REG_SYSCALLNO)
0636 
0637     # store CPU-specific regs
0638     movsg       iacc0h,gr4
0639     movsg       iacc0l,gr5
0640     stdi        gr4,@(gr31,#REG_IACC0)
0641 
0642     movsg       gner0,gr4
0643     movsg       gner1,gr5
0644     stdi        gr4,@(gr31,#REG_GNER0)
0645 
0646     # build the debug register frame
0647     movsg       brr,gr4
0648     movgs       gr0,brr
0649     movsg       nmar,gr5
0650     movsg       dcr,gr6
0651 
0652     sethi.p     %hi(__debug_status),gr7
0653     setlo       %lo(__debug_status),gr7
0654 
0655     stdi        gr4 ,@(gr7,#DEBUG_BRR)
0656     sti     gr19,@(gr7,#DEBUG_BPSR)
0657     sti.p       gr6 ,@(gr7,#DEBUG_DCR)
0658 
0659     # trap exceptions during break handling and disable h/w breakpoints/watchpoints
0660     sethi       %hi(DCR_EBE),gr5
0661     setlo.p     %lo(DCR_EBE),gr5
0662     sethi       %hi(__entry_breaktrap_table),gr4
0663     setlo       %lo(__entry_breaktrap_table),gr4
0664     movgs       gr5,dcr
0665     movgs       gr4,tbr
0666 
0667     # set up kernel global registers
0668     sethi.p     %hi(__kernel_current_task),gr5
0669     setlo       %lo(__kernel_current_task),gr5
0670     ld      @(gr5,gr0),gr29
0671     ldi.p       @(gr29,#4),gr15     ; __current_thread_info = current->thread_info
0672 
0673     sethi       %hi(_gp),gr16
0674     setlo.p     %lo(_gp),gr16
0675 
0676     # make sure we (the kernel) get div-zero and misalignment exceptions
0677     setlos      #ISR_EDE|ISR_DTT_DIVBYZERO|ISR_EMAM_EXCEPTION,gr5
0678     movgs       gr5,isr
0679 
0680     # enter the GDB stub
0681     LEDS        0x4007,gr2
0682 
0683     or.p        gr0,gr0,fp
0684     call        debug_stub
0685 
0686     LEDS        0x403f,gr2
0687 
0688     # return from break
0689     lddi        @(gr31,#REG_IACC0),gr4
0690     movgs       gr4,iacc0h
0691     movgs       gr5,iacc0l
0692 
0693     lddi        @(gr31,#REG_GNER0),gr4
0694     movgs       gr4,gner0
0695     movgs       gr5,gner1
0696 
0697     lddi        @(gr31,#REG_LR)  ,gr26
0698     lddi        @(gr31,#REG_CCR) ,gr24
0699     lddi        @(gr31,#REG_PSR) ,gr22
0700     ldi     @(gr31,#REG_PC)  ,gr21
0701     ldi     @(gr31,#REG_TBR) ,gr20
0702 
0703     sethi.p     %hi(__debug_status),gr6
0704     setlo       %lo(__debug_status),gr6
0705     ldi.p       @(gr6,#DEBUG_DCR) ,gr6
0706 
0707     andi        gr22,#PSR_S,gr19        /* rebuild BPSR */
0708     andi.p      gr22,#PSR_ET,gr5
0709     slli        gr19,#10,gr19
0710     or      gr5,gr19,gr19
0711 
0712     movgs       gr6 ,dcr
0713     movgs       gr19,bpsr
0714     movgs       gr20,tbr
0715     movgs       gr21,bpcsr
0716     movgs       gr23,isr
0717     movgs       gr24,ccr
0718     movgs       gr25,cccr
0719     movgs       gr26,lr
0720     movgs       gr27,lcr
0721 
0722     LEDS        0x407f,gr2
0723 
0724 #ifdef CONFIG_MMU
0725     ldi     @(gr31,#REG_GR(31)),gr2
0726     movgs       gr2,scr3
0727 #endif
0728 
0729     ldi     @(gr31,#REG_GR(30)),gr30
0730     ldi     @(gr31,#REG_GR(29)),gr29
0731     lddi        @(gr31,#REG_GR(26)),gr26
0732     lddi        @(gr31,#REG_GR(24)),gr24
0733     lddi        @(gr31,#REG_GR(22)),gr22
0734     lddi        @(gr31,#REG_GR(20)),gr20
0735     lddi        @(gr31,#REG_GR(18)),gr18
0736     lddi        @(gr31,#REG_GR(16)),gr16
0737     lddi        @(gr31,#REG_GR(14)),gr14
0738     lddi        @(gr31,#REG_GR(12)),gr12
0739     lddi        @(gr31,#REG_GR(10)),gr10
0740     lddi        @(gr31,#REG_GR(8)) ,gr8
0741     lddi        @(gr31,#REG_GR(6)) ,gr6
0742     lddi        @(gr31,#REG_GR(4)) ,gr4
0743     lddi        @(gr31,#REG_GR(2)) ,gr2
0744     ldi.p       @(gr31,#REG_SP)    ,sp
0745 
0746     xor     gr31,gr31,gr31
0747     movgs       gr0,brr
0748 #ifdef CONFIG_MMU
0749     movsg       scr3,gr31
0750 #endif
0751     rett        #1
0752 
0753 ###################################################################################################
0754 #
0755 # GDB stub "system calls"
0756 #
0757 ###################################################################################################
0758 
0759 #ifdef CONFIG_GDBSTUB
0760     # void gdbstub_console_write(struct console *con, const char *p, unsigned n)
0761     .globl      gdbstub_console_write
0762 gdbstub_console_write:
0763     break
0764     bralr
0765 #endif
0766 
0767     # GDB stub BUG() trap
0768     # GR8 is the proposed signal number
0769     .globl      __debug_bug_trap
0770 __debug_bug_trap:
0771     break
0772     bralr
0773 
0774     # transfer kernel exeception to GDB for handling
0775     .globl      __break_hijack_kernel_event
0776 __break_hijack_kernel_event:
0777     break
0778     .globl      __break_hijack_kernel_event_breaks_here
0779 __break_hijack_kernel_event_breaks_here:
0780     nop
0781 
0782 #ifdef CONFIG_MMU
0783     # handle a return from TLB-miss that requires single-step reactivation
0784     .globl      __break_tlb_miss_return_break
0785 __break_tlb_miss_return_break:
0786     break
0787 __break_tlb_miss_return_breaks_here:
0788     nop
0789 #endif
0790 
0791     # guard the first .text label in the next file from confusion
0792     nop