📄 break.s
字号:
/* break.S: Break interrupt handling (kept separate from entry.S) * * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */#include <linux/linkage.h>#include <asm/setup.h>#include <asm/segment.h>#include <asm/ptrace.h>#include <asm/thread_info.h>#include <asm/spr-regs.h>#include <asm/errno.h>## the break handler has its own stack# .section .bss.stack .globl __break_user_context .balign THREAD_SIZE__break_stack: .space THREAD_SIZE - FRV_FRAME0_SIZE__break_frame_0: .space FRV_FRAME0_SIZE## miscellaneous variables# .section .bss#ifdef CONFIG_MMU .globl __break_tlb_miss_real_return_info__break_tlb_miss_real_return_info: .balign 8 .space 2*4 /* saved PCSR, PSR for TLB-miss handler fixup */#endif__break_trace_through_exceptions: .space 4#define CS2_ECS1 0xe1200000#define CS2_USERLED 0x4.macro LEDS val,reg# sethi.p %hi(CS2_ECS1+CS2_USERLED),gr30# setlo %lo(CS2_ECS1+CS2_USERLED),gr30# setlos #~\val,\reg# st \reg,@(gr30,gr0)# setlos #0x5555,\reg# sethi.p %hi(0xffc00100),gr30# setlo %lo(0xffc00100),gr30# sth \reg,@(gr30,gr0)# membar.endm################################################################################# entry point for Break Exceptions/Interrupts################################################################################ .section .text.break .balign 4 .globl __entry_break__entry_break:#ifdef CONFIG_MMU movgs gr31,scr3#endif LEDS 0x1001,gr31 sethi.p %hi(__break_frame_0),gr31 setlo %lo(__break_frame_0),gr31 stdi gr2,@(gr31,#REG_GR(2)) movsg ccr,gr3 sti gr3,@(gr31,#REG_CCR) # catch the return from a TLB-miss handler that had single-step disabled # traps will be enabled, so we have to do this now#ifdef CONFIG_MMU movsg bpcsr,gr3 sethi.p %hi(__break_tlb_miss_return_breaks_here),gr2 setlo %lo(__break_tlb_miss_return_breaks_here),gr2 subcc gr2,gr3,gr0,icc0 beq icc0,#2,__break_return_singlestep_tlbmiss#endif # determine whether we have stepped through into an exception # - we need to take special action to suspend h/w single stepping if we've done # that, so that the gdbstub doesn't get bogged down endlessly stepping through # external interrupt handling movsg bpsr,gr3 andicc gr3,#BPSR_BET,gr0,icc0 bne icc0,#2,__break_maybe_userspace /* jump if PSR.ET was 1 */ LEDS 0x1003,gr2 movsg brr,gr3 andicc gr3,#BRR_ST,gr0,icc0 andicc.p gr3,#BRR_SB,gr0,icc1 bne icc0,#2,__break_step /* jump if single-step caused break */ beq icc1,#2,__break_continue /* jump if BREAK didn't cause break */ LEDS 0x1007,gr2 # handle special breaks movsg bpcsr,gr3 sethi.p %hi(__entry_return_singlestep_breaks_here),gr2 setlo %lo(__entry_return_singlestep_breaks_here),gr2 subcc gr2,gr3,gr0,icc0 beq icc0,#2,__break_return_singlestep bra __break_continue################################################################################# handle BREAK instruction in kernel-mode exception epilogue################################################################################__break_return_singlestep: LEDS 0x100f,gr2 # special break insn requests single-stepping to be turned back on # HERE RETT # PSR.ET 0 0 # PSR.PS old PSR.S ? # PSR.S 1 1 # BPSR.ET 0 1 (can't have caused orig excep otherwise) # BPSR.BS 1 old PSR.S movsg dcr,gr2 sethi.p %hi(DCR_SE),gr3 setlo %lo(DCR_SE),gr3 or gr2,gr3,gr2 movgs gr2,dcr movsg psr,gr2 andi gr2,#PSR_PS,gr2 slli gr2,#11,gr2 /* PSR.PS -> BPSR.BS */ ori gr2,#BPSR_BET,gr2 /* 1 -> BPSR.BET */ movgs gr2,bpsr # return to the invoker of the original kernel exception movsg pcsr,gr2 movgs gr2,bpcsr LEDS 0x101f,gr2 ldi @(gr31,#REG_CCR),gr3 movgs gr3,ccr lddi.p @(gr31,#REG_GR(2)),gr2 xor gr31,gr31,gr31 movgs gr0,brr#ifdef CONFIG_MMU movsg scr3,gr31#endif rett #1################################################################################# handle BREAK instruction in TLB-miss handler return path#################################################################################ifdef CONFIG_MMU__break_return_singlestep_tlbmiss: LEDS 0x1100,gr2 sethi.p %hi(__break_tlb_miss_real_return_info),gr3 setlo %lo(__break_tlb_miss_real_return_info),gr3 lddi @(gr3,#0),gr2 movgs gr2,pcsr movgs gr3,psr bra __break_return_singlestep#endif################################################################################# handle single stepping into an exception prologue from kernel mode# - we try and catch it whilst it is still in the main vector table# - if we catch it there, we have to jump to the fixup handler# - there is a fixup table that has a pointer for every 16b slot in the trap# table################################################################################__break_step: LEDS 0x2003,gr2 # external interrupts seem to escape from the trap table before single # step catches up with them movsg bpcsr,gr2 sethi.p %hi(__entry_kernel_external_interrupt),gr3 setlo %lo(__entry_kernel_external_interrupt),gr3 subcc.p gr2,gr3,gr0,icc0 sethi %hi(__entry_uspace_external_interrupt),gr3 setlo.p %lo(__entry_uspace_external_interrupt),gr3 beq icc0,#2,__break_step_kernel_external_interrupt subcc.p gr2,gr3,gr0,icc0 sethi %hi(__entry_kernel_external_interrupt_virtually_disabled),gr3 setlo.p %lo(__entry_kernel_external_interrupt_virtually_disabled),gr3 beq icc0,#2,__break_step_uspace_external_interrupt subcc.p gr2,gr3,gr0,icc0 sethi %hi(__entry_kernel_external_interrupt_virtual_reenable),gr3 setlo.p %lo(__entry_kernel_external_interrupt_virtual_reenable),gr3 beq icc0,#2,__break_step_kernel_external_interrupt_virtually_disabled subcc gr2,gr3,gr0,icc0 beq icc0,#2,__break_step_kernel_external_interrupt_virtual_reenable LEDS 0x2007,gr2 # the two main vector tables are adjacent on one 8Kb slab movsg bpcsr,gr2 setlos #0xffffe000,gr3 and gr2,gr3,gr2 sethi.p %hi(__trap_tables),gr3 setlo %lo(__trap_tables),gr3 subcc gr2,gr3,gr0,icc0 bne icc0,#2,__break_continue LEDS 0x200f,gr2 # skip workaround if so requested by GDB sethi.p %hi(__break_trace_through_exceptions),gr3 setlo %lo(__break_trace_through_exceptions),gr3 ld @(gr3,gr0),gr3 subcc gr3,gr0,gr0,icc0 bne icc0,#0,__break_continue LEDS 0x201f,gr2 # access the fixup table - there's a 1:1 mapping between the slots in the trap tables and # the slots in the trap fixup tables allowing us to simply divide the offset into the # former by 4 to access the latter sethi.p %hi(__trap_tables),gr3 setlo %lo(__trap_tables),gr3 movsg bpcsr,gr2 sub gr2,gr3,gr2 srli.p gr2,#2,gr2 sethi %hi(__trap_fixup_tables),gr3 setlo.p %lo(__trap_fixup_tables),gr3 andi gr2,#~3,gr2 ld @(gr2,gr3),gr2 jmpil @(gr2,#0)# step through an internal exception from kernel mode .globl __break_step_kernel_softprog_interrupt__break_step_kernel_softprog_interrupt: sethi.p %hi(__entry_kernel_softprog_interrupt_reentry),gr3 setlo %lo(__entry_kernel_softprog_interrupt_reentry),gr3 bra __break_return_as_kernel_prologue# step through an external interrupt from kernel mode .globl __break_step_kernel_external_interrupt__break_step_kernel_external_interrupt: # deal with virtual interrupt disablement beq icc2,#0,__break_step_kernel_external_interrupt_virtually_disabled sethi.p %hi(__entry_kernel_external_interrupt_reentry),gr3 setlo %lo(__entry_kernel_external_interrupt_reentry),gr3__break_return_as_kernel_prologue: LEDS 0x203f,gr2 movgs gr3,bpcsr # do the bit we had to skip#ifdef CONFIG_MMU movsg ear0,gr2 /* EAR0 can get clobbered by gdb-stub (ICI/ICEI) */ movgs gr2,scr2#endif or.p sp,gr0,gr2 /* set up the stack pointer */ subi sp,#REG__END,sp sti.p gr2,@(sp,#REG_SP) setlos #REG__STATUS_STEP,gr2 sti gr2,@(sp,#REG__STATUS) /* record single step status */ # cancel single-stepping mode movsg dcr,gr2 sethi.p %hi(~DCR_SE),gr3 setlo %lo(~DCR_SE),gr3 and gr2,gr3,gr2 movgs gr2,dcr LEDS 0x207f,gr2 ldi @(gr31,#REG_CCR),gr3 movgs gr3,ccr lddi.p @(gr31,#REG_GR(2)),gr2 xor gr31,gr31,gr31 movgs gr0,brr#ifdef CONFIG_MMU movsg scr3,gr31#endif rett #1# we single-stepped into an interrupt handler whilst interrupts were merely virtually disabled# need to really disable interrupts, set flag, fix up and return__break_step_kernel_external_interrupt_virtually_disabled: movsg psr,gr2 andi gr2,#~PSR_PIL,gr2 ori gr2,#PSR_PIL_14,gr2 /* debugging interrupts only */ movgs gr2,psr ldi @(gr31,#REG_CCR),gr3 movgs gr3,ccr subcc.p gr0,gr0,gr0,icc2 /* leave Z set, clear C */ # exceptions must've been enabled and we must've been in supervisor mode setlos BPSR_BET|BPSR_BS,gr3 movgs gr3,bpsr # return to where the interrupt happened movsg pcsr,gr2 movgs gr2,bpcsr lddi.p @(gr31,#REG_GR(2)),gr2 xor gr31,gr31,gr31 movgs gr0,brr#ifdef CONFIG_MMU movsg scr3,gr31#endif rett #1# we stepped through into the virtual interrupt reenablement trap## we also want to single step anyway, but after fixing up so that we get an event on the# instruction after the broken-into exception returns .globl __break_step_kernel_external_interrupt_virtual_reenable__break_step_kernel_external_interrupt_virtual_reenable: movsg psr,gr2 andi gr2,#~PSR_PIL,gr2 movgs gr2,psr ldi @(gr31,#REG_CCR),gr3 movgs gr3,ccr subicc gr0,#1,gr0,icc2 /* clear Z, set C */ # save the adjusted ICC2 movsg ccr,gr3 sti gr3,@(gr31,#REG_CCR) # exceptions must've been enabled and we must've been in supervisor mode setlos BPSR_BET|BPSR_BS,gr3 movgs gr3,bpsr # return to where the trap happened movsg pcsr,gr2 movgs gr2,bpcsr # and then process the single step bra __break_continue# step through an internal exception from uspace mode .globl __break_step_uspace_softprog_interrupt__break_step_uspace_softprog_interrupt: sethi.p %hi(__entry_uspace_softprog_interrupt_reentry),gr3 setlo %lo(__entry_uspace_softprog_interrupt_reentry),gr3 bra __break_return_as_uspace_prologue# step through an external interrupt from kernel mode .globl __break_step_uspace_external_interrupt__break_step_uspace_external_interrupt: sethi.p %hi(__entry_uspace_external_interrupt_reentry),gr3 setlo %lo(__entry_uspace_external_interrupt_reentry),gr3__break_return_as_uspace_prologue: LEDS 0x20ff,gr2 movgs gr3,bpcsr # do the bit we had to skip sethi.p %hi(__kernel_frame0_ptr),gr28 setlo %lo(__kernel_frame0_ptr),gr28 ldi.p @(gr28,#0),gr28 setlos #REG__STATUS_STEP,gr2 sti gr2,@(gr28,#REG__STATUS) /* record single step status */ # cancel single-stepping mode movsg dcr,gr2 sethi.p %hi(~DCR_SE),gr3 setlo %lo(~DCR_SE),gr3 and gr2,gr3,gr2 movgs gr2,dcr LEDS 0x20fe,gr2
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -