avr32: Store virtual addresses in the PGD
[linux-2.6] / arch / avr32 / kernel / entry-avr32b.S
1 /*
2  * Copyright (C) 2004-2006 Atmel Corporation
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  */
8
9 /*
10  * This file contains the low-level entry-points into the kernel, that is,
11  * exception handlers, debug trap handlers, interrupt handlers and the
12  * system call handler.
13  */
14 #include <linux/errno.h>
15
16 #include <asm/asm.h>
17 #include <asm/hardirq.h>
18 #include <asm/irq.h>
19 #include <asm/ocd.h>
20 #include <asm/page.h>
21 #include <asm/pgtable.h>
22 #include <asm/ptrace.h>
23 #include <asm/sysreg.h>
24 #include <asm/thread_info.h>
25 #include <asm/unistd.h>
26
27 #ifdef CONFIG_PREEMPT
28 # define preempt_stop           mask_interrupts
29 #else
30 # define preempt_stop
31 # define fault_resume_kernel    fault_restore_all
32 #endif
33
34 #define __MASK(x)       ((1 << (x)) - 1)
35 #define IRQ_MASK        ((__MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT) | \
36                          (__MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT))
37
38         .section .ex.text,"ax",@progbits
39         .align  2
40 exception_vectors:
41         bral    handle_critical
42         .align  2
43         bral    handle_critical
44         .align  2
45         bral    do_bus_error_write
46         .align  2
47         bral    do_bus_error_read
48         .align  2
49         bral    do_nmi_ll
50         .align  2
51         bral    handle_address_fault
52         .align  2
53         bral    handle_protection_fault
54         .align  2
55         bral    handle_debug
56         .align  2
57         bral    do_illegal_opcode_ll
58         .align  2
59         bral    do_illegal_opcode_ll
60         .align  2
61         bral    do_illegal_opcode_ll
62         .align  2
63         bral    do_fpe_ll
64         .align  2
65         bral    do_illegal_opcode_ll
66         .align  2
67         bral    handle_address_fault
68         .align  2
69         bral    handle_address_fault
70         .align  2
71         bral    handle_protection_fault
72         .align  2
73         bral    handle_protection_fault
74         .align  2
75         bral    do_dtlb_modified
76
77 #define tlbmiss_save    pushm   r0-r3
78 #define tlbmiss_restore popm    r0-r3
79
80         .org    0x50
81         .global itlb_miss
82 itlb_miss:
83         tlbmiss_save
84         rjmp    tlb_miss_common
85
86         .org    0x60
87 dtlb_miss_read:
88         tlbmiss_save
89         rjmp    tlb_miss_common
90
91         .org    0x70
92 dtlb_miss_write:
93         tlbmiss_save
94
95         .global tlb_miss_common
96         .align  2
97 tlb_miss_common:
98         mfsr    r0, SYSREG_TLBEAR
99         mfsr    r1, SYSREG_PTBR
100
101         /* Is it the vmalloc space? */
102         bld     r0, 31
103         brcs    handle_vmalloc_miss
104
105         /*
106          * First level lookup: The PGD contains virtual pointers to
107          * the second-level page tables, but they may be NULL if not
108          * present.
109          */
110 pgtbl_lookup:
111         lsr     r2, r0, PGDIR_SHIFT
112         ld.w    r3, r1[r2 << 2]
113         bfextu  r1, r0, PAGE_SHIFT, PGDIR_SHIFT - PAGE_SHIFT
114         cp.w    r3, 0
115         breq    page_table_not_present
116
117         /* Second level lookup */
118         ld.w    r2, r3[r1 << 2]
119         mfsr    r0, SYSREG_TLBARLO
120         bld     r2, _PAGE_BIT_PRESENT
121         brcc    page_not_present
122
123         /* Mark the page as accessed */
124         sbr     r2, _PAGE_BIT_ACCESSED
125         st.w    r3[r1 << 2], r2
126
127         /* Drop software flags */
128         andl    r2, _PAGE_FLAGS_HARDWARE_MASK & 0xffff
129         mtsr    SYSREG_TLBELO, r2
130
131         /* Figure out which entry we want to replace */
132         mfsr    r1, SYSREG_MMUCR
133         clz     r2, r0
134         brcc    1f
135         mov     r3, -1                  /* All entries have been accessed, */
136         mov     r2, 0                   /* so start at 0 */
137         mtsr    SYSREG_TLBARLO, r3      /* and reset TLBAR */
138
139 1:      bfins   r1, r2, SYSREG_DRP_OFFSET, SYSREG_DRP_SIZE
140         mtsr    SYSREG_MMUCR, r1
141         tlbw
142
143         tlbmiss_restore
144         rete
145
146 handle_vmalloc_miss:
147         /* Simply do the lookup in init's page table */
148         mov     r1, lo(swapper_pg_dir)
149         orh     r1, hi(swapper_pg_dir)
150         rjmp    pgtbl_lookup
151
152         /* The slow path of the TLB miss handler */
153         .align  2
154 page_table_not_present:
155 page_not_present:
156         tlbmiss_restore
157         sub     sp, 4
158         stmts   --sp, r0-lr
159         rcall   save_full_context_ex
160         mfsr    r12, SYSREG_ECR
161         mov     r11, sp
162         rcall   do_page_fault
163         rjmp    ret_from_exception
164
165
166         /* ---                    System Call                    --- */
167
168         .org    0x100
169 system_call:
170 #ifdef CONFIG_PREEMPT
171         mask_interrupts
172 #endif
173         pushm   r12             /* r12_orig */
174         stmts   --sp, r0-lr
175
176         mfsr    r0, SYSREG_RAR_SUP
177         mfsr    r1, SYSREG_RSR_SUP
178 #ifdef CONFIG_PREEMPT
179         unmask_interrupts
180 #endif
181         zero_fp
182         stm     --sp, r0-r1
183
184         /* check for syscall tracing */
185         get_thread_info r0
186         ld.w    r1, r0[TI_flags]
187         bld     r1, TIF_SYSCALL_TRACE
188         brcs    syscall_trace_enter
189
190 syscall_trace_cont:
191         cp.w    r8, NR_syscalls
192         brhs    syscall_badsys
193
194         lddpc   lr, syscall_table_addr
195         ld.w    lr, lr[r8 << 2]
196         mov     r8, r5          /* 5th argument (6th is pushed by stub) */
197         icall   lr
198
199         .global syscall_return
200 syscall_return:
201         get_thread_info r0
202         mask_interrupts         /* make sure we don't miss an interrupt
203                                    setting need_resched or sigpending
204                                    between sampling and the rets */
205
206         /* Store the return value so that the correct value is loaded below */
207         stdsp   sp[REG_R12], r12
208
209         ld.w    r1, r0[TI_flags]
210         andl    r1, _TIF_ALLWORK_MASK, COH
211         brne    syscall_exit_work
212
213 syscall_exit_cont:
214         popm    r8-r9
215         mtsr    SYSREG_RAR_SUP, r8
216         mtsr    SYSREG_RSR_SUP, r9
217         ldmts   sp++, r0-lr
218         sub     sp, -4          /* r12_orig */
219         rets
220
221         .align  2
222 syscall_table_addr:
223         .long   sys_call_table
224
225 syscall_badsys:
226         mov     r12, -ENOSYS
227         rjmp    syscall_return
228
229         .global ret_from_fork
230 ret_from_fork:
231         rcall   schedule_tail
232
233         /* check for syscall tracing */
234         get_thread_info r0
235         ld.w    r1, r0[TI_flags]
236         andl    r1, _TIF_ALLWORK_MASK, COH
237         brne    syscall_exit_work
238         rjmp    syscall_exit_cont
239
240 syscall_trace_enter:
241         pushm   r8-r12
242         rcall   syscall_trace
243         popm    r8-r12
244         rjmp    syscall_trace_cont
245
246 syscall_exit_work:
247         bld     r1, TIF_SYSCALL_TRACE
248         brcc    1f
249         unmask_interrupts
250         rcall   syscall_trace
251         mask_interrupts
252         ld.w    r1, r0[TI_flags]
253
254 1:      bld     r1, TIF_NEED_RESCHED
255         brcc    2f
256         unmask_interrupts
257         rcall   schedule
258         mask_interrupts
259         ld.w    r1, r0[TI_flags]
260         rjmp    1b
261
262 2:      mov     r2, _TIF_SIGPENDING | _TIF_RESTORE_SIGMASK
263         tst     r1, r2
264         breq    3f
265         unmask_interrupts
266         mov     r12, sp
267         mov     r11, r0
268         rcall   do_notify_resume
269         mask_interrupts
270         ld.w    r1, r0[TI_flags]
271         rjmp    1b
272
273 3:      bld     r1, TIF_BREAKPOINT
274         brcc    syscall_exit_cont
275         rjmp    enter_monitor_mode
276
277         /* This function expects to find offending PC in SYSREG_RAR_EX */
278         .type   save_full_context_ex, @function
279         .align  2
280 save_full_context_ex:
281         mfsr    r11, SYSREG_RAR_EX
282         sub     r9, pc, . - debug_trampoline
283         mfsr    r8, SYSREG_RSR_EX
284         cp.w    r9, r11
285         breq    3f
286         mov     r12, r8
287         andh    r8, (MODE_MASK >> 16), COH
288         brne    2f
289
290 1:      pushm   r11, r12        /* PC and SR */
291         unmask_exceptions
292         ret     r12
293
294 2:      sub     r10, sp, -(FRAME_SIZE_FULL - REG_LR)
295         stdsp   sp[4], r10      /* replace saved SP */
296         rjmp    1b
297
298         /*
299          * The debug handler set up a trampoline to make us
300          * automatically enter monitor mode upon return, but since
301          * we're saving the full context, we must assume that the
302          * exception handler might want to alter the return address
303          * and/or status register. So we need to restore the original
304          * context and enter monitor mode manually after the exception
305          * has been handled.
306          */
307 3:      get_thread_info r8
308         ld.w    r11, r8[TI_rar_saved]
309         ld.w    r12, r8[TI_rsr_saved]
310         rjmp    1b
311         .size   save_full_context_ex, . - save_full_context_ex
312
313         /* Low-level exception handlers */
314 handle_critical:
315         sub     sp, 4
316         stmts   --sp, r0-lr
317         rcall   save_full_context_ex
318         mfsr    r12, SYSREG_ECR
319         mov     r11, sp
320         rcall   do_critical_exception
321
322         /* We should never get here... */
323 bad_return:
324         sub     r12, pc, (. - 1f)
325         bral    panic
326         .align  2
327 1:      .asciz  "Return from critical exception!"
328
329         .align  1
330 do_bus_error_write:
331         sub     sp, 4
332         stmts   --sp, r0-lr
333         rcall   save_full_context_ex
334         mov     r11, 1
335         rjmp    1f
336
337 do_bus_error_read:
338         sub     sp, 4
339         stmts   --sp, r0-lr
340         rcall   save_full_context_ex
341         mov     r11, 0
342 1:      mfsr    r12, SYSREG_BEAR
343         mov     r10, sp
344         rcall   do_bus_error
345         rjmp    ret_from_exception
346
347         .align  1
348 do_nmi_ll:
349         sub     sp, 4
350         stmts   --sp, r0-lr
351         mfsr    r9, SYSREG_RSR_NMI
352         mfsr    r8, SYSREG_RAR_NMI
353         bfextu  r0, r9, MODE_SHIFT, 3
354         brne    2f
355
356 1:      pushm   r8, r9  /* PC and SR */
357         mfsr    r12, SYSREG_ECR
358         mov     r11, sp
359         rcall   do_nmi
360         popm    r8-r9
361         mtsr    SYSREG_RAR_NMI, r8
362         tst     r0, r0
363         mtsr    SYSREG_RSR_NMI, r9
364         brne    3f
365
366         ldmts   sp++, r0-lr
367         sub     sp, -4          /* skip r12_orig */
368         rete
369
370 2:      sub     r10, sp, -(FRAME_SIZE_FULL - REG_LR)
371         stdsp   sp[4], r10      /* replace saved SP */
372         rjmp    1b
373
374 3:      popm    lr
375         sub     sp, -4          /* skip sp */
376         popm    r0-r12
377         sub     sp, -4          /* skip r12_orig */
378         rete
379
380 handle_address_fault:
381         sub     sp, 4
382         stmts   --sp, r0-lr
383         rcall   save_full_context_ex
384         mfsr    r12, SYSREG_ECR
385         mov     r11, sp
386         rcall   do_address_exception
387         rjmp    ret_from_exception
388
389 handle_protection_fault:
390         sub     sp, 4
391         stmts   --sp, r0-lr
392         rcall   save_full_context_ex
393         mfsr    r12, SYSREG_ECR
394         mov     r11, sp
395         rcall   do_page_fault
396         rjmp    ret_from_exception
397
398         .align  1
399 do_illegal_opcode_ll:
400         sub     sp, 4
401         stmts   --sp, r0-lr
402         rcall   save_full_context_ex
403         mfsr    r12, SYSREG_ECR
404         mov     r11, sp
405         rcall   do_illegal_opcode
406         rjmp    ret_from_exception
407
408 do_dtlb_modified:
409         pushm   r0-r3
410         mfsr    r1, SYSREG_TLBEAR
411         mfsr    r0, SYSREG_PTBR
412         lsr     r2, r1, PGDIR_SHIFT
413         ld.w    r0, r0[r2 << 2]
414         lsl     r1, (32 - PGDIR_SHIFT)
415         lsr     r1, (32 - PGDIR_SHIFT) + PAGE_SHIFT
416
417         /* Translate to virtual address in P1 */
418         andl    r0, 0xf000
419         sbr     r0, 31
420         add     r2, r0, r1 << 2
421         ld.w    r3, r2[0]
422         sbr     r3, _PAGE_BIT_DIRTY
423         mov     r0, r3
424         st.w    r2[0], r3
425
426         /* The page table is up-to-date. Update the TLB entry as well */
427         andl    r0, lo(_PAGE_FLAGS_HARDWARE_MASK)
428         mtsr    SYSREG_TLBELO, r0
429
430         /* MMUCR[DRP] is updated automatically, so let's go... */
431         tlbw
432
433         popm    r0-r3
434         rete
435
436 do_fpe_ll:
437         sub     sp, 4
438         stmts   --sp, r0-lr
439         rcall   save_full_context_ex
440         unmask_interrupts
441         mov     r12, 26
442         mov     r11, sp
443         rcall   do_fpe
444         rjmp    ret_from_exception
445
446 ret_from_exception:
447         mask_interrupts
448         lddsp   r4, sp[REG_SR]
449
450         andh    r4, (MODE_MASK >> 16), COH
451         brne    fault_resume_kernel
452
453         get_thread_info r0
454         ld.w    r1, r0[TI_flags]
455         andl    r1, _TIF_WORK_MASK, COH
456         brne    fault_exit_work
457
458 fault_resume_user:
459         popm    r8-r9
460         mask_exceptions
461         mtsr    SYSREG_RAR_EX, r8
462         mtsr    SYSREG_RSR_EX, r9
463         ldmts   sp++, r0-lr
464         sub     sp, -4
465         rete
466
467 fault_resume_kernel:
468 #ifdef CONFIG_PREEMPT
469         get_thread_info r0
470         ld.w    r2, r0[TI_preempt_count]
471         cp.w    r2, 0
472         brne    1f
473         ld.w    r1, r0[TI_flags]
474         bld     r1, TIF_NEED_RESCHED
475         brcc    1f
476         lddsp   r4, sp[REG_SR]
477         bld     r4, SYSREG_GM_OFFSET
478         brcs    1f
479         rcall   preempt_schedule_irq
480 1:
481 #endif
482
483         popm    r8-r9
484         mask_exceptions
485         mfsr    r1, SYSREG_SR
486         mtsr    SYSREG_RAR_EX, r8
487         mtsr    SYSREG_RSR_EX, r9
488         popm    lr
489         sub     sp, -4          /* ignore SP */
490         popm    r0-r12
491         sub     sp, -4          /* ignore r12_orig */
492         rete
493
494 irq_exit_work:
495         /* Switch to exception mode so that we can share the same code. */
496         mfsr    r8, SYSREG_SR
497         cbr     r8, SYSREG_M0_OFFSET
498         orh     r8, hi(SYSREG_BIT(M1) | SYSREG_BIT(M2))
499         mtsr    SYSREG_SR, r8
500         sub     pc, -2
501         get_thread_info r0
502         ld.w    r1, r0[TI_flags]
503
504 fault_exit_work:
505         bld     r1, TIF_NEED_RESCHED
506         brcc    1f
507         unmask_interrupts
508         rcall   schedule
509         mask_interrupts
510         ld.w    r1, r0[TI_flags]
511         rjmp    fault_exit_work
512
513 1:      mov     r2, _TIF_SIGPENDING | _TIF_RESTORE_SIGMASK
514         tst     r1, r2
515         breq    2f
516         unmask_interrupts
517         mov     r12, sp
518         mov     r11, r0
519         rcall   do_notify_resume
520         mask_interrupts
521         ld.w    r1, r0[TI_flags]
522         rjmp    fault_exit_work
523
524 2:      bld     r1, TIF_BREAKPOINT
525         brcc    fault_resume_user
526         rjmp    enter_monitor_mode
527
528         .section .kprobes.text, "ax", @progbits
529         .type   handle_debug, @function
530 handle_debug:
531         sub     sp, 4           /* r12_orig */
532         stmts   --sp, r0-lr
533         mfsr    r8, SYSREG_RAR_DBG
534         mfsr    r9, SYSREG_RSR_DBG
535         unmask_exceptions
536         pushm   r8-r9
537         bfextu  r9, r9, SYSREG_MODE_OFFSET, SYSREG_MODE_SIZE
538         brne    debug_fixup_regs
539
540 .Ldebug_fixup_cont:
541 #ifdef CONFIG_TRACE_IRQFLAGS
542         rcall   trace_hardirqs_off
543 #endif
544         mov     r12, sp
545         rcall   do_debug
546         mov     sp, r12
547
548         lddsp   r2, sp[REG_SR]
549         bfextu  r3, r2, SYSREG_MODE_OFFSET, SYSREG_MODE_SIZE
550         brne    debug_resume_kernel
551
552         get_thread_info r0
553         ld.w    r1, r0[TI_flags]
554         mov     r2, _TIF_DBGWORK_MASK
555         tst     r1, r2
556         brne    debug_exit_work
557
558         bld     r1, TIF_SINGLE_STEP
559         brcc    1f
560         mfdr    r4, OCD_DC
561         sbr     r4, OCD_DC_SS_BIT
562         mtdr    OCD_DC, r4
563
564 1:      popm    r10,r11
565         mask_exceptions
566         mtsr    SYSREG_RSR_DBG, r11
567         mtsr    SYSREG_RAR_DBG, r10
568 #ifdef CONFIG_TRACE_IRQFLAGS
569         rcall   trace_hardirqs_on
570 1:
571 #endif
572         ldmts   sp++, r0-lr
573         sub     sp, -4
574         retd
575         .size   handle_debug, . - handle_debug
576
577         /* Mode of the trapped context is in r9 */
578         .type   debug_fixup_regs, @function
579 debug_fixup_regs:
580         mfsr    r8, SYSREG_SR
581         mov     r10, r8
582         bfins   r8, r9, SYSREG_MODE_OFFSET, SYSREG_MODE_SIZE
583         mtsr    SYSREG_SR, r8
584         sub     pc, -2
585         stdsp   sp[REG_LR], lr
586         mtsr    SYSREG_SR, r10
587         sub     pc, -2
588         sub     r8, sp, -FRAME_SIZE_FULL
589         stdsp   sp[REG_SP], r8
590         rjmp    .Ldebug_fixup_cont
591         .size   debug_fixup_regs, . - debug_fixup_regs
592
593         .type   debug_resume_kernel, @function
594 debug_resume_kernel:
595         mask_exceptions
596         popm    r10, r11
597         mtsr    SYSREG_RAR_DBG, r10
598         mtsr    SYSREG_RSR_DBG, r11
599 #ifdef CONFIG_TRACE_IRQFLAGS
600         bld     r11, SYSREG_GM_OFFSET
601         brcc    1f
602         rcall   trace_hardirqs_on
603 1:
604 #endif
605         mfsr    r2, SYSREG_SR
606         mov     r1, r2
607         bfins   r2, r3, SYSREG_MODE_OFFSET, SYSREG_MODE_SIZE
608         mtsr    SYSREG_SR, r2
609         sub     pc, -2
610         popm    lr
611         mtsr    SYSREG_SR, r1
612         sub     pc, -2
613         sub     sp, -4          /* skip SP */
614         popm    r0-r12
615         sub     sp, -4
616         retd
617         .size   debug_resume_kernel, . - debug_resume_kernel
618
619         .type   debug_exit_work, @function
620 debug_exit_work:
621         /*
622          * We must return from Monitor Mode using a retd, and we must
623          * not schedule since that involves the D bit in SR getting
624          * cleared by something other than the debug hardware. This
625          * may cause undefined behaviour according to the Architecture
626          * manual.
627          *
628          * So we fix up the return address and status and return to a
629          * stub below in Exception mode. From there, we can follow the
630          * normal exception return path.
631          *
632          * The real return address and status registers are stored on
633          * the stack in the way the exception return path understands,
634          * so no need to fix anything up there.
635          */
636         sub     r8, pc, . - fault_exit_work
637         mtsr    SYSREG_RAR_DBG, r8
638         mov     r9, 0
639         orh     r9, hi(SR_EM | SR_GM | MODE_EXCEPTION)
640         mtsr    SYSREG_RSR_DBG, r9
641         sub     pc, -2
642         retd
643         .size   debug_exit_work, . - debug_exit_work
644
645         .set    rsr_int0,       SYSREG_RSR_INT0
646         .set    rsr_int1,       SYSREG_RSR_INT1
647         .set    rsr_int2,       SYSREG_RSR_INT2
648         .set    rsr_int3,       SYSREG_RSR_INT3
649         .set    rar_int0,       SYSREG_RAR_INT0
650         .set    rar_int1,       SYSREG_RAR_INT1
651         .set    rar_int2,       SYSREG_RAR_INT2
652         .set    rar_int3,       SYSREG_RAR_INT3
653
654         .macro  IRQ_LEVEL level
655         .type   irq_level\level, @function
656 irq_level\level:
657         sub     sp, 4           /* r12_orig */
658         stmts   --sp,r0-lr
659         mfsr    r8, rar_int\level
660         mfsr    r9, rsr_int\level
661
662 #ifdef CONFIG_PREEMPT
663         sub     r11, pc, (. - system_call)
664         cp.w    r11, r8
665         breq    4f
666 #endif
667
668         pushm   r8-r9
669
670         mov     r11, sp
671         mov     r12, \level
672
673         rcall   do_IRQ
674
675         lddsp   r4, sp[REG_SR]
676         bfextu  r4, r4, SYSREG_M0_OFFSET, 3
677         cp.w    r4, MODE_SUPERVISOR >> SYSREG_M0_OFFSET
678         breq    2f
679         cp.w    r4, MODE_USER >> SYSREG_M0_OFFSET
680 #ifdef CONFIG_PREEMPT
681         brne    3f
682 #else
683         brne    1f
684 #endif
685
686         get_thread_info r0
687         ld.w    r1, r0[TI_flags]
688         andl    r1, _TIF_WORK_MASK, COH
689         brne    irq_exit_work
690
691 1:
692 #ifdef CONFIG_TRACE_IRQFLAGS
693         rcall   trace_hardirqs_on
694 #endif
695         popm    r8-r9
696         mtsr    rar_int\level, r8
697         mtsr    rsr_int\level, r9
698         ldmts   sp++,r0-lr
699         sub     sp, -4          /* ignore r12_orig */
700         rete
701
702 #ifdef CONFIG_PREEMPT
703 4:      mask_interrupts
704         mfsr    r8, rsr_int\level
705         sbr     r8, 16
706         mtsr    rsr_int\level, r8
707         ldmts   sp++, r0-lr
708         sub     sp, -4          /* ignore r12_orig */
709         rete
710 #endif
711
712 2:      get_thread_info r0
713         ld.w    r1, r0[TI_flags]
714         bld     r1, TIF_CPU_GOING_TO_SLEEP
715 #ifdef CONFIG_PREEMPT
716         brcc    3f
717 #else
718         brcc    1b
719 #endif
720         sub     r1, pc, . - cpu_idle_skip_sleep
721         stdsp   sp[REG_PC], r1
722 #ifdef CONFIG_PREEMPT
723 3:      get_thread_info r0
724         ld.w    r2, r0[TI_preempt_count]
725         cp.w    r2, 0
726         brne    1b
727         ld.w    r1, r0[TI_flags]
728         bld     r1, TIF_NEED_RESCHED
729         brcc    1b
730         lddsp   r4, sp[REG_SR]
731         bld     r4, SYSREG_GM_OFFSET
732         brcs    1b
733         rcall   preempt_schedule_irq
734 #endif
735         rjmp    1b
736         .endm
737
738         .section .irq.text,"ax",@progbits
739
740         .global irq_level0
741         .global irq_level1
742         .global irq_level2
743         .global irq_level3
744         IRQ_LEVEL 0
745         IRQ_LEVEL 1
746         IRQ_LEVEL 2
747         IRQ_LEVEL 3
748
749         .section .kprobes.text, "ax", @progbits
750         .type   enter_monitor_mode, @function
751 enter_monitor_mode:
752         /*
753          * We need to enter monitor mode to do a single step. The
754          * monitor code will alter the return address so that we
755          * return directly to the user instead of returning here.
756          */
757         breakpoint
758         rjmp    breakpoint_failed
759
760         .size   enter_monitor_mode, . - enter_monitor_mode
761
762         .type   debug_trampoline, @function
763         .global debug_trampoline
764 debug_trampoline:
765         /*
766          * Save the registers on the stack so that the monitor code
767          * can find them easily.
768          */
769         sub     sp, 4           /* r12_orig */
770         stmts   --sp, r0-lr
771         get_thread_info r0
772         ld.w    r8, r0[TI_rar_saved]
773         ld.w    r9, r0[TI_rsr_saved]
774         pushm   r8-r9
775
776         /*
777          * The monitor code will alter the return address so we don't
778          * return here.
779          */
780         breakpoint
781         rjmp    breakpoint_failed
782         .size   debug_trampoline, . - debug_trampoline
783
784         .type breakpoint_failed, @function
785 breakpoint_failed:
786         /*
787          * Something went wrong. Perhaps the debug hardware isn't
788          * enabled?
789          */
790         lda.w   r12, msg_breakpoint_failed
791         mov     r11, sp
792         mov     r10, 9          /* SIGKILL */
793         call    die
794 1:      rjmp    1b
795
796 msg_breakpoint_failed:
797         .asciz  "Failed to enter Debug Mode"