@@ -207,12 +207,36 @@ _firq_reschedule:
207207 * point , so when switching back to register bank 0 , it will contain the
208208 * registers from the interrupted thread.
209209 * /
210-
210+ #if defined(CONFIG_USERSPACE)
211+ / * when USERSPACE is configured , here need to consider the case where firq comes
212+ * out in user mode , according to ARCv2 ISA and nsim , the following micro ops
213+ * will be executed:
214+ * sp < - reg bank1' sp
215+ * switch between sp and _ARC_V2_USER_SP
216+ * then:
217+ * sp is the sp of kernel stack of interrupted thread
218+ * _ARC_V2_USER_SP is reg bank1' sp
219+ * the sp of user stack of interrupted thread is reg bank0' sp
220+ * if firq comes out in kernel mode , the following micro ops will be executed:
221+ * sp < - reg bank' sp
222+ * so , sw needs to do necessary handling to set up the correct sp
223+ * /
224+ lr r0 , [ _ARC_V2_AUX_IRQ_ACT ]
225+ bbit0 r0 , 31 , _firq_from_kernel
226+ aex sp , [ _ARC_V2_USER_SP ]
227+ lr r0 , [ _ARC_V2_STATUS32 ]
228+ and r0 , r0 , ~_ARC_V2_STATUS32_RB( 7 )
229+ kflag r0
230+ aex sp , [ _ARC_V2_USER_SP ]
231+ b _firq_create_irq_stack_frame
232+ _firq_from_kernel:
233+ #endif
211234 / * chose register bank # 0 * /
212235 lr r0 , [ _ARC_V2_STATUS32 ]
213236 and r0 , r0 , ~_ARC_V2_STATUS32_RB( 7 )
214237 kflag r0
215238
239+ _firq_create_irq_stack_frame:
216240 / * we 're back on the outgoing thread' s stack * /
217241 _create_irq_stack_frame
218242
@@ -225,6 +249,7 @@ _firq_reschedule:
225249 st_s r0 , [ sp , ___isf_t_status32_OFFSET ]
226250
227251 st ilink , [ sp , ___isf_t_pc_OFFSET ] / * ilink into pc * /
252+
228253#ifdef CONFIG_SMP
229254/ *
230255 * load r0 , r1 from irq stack
@@ -235,6 +260,16 @@ _firq_reschedule:
235260#endif
236261#endif
237262
263+ #if defined(CONFIG_USERSPACE)
264+ / *
265+ * need to remember the user/kernel status of interrupted thread , will be
266+ * restored when thread switched back
267+ * /
268+ lr r3 , [ _ARC_V2_AUX_IRQ_ACT ]
269+ and r3 , r3 , 0x80000000
270+ push_s r3
271+ #endif
272+
238273#ifdef CONFIG_SMP
239274 mov_s r2 , r1
240275#else
@@ -300,6 +335,16 @@ _firq_return_from_coop:
300335_firq_return_from_rirq:
301336_firq_return_from_firq:
302337
338+ #if defined(CONFIG_USERSPACE)
339+ / *
340+ * need to recover the user/kernel status of interrupted thread
341+ * /
342+ pop_s r3
343+ lr r2 , [ _ARC_V2_AUX_IRQ_ACT ]
344+ or r2 , r2 , r3
345+ sr r2 , [ _ARC_V2_AUX_IRQ_ACT ]
346+ #endif
347+
303348 _pop_irq_stack_frame
304349
305350 ld ilink , [ sp , - 4 ] / * status32 into ilink * /
0 commit comments