-/* $Id: entry.S,v 1.33 2003/11/22 15:39:51 lethal Exp $
+/* $Id: entry.S,v 1.34 2004/01/13 05:52:11 kkojima Exp $
*
* linux/arch/sh/entry.S
*
GET_THREAD_INFO(r8)
#ifdef CONFIG_PREEMPT
+ bra resume_userspace
+ nop
ENTRY(resume_kernel)
mov.l @(TI_PRE_COUNT,r8), r0 ! current_thread_info->preempt_count
tst r0, r0
- bf restore_all
+ bf noresched
need_resched:
mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
tst #_TIF_NEED_RESCHED, r0 ! need_resched set?
- bt restore_all
+ bt noresched
- stc sr, r0 ! interrupts disabled?
- tst #0xf0, r0
- bf restore_all
+ mov #OFF_SR, r0
+ mov.l @(r0,r15), r0 ! get status register
+ and #0xf0, r0 ! interrupts off (exception path)?
+ cmp/eq #0xf0, r0
+ bt noresched
mov.l 1f, r0
mov.l r0, @(TI_PRE_COUNT,r8)
mov.l r0, @(TI_PRE_COUNT,r8)
CLI()
- bra need_resched
+ bra need_resched
+ nop
+noresched:
+ bra restore_all
nop
.align 2
! Is the trap argument >= 0x20? (TRA will be >= 0x80)
mov #0x7f, r9
cmp/hi r9, r8
- bt/s debug_trap
+ bt/s 0f
mov #OFF_TRA, r9
add r15, r9
!
bra resume_userspace
mov.l r0, @(OFF_R0,r15) ! Return value
!
+0:
+ bra debug_trap
+ nop
+ !
good_system_call: ! Good syscall number
mov.l @(TI_FLAGS,r8), r8
mov #_TIF_SYSCALL_TRACE, r10
!
! Calculate new SR value
mov k3, k2 ! original SR value
- mov.l 8f, k1
- stc sr, k0
- and k1, k0 ! Get current FD-bit
mov.l 9f, k1
and k1, k2 ! Mask orignal SR value
- or k0, k2 ! Inherit current FD-bit
!
mov k3, k0 ! Calculate IMASK-bits
shlr2 k0
4: .long do_syscall_trace
5: .long 0x00001000 ! DSP
7: .long 0x30000000
-8: .long 0x00008000 ! FD
-9: .long 0xffff7f0f ! ~(IMASK+FD)
+9:
__INV_IMASK:
.long 0xffffff0f ! ~(IMASK)
.align 2
1: .long 0x00001000 ! DSP=1
-2: .long 0x000000f0 ! FD=0, IMASK=15
+2: .long 0x000080f0 ! FD=1, IMASK=15
3: .long 0xcfffffff ! RB=0, BL=0
4: .long exception_handling_table
-/* $Id: irq.c,v 1.19 2004/01/10 01:25:32 lethal Exp $
+/* $Id: irq.c,v 1.20 2004/01/13 05:52:11 kkojima Exp $
*
* linux/arch/sh/kernel/irq.c
*
irq_enter();
+#ifdef CONFIG_PREEMPT
+ /*
+ * At this point we're now about to actually call handlers,
+ * and interrupts might get reenabled during them... bump
+ * preempt_count to prevent any preemption while the handler
+ * called here is pending...
+ */
+ preempt_disable();
+#endif
+
/* Get IRQ number */
asm volatile("stc r2_bank, %0\n\t"
"shlr2 %0\n\t"
irq_exit();
+#ifdef CONFIG_PREEMPT
+ /*
+ * We're done with the handlers, interrupts should be
+ * currently disabled; decrement preempt_count now so
+ * as we return preemption may be allowed...
+ */
+ preempt_enable_no_resched();
+#endif
+
return 1;
}