@@ -222,11 +222,36 @@ _firq_reschedule:
222
222
* registers from the interrupted thread.
223
223
* /
224
224
225
+ #if defined(CONFIG_USERSPACE)
226
+ / * when USERSPACE is configured , here need to consider the case where firq comes
227
+ * out in user mode , according to ARCv2 ISA and nsim , the following micro ops
228
+ * will be executed:
229
+ * sp < - reg bank1' sp
230
+ * switch between sp and _ARC_V2_USER_SP
231
+ * then:
232
+ * sp is the sp of kernel stack of interrupted thread
233
+ * _ARC_V2_USER_SP is reg bank1' sp
234
+ * the sp of user stack of interrupted thread is reg bank0' sp
235
+ * if firq comes out in kernel mode , the following micro ops will be executed:
236
+ * sp < - reg bank' sp
237
+ * so , sw needs to do necessary handling to set up the correct sp
238
+ * /
239
+ lr r0 , [ _ARC_V2_AUX_IRQ_ACT ]
240
+ bbit0 r0 , 31 , _firq_from_kernel
241
+ aex sp , [ _ARC_V2_USER_SP ]
242
+ lr r0 , [ _ARC_V2_STATUS32 ]
243
+ and r0 , r0 , ~_ARC_V2_STATUS32_RB( 7 )
244
+ kflag r0
245
+ aex sp , [ _ARC_V2_USER_SP ]
246
+ b _firq_create_irq_stack_frame
247
+ _firq_from_kernel:
248
+ #endif
225
249
/ * chose register bank # 0 * /
226
250
lr r0 , [ _ARC_V2_STATUS32 ]
227
251
and r0 , r0 , ~_ARC_V2_STATUS32_RB( 7 )
228
252
kflag r0
229
253
254
+ _firq_create_irq_stack_frame:
230
255
/ * we 're back on the outgoing thread' s stack * /
231
256
_create_irq_stack_frame
232
257
@@ -241,6 +266,24 @@ _firq_reschedule:
241
266
st ilink , [ sp , ___isf_t_pc_OFFSET ] / * ilink into pc * /
242
267
#endif
243
268
269
+ #if defined(CONFIG_USERSPACE)
270
+ / *
271
+ * when USERSPACE is enabled , according to ARCv2 ISA , SP will be switched
272
+ * if interrupt comes out in user mode , and will be recorded in bit 31
273
+ * (U bit) of IRQ_ACT. when interrupt exits , SP will be switched back
274
+ * according to U bit.
275
+ *
276
+ * need to remember the user/kernel status of interrupted thread , will be
277
+ * restored when thread switched back
278
+ *
279
+ * /
280
+ lr r4 , [ _ARC_V2_AUX_IRQ_ACT ]
281
+ and r3 , r4 , 0x80000000
282
+ push_s r3
283
+
284
+ bclr r4 , r4 , 31
285
+ sr r4 , [ _ARC_V2_AUX_IRQ_ACT ]
286
+ #endif
244
287
mov_s r1 , _kernel
245
288
ld_s r2 , [ r1 , _kernel_offset_to_current ]
246
289
@@ -323,6 +366,15 @@ _firq_return_from_coop:
323
366
_firq_return_from_rirq:
324
367
_firq_return_from_firq:
325
368
369
+ #if defined(CONFIG_USERSPACE)
370
+ / *
371
+ * need to recover the user/kernel status of interrupted thread
372
+ * /
373
+ pop_s r3
374
+ lr r2 , [ _ARC_V2_AUX_IRQ_ACT ]
375
+ or r2 , r2 , r3
376
+ sr r2 , [ _ARC_V2_AUX_IRQ_ACT ]
377
+ #endif
326
378
_pop_irq_stack_frame
327
379
328
380
ld ilink , [ sp , - 4 ] / * status32 into ilink * /
0 commit comments