Commit 75370ad4 authored by Vineet Gupta's avatar Vineet Gupta

ARCv2: entry: simplify return to Delay Slot via interrupt

Commit 4255b07f ("ARCv2: STAR 9000793984: Handle return
from intr to Delay Slot") involved a complex 2 staged trampoline.

Apparently this can be greatly simplified by returning from pure
kernel mode (iso interrupt) so drop to pure kernel mdoe and execute
the normal exception return path.

Testing this was a bit of challenge as return from interrupt is rarely
executed now after commit 4de0e528 ("ARCv2: STAR 9000814690:
Really Re-enable interrupts to avoid deadlocks"). That fix is necessary
evil and pct interrupts etc do exercise intr return path.
Anyhow after a revert of above in my local test setup I was able to hit
this case and verify the patch works.
Signed-off-by: default avatarVineet Gupta <vgupta@synopsys.com>
parent 68e5c6f0
...@@ -79,7 +79,7 @@ ENTRY(handle_interrupt) ...@@ -79,7 +79,7 @@ ENTRY(handle_interrupt)
# #
# Note this disable is only for consistent book-keeping as further interrupts # Note this disable is only for consistent book-keeping as further interrupts
# will be disabled anyways even w/o this. Hardware tracks active interrupts # will be disabled anyways even w/o this. Hardware tracks active interrupts
# seperately in AUX_IRQ_ACTIVE.active and will not take new interrupts # seperately in AUX_IRQ_ACT.active and will not take new interrupts
# unless this one returns (or higher prio becomes pending in 2-prio scheme) # unless this one returns (or higher prio becomes pending in 2-prio scheme)
IRQ_DISABLE IRQ_DISABLE
...@@ -200,17 +200,18 @@ restore_regs: ...@@ -200,17 +200,18 @@ restore_regs:
ld r0, [sp, PT_status32] ; U/K mode at time of entry ld r0, [sp, PT_status32] ; U/K mode at time of entry
lr r10, [AUX_IRQ_ACT] lr r10, [AUX_IRQ_ACT]
bmsk r11, r10, 15 ; AUX_IRQ_ACT.ACTIVE bmsk r11, r10, 15 ; extract AUX_IRQ_ACT.active
breq r11, 0, .Lexcept_ret ; No intr active, ret from Exception breq r11, 0, .Lexcept_ret ; No intr active, ret from Exception
;####### Return from Intr ####### ;####### Return from Intr #######
.Lisr_ret:
debug_marker_l1: debug_marker_l1:
; bbit1.nt r0, STATUS_DE_BIT, .Lintr_ret_to_delay_slot ; bbit1.nt r0, STATUS_DE_BIT, .Lintr_ret_to_delay_slot
btst r0, STATUS_DE_BIT ; Z flag set if bit clear btst r0, STATUS_DE_BIT ; Z flag set if bit clear
bnz .Lintr_ret_to_delay_slot ; branch if STATUS_DE_BIT set bnz .Lintr_ret_to_delay_slot ; branch if STATUS_DE_BIT set
.Lisr_ret_fast_path:
; Handle special case #1: (Entry via Exception, Return via IRQ) ; Handle special case #1: (Entry via Exception, Return via IRQ)
; ;
; Exception in U mode, preempted in kernel, Intr taken (K mode), orig ; Exception in U mode, preempted in kernel, Intr taken (K mode), orig
...@@ -244,8 +245,8 @@ debug_marker_syscall: ...@@ -244,8 +245,8 @@ debug_marker_syscall:
; ;
; IRQ RTIE won't reliably restore DE bit and/or BTA, needs workaround ; IRQ RTIE won't reliably restore DE bit and/or BTA, needs workaround
; ;
; Solution is return from Intr w/o any delay slot quirks into a kernel trampoline ; Solution is to drop out of interrupt context into pure kernel mode
; and from pure kernel mode return to delay slot which handles DS bit/BTA correctly ; and return from pure kernel mode which does right things for delay slot
.Lintr_ret_to_delay_slot: .Lintr_ret_to_delay_slot:
debug_marker_ds: debug_marker_ds:
...@@ -254,48 +255,9 @@ debug_marker_ds: ...@@ -254,48 +255,9 @@ debug_marker_ds:
add r2, r2, 1 add r2, r2, 1
st r2, [@intr_to_DE_cnt] st r2, [@intr_to_DE_cnt]
ld r2, [sp, PT_ret] ; drop out of interrupt context (clear AUX_IRQ_ACT.active)
ld r3, [sp, PT_status32] bmskn r11, r10, 15
sr r11, [AUX_IRQ_ACT]
; STAT32 for Int return created from scratch b .Lexcept_ret
; (No delay dlot, disable Further intr in trampoline)
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]
; Orig exception PC/STAT32 safekept @orig_r0 and @event stack slots
st r2, [sp, 0]
st r3, [sp, 4]
b .Lisr_ret_fast_path
.Lintr_ret_to_delay_slot_2:
; Trampoline to restore orig exception PC/STAT32/BTA/AUX_USER_SP
sub sp, sp, SZ_PT_REGS
st r9, [sp, -4]
ld r9, [sp, 0]
sr r9, [eret]
ld r9, [sp, 4]
sr r9, [erstatus]
; restore AUX_USER_SP if returning to U mode
bbit0 r9, STATUS_U_BIT, 1f
ld r9, [sp, PT_sp]
sr r9, [AUX_USER_SP]
1:
ld r9, [sp, 8]
sr r9, [erbta]
ld r9, [sp, -4]
add sp, sp, SZ_PT_REGS
; return from pure kernel mode to delay slot
rtie
END(ret_from_exception) END(ret_from_exception)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment