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