ARCv2: STAR 9000793984: Handle return from intr to Delay Slot
authorVineet Gupta <vgupta@synopsys.com>
Mon, 22 Sep 2014 11:21:47 +0000 (16:51 +0530)
committerVineet Gupta <vgupta@synopsys.com>
Mon, 22 Jun 2015 08:36:55 +0000 (14:06 +0530)
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
arch/arc/kernel/asm-offsets.c
arch/arc/kernel/entry-arcv2.S
arch/arc/kernel/setup.c

index 6c3aa0edb9b5bc1914d006b2a22b766f71adba9c..b9cf23313273d460f7fb802464ded68e3809c441 100644 (file)
@@ -56,6 +56,7 @@ int main(void)
        DEFINE(PT_r5, offsetof(struct pt_regs, r5));
        DEFINE(PT_r6, offsetof(struct pt_regs, r6));
        DEFINE(PT_r7, offsetof(struct pt_regs, r7));
+       DEFINE(PT_ret, offsetof(struct pt_regs, ret));
 
        DEFINE(SZ_CALLEE_REGS, sizeof(struct callee_regs));
        DEFINE(SZ_PT_REGS, sizeof(struct pt_regs));
index c59a396b7b98696add49c30948686ca7dadda114..bd7105d3172f19e83cf4c2507fdb23b9da5509d8 100644 (file)
@@ -163,6 +163,9 @@ END(EV_TLBProtV)
 ;####### Return from Intr #######
 
 debug_marker_l1:
+       bbit1.nt r0, STATUS_DE_BIT, .Lintr_ret_to_delay_slot
+
+.Lisr_ret_fast_path:
        ; Handle special case #1: (Entry via Exception, Return via IRQ)
        ;
        ; Exception in U mode, preempted in kernel, Intr taken (K mode), orig
@@ -186,4 +189,51 @@ debug_marker_syscall:
        EXCEPTION_EPILOGUE
        rtie
 
+;####### Return from Intr to insn in delay slot #######
+
+; Handle special case #2: (Entry via Exception in Delay Slot, Return via IRQ)
+;
+; Intr returning to a Delay Slot (DS) insn
+; (since IRQ NOT allowed in DS in ARCv2, this can only happen if orig
+; entry was via Exception in DS which got preempted in kernel).
+;
+; IRQ RTIE won't reliably restore DE bit and/or BTA, needs handling
+.Lintr_ret_to_delay_slot:
+debug_marker_ds:
+
+       ld      r2, [@intr_to_DE_cnt]
+       add     r2, r2, 1
+       st      r2, [@intr_to_DE_cnt]
+
+       ld      r2, [sp, PT_ret]
+       ld      r3, [sp, PT_status32]
+
+       bic     r0, r3, STATUS_U_MASK|STATUS_DE_MASK|STATUS_IE_MASK|STATUS_L_MASK
+       st      r0, [sp, PT_status32]
+
+       mov     r1, .Lintr_ret_to_delay_slot_2
+       st      r1, [sp, PT_ret]
+
+       st      r2, [sp, 0]
+       st      r3, [sp, 4]
+
+       b       .Lisr_ret_fast_path
+
+.Lintr_ret_to_delay_slot_2:
+       sub     sp, sp, SZ_PT_REGS
+       st      r9, [sp, -4]
+
+       ld      r9, [sp, 0]
+       sr      r9, [eret]
+
+       ld      r9, [sp, 4]
+       sr      r9, [erstatus]
+
+       ld      r9, [sp, 8]
+       sr      r9, [erbta]
+
+       ld      r9, [sp, -4]
+       add     sp, sp, SZ_PT_REGS
+       rtie
+
 END(ret_from_exception)
index d6fe80070bbf5c13dcb80e623219f4a700222f22..ca71cef4bafdd81fd5ca983139a991cac2c1586e 100644 (file)
@@ -30,6 +30,8 @@
 
 #define FIX_PTR(x)  __asm__ __volatile__(";" : "+r"(x))
 
+unsigned int intr_to_DE_cnt;
+
 /* Part of U-boot ABI: see head.S */
 int __initdata uboot_tag;
 char __initdata *uboot_arg;