📄 entry-avr32b.s
字号:
do_dtlb_modified: pushm r0-r3 mfsr r1, SYSREG_TLBEAR mfsr r0, SYSREG_PTBR lsr r2, r1, PGDIR_SHIFT ld.w r0, r0[r2 << 2] lsl r1, (32 - PGDIR_SHIFT) lsr r1, (32 - PGDIR_SHIFT) + PAGE_SHIFT /* Translate to virtual address in P1 */ andl r0, 0xf000 sbr r0, 31 add r2, r0, r1 << 2 ld.w r3, r2[0] sbr r3, _PAGE_BIT_DIRTY mov r0, r3 st.w r2[0], r3 /* The page table is up-to-date. Update the TLB entry as well */ andl r0, lo(_PAGE_FLAGS_HARDWARE_MASK) mtsr SYSREG_TLBELO, r0 /* MMUCR[DRP] is updated automatically, so let's go... */ tlbw popm r0-r3 retedo_fpe_ll: sub sp, 4 stmts --sp, r0-lr rcall save_full_context_ex unmask_interrupts mov r12, 26 mov r11, sp rcall do_fpe rjmp ret_from_exceptionret_from_exception: mask_interrupts lddsp r4, sp[REG_SR] andh r4, (MODE_MASK >> 16), COH brne fault_resume_kernel get_thread_info r0 ld.w r1, r0[TI_flags] andl r1, _TIF_WORK_MASK, COH brne fault_exit_workfault_resume_user: popm r8-r9 mask_exceptions mtsr SYSREG_RAR_EX, r8 mtsr SYSREG_RSR_EX, r9 ldmts sp++, r0-lr sub sp, -4 retefault_resume_kernel:#ifdef CONFIG_PREEMPT get_thread_info r0 ld.w r2, r0[TI_preempt_count] cp.w r2, 0 brne 1f ld.w r1, r0[TI_flags] bld r1, TIF_NEED_RESCHED brcc 1f lddsp r4, sp[REG_SR] bld r4, SYSREG_GM_OFFSET brcs 1f rcall preempt_schedule_irq1:#endif popm r8-r9 mask_exceptions mfsr r1, SYSREG_SR mtsr SYSREG_RAR_EX, r8 mtsr SYSREG_RSR_EX, r9 popm lr sub sp, -4 /* ignore SP */ popm r0-r12 sub sp, -4 /* ignore r12_orig */ reteirq_exit_work: /* Switch to exception mode so that we can share the same code. */ mfsr r8, SYSREG_SR cbr r8, SYSREG_M0_OFFSET orh r8, hi(SYSREG_BIT(M1) | SYSREG_BIT(M2)) mtsr SYSREG_SR, r8 sub pc, -2 get_thread_info r0 ld.w r1, r0[TI_flags]fault_exit_work: bld r1, TIF_NEED_RESCHED brcc 1f unmask_interrupts rcall schedule mask_interrupts ld.w r1, r0[TI_flags] rjmp fault_exit_work1: mov r2, _TIF_SIGPENDING | _TIF_RESTORE_SIGMASK tst r1, r2 breq 2f unmask_interrupts mov r12, sp mov r11, r0 rcall do_notify_resume mask_interrupts ld.w r1, r0[TI_flags] rjmp fault_exit_work2: bld r1, TIF_BREAKPOINT brcc fault_resume_user rjmp enter_monitor_mode .section .kprobes.text, "ax", @progbits .type handle_debug, @functionhandle_debug: sub sp, 4 /* r12_orig */ stmts --sp, r0-lr mfsr r8, SYSREG_RAR_DBG mfsr r9, SYSREG_RSR_DBG unmask_exceptions pushm r8-r9 bfextu r9, r9, SYSREG_MODE_OFFSET, SYSREG_MODE_SIZE brne debug_fixup_regs.Ldebug_fixup_cont:#ifdef CONFIG_TRACE_IRQFLAGS rcall trace_hardirqs_off#endif mov r12, sp rcall do_debug mov sp, r12 lddsp r2, sp[REG_SR] bfextu r3, r2, SYSREG_MODE_OFFSET, SYSREG_MODE_SIZE brne debug_resume_kernel get_thread_info r0 ld.w r1, r0[TI_flags] mov r2, _TIF_DBGWORK_MASK tst r1, r2 brne debug_exit_work bld r1, TIF_SINGLE_STEP brcc 1f mfdr r4, OCD_DC sbr r4, OCD_DC_SS_BIT mtdr OCD_DC, r41: popm r10,r11 mask_exceptions mtsr SYSREG_RSR_DBG, r11 mtsr SYSREG_RAR_DBG, r10#ifdef CONFIG_TRACE_IRQFLAGS rcall trace_hardirqs_on1:#endif ldmts sp++, r0-lr sub sp, -4 retd .size handle_debug, . - handle_debug /* Mode of the trapped context is in r9 */ .type debug_fixup_regs, @functiondebug_fixup_regs: mfsr r8, SYSREG_SR mov r10, r8 bfins r8, r9, SYSREG_MODE_OFFSET, SYSREG_MODE_SIZE mtsr SYSREG_SR, r8 sub pc, -2 stdsp sp[REG_LR], lr mtsr SYSREG_SR, r10 sub pc, -2 sub r8, sp, -FRAME_SIZE_FULL stdsp sp[REG_SP], r8 rjmp .Ldebug_fixup_cont .size debug_fixup_regs, . - debug_fixup_regs .type debug_resume_kernel, @functiondebug_resume_kernel: mask_exceptions popm r10, r11 mtsr SYSREG_RAR_DBG, r10 mtsr SYSREG_RSR_DBG, r11#ifdef CONFIG_TRACE_IRQFLAGS bld r11, SYSREG_GM_OFFSET brcc 1f rcall trace_hardirqs_on1:#endif mfsr r2, SYSREG_SR mov r1, r2 bfins r2, r3, SYSREG_MODE_OFFSET, SYSREG_MODE_SIZE mtsr SYSREG_SR, r2 sub pc, -2 popm lr mtsr SYSREG_SR, r1 sub pc, -2 sub sp, -4 /* skip SP */ popm r0-r12 sub sp, -4 retd .size debug_resume_kernel, . - debug_resume_kernel .type debug_exit_work, @functiondebug_exit_work: /* * We must return from Monitor Mode using a retd, and we must * not schedule since that involves the D bit in SR getting * cleared by something other than the debug hardware. This * may cause undefined behaviour according to the Architecture * manual. * * So we fix up the return address and status and return to a * stub below in Exception mode. From there, we can follow the * normal exception return path. * * The real return address and status registers are stored on * the stack in the way the exception return path understands, * so no need to fix anything up there. */ sub r8, pc, . - fault_exit_work mtsr SYSREG_RAR_DBG, r8 mov r9, 0 orh r9, hi(SR_EM | SR_GM | MODE_EXCEPTION) mtsr SYSREG_RSR_DBG, r9 sub pc, -2 retd .size debug_exit_work, . - debug_exit_work .set rsr_int0, SYSREG_RSR_INT0 .set rsr_int1, SYSREG_RSR_INT1 .set rsr_int2, SYSREG_RSR_INT2 .set rsr_int3, SYSREG_RSR_INT3 .set rar_int0, SYSREG_RAR_INT0 .set rar_int1, SYSREG_RAR_INT1 .set rar_int2, SYSREG_RAR_INT2 .set rar_int3, SYSREG_RAR_INT3 .macro IRQ_LEVEL level .type irq_level\level, @functionirq_level\level: sub sp, 4 /* r12_orig */ stmts --sp,r0-lr mfsr r8, rar_int\level mfsr r9, rsr_int\level#ifdef CONFIG_PREEMPT sub r11, pc, (. - system_call) cp.w r11, r8 breq 4f#endif pushm r8-r9 mov r11, sp mov r12, \level rcall do_IRQ lddsp r4, sp[REG_SR] bfextu r4, r4, SYSREG_M0_OFFSET, 3 cp.w r4, MODE_SUPERVISOR >> SYSREG_M0_OFFSET breq 2f cp.w r4, MODE_USER >> SYSREG_M0_OFFSET#ifdef CONFIG_PREEMPT brne 3f#else brne 1f#endif get_thread_info r0 ld.w r1, r0[TI_flags] andl r1, _TIF_WORK_MASK, COH brne irq_exit_work1:#ifdef CONFIG_TRACE_IRQFLAGS rcall trace_hardirqs_on#endif popm r8-r9 mtsr rar_int\level, r8 mtsr rsr_int\level, r9 ldmts sp++,r0-lr sub sp, -4 /* ignore r12_orig */ rete#ifdef CONFIG_PREEMPT4: mask_interrupts mfsr r8, rsr_int\level sbr r8, 16 mtsr rsr_int\level, r8 ldmts sp++, r0-lr sub sp, -4 /* ignore r12_orig */ rete#endif2: get_thread_info r0 ld.w r1, r0[TI_flags] bld r1, TIF_CPU_GOING_TO_SLEEP#ifdef CONFIG_PREEMPT brcc 3f#else brcc 1b#endif sub r1, pc, . - cpu_idle_skip_sleep stdsp sp[REG_PC], r1#ifdef CONFIG_PREEMPT3: get_thread_info r0 ld.w r2, r0[TI_preempt_count] cp.w r2, 0 brne 1b ld.w r1, r0[TI_flags] bld r1, TIF_NEED_RESCHED brcc 1b lddsp r4, sp[REG_SR] bld r4, SYSREG_GM_OFFSET brcs 1b rcall preempt_schedule_irq#endif rjmp 1b .endm .section .irq.text,"ax",@progbits.global cpu_idle_sleepcpu_idle_sleep: mask_interrupts get_thread_info r8 ld.w r9, r8[TI_flags] bld r9, TIF_NEED_RESCHED brcs cpu_idle_enable_int_and_exit sbr r9, TIF_CPU_GOING_TO_SLEEP st.w r8[TI_flags], r9 unmask_interrupts sleep 0cpu_idle_skip_sleep: mask_interrupts ld.w r9, r8[TI_flags] cbr r9, TIF_CPU_GOING_TO_SLEEP st.w r8[TI_flags], r9cpu_idle_enable_int_and_exit: unmask_interrupts retal r12 .global irq_level0 .global irq_level1 .global irq_level2 .global irq_level3 IRQ_LEVEL 0 IRQ_LEVEL 1 IRQ_LEVEL 2 IRQ_LEVEL 3 .section .kprobes.text, "ax", @progbits .type enter_monitor_mode, @functionenter_monitor_mode: /* * We need to enter monitor mode to do a single step. The * monitor code will alter the return address so that we * return directly to the user instead of returning here. */ breakpoint rjmp breakpoint_failed .size enter_monitor_mode, . - enter_monitor_mode .type debug_trampoline, @function .global debug_trampolinedebug_trampoline: /* * Save the registers on the stack so that the monitor code * can find them easily. */ sub sp, 4 /* r12_orig */ stmts --sp, r0-lr get_thread_info r0 ld.w r8, r0[TI_rar_saved] ld.w r9, r0[TI_rsr_saved] pushm r8-r9 /* * The monitor code will alter the return address so we don't * return here. */ breakpoint rjmp breakpoint_failed .size debug_trampoline, . - debug_trampoline .type breakpoint_failed, @functionbreakpoint_failed: /* * Something went wrong. Perhaps the debug hardware isn't * enabled? */ lda.w r12, msg_breakpoint_failed mov r11, sp mov r10, 9 /* SIGKILL */ call die1: rjmp 1bmsg_breakpoint_failed: .asciz "Failed to enter Debug Mode"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -