Merge branch 'for-linus' of git://neil.brown.name/md
[linux-2.6] / 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/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
762 gdbstub_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