aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arc/kernel/entry-arcv2.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arc/kernel/entry-arcv2.S')
-rw-r--r--arch/arc/kernel/entry-arcv2.S62
1 files changed, 12 insertions, 50 deletions
diff --git a/arch/arc/kernel/entry-arcv2.S b/arch/arc/kernel/entry-arcv2.S
index 14254b866fdc..12d5f12d10d2 100644
--- a/arch/arc/kernel/entry-arcv2.S
+++ b/arch/arc/kernel/entry-arcv2.S
@@ -67,7 +67,7 @@ reserved:
67 67
68ENTRY(handle_interrupt) 68ENTRY(handle_interrupt)
69 69
70 INTERRUPT_PROLOGUE irq 70 INTERRUPT_PROLOGUE
71 71
72 # irq control APIs local_irq_save/restore/disable/enable fiddle with 72 # irq control APIs local_irq_save/restore/disable/enable fiddle with
73 # global interrupt enable bits in STATUS32 (.IE for 1 prio, .E[] for 2 prio) 73 # global interrupt enable bits in STATUS32 (.IE for 1 prio, .E[] for 2 prio)
@@ -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
@@ -223,7 +224,7 @@ debug_marker_l1:
223 bset.nz r11, r11, AUX_IRQ_ACT_BIT_U ; NZ means U 224 bset.nz r11, r11, AUX_IRQ_ACT_BIT_U ; NZ means U
224 sr r11, [AUX_IRQ_ACT] 225 sr r11, [AUX_IRQ_ACT]
225 226
226 INTERRUPT_EPILOGUE irq 227 INTERRUPT_EPILOGUE
227 rtie 228 rtie
228 229
229;####### Return from Exception / pure kernel mode ####### 230;####### Return from Exception / pure kernel mode #######
@@ -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)