Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 96326
b: refs/heads/master
c: 0893f12
h: refs/heads/master
v: v3
  • Loading branch information
Bernd Schmidt authored and Bryan Wu committed May 7, 2008
1 parent ffd763d commit dde49e2
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 32 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8513c42edb3f1c91a8418fae11846c87cf7b8581
refs/heads/master: 0893f1250f87e0a832f47bb60fb69ed0d52be7a3
108 changes: 77 additions & 31 deletions trunk/arch/blackfin/mach-common/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -151,26 +151,62 @@ ENTRY(_ex_soft_bp)
ENDPROC(_ex_soft_bp)

ENTRY(_ex_single_step)
/* If we just returned from an interrupt, the single step event is
for the RTI instruction. */
r7 = retx;
r6 = reti;
cc = r7 == r6;
if cc jump _bfin_return_from_exception
r7 = syscfg;
bitclr (r7, 0);
syscfg = R7;
if cc jump _bfin_return_from_exception;

/* If we were in user mode, do the single step normally. */
p5.l = lo(IPEND);
p5.h = hi(IPEND);
r6 = [p5];
cc = bittst(r6, 5);
if !cc jump _ex_trap_c;
p4.l = lo(EVT5);
p4.h = hi(EVT5);
r6.h = _exception_to_level5;
r6.l = _exception_to_level5;
r7 = [p4];
cc = r6 == r7;
if !cc jump _ex_trap_c;
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;

1:
/*
* We were in an interrupt handler. By convention, all of them save
* SYSCFG with their first instruction, so by checking whether our
* RETX points at the entry point, we can determine whether to allow
* a single step, or whether to clear SYSCFG.
*
* First, find out the interrupt level and the event vector for it.
*/
p5.l = lo(EVT0);
p5.h = hi(EVT0);
p5 += -4;
2:
r7 = rot r7 by -1;
p5 += 4;
if !cc jump 2b;

/* What we actually do is test for the _second_ instruction in the
* IRQ handler. That way, if there are insns following the restore
* of SYSCFG after leaving the handler, we will not turn off SYSCFG
* for them. */

r7 = [p5];
r7 += 2;
r6 = RETX;
cc = R7 == R6;
if !cc jump _bfin_return_from_exception;

r7 = syscfg;
bitclr (r7, 0);
syscfg = R7;

/* Fall through to _bfin_return_from_exception. */
ENDPROC(_ex_single_step)

ENTRY(_bfin_return_from_exception)
Expand Down Expand Up @@ -234,20 +270,26 @@ ENTRY(_ex_trap_c)
p5.l = _saved_icplb_fault_addr;
[p5] = r7;

p4.l = __retx;
p4.h = __retx;
p4.l = _excpt_saved_stuff;
p4.h = _excpt_saved_stuff;

r6 = retx;
[p4] = r6;
p4.l = lo(SAFE_USER_INSTRUCTION);
p4.h = hi(SAFE_USER_INSTRUCTION);
retx = p4;

r6 = SYSCFG;
[p4 + 4] = r6;
BITCLR(r6, 0);
SYSCFG = r6;

/* Disable all interrupts, but make sure level 5 is enabled so
* we can switch to that level. Save the old mask. */
cli r6;
p4.l = _excpt_saved_imask;
p4.h = _excpt_saved_imask;
[p4] = r6;
[p4 + 8] = r6;

p4.l = lo(SAFE_USER_INSTRUCTION);
p4.h = hi(SAFE_USER_INSTRUCTION);
retx = p4;

r6 = 0x3f;
sti r6;

Expand Down Expand Up @@ -312,16 +354,17 @@ ENDPROC(_double_fault)
ENTRY(_exception_to_level5)
SAVE_ALL_SYS

p4.l = __retx;
p4.h = __retx;
p4.l = _excpt_saved_stuff;
p4.h = _excpt_saved_stuff;
r6 = [p4];
[sp + PT_PC] = r6;

r6 = [p4 + 4];
[sp + PT_SYSCFG] = r6;

/* Restore interrupt mask. We haven't pushed RETI, so this
* doesn't enable interrupts until we return from this handler. */
p4.l = _excpt_saved_imask;
p4.h = _excpt_saved_imask;
r6 = [p4];
r6 = [p4 + 8];
sti r6;

/* Restore the hardware error vector. */
Expand Down Expand Up @@ -1349,7 +1392,14 @@ ENTRY(_sys_call_table)
.rept NR_syscalls-(.-_sys_call_table)/4
.long _sys_ni_syscall
.endr
_excpt_saved_imask:

/*
* Used to save the real RETX, IMASK and SYSCFG when temporarily
* storing safe values across the transition from exception to IRQ5.
*/
_excpt_saved_stuff:
.long 0;
.long 0;
.long 0;

_exception_stack:
Expand All @@ -1363,7 +1413,3 @@ _exception_stack_top:
_last_cplb_fault_retx:
.long 0;
#endif
/* Used to save the real RETX when temporarily storing a safe
* return address. */
__retx:
.long 0;
5 changes: 5 additions & 0 deletions trunk/include/asm-blackfin/entry.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
#define PF_DTRACE_OFF 1
#define PF_DTRACE_BIT 5

/*
* NOTE! The single-stepping code assumes that all interrupt handlers
* start by saving SYSCFG on the stack with their first instruction.
*/

/* This one is used for exceptions, emulation, and NMI. It doesn't push
RETI and doesn't do cli. */
#define SAVE_ALL_SYS save_context_no_interrupts
Expand Down
5 changes: 5 additions & 0 deletions trunk/include/asm-blackfin/mach-common/context.S
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

/*
* NOTE! The single-stepping code assumes that all interrupt handlers
* start by saving SYSCFG on the stack with their first instruction.
*/

/*
* Code to save processor context.
* We even save the register which are preserved by a function call
Expand Down

0 comments on commit dde49e2

Please sign in to comment.