aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arc/kernel
diff options
context:
space:
mode:
authorVineet Gupta <vgupta@synopsys.com>2019-05-22 11:47:13 -0400
committerVineet Gupta <vgupta@synopsys.com>2019-07-08 04:24:45 -0400
commit75370ad44075e832966a6dd1f6a649b8aee2325b (patch)
tree0276bdc7401bbf82fa92967e11a91378a343b540 /arch/arc/kernel
parent68e5c6f073bcf70da5f8eef88eb2d98f7c560bb6 (diff)
ARCv2: entry: simplify return to Delay Slot via interrupt
Commit 4255b07f2c9c43540 ("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 4de0e52867d83105767 ("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: Vineet Gupta <vgupta@synopsys.com>
Diffstat (limited to 'arch/arc/kernel')
-rw-r--r--arch/arc/kernel/entry-arcv2.S58
1 files changed, 10 insertions, 48 deletions
diff --git a/arch/arc/kernel/entry-arcv2.S b/arch/arc/kernel/entry-arcv2.S
index 0fc408ec0814..12d5f12d10d2 100644
--- a/arch/arc/kernel/entry-arcv2.S
+++ b/arch/arc/kernel/entry-arcv2.S
@@ -79,7 +79,7 @@ ENTRY(handle_interrupt)
79 # 79 #
80 # Note this disable is only for consistent book-keeping as further interrupts 80 # Note this disable is only for consistent book-keeping as further interrupts
81 # will be disabled anyways even w/o this. Hardware tracks active interrupts 81 # will be disabled anyways even w/o this. Hardware tracks active interrupts
82 # seperately in AUX_IRQ_ACTIVE.active and will not take new interrupts 82 # seperately in AUX_IRQ_ACT.active and will not take new interrupts
83 # unless this one returns (or higher prio becomes pending in 2-prio scheme) 83 # unless this one returns (or higher prio becomes pending in 2-prio scheme)
84 84
85 IRQ_DISABLE 85 IRQ_DISABLE
@@ -200,17 +200,18 @@ restore_regs:
200 ld r0, [sp, PT_status32] ; U/K mode at time of entry 200 ld r0, [sp, PT_status32] ; U/K mode at time of entry
201 lr r10, [AUX_IRQ_ACT] 201 lr r10, [AUX_IRQ_ACT]
202 202
203 bmsk r11, r10, 15 ; AUX_IRQ_ACT.ACTIVE 203 bmsk r11, r10, 15 ; extract AUX_IRQ_ACT.active
204 breq r11, 0, .Lexcept_ret ; No intr active, ret from Exception 204 breq r11, 0, .Lexcept_ret ; No intr active, ret from Exception
205 205
206;####### Return from Intr ####### 206;####### Return from Intr #######
207 207
208.Lisr_ret:
209
208debug_marker_l1: 210debug_marker_l1:
209 ; bbit1.nt r0, STATUS_DE_BIT, .Lintr_ret_to_delay_slot 211 ; bbit1.nt r0, STATUS_DE_BIT, .Lintr_ret_to_delay_slot
210 btst r0, STATUS_DE_BIT ; Z flag set if bit clear 212 btst r0, STATUS_DE_BIT ; Z flag set if bit clear
211 bnz .Lintr_ret_to_delay_slot ; branch if STATUS_DE_BIT set 213 bnz .Lintr_ret_to_delay_slot ; branch if STATUS_DE_BIT set
212 214
213.Lisr_ret_fast_path:
214 ; Handle special case #1: (Entry via Exception, Return via IRQ) 215 ; Handle special case #1: (Entry via Exception, Return via IRQ)
215 ; 216 ;
216 ; Exception in U mode, preempted in kernel, Intr taken (K mode), orig 217 ; Exception in U mode, preempted in kernel, Intr taken (K mode), orig
@@ -244,8 +245,8 @@ debug_marker_syscall:
244; 245;
245; IRQ RTIE won't reliably restore DE bit and/or BTA, needs workaround 246; IRQ RTIE won't reliably restore DE bit and/or BTA, needs workaround
246; 247;
247; Solution is return from Intr w/o any delay slot quirks into a kernel trampoline 248; Solution is to drop out of interrupt context into pure kernel mode
248; and from pure kernel mode return to delay slot which handles DS bit/BTA correctly 249; and return from pure kernel mode which does right things for delay slot
249 250
250.Lintr_ret_to_delay_slot: 251.Lintr_ret_to_delay_slot:
251debug_marker_ds: 252debug_marker_ds:
@@ -254,48 +255,9 @@ debug_marker_ds:
254 add r2, r2, 1 255 add r2, r2, 1
255 st r2, [@intr_to_DE_cnt] 256 st r2, [@intr_to_DE_cnt]
256 257
257 ld r2, [sp, PT_ret] 258 ; drop out of interrupt context (clear AUX_IRQ_ACT.active)
258 ld r3, [sp, PT_status32] 259 bmskn r11, r10, 15
259 260 sr r11, [AUX_IRQ_ACT]
260 ; STAT32 for Int return created from scratch 261 b .Lexcept_ret
261 ; (No delay dlot, disable Further intr in trampoline)
262
263 bic r0, r3, STATUS_U_MASK|STATUS_DE_MASK|STATUS_IE_MASK|STATUS_L_MASK
264 st r0, [sp, PT_status32]
265
266 mov r1, .Lintr_ret_to_delay_slot_2
267 st r1, [sp, PT_ret]
268
269 ; Orig exception PC/STAT32 safekept @orig_r0 and @event stack slots
270 st r2, [sp, 0]
271 st r3, [sp, 4]
272
273 b .Lisr_ret_fast_path
274
275.Lintr_ret_to_delay_slot_2:
276 ; Trampoline to restore orig exception PC/STAT32/BTA/AUX_USER_SP
277 sub sp, sp, SZ_PT_REGS
278 st r9, [sp, -4]
279
280 ld r9, [sp, 0]
281 sr r9, [eret]
282
283 ld r9, [sp, 4]
284 sr r9, [erstatus]
285
286 ; restore AUX_USER_SP if returning to U mode
287 bbit0 r9, STATUS_U_BIT, 1f
288 ld r9, [sp, PT_sp]
289 sr r9, [AUX_USER_SP]
290
2911:
292 ld r9, [sp, 8]
293 sr r9, [erbta]
294
295 ld r9, [sp, -4]
296 add sp, sp, SZ_PT_REGS
297
298 ; return from pure kernel mode to delay slot
299 rtie
300 262
301END(ret_from_exception) 263END(ret_from_exception)