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 40exception_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 82itlb_miss: 83 tlbmiss_save 84 rjmp tlb_miss_common 85 86 .org 0x60 87dtlb_miss_read: 88 tlbmiss_save 89 rjmp tlb_miss_common 90 91 .org 0x70 92dtlb_miss_write: 93 tlbmiss_save 94 95 .global tlb_miss_common 96 .align 2 97tlb_miss_common: 98 mfsr r0, SYSREG_TLBEAR 99 mfsr r1, SYSREG_PTBR 100 101 /* 102 * First level lookup: The PGD contains virtual pointers to 103 * the second-level page tables, but they may be NULL if not 104 * present. 105 */ 106pgtbl_lookup: 107 lsr r2, r0, PGDIR_SHIFT 108 ld.w r3, r1[r2 << 2] 109 bfextu r1, r0, PAGE_SHIFT, PGDIR_SHIFT - PAGE_SHIFT 110 cp.w r3, 0 111 breq page_table_not_present 112 113 /* Second level lookup */ 114 ld.w r2, r3[r1 << 2] 115 mfsr r0, SYSREG_TLBARLO 116 bld r2, _PAGE_BIT_PRESENT 117 brcc page_not_present 118 119 /* Mark the page as accessed */ 120 sbr r2, _PAGE_BIT_ACCESSED 121 st.w r3[r1 << 2], r2 122 123 /* Drop software flags */ 124 andl r2, _PAGE_FLAGS_HARDWARE_MASK & 0xffff 125 mtsr SYSREG_TLBELO, r2 126 127 /* Figure out which entry we want to replace */ 128 mfsr r1, SYSREG_MMUCR 129 clz r2, r0 130 brcc 1f 131 mov r3, -1 /* All entries have been accessed, */ 132 mov r2, 0 /* so start at 0 */ 133 mtsr SYSREG_TLBARLO, r3 /* and reset TLBAR */ 134 1351: bfins r1, r2, SYSREG_DRP_OFFSET, SYSREG_DRP_SIZE 136 mtsr SYSREG_MMUCR, r1 137 tlbw 138 139 tlbmiss_restore 140 rete 141 142 /* The slow path of the TLB miss handler */ 143 .align 2 144page_table_not_present: 145 /* Do we need to synchronize with swapper_pg_dir? */ 146 bld r0, 31 147 brcs sync_with_swapper_pg_dir 148 149page_not_present: 150 tlbmiss_restore 151 sub sp, 4 152 stmts --sp, r0-lr 153 call save_full_context_ex 154 mfsr r12, SYSREG_ECR 155 mov r11, sp 156 call do_page_fault 157 rjmp ret_from_exception 158 159 .align 2 160sync_with_swapper_pg_dir: 161 /* 162 * If swapper_pg_dir contains a non-NULL second-level page 163 * table pointer, copy it into the current PGD. If not, we 164 * must handle it as a full-blown page fault. 165 * 166 * Jumping back to pgtbl_lookup causes an unnecessary lookup, 167 * but it is guaranteed to be a cache hit, it won't happen 168 * very often, and we absolutely do not want to sacrifice any 169 * performance in the fast path in order to improve this. 170 */ 171 mov r1, lo(swapper_pg_dir) 172 orh r1, hi(swapper_pg_dir) 173 ld.w r3, r1[r2 << 2] 174 cp.w r3, 0 175 breq page_not_present 176 mfsr r1, SYSREG_PTBR 177 st.w r1[r2 << 2], r3 178 rjmp pgtbl_lookup 179 180 /* 181 * We currently have two bytes left at this point until we 182 * crash into the system call handler... 183 * 184 * Don't worry, the assembler will let us know. 185 */ 186 187 188 /* --- System Call --- */ 189 190 .org 0x100 191system_call: 192#ifdef CONFIG_PREEMPT 193 mask_interrupts 194#endif 195 pushm r12 /* r12_orig */ 196 stmts --sp, r0-lr 197 198 mfsr r0, SYSREG_RAR_SUP 199 mfsr r1, SYSREG_RSR_SUP 200#ifdef CONFIG_PREEMPT 201 unmask_interrupts 202#endif 203 zero_fp 204 stm --sp, r0-r1 205 206 /* check for syscall tracing */ 207 get_thread_info r0 208 ld.w r1, r0[TI_flags] 209 bld r1, TIF_SYSCALL_TRACE 210 brcs syscall_trace_enter 211 212syscall_trace_cont: 213 cp.w r8, NR_syscalls 214 brhs syscall_badsys 215 216 lddpc lr, syscall_table_addr 217 ld.w lr, lr[r8 << 2] 218 mov r8, r5 /* 5th argument (6th is pushed by stub) */ 219 icall lr 220 221 .global syscall_return 222syscall_return: 223 get_thread_info r0 224 mask_interrupts /* make sure we don't miss an interrupt 225 setting need_resched or sigpending 226 between sampling and the rets */ 227 228 /* Store the return value so that the correct value is loaded below */ 229 stdsp sp[REG_R12], r12 230 231 ld.w r1, r0[TI_flags] 232 andl r1, _TIF_ALLWORK_MASK, COH 233 brne syscall_exit_work 234 235syscall_exit_cont: 236 popm r8-r9 237 mtsr SYSREG_RAR_SUP, r8 238 mtsr SYSREG_RSR_SUP, r9 239 ldmts sp++, r0-lr 240 sub sp, -4 /* r12_orig */ 241 rets 242 243 .align 2 244syscall_table_addr: 245 .long sys_call_table 246 247syscall_badsys: 248 mov r12, -ENOSYS 249 rjmp syscall_return 250 251 .global ret_from_fork 252ret_from_fork: 253 call schedule_tail 254 255 /* check for syscall tracing */ 256 get_thread_info r0 257 ld.w r1, r0[TI_flags] 258 andl r1, _TIF_ALLWORK_MASK, COH 259 brne syscall_exit_work 260 rjmp syscall_exit_cont 261 262syscall_trace_enter: 263 pushm r8-r12 264 call syscall_trace 265 popm r8-r12 266 rjmp syscall_trace_cont 267 268syscall_exit_work: 269 bld r1, TIF_SYSCALL_TRACE 270 brcc 1f 271 unmask_interrupts 272 call syscall_trace 273 mask_interrupts 274 ld.w r1, r0[TI_flags] 275 2761: bld r1, TIF_NEED_RESCHED 277 brcc 2f 278 unmask_interrupts 279 call schedule 280 mask_interrupts 281 ld.w r1, r0[TI_flags] 282 rjmp 1b 283 2842: mov r2, _TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NOTIFY_RESUME 285 tst r1, r2 286 breq 3f 287 unmask_interrupts 288 mov r12, sp 289 mov r11, r0 290 call do_notify_resume 291 mask_interrupts 292 ld.w r1, r0[TI_flags] 293 rjmp 1b 294 2953: bld r1, TIF_BREAKPOINT 296 brcc syscall_exit_cont 297 rjmp enter_monitor_mode 298 299 /* This function expects to find offending PC in SYSREG_RAR_EX */ 300 .type save_full_context_ex, @function 301 .align 2 302save_full_context_ex: 303 mfsr r11, SYSREG_RAR_EX 304 sub r9, pc, . - debug_trampoline 305 mfsr r8, SYSREG_RSR_EX 306 cp.w r9, r11 307 breq 3f 308 mov r12, r8 309 andh r8, (MODE_MASK >> 16), COH 310 brne 2f 311 3121: pushm r11, r12 /* PC and SR */ 313 unmask_exceptions 314 ret r12 315 3162: sub r10, sp, -(FRAME_SIZE_FULL - REG_LR) 317 stdsp sp[4], r10 /* replace saved SP */ 318 rjmp 1b 319 320 /* 321 * The debug handler set up a trampoline to make us 322 * automatically enter monitor mode upon return, but since 323 * we're saving the full context, we must assume that the 324 * exception handler might want to alter the return address 325 * and/or status register. So we need to restore the original 326 * context and enter monitor mode manually after the exception 327 * has been handled. 328 */ 3293: get_thread_info r8 330 ld.w r11, r8[TI_rar_saved] 331 ld.w r12, r8[TI_rsr_saved] 332 rjmp 1b 333 .size save_full_context_ex, . - save_full_context_ex 334 335 /* Low-level exception handlers */ 336handle_critical: 337 /* 338 * AT32AP700x errata: 339 * 340 * After a Java stack overflow or underflow trap, any CPU 341 * memory access may cause erratic behavior. This will happen 342 * when the four least significant bits of the JOSP system 343 * register contains any value between 9 and 15 (inclusive). 344 * 345 * Possible workarounds: 346 * - Don't use the Java Extension Module 347 * - Ensure that the stack overflow and underflow trap 348 * handlers do not do any memory access or trigger any 349 * exceptions before the overflow/underflow condition is 350 * cleared (by incrementing or decrementing the JOSP) 351 * - Make sure that JOSP does not contain any problematic 352 * value before doing any exception or interrupt 353 * processing. 354 * - Set up a critical exception handler which writes a 355 * known-to-be-safe value, e.g. 4, to JOSP before doing 356 * any further processing. 357 * 358 * We'll use the last workaround for now since we cannot 359 * guarantee that user space processes don't use Java mode. 360 * Non-well-behaving userland will be terminated with extreme 361 * prejudice. 362 */ 363#ifdef CONFIG_CPU_AT32AP700X 364 /* 365 * There's a chance we can't touch memory, so temporarily 366 * borrow PTBR to save the stack pointer while we fix things 367 * up... 368 */ 369 mtsr SYSREG_PTBR, sp 370 mov sp, 4 371 mtsr SYSREG_JOSP, sp 372 mfsr sp, SYSREG_PTBR 373 sub pc, -2 374 375 /* Push most of pt_regs on stack. We'll do the rest later */ 376 sub sp, 4 377 pushm r0-r12 378 379 /* PTBR mirrors current_thread_info()->task->active_mm->pgd */ 380 get_thread_info r0 381 ld.w r1, r0[TI_task] 382 ld.w r2, r1[TSK_active_mm] 383 ld.w r3, r2[MM_pgd] 384 mtsr SYSREG_PTBR, r3 385#else 386 sub sp, 4 387 pushm r0-r12 388#endif 389 sub r0, sp, -(14 * 4) 390 mov r1, lr 391 mfsr r2, SYSREG_RAR_EX 392 mfsr r3, SYSREG_RSR_EX 393 pushm r0-r3 394 395 mfsr r12, SYSREG_ECR 396 mov r11, sp 397 call do_critical_exception 398 399 /* We should never get here... */ 400bad_return: 401 sub r12, pc, (. - 1f) 402 bral panic 403 .align 2 4041: .asciz "Return from critical exception!" 405 406 .align 1 407do_bus_error_write: 408 sub sp, 4 409 stmts --sp, r0-lr 410 call save_full_context_ex 411 mov r11, 1 412 rjmp 1f 413 414do_bus_error_read: 415 sub sp, 4 416 stmts --sp, r0-lr 417 call save_full_context_ex 418 mov r11, 0 4191: mfsr r12, SYSREG_BEAR 420 mov r10, sp 421 call do_bus_error 422 rjmp ret_from_exception 423 424 .align 1 425do_nmi_ll: 426 sub sp, 4 427 stmts --sp, r0-lr 428 mfsr r9, SYSREG_RSR_NMI 429 mfsr r8, SYSREG_RAR_NMI 430 bfextu r0, r9, MODE_SHIFT, 3 431 brne 2f 432 4331: pushm r8, r9 /* PC and SR */ 434 mfsr r12, SYSREG_ECR 435 mov r11, sp 436 call do_nmi 437 popm r8-r9 438 mtsr SYSREG_RAR_NMI, r8 439 tst r0, r0 440 mtsr SYSREG_RSR_NMI, r9 441 brne 3f 442 443 ldmts sp++, r0-lr 444 sub sp, -4 /* skip r12_orig */ 445 rete 446 4472: sub r10, sp, -(FRAME_SIZE_FULL - REG_LR) 448 stdsp sp[4], r10 /* replace saved SP */ 449 rjmp 1b 450 4513: popm lr 452 sub sp, -4 /* skip sp */ 453 popm r0-r12 454 sub sp, -4 /* skip r12_orig */ 455 rete 456 457handle_address_fault: 458 sub sp, 4 459 stmts --sp, r0-lr 460 call save_full_context_ex 461 mfsr r12, SYSREG_ECR 462 mov r11, sp 463 call do_address_exception 464 rjmp ret_from_exception 465 466handle_protection_fault: 467 sub sp, 4 468 stmts --sp, r0-lr 469 call save_full_context_ex 470 mfsr r12, SYSREG_ECR 471 mov r11, sp 472 call do_page_fault 473 rjmp ret_from_exception 474 475 .align 1 476do_illegal_opcode_ll: 477 sub sp, 4 478 stmts --sp, r0-lr 479 call save_full_context_ex 480 mfsr r12, SYSREG_ECR 481 mov r11, sp 482 call do_illegal_opcode 483 rjmp ret_from_exception 484 485do_dtlb_modified: 486 pushm r0-r3 487 mfsr r1, SYSREG_TLBEAR 488 mfsr r0, SYSREG_PTBR 489 lsr r2, r1, PGDIR_SHIFT 490 ld.w r0, r0[r2 << 2] 491 lsl r1, (32 - PGDIR_SHIFT) 492 lsr r1, (32 - PGDIR_SHIFT) + PAGE_SHIFT 493 494 /* Translate to virtual address in P1 */ 495 andl r0, 0xf000 496 sbr r0, 31 497 add r2, r0, r1 << 2 498 ld.w r3, r2[0] 499 sbr r3, _PAGE_BIT_DIRTY 500 mov r0, r3 501 st.w r2[0], r3 502 503 /* The page table is up-to-date. Update the TLB entry as well */ 504 andl r0, lo(_PAGE_FLAGS_HARDWARE_MASK) 505 mtsr SYSREG_TLBELO, r0 506 507 /* MMUCR[DRP] is updated automatically, so let's go... */ 508 tlbw 509 510 popm r0-r3 511 rete 512 513do_fpe_ll: 514 sub sp, 4 515 stmts --sp, r0-lr 516 call save_full_context_ex 517 unmask_interrupts 518 mov r12, 26 519 mov r11, sp 520 call do_fpe 521 rjmp ret_from_exception 522 523ret_from_exception: 524 mask_interrupts 525 lddsp r4, sp[REG_SR] 526 527 andh r4, (MODE_MASK >> 16), COH 528 brne fault_resume_kernel 529 530 get_thread_info r0 531 ld.w r1, r0[TI_flags] 532 andl r1, _TIF_WORK_MASK, COH 533 brne fault_exit_work 534 535fault_resume_user: 536 popm r8-r9 537 mask_exceptions 538 mtsr SYSREG_RAR_EX, r8 539 mtsr SYSREG_RSR_EX, r9 540 ldmts sp++, r0-lr 541 sub sp, -4 542 rete 543 544fault_resume_kernel: 545#ifdef CONFIG_PREEMPT 546 get_thread_info r0 547 ld.w r2, r0[TI_preempt_count] 548 cp.w r2, 0 549 brne 1f 550 ld.w r1, r0[TI_flags] 551 bld r1, TIF_NEED_RESCHED 552 brcc 1f 553 lddsp r4, sp[REG_SR] 554 bld r4, SYSREG_GM_OFFSET 555 brcs 1f 556 call preempt_schedule_irq 5571: 558#endif 559 560 popm r8-r9 561 mask_exceptions 562 mfsr r1, SYSREG_SR 563 mtsr SYSREG_RAR_EX, r8 564 mtsr SYSREG_RSR_EX, r9 565 popm lr 566 sub sp, -4 /* ignore SP */ 567 popm r0-r12 568 sub sp, -4 /* ignore r12_orig */ 569 rete 570 571irq_exit_work: 572 /* Switch to exception mode so that we can share the same code. */ 573 mfsr r8, SYSREG_SR 574 cbr r8, SYSREG_M0_OFFSET 575 orh r8, hi(SYSREG_BIT(M1) | SYSREG_BIT(M2)) 576 mtsr SYSREG_SR, r8 577 sub pc, -2 578 get_thread_info r0 579 ld.w r1, r0[TI_flags] 580 581fault_exit_work: 582 bld r1, TIF_NEED_RESCHED 583 brcc 1f 584 unmask_interrupts 585 call schedule 586 mask_interrupts 587 ld.w r1, r0[TI_flags] 588 rjmp fault_exit_work 589 5901: mov r2, _TIF_SIGPENDING | _TIF_RESTORE_SIGMASK 591 tst r1, r2 592 breq 2f 593 unmask_interrupts 594 mov r12, sp 595 mov r11, r0 596 call do_notify_resume 597 mask_interrupts 598 ld.w r1, r0[TI_flags] 599 rjmp fault_exit_work 600 6012: bld r1, TIF_BREAKPOINT 602 brcc fault_resume_user 603 rjmp enter_monitor_mode 604 605 .section .kprobes.text, "ax", @progbits 606 .type handle_debug, @function 607handle_debug: 608 sub sp, 4 /* r12_orig */ 609 stmts --sp, r0-lr 610 mfsr r8, SYSREG_RAR_DBG 611 mfsr r9, SYSREG_RSR_DBG 612 unmask_exceptions 613 pushm r8-r9 614 bfextu r9, r9, SYSREG_MODE_OFFSET, SYSREG_MODE_SIZE 615 brne debug_fixup_regs 616 617.Ldebug_fixup_cont: 618#ifdef CONFIG_TRACE_IRQFLAGS 619 call trace_hardirqs_off 620#endif 621 mov r12, sp 622 call do_debug 623 mov sp, r12 624 625 lddsp r2, sp[REG_SR] 626 bfextu r3, r2, SYSREG_MODE_OFFSET, SYSREG_MODE_SIZE 627 brne debug_resume_kernel 628 629 get_thread_info r0 630 ld.w r1, r0[TI_flags] 631 mov r2, _TIF_DBGWORK_MASK 632 tst r1, r2 633 brne debug_exit_work 634 635 bld r1, TIF_SINGLE_STEP 636 brcc 1f 637 mfdr r4, OCD_DC 638 sbr r4, OCD_DC_SS_BIT 639 mtdr OCD_DC, r4 640 6411: popm r10,r11 642 mask_exceptions 643 mtsr SYSREG_RSR_DBG, r11 644 mtsr SYSREG_RAR_DBG, r10 645#ifdef CONFIG_TRACE_IRQFLAGS 646 call trace_hardirqs_on 6471: 648#endif 649 ldmts sp++, r0-lr 650 sub sp, -4 651 retd 652 .size handle_debug, . - handle_debug 653 654 /* Mode of the trapped context is in r9 */ 655 .type debug_fixup_regs, @function 656debug_fixup_regs: 657 mfsr r8, SYSREG_SR 658 mov r10, r8 659 bfins r8, r9, SYSREG_MODE_OFFSET, SYSREG_MODE_SIZE 660 mtsr SYSREG_SR, r8 661 sub pc, -2 662 stdsp sp[REG_LR], lr 663 mtsr SYSREG_SR, r10 664 sub pc, -2 665 sub r8, sp, -FRAME_SIZE_FULL 666 stdsp sp[REG_SP], r8 667 rjmp .Ldebug_fixup_cont 668 .size debug_fixup_regs, . - debug_fixup_regs 669 670 .type debug_resume_kernel, @function 671debug_resume_kernel: 672 mask_exceptions 673 popm r10, r11 674 mtsr SYSREG_RAR_DBG, r10 675 mtsr SYSREG_RSR_DBG, r11 676#ifdef CONFIG_TRACE_IRQFLAGS 677 bld r11, SYSREG_GM_OFFSET 678 brcc 1f 679 call trace_hardirqs_on 6801: 681#endif 682 mfsr r2, SYSREG_SR 683 mov r1, r2 684 bfins r2, r3, SYSREG_MODE_OFFSET, SYSREG_MODE_SIZE 685 mtsr SYSREG_SR, r2 686 sub pc, -2 687 popm lr 688 mtsr SYSREG_SR, r1 689 sub pc, -2 690 sub sp, -4 /* skip SP */ 691 popm r0-r12 692 sub sp, -4 693 retd 694 .size debug_resume_kernel, . - debug_resume_kernel 695 696 .type debug_exit_work, @function 697debug_exit_work: 698 /* 699 * We must return from Monitor Mode using a retd, and we must 700 * not schedule since that involves the D bit in SR getting 701 * cleared by something other than the debug hardware. This 702 * may cause undefined behaviour according to the Architecture 703 * manual. 704 * 705 * So we fix up the return address and status and return to a 706 * stub below in Exception mode. From there, we can follow the 707 * normal exception return path. 708 * 709 * The real return address and status registers are stored on 710 * the stack in the way the exception return path understands, 711 * so no need to fix anything up there. 712 */ 713 sub r8, pc, . - fault_exit_work 714 mtsr SYSREG_RAR_DBG, r8 715 mov r9, 0 716 orh r9, hi(SR_EM | SR_GM | MODE_EXCEPTION) 717 mtsr SYSREG_RSR_DBG, r9 718 sub pc, -2 719 retd 720 .size debug_exit_work, . - debug_exit_work 721 722 .set rsr_int0, SYSREG_RSR_INT0 723 .set rsr_int1, SYSREG_RSR_INT1 724 .set rsr_int2, SYSREG_RSR_INT2 725 .set rsr_int3, SYSREG_RSR_INT3 726 .set rar_int0, SYSREG_RAR_INT0 727 .set rar_int1, SYSREG_RAR_INT1 728 .set rar_int2, SYSREG_RAR_INT2 729 .set rar_int3, SYSREG_RAR_INT3 730 731 .macro IRQ_LEVEL level 732 .type irq_level\level, @function 733irq_level\level: 734 sub sp, 4 /* r12_orig */ 735 stmts --sp,r0-lr 736 mfsr r8, rar_int\level 737 mfsr r9, rsr_int\level 738 739#ifdef CONFIG_PREEMPT 740 sub r11, pc, (. - system_call) 741 cp.w r11, r8 742 breq 4f 743#endif 744 745 pushm r8-r9 746 747 mov r11, sp 748 mov r12, \level 749 750 call do_IRQ 751 752 lddsp r4, sp[REG_SR] 753 bfextu r4, r4, SYSREG_M0_OFFSET, 3 754 cp.w r4, MODE_SUPERVISOR >> SYSREG_M0_OFFSET 755 breq 2f 756 cp.w r4, MODE_USER >> SYSREG_M0_OFFSET 757#ifdef CONFIG_PREEMPT 758 brne 3f 759#else 760 brne 1f 761#endif 762 763 get_thread_info r0 764 ld.w r1, r0[TI_flags] 765 andl r1, _TIF_WORK_MASK, COH 766 brne irq_exit_work 767 7681: 769#ifdef CONFIG_TRACE_IRQFLAGS 770 call trace_hardirqs_on 771#endif 772 popm r8-r9 773 mtsr rar_int\level, r8 774 mtsr rsr_int\level, r9 775 ldmts sp++,r0-lr 776 sub sp, -4 /* ignore r12_orig */ 777 rete 778 779#ifdef CONFIG_PREEMPT 7804: mask_interrupts 781 mfsr r8, rsr_int\level 782 sbr r8, 16 783 mtsr rsr_int\level, r8 784 ldmts sp++, r0-lr 785 sub sp, -4 /* ignore r12_orig */ 786 rete 787#endif 788 7892: get_thread_info r0 790 ld.w r1, r0[TI_flags] 791 bld r1, TIF_CPU_GOING_TO_SLEEP 792#ifdef CONFIG_PREEMPT 793 brcc 3f 794#else 795 brcc 1b 796#endif 797 sub r1, pc, . - cpu_idle_skip_sleep 798 stdsp sp[REG_PC], r1 799#ifdef CONFIG_PREEMPT 8003: get_thread_info r0 801 ld.w r2, r0[TI_preempt_count] 802 cp.w r2, 0 803 brne 1b 804 ld.w r1, r0[TI_flags] 805 bld r1, TIF_NEED_RESCHED 806 brcc 1b 807 lddsp r4, sp[REG_SR] 808 bld r4, SYSREG_GM_OFFSET 809 brcs 1b 810 call preempt_schedule_irq 811#endif 812 rjmp 1b 813 .endm 814 815 .section .irq.text,"ax",@progbits 816 817 .global irq_level0 818 .global irq_level1 819 .global irq_level2 820 .global irq_level3 821 IRQ_LEVEL 0 822 IRQ_LEVEL 1 823 IRQ_LEVEL 2 824 IRQ_LEVEL 3 825 826 .section .kprobes.text, "ax", @progbits 827 .type enter_monitor_mode, @function 828enter_monitor_mode: 829 /* 830 * We need to enter monitor mode to do a single step. The 831 * monitor code will alter the return address so that we 832 * return directly to the user instead of returning here. 833 */ 834 breakpoint 835 rjmp breakpoint_failed 836 837 .size enter_monitor_mode, . - enter_monitor_mode 838 839 .type debug_trampoline, @function 840 .global debug_trampoline 841debug_trampoline: 842 /* 843 * Save the registers on the stack so that the monitor code 844 * can find them easily. 845 */ 846 sub sp, 4 /* r12_orig */ 847 stmts --sp, r0-lr 848 get_thread_info r0 849 ld.w r8, r0[TI_rar_saved] 850 ld.w r9, r0[TI_rsr_saved] 851 pushm r8-r9 852 853 /* 854 * The monitor code will alter the return address so we don't 855 * return here. 856 */ 857 breakpoint 858 rjmp breakpoint_failed 859 .size debug_trampoline, . - debug_trampoline 860 861 .type breakpoint_failed, @function 862breakpoint_failed: 863 /* 864 * Something went wrong. Perhaps the debug hardware isn't 865 * enabled? 866 */ 867 lda.w r12, msg_breakpoint_failed 868 mov r11, sp 869 mov r10, 9 /* SIGKILL */ 870 call die 8711: rjmp 1b 872 873msg_breakpoint_failed: 874 .asciz "Failed to enter Debug Mode" 875