diff options
Diffstat (limited to 'arch/blackfin/mach-common/entry.S')
-rw-r--r-- | arch/blackfin/mach-common/entry.S | 50 |
1 files changed, 38 insertions, 12 deletions
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index 038f70e0be65..eceb484d90f9 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S @@ -158,23 +158,45 @@ ENTRY(_ex_single_step) cc = r7 == r6; if cc jump _bfin_return_from_exception; + /* Don't do single step in hardware exception handler */ + p5.l = lo(IPEND); + p5.h = hi(IPEND); + r6 = [p5]; + cc = bittst(r6, 5); + if cc jump _bfin_return_from_exception; + +#ifdef CONFIG_KGDB + /* skip single step if current interrupt priority is higher than + * that of the first instruction, from which gdb starts single step */ + r6 >>= 6; + r7 = 10; +.Lfind_priority_start: + cc = bittst(r6, 0); + if cc jump .Lfind_priority_done; + r6 >>= 1; + r7 += -1; + cc = r7 == 0; + if cc jump .Lfind_priority_done; + jump.s .Lfind_priority_start; +.Lfind_priority_done: + p4.l = _debugger_step; + p4.h = _debugger_step; + r6 = [p4]; + cc = r6 == 0; + if cc jump .Ldo_single_step; + r6 += -1; + cc = r6 < r7; + if cc jump _bfin_return_from_exception; +.Ldo_single_step: +#endif + /* If we were in user mode, do the single step normally. */ - p5.l = lo(IPEND); - p5.h = hi(IPEND); r6 = [p5]; r7 = 0xffe0 (z); r7 = r7 & r6; cc = r7 == 0; - if !cc jump 1f; - - /* Single stepping only a single instruction, so clear the trace - * bit here. */ - r7 = syscfg; - bitclr (r7, 0); - syscfg = R7; - jump _ex_trap_c; + if cc jump 1f; -1: /* * We were in an interrupt handler. By convention, all of them save * SYSCFG with their first instruction, so by checking whether our @@ -202,11 +224,15 @@ ENTRY(_ex_single_step) cc = R7 == R6; if !cc jump _bfin_return_from_exception; +1: + /* Single stepping only a single instruction, so clear the trace + * bit here. */ r7 = syscfg; bitclr (r7, 0); syscfg = R7; - /* Fall through to _bfin_return_from_exception. */ + jump _ex_trap_c; + ENDPROC(_ex_single_step) ENTRY(_bfin_return_from_exception) |