linux/arch/frv/kernel/break.S
<<
>>
Prefs
   1/* break.S: Break interrupt handling (kept separate from entry.S)
   2 *
   3 * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
   4 * Written by David Howells (dhowells@redhat.com)
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License
   8 * as published by the Free Software Foundation; either version
   9 * 2 of the License, or (at your option) any later version.
  10 */
  11
  12#include <linux/linkage.h>
  13#include <asm/setup.h>
  14#include <asm/segment.h>
  15#include <asm/ptrace.h>
  16#include <asm/thread_info.h>
  17#include <asm/spr-regs.h>
  18
  19#include <asm/errno.h>
  20
  21#
  22# the break handler has its own stack
  23#
  24        .section        .bss..stack
  25        .globl          __break_user_context
  26        .balign         THREAD_SIZE
  27__break_stack:
  28        .space          THREAD_SIZE - FRV_FRAME0_SIZE
  29__break_frame_0:
  30        .space          FRV_FRAME0_SIZE
  31
  32#
  33# miscellaneous variables
  34#
  35        .section        .bss
  36#ifdef CONFIG_MMU
  37        .globl          __break_tlb_miss_real_return_info
  38__break_tlb_miss_real_return_info:
  39        .balign         8
  40        .space          2*4                     /* saved PCSR, PSR for TLB-miss handler fixup */
  41#endif
  42
  43__break_trace_through_exceptions:
  44        .space          4
  45
  46#define CS2_ECS1        0xe1200000
  47#define CS2_USERLED     0x4
  48
  49.macro LEDS val,reg
  50#       sethi.p         %hi(CS2_ECS1+CS2_USERLED),gr30
  51#       setlo           %lo(CS2_ECS1+CS2_USERLED),gr30
  52#       setlos          #~\val,\reg
  53#       st              \reg,@(gr30,gr0)
  54#       setlos          #0x5555,\reg
  55#       sethi.p         %hi(0xffc00100),gr30
  56#       setlo           %lo(0xffc00100),gr30
  57#       sth             \reg,@(gr30,gr0)
  58#       membar
  59.endm
  60
  61###############################################################################
  62#
  63# entry point for Break Exceptions/Interrupts
  64#
  65###############################################################################
  66        .section        .text..break
  67        .balign         4
  68        .globl          __entry_break
  69__entry_break:
  70#ifdef CONFIG_MMU
  71        movgs           gr31,scr3
  72#endif
  73        LEDS            0x1001,gr31
  74
  75        sethi.p         %hi(__break_frame_0),gr31
  76        setlo           %lo(__break_frame_0),gr31
  77
  78        stdi            gr2,@(gr31,#REG_GR(2))
  79        movsg           ccr,gr3
  80        sti             gr3,@(gr31,#REG_CCR)
  81
  82        # catch the return from a TLB-miss handler that had single-step disabled
  83        # traps will be enabled, so we have to do this now
  84#ifdef CONFIG_MMU
  85        movsg           bpcsr,gr3
  86        sethi.p         %hi(__break_tlb_miss_return_breaks_here),gr2
  87        setlo           %lo(__break_tlb_miss_return_breaks_here),gr2
  88        subcc           gr2,gr3,gr0,icc0
  89        beq             icc0,#2,__break_return_singlestep_tlbmiss
  90#endif
  91
  92        # determine whether we have stepped through into an exception
  93        # - we need to take special action to suspend h/w single stepping if we've done
  94        #   that, so that the gdbstub doesn't get bogged down endlessly stepping through
  95        #   external interrupt handling
  96        movsg           bpsr,gr3
  97        andicc          gr3,#BPSR_BET,gr0,icc0
  98        bne             icc0,#2,__break_maybe_userspace /* jump if PSR.ET was 1 */
  99
 100        LEDS            0x1003,gr2
 101
 102        movsg           brr,gr3
 103        andicc          gr3,#BRR_ST,gr0,icc0
 104        andicc.p        gr3,#BRR_SB,gr0,icc1
 105        bne             icc0,#2,__break_step            /* jump if single-step caused break */
 106        beq             icc1,#2,__break_continue        /* jump if BREAK didn't cause break */
 107
 108        LEDS            0x1007,gr2
 109
 110        # handle special breaks
 111        movsg           bpcsr,gr3
 112
 113        sethi.p         %hi(__entry_return_singlestep_breaks_here),gr2
 114        setlo           %lo(__entry_return_singlestep_breaks_here),gr2
 115        subcc           gr2,gr3,gr0,icc0
 116        beq             icc0,#2,__break_return_singlestep
 117
 118        bra             __break_continue
 119
 120
 121###############################################################################
 122#
 123# handle BREAK instruction in kernel-mode exception epilogue
 124#
 125###############################################################################
 126__break_return_singlestep:
 127        LEDS            0x100f,gr2
 128
 129        # special break insn requests single-stepping to be turned back on
 130        #               HERE            RETT
 131        # PSR.ET        0               0
 132        # PSR.PS        old PSR.S       ?
 133        # PSR.S         1               1
 134        # BPSR.ET       0               1 (can't have caused orig excep otherwise)
 135        # BPSR.BS       1               old PSR.S
 136        movsg           dcr,gr2
 137        sethi.p         %hi(DCR_SE),gr3
 138        setlo           %lo(DCR_SE),gr3
 139        or              gr2,gr3,gr2
 140        movgs           gr2,dcr
 141
 142        movsg           psr,gr2
 143        andi            gr2,#PSR_PS,gr2
 144        slli            gr2,#11,gr2                     /* PSR.PS -> BPSR.BS */
 145        ori             gr2,#BPSR_BET,gr2               /* 1 -> BPSR.BET */
 146        movgs           gr2,bpsr
 147
 148        # return to the invoker of the original kernel exception
 149        movsg           pcsr,gr2
 150        movgs           gr2,bpcsr
 151
 152        LEDS            0x101f,gr2
 153
 154        ldi             @(gr31,#REG_CCR),gr3
 155        movgs           gr3,ccr
 156        lddi.p          @(gr31,#REG_GR(2)),gr2
 157        xor             gr31,gr31,gr31
 158        movgs           gr0,brr
 159#ifdef CONFIG_MMU
 160        movsg           scr3,gr31
 161#endif
 162        rett            #1
 163
 164###############################################################################
 165#
 166# handle BREAK instruction in TLB-miss handler return path
 167#
 168###############################################################################
 169#ifdef CONFIG_MMU
 170__break_return_singlestep_tlbmiss:
 171        LEDS            0x1100,gr2
 172
 173        sethi.p         %hi(__break_tlb_miss_real_return_info),gr3
 174        setlo           %lo(__break_tlb_miss_real_return_info),gr3
 175        lddi            @(gr3,#0),gr2
 176        movgs           gr2,pcsr
 177        movgs           gr3,psr
 178
 179        bra             __break_return_singlestep
 180#endif
 181
 182
 183###############################################################################
 184#
 185# handle single stepping into an exception prologue from kernel mode
 186# - we try and catch it whilst it is still in the main vector table
 187# - if we catch it there, we have to jump to the fixup handler
 188#   - there is a fixup table that has a pointer for every 16b slot in the trap
 189#     table
 190#
 191###############################################################################
 192__break_step:
 193        LEDS            0x2003,gr2
 194
 195        # external interrupts seem to escape from the trap table before single
 196        # step catches up with them
 197        movsg           bpcsr,gr2
 198        sethi.p         %hi(__entry_kernel_external_interrupt),gr3
 199        setlo           %lo(__entry_kernel_external_interrupt),gr3
 200        subcc.p         gr2,gr3,gr0,icc0
 201        sethi           %hi(__entry_uspace_external_interrupt),gr3
 202        setlo.p         %lo(__entry_uspace_external_interrupt),gr3
 203        beq             icc0,#2,__break_step_kernel_external_interrupt
 204        subcc.p         gr2,gr3,gr0,icc0
 205        sethi           %hi(__entry_kernel_external_interrupt_virtually_disabled),gr3
 206        setlo.p         %lo(__entry_kernel_external_interrupt_virtually_disabled),gr3
 207        beq             icc0,#2,__break_step_uspace_external_interrupt
 208        subcc.p         gr2,gr3,gr0,icc0
 209        sethi           %hi(__entry_kernel_external_interrupt_virtual_reenable),gr3
 210        setlo.p         %lo(__entry_kernel_external_interrupt_virtual_reenable),gr3
 211        beq             icc0,#2,__break_step_kernel_external_interrupt_virtually_disabled
 212        subcc           gr2,gr3,gr0,icc0
 213        beq             icc0,#2,__break_step_kernel_external_interrupt_virtual_reenable
 214
 215        LEDS            0x2007,gr2
 216
 217        # the two main vector tables are adjacent on one 8Kb slab
 218        movsg           bpcsr,gr2
 219        setlos          #0xffffe000,gr3
 220        and             gr2,gr3,gr2
 221        sethi.p         %hi(__trap_tables),gr3
 222        setlo           %lo(__trap_tables),gr3
 223        subcc           gr2,gr3,gr0,icc0
 224        bne             icc0,#2,__break_continue
 225
 226        LEDS            0x200f,gr2
 227
 228        # skip workaround if so requested by GDB
 229        sethi.p         %hi(__break_trace_through_exceptions),gr3
 230        setlo           %lo(__break_trace_through_exceptions),gr3
 231        ld              @(gr3,gr0),gr3
 232        subcc           gr3,gr0,gr0,icc0
 233        bne             icc0,#0,__break_continue
 234
 235        LEDS            0x201f,gr2
 236
 237        # access the fixup table - there's a 1:1 mapping between the slots in the trap tables and
 238        # the slots in the trap fixup tables allowing us to simply divide the offset into the
 239        # former by 4 to access the latter
 240        sethi.p         %hi(__trap_tables),gr3
 241        setlo           %lo(__trap_tables),gr3
 242        movsg           bpcsr,gr2
 243        sub             gr2,gr3,gr2
 244        srli.p          gr2,#2,gr2
 245
 246        sethi           %hi(__trap_fixup_tables),gr3
 247        setlo.p         %lo(__trap_fixup_tables),gr3
 248        andi            gr2,#~3,gr2
 249        ld              @(gr2,gr3),gr2
 250        jmpil           @(gr2,#0)
 251
 252# step through an internal exception from kernel mode
 253        .globl          __break_step_kernel_softprog_interrupt
 254__break_step_kernel_softprog_interrupt:
 255        sethi.p         %hi(__entry_kernel_softprog_interrupt_reentry),gr3
 256        setlo           %lo(__entry_kernel_softprog_interrupt_reentry),gr3
 257        bra             __break_return_as_kernel_prologue
 258
 259# step through an external interrupt from kernel mode
 260        .globl          __break_step_kernel_external_interrupt
 261__break_step_kernel_external_interrupt:
 262        # deal with virtual interrupt disablement
 263        beq             icc2,#0,__break_step_kernel_external_interrupt_virtually_disabled
 264
 265        sethi.p         %hi(__entry_kernel_external_interrupt_reentry),gr3
 266        setlo           %lo(__entry_kernel_external_interrupt_reentry),gr3
 267
 268__break_return_as_kernel_prologue:
 269        LEDS            0x203f,gr2
 270
 271        movgs           gr3,bpcsr
 272
 273        # do the bit we had to skip
 274#ifdef CONFIG_MMU
 275        movsg           ear0,gr2                /* EAR0 can get clobbered by gdb-stub (ICI/ICEI) */
 276        movgs           gr2,scr2
 277#endif
 278
 279        or.p            sp,gr0,gr2              /* set up the stack pointer */
 280        subi            sp,#REG__END,sp
 281        sti.p           gr2,@(sp,#REG_SP)
 282
 283        setlos          #REG__STATUS_STEP,gr2
 284        sti             gr2,@(sp,#REG__STATUS)          /* record single step status */
 285
 286        # cancel single-stepping mode
 287        movsg           dcr,gr2
 288        sethi.p         %hi(~DCR_SE),gr3
 289        setlo           %lo(~DCR_SE),gr3
 290        and             gr2,gr3,gr2
 291        movgs           gr2,dcr
 292
 293        LEDS            0x207f,gr2
 294
 295        ldi             @(gr31,#REG_CCR),gr3
 296        movgs           gr3,ccr
 297        lddi.p          @(gr31,#REG_GR(2)),gr2
 298        xor             gr31,gr31,gr31
 299        movgs           gr0,brr
 300#ifdef CONFIG_MMU
 301        movsg           scr3,gr31
 302#endif
 303        rett            #1
 304
 305# we single-stepped into an interrupt handler whilst interrupts were merely virtually disabled
 306# need to really disable interrupts, set flag, fix up and return
 307__break_step_kernel_external_interrupt_virtually_disabled:
 308        movsg           psr,gr2
 309        andi            gr2,#~PSR_PIL,gr2
 310        ori             gr2,#PSR_PIL_14,gr2     /* debugging interrupts only */
 311        movgs           gr2,psr
 312
 313        ldi             @(gr31,#REG_CCR),gr3
 314        movgs           gr3,ccr
 315        subcc.p         gr0,gr0,gr0,icc2        /* leave Z set, clear C */
 316
 317        # exceptions must've been enabled and we must've been in supervisor mode
 318        setlos          BPSR_BET|BPSR_BS,gr3
 319        movgs           gr3,bpsr
 320
 321        # return to where the interrupt happened
 322        movsg           pcsr,gr2
 323        movgs           gr2,bpcsr
 324
 325        lddi.p          @(gr31,#REG_GR(2)),gr2
 326
 327        xor             gr31,gr31,gr31
 328        movgs           gr0,brr
 329#ifdef CONFIG_MMU
 330        movsg           scr3,gr31
 331#endif
 332        rett            #1
 333
 334# we stepped through into the virtual interrupt reenablement trap
 335#
 336# we also want to single step anyway, but after fixing up so that we get an event on the
 337# instruction after the broken-into exception returns
 338        .globl          __break_step_kernel_external_interrupt_virtual_reenable
 339__break_step_kernel_external_interrupt_virtual_reenable:
 340        movsg           psr,gr2
 341        andi            gr2,#~PSR_PIL,gr2
 342        movgs           gr2,psr
 343
 344        ldi             @(gr31,#REG_CCR),gr3
 345        movgs           gr3,ccr
 346        subicc          gr0,#1,gr0,icc2         /* clear Z, set C */
 347
 348        # save the adjusted ICC2
 349        movsg           ccr,gr3
 350        sti             gr3,@(gr31,#REG_CCR)
 351
 352        # exceptions must've been enabled and we must've been in supervisor mode
 353        setlos          BPSR_BET|BPSR_BS,gr3
 354        movgs           gr3,bpsr
 355
 356        # return to where the trap happened
 357        movsg           pcsr,gr2
 358        movgs           gr2,bpcsr
 359
 360        # and then process the single step
 361        bra             __break_continue
 362
 363# step through an internal exception from uspace mode
 364        .globl          __break_step_uspace_softprog_interrupt
 365__break_step_uspace_softprog_interrupt:
 366        sethi.p         %hi(__entry_uspace_softprog_interrupt_reentry),gr3
 367        setlo           %lo(__entry_uspace_softprog_interrupt_reentry),gr3
 368        bra             __break_return_as_uspace_prologue
 369
 370# step through an external interrupt from kernel mode
 371        .globl          __break_step_uspace_external_interrupt
 372__break_step_uspace_external_interrupt:
 373        sethi.p         %hi(__entry_uspace_external_interrupt_reentry),gr3
 374        setlo           %lo(__entry_uspace_external_interrupt_reentry),gr3
 375
 376__break_return_as_uspace_prologue:
 377        LEDS            0x20ff,gr2
 378
 379        movgs           gr3,bpcsr
 380
 381        # do the bit we had to skip
 382        sethi.p         %hi(__kernel_frame0_ptr),gr28
 383        setlo           %lo(__kernel_frame0_ptr),gr28
 384        ldi.p           @(gr28,#0),gr28
 385
 386        setlos          #REG__STATUS_STEP,gr2
 387        sti             gr2,@(gr28,#REG__STATUS)        /* record single step status */
 388
 389        # cancel single-stepping mode
 390        movsg           dcr,gr2
 391        sethi.p         %hi(~DCR_SE),gr3
 392        setlo           %lo(~DCR_SE),gr3
 393        and             gr2,gr3,gr2
 394        movgs           gr2,dcr
 395
 396        LEDS            0x20fe,gr2
 397
 398        ldi             @(gr31,#REG_CCR),gr3
 399        movgs           gr3,ccr
 400        lddi.p          @(gr31,#REG_GR(2)),gr2
 401        xor             gr31,gr31,gr31
 402        movgs           gr0,brr
 403#ifdef CONFIG_MMU
 404        movsg           scr3,gr31
 405#endif
 406        rett            #1
 407
 408#ifdef CONFIG_MMU
 409# step through an ITLB-miss handler from user mode
 410        .globl          __break_user_insn_tlb_miss
 411__break_user_insn_tlb_miss:
 412        # we'll want to try the trap stub again
 413        sethi.p         %hi(__trap_user_insn_tlb_miss),gr2
 414        setlo           %lo(__trap_user_insn_tlb_miss),gr2
 415        movgs           gr2,bpcsr
 416
 417__break_tlb_miss_common:
 418        LEDS            0x2101,gr2
 419
 420        # cancel single-stepping mode
 421        movsg           dcr,gr2
 422        sethi.p         %hi(~DCR_SE),gr3
 423        setlo           %lo(~DCR_SE),gr3
 424        and             gr2,gr3,gr2
 425        movgs           gr2,dcr
 426
 427        # we'll swap the real return address for one with a BREAK insn so that we can re-enable
 428        # single stepping on return
 429        movsg           pcsr,gr2
 430        sethi.p         %hi(__break_tlb_miss_real_return_info),gr3
 431        setlo           %lo(__break_tlb_miss_real_return_info),gr3
 432        sti             gr2,@(gr3,#0)
 433
 434        sethi.p         %hi(__break_tlb_miss_return_break),gr2
 435        setlo           %lo(__break_tlb_miss_return_break),gr2
 436        movgs           gr2,pcsr
 437
 438        # we also have to fudge PSR because the return BREAK is in kernel space and we want
 439        # to get a BREAK fault not an access violation should the return be to userspace
 440        movsg           psr,gr2
 441        sti.p           gr2,@(gr3,#4)
 442        ori             gr2,#PSR_PS,gr2
 443        movgs           gr2,psr
 444
 445        LEDS            0x2102,gr2
 446
 447        ldi             @(gr31,#REG_CCR),gr3
 448        movgs           gr3,ccr
 449        lddi            @(gr31,#REG_GR(2)),gr2
 450        movsg           scr3,gr31
 451        movgs           gr0,brr
 452        rett            #1
 453
 454# step through a DTLB-miss handler from user mode
 455        .globl          __break_user_data_tlb_miss
 456__break_user_data_tlb_miss:
 457        # we'll want to try the trap stub again
 458        sethi.p         %hi(__trap_user_data_tlb_miss),gr2
 459        setlo           %lo(__trap_user_data_tlb_miss),gr2
 460        movgs           gr2,bpcsr
 461        bra             __break_tlb_miss_common
 462
 463# step through an ITLB-miss handler from kernel mode
 464        .globl          __break_kernel_insn_tlb_miss
 465__break_kernel_insn_tlb_miss:
 466        # we'll want to try the trap stub again
 467        sethi.p         %hi(__trap_kernel_insn_tlb_miss),gr2
 468        setlo           %lo(__trap_kernel_insn_tlb_miss),gr2
 469        movgs           gr2,bpcsr
 470        bra             __break_tlb_miss_common
 471
 472# step through a DTLB-miss handler from kernel mode
 473        .globl          __break_kernel_data_tlb_miss
 474__break_kernel_data_tlb_miss:
 475        # we'll want to try the trap stub again
 476        sethi.p         %hi(__trap_kernel_data_tlb_miss),gr2
 477        setlo           %lo(__trap_kernel_data_tlb_miss),gr2
 478        movgs           gr2,bpcsr
 479        bra             __break_tlb_miss_common
 480#endif
 481
 482###############################################################################
 483#
 484# handle debug events originating with userspace
 485#
 486###############################################################################
 487__break_maybe_userspace:
 488        LEDS            0x3003,gr2
 489
 490        setlos          #BPSR_BS,gr2
 491        andcc           gr3,gr2,gr0,icc0
 492        bne             icc0,#0,__break_continue        /* skip if PSR.S was 1 */
 493
 494        movsg           brr,gr2
 495        andicc          gr2,#BRR_ST|BRR_SB,gr0,icc0
 496        beq             icc0,#0,__break_continue        /* jump if not BREAK or single-step */
 497
 498        LEDS            0x3007,gr2
 499
 500        # do the first part of the exception prologue here
 501        sethi.p         %hi(__kernel_frame0_ptr),gr28
 502        setlo           %lo(__kernel_frame0_ptr),gr28
 503        ldi             @(gr28,#0),gr28
 504        andi            gr28,#~7,gr28
 505
 506        # set up the kernel stack pointer
 507        sti             sp  ,@(gr28,#REG_SP)
 508        ori             gr28,0,sp
 509        sti             gr0 ,@(gr28,#REG_GR(28))
 510
 511        stdi            gr20,@(gr28,#REG_GR(20))
 512        stdi            gr22,@(gr28,#REG_GR(22))
 513
 514        movsg           tbr,gr20
 515        movsg           bpcsr,gr21
 516        movsg           psr,gr22
 517
 518        # determine the exception type and cancel single-stepping mode
 519        or              gr0,gr0,gr23
 520
 521        movsg           dcr,gr2
 522        sethi.p         %hi(DCR_SE),gr3
 523        setlo           %lo(DCR_SE),gr3
 524        andcc           gr2,gr3,gr0,icc0
 525        beq             icc0,#0,__break_no_user_sstep   /* must have been a BREAK insn */
 526
 527        not             gr3,gr3
 528        and             gr2,gr3,gr2
 529        movgs           gr2,dcr
 530        ori             gr23,#REG__STATUS_STEP,gr23
 531
 532__break_no_user_sstep:
 533        LEDS            0x300f,gr2
 534
 535        movsg           brr,gr2
 536        andi            gr2,#BRR_ST|BRR_SB,gr2
 537        slli            gr2,#1,gr2
 538        or              gr23,gr2,gr23
 539        sti.p           gr23,@(gr28,#REG__STATUS)       /* record single step status */
 540
 541        # adjust the value acquired from TBR - this indicates the exception
 542        setlos          #~TBR_TT,gr2
 543        and.p           gr20,gr2,gr20
 544        setlos          #TBR_TT_BREAK,gr2
 545        or.p            gr20,gr2,gr20
 546
 547        # fudge PSR.PS and BPSR.BS to return to kernel mode through the trap
 548        # table as trap 126
 549        andi            gr22,#~PSR_PS,gr22              /* PSR.PS should be 0 */
 550        movgs           gr22,psr
 551
 552        setlos          #BPSR_BS,gr2                    /* BPSR.BS should be 1 and BPSR.BET 0 */
 553        movgs           gr2,bpsr
 554
 555        # return through remainder of the exception prologue
 556        # - need to load gr23 with return handler address
 557        sethi.p         %hi(__entry_return_from_user_exception),gr23
 558        setlo           %lo(__entry_return_from_user_exception),gr23
 559        sethi.p         %hi(__entry_common),gr3
 560        setlo           %lo(__entry_common),gr3
 561        movgs           gr3,bpcsr
 562
 563        LEDS            0x301f,gr2
 564
 565        ldi             @(gr31,#REG_CCR),gr3
 566        movgs           gr3,ccr
 567        lddi.p          @(gr31,#REG_GR(2)),gr2
 568        xor             gr31,gr31,gr31
 569        movgs           gr0,brr
 570#ifdef CONFIG_MMU
 571        movsg           scr3,gr31
 572#endif
 573        rett            #1
 574
 575###############################################################################
 576#
 577# resume normal debug-mode entry
 578#
 579###############################################################################
 580__break_continue:
 581        LEDS            0x4003,gr2
 582
 583        # set up the kernel stack pointer
 584        sti             sp,@(gr31,#REG_SP)
 585
 586        sethi.p         %hi(__break_frame_0),sp
 587        setlo           %lo(__break_frame_0),sp
 588
 589        # finish building the exception frame
 590        stdi            gr4 ,@(gr31,#REG_GR(4))
 591        stdi            gr6 ,@(gr31,#REG_GR(6))
 592        stdi            gr8 ,@(gr31,#REG_GR(8))
 593        stdi            gr10,@(gr31,#REG_GR(10))
 594        stdi            gr12,@(gr31,#REG_GR(12))
 595        stdi            gr14,@(gr31,#REG_GR(14))
 596        stdi            gr16,@(gr31,#REG_GR(16))
 597        stdi            gr18,@(gr31,#REG_GR(18))
 598        stdi            gr20,@(gr31,#REG_GR(20))
 599        stdi            gr22,@(gr31,#REG_GR(22))
 600        stdi            gr24,@(gr31,#REG_GR(24))
 601        stdi            gr26,@(gr31,#REG_GR(26))
 602        sti             gr0 ,@(gr31,#REG_GR(28))        /* NULL frame pointer */
 603        sti             gr29,@(gr31,#REG_GR(29))
 604        sti             gr30,@(gr31,#REG_GR(30))
 605        sti             gr8 ,@(gr31,#REG_ORIG_GR8)
 606
 607#ifdef CONFIG_MMU
 608        movsg           scr3,gr19
 609        sti             gr19,@(gr31,#REG_GR(31))
 610#endif
 611
 612        movsg           bpsr ,gr19
 613        movsg           tbr  ,gr20
 614        movsg           bpcsr,gr21
 615        movsg           psr  ,gr22
 616        movsg           isr  ,gr23
 617        movsg           cccr ,gr25
 618        movsg           lr   ,gr26
 619        movsg           lcr  ,gr27
 620
 621        andi.p          gr22,#~(PSR_S|PSR_ET),gr5       /* rebuild PSR */
 622        andi            gr19,#PSR_ET,gr4
 623        or.p            gr4,gr5,gr5
 624        srli            gr19,#10,gr4
 625        andi            gr4,#PSR_S,gr4
 626        or.p            gr4,gr5,gr5
 627
 628        setlos          #-1,gr6
 629        sti             gr20,@(gr31,#REG_TBR)
 630        sti             gr21,@(gr31,#REG_PC)
 631        sti             gr5 ,@(gr31,#REG_PSR)
 632        sti             gr23,@(gr31,#REG_ISR)
 633        sti             gr25,@(gr31,#REG_CCCR)
 634        stdi            gr26,@(gr31,#REG_LR)
 635        sti             gr6 ,@(gr31,#REG_SYSCALLNO)
 636
 637        # store CPU-specific regs
 638        movsg           iacc0h,gr4
 639        movsg           iacc0l,gr5
 640        stdi            gr4,@(gr31,#REG_IACC0)
 641
 642        movsg           gner0,gr4
 643        movsg           gner1,gr5
 644        stdi            gr4,@(gr31,#REG_GNER0)
 645
 646        # build the debug register frame
 647        movsg           brr,gr4
 648        movgs           gr0,brr
 649        movsg           nmar,gr5
 650        movsg           dcr,gr6
 651
 652        sethi.p         %hi(__debug_status),gr7
 653        setlo           %lo(__debug_status),gr7
 654
 655        stdi            gr4 ,@(gr7,#DEBUG_BRR)
 656        sti             gr19,@(gr7,#DEBUG_BPSR)
 657        sti.p           gr6 ,@(gr7,#DEBUG_DCR)
 658
 659        # trap exceptions during break handling and disable h/w breakpoints/watchpoints
 660        sethi           %hi(DCR_EBE),gr5
 661        setlo.p         %lo(DCR_EBE),gr5
 662        sethi           %hi(__entry_breaktrap_table),gr4
 663        setlo           %lo(__entry_breaktrap_table),gr4
 664        movgs           gr5,dcr
 665        movgs           gr4,tbr
 666
 667        # set up kernel global registers
 668        sethi.p         %hi(__kernel_current_task),gr5
 669        setlo           %lo(__kernel_current_task),gr5
 670        ld              @(gr5,gr0),gr29
 671        ldi.p           @(gr29,#4),gr15         ; __current_thread_info = current->thread_info
 672
 673        sethi           %hi(_gp),gr16
 674        setlo.p         %lo(_gp),gr16
 675
 676        # make sure we (the kernel) get div-zero and misalignment exceptions
 677        setlos          #ISR_EDE|ISR_DTT_DIVBYZERO|ISR_EMAM_EXCEPTION,gr5
 678        movgs           gr5,isr
 679
 680        # enter the GDB stub
 681        LEDS            0x4007,gr2
 682
 683        or.p            gr0,gr0,fp
 684        call            debug_stub
 685
 686        LEDS            0x403f,gr2
 687
 688        # return from break
 689        lddi            @(gr31,#REG_IACC0),gr4
 690        movgs           gr4,iacc0h
 691        movgs           gr5,iacc0l
 692
 693        lddi            @(gr31,#REG_GNER0),gr4
 694        movgs           gr4,gner0
 695        movgs           gr5,gner1
 696
 697        lddi            @(gr31,#REG_LR)  ,gr26
 698        lddi            @(gr31,#REG_CCR) ,gr24
 699        lddi            @(gr31,#REG_PSR) ,gr22
 700        ldi             @(gr31,#REG_PC)  ,gr21
 701        ldi             @(gr31,#REG_TBR) ,gr20
 702
 703        sethi.p         %hi(__debug_status),gr6
 704        setlo           %lo(__debug_status),gr6
 705        ldi.p           @(gr6,#DEBUG_DCR) ,gr6
 706
 707        andi            gr22,#PSR_S,gr19                /* rebuild BPSR */
 708        andi.p          gr22,#PSR_ET,gr5
 709        slli            gr19,#10,gr19
 710        or              gr5,gr19,gr19
 711
 712        movgs           gr6 ,dcr
 713        movgs           gr19,bpsr
 714        movgs           gr20,tbr
 715        movgs           gr21,bpcsr
 716        movgs           gr23,isr
 717        movgs           gr24,ccr
 718        movgs           gr25,cccr
 719        movgs           gr26,lr
 720        movgs           gr27,lcr
 721
 722        LEDS            0x407f,gr2
 723
 724#ifdef CONFIG_MMU
 725        ldi             @(gr31,#REG_GR(31)),gr2
 726        movgs           gr2,scr3
 727#endif
 728
 729        ldi             @(gr31,#REG_GR(30)),gr30
 730        ldi             @(gr31,#REG_GR(29)),gr29
 731        lddi            @(gr31,#REG_GR(26)),gr26
 732        lddi            @(gr31,#REG_GR(24)),gr24
 733        lddi            @(gr31,#REG_GR(22)),gr22
 734        lddi            @(gr31,#REG_GR(20)),gr20
 735        lddi            @(gr31,#REG_GR(18)),gr18
 736        lddi            @(gr31,#REG_GR(16)),gr16
 737        lddi            @(gr31,#REG_GR(14)),gr14
 738        lddi            @(gr31,#REG_GR(12)),gr12
 739        lddi            @(gr31,#REG_GR(10)),gr10
 740        lddi            @(gr31,#REG_GR(8)) ,gr8
 741        lddi            @(gr31,#REG_GR(6)) ,gr6
 742        lddi            @(gr31,#REG_GR(4)) ,gr4
 743        lddi            @(gr31,#REG_GR(2)) ,gr2
 744        ldi.p           @(gr31,#REG_SP)    ,sp
 745
 746        xor             gr31,gr31,gr31
 747        movgs           gr0,brr
 748#ifdef CONFIG_MMU
 749        movsg           scr3,gr31
 750#endif
 751        rett            #1
 752
 753###################################################################################################
 754#
 755# GDB stub "system calls"
 756#
 757###################################################################################################
 758
 759#ifdef CONFIG_GDBSTUB
 760        # void gdbstub_console_write(struct console *con, const char *p, unsigned n)
 761        .globl          gdbstub_console_write
 762gdbstub_console_write:
 763        break
 764        bralr
 765#endif
 766
 767        # GDB stub BUG() trap
 768        # GR8 is the proposed signal number
 769        .globl          __debug_bug_trap
 770__debug_bug_trap:
 771        break
 772        bralr
 773
 774        # transfer kernel exeception to GDB for handling
 775        .globl          __break_hijack_kernel_event
 776__break_hijack_kernel_event:
 777        break
 778        .globl          __break_hijack_kernel_event_breaks_here
 779__break_hijack_kernel_event_breaks_here:
 780        nop
 781
 782#ifdef CONFIG_MMU
 783        # handle a return from TLB-miss that requires single-step reactivation
 784        .globl          __break_tlb_miss_return_break
 785__break_tlb_miss_return_break:
 786        break
 787__break_tlb_miss_return_breaks_here:
 788        nop
 789#endif
 790
 791        # guard the first .text label in the next file from confusion
 792        nop
 793