summaryrefslogtreecommitdiff
path: root/arch/blackfin/mach-common/entry.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/blackfin/mach-common/entry.S')
-rw-r--r--arch/blackfin/mach-common/entry.S70
1 files changed, 61 insertions, 9 deletions
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
index fae774651374..21e65a339a22 100644
--- a/arch/blackfin/mach-common/entry.S
+++ b/arch/blackfin/mach-common/entry.S
@@ -151,13 +151,6 @@ ENTRY(_ex_syscall)
jump.s _bfin_return_from_exception;
ENDPROC(_ex_syscall)
-ENTRY(_ex_soft_bp)
- r7 = retx;
- r7 += -2;
- retx = r7;
- jump.s _ex_trap_c;
-ENDPROC(_ex_soft_bp)
-
ENTRY(_ex_single_step)
/* If we just returned from an interrupt, the single step event is
for the RTI instruction. */
@@ -607,6 +600,19 @@ ENTRY(_system_call)
p2 = [p2];
[p2+(TASK_THREAD+THREAD_KSP)] = sp;
+#ifdef CONFIG_IPIPE
+ r0 = sp;
+ SP += -12;
+ call ___ipipe_syscall_root;
+ SP += 12;
+ cc = r0 == 1;
+ if cc jump .Lsyscall_really_exit;
+ cc = r0 == -1;
+ if cc jump .Lresume_userspace;
+ r3 = [sp + PT_R3];
+ r4 = [sp + PT_R4];
+ p0 = [sp + PT_ORIG_P0];
+#endif /* CONFIG_IPIPE */
/* Check the System Call */
r7 = __NR_syscall;
@@ -661,6 +667,17 @@ ENTRY(_system_call)
r7 = r7 & r4;
.Lsyscall_resched:
+#ifdef CONFIG_IPIPE
+ cc = BITTST(r7, TIF_IRQ_SYNC);
+ if !cc jump .Lsyscall_no_irqsync;
+ [--sp] = reti;
+ r0 = [sp++];
+ SP += -12;
+ call ___ipipe_sync_root;
+ SP += 12;
+ jump .Lresume_userspace_1;
+.Lsyscall_no_irqsync:
+#endif
cc = BITTST(r7, TIF_NEED_RESCHED);
if !cc jump .Lsyscall_sigpending;
@@ -692,6 +709,10 @@ ENTRY(_system_call)
.Lsyscall_really_exit:
r5 = [sp + PT_RESERVED];
rets = r5;
+#ifdef CONFIG_IPIPE
+ [--sp] = reti;
+ r5 = [sp++];
+#endif /* CONFIG_IPIPE */
rts;
ENDPROC(_system_call)
@@ -778,6 +799,15 @@ _new_old_task:
ENDPROC(_resume)
ENTRY(_ret_from_exception)
+#ifdef CONFIG_IPIPE
+ [--sp] = rets;
+ SP += -12;
+ call ___ipipe_check_root
+ SP += 12
+ rets = [sp++];
+ cc = r0 == 0;
+ if cc jump 4f; /* not on behalf of Linux, get out */
+#endif /* CONFIG_IPIPE */
p2.l = lo(IPEND);
p2.h = hi(IPEND);
@@ -834,6 +864,28 @@ ENTRY(_ret_from_exception)
rts;
ENDPROC(_ret_from_exception)
+#ifdef CONFIG_IPIPE
+
+_sync_root_irqs:
+ [--sp] = reti; /* Reenable interrupts */
+ r0 = [sp++];
+ jump.l ___ipipe_sync_root
+
+_resume_kernel_from_int:
+ r0.l = _sync_root_irqs
+ r0.h = _sync_root_irqs
+ [--sp] = rets;
+ [--sp] = ( r7:4, p5:3 );
+ SP += -12;
+ call ___ipipe_call_irqtail
+ SP += 12;
+ ( r7:4, p5:3 ) = [sp++];
+ rets = [sp++];
+ rts
+#else
+#define _resume_kernel_from_int 2f
+#endif
+
ENTRY(_return_from_int)
/* If someone else already raised IRQ 15, do nothing. */
csync;
@@ -855,7 +907,7 @@ ENTRY(_return_from_int)
r1 = r0 - r1;
r2 = r0 & r1;
cc = r2 == 0;
- if !cc jump 2f;
+ if !cc jump _resume_kernel_from_int;
/* Lower the interrupt level to 15. */
p0.l = lo(EVT15);
@@ -1087,7 +1139,7 @@ ENTRY(_ex_table)
* EXCPT instruction can provide 4 bits of EXCAUSE, allowing 16 to be user defined
*/
.long _ex_syscall /* 0x00 - User Defined - Linux Syscall */
- .long _ex_soft_bp /* 0x01 - User Defined - Software breakpoint */
+ .long _ex_trap_c /* 0x01 - User Defined - Software breakpoint */
#ifdef CONFIG_KGDB
.long _ex_trap_c /* 0x02 - User Defined - KGDB initial connection
and break signal trap */