FIQ support in Linux Kernel

Konstantin Zertsekel zertsekel at gmail.com
Mon Nov 14 12:26:20 EST 2011


Intro: basically, I tried to post this question to
linux-arm-kernel-request at lists.arm.linux.org.uk, but the email just
fails to reach the server or something...  :-(

Following the FIQ disscussion here:
http://www.spinics.net/lists/arm-kernel/msg14959.html
and here:

>> /*=============================================================================
>>  * Undefined FIQs
>>  *-----------------------------------------------------------------------------
>>  * Enter in FIQ mode, spsr = ANY CPSR, lr = ANY PC
>>  * MUST PRESERVE SVC SPSR, but need to switch to SVC mode to show our msg.
>>  * Basically to switch modes, we *HAVE* to clobber one register...  brain
>>  * damage alert!  I don't think that we can execute any code in here in any
>>  * other mode than FIQ...  Ok you can switch to another mode, but you can't
>>  * get out of that mode without clobbering one register.
>>  *
>>  * Fast Interrupt dispatcher
>>  * Enter in FIQ mode, spsr = SVC/USR/IRQ/dABT CPSR, lr = SVC/USR/IRQ/dABT PC
>>  */

> Subject: Linux crashes with FIQs enabled
> From: linux at arm.linux.org.uk (Russell King - ARM Linux)
> Date: Fri, 15 Aug 2003 18:00:33 +0100
> In-reply-to: <007201c3634c$2b61cd40$3f00a8c0 at geomation.com>; from registration at junck.com on Fri, Aug 15, 2003 at 10:42:03AM -0600
> References: <007201c3634c$2b61cd40$3f00a8c0 at geomation.com>

> It looks like you failed to read my comments above - this may be why
> you're seeing the occasional problem.

> Think what happens when you've just entered SVC mode (eg, due to a SWI) and
> you haven't saved any state.  The previous context is saved in SPSR_svc,
> and the processor has disabled IRQs for you, but not FIQs.

> You take a FIQ from SVC mode before you've saved any state.  The SVC-mode
> CPSR gets saved in SPSR_fiq.  What about SPSR_svc?  How are you saving/
> restoring that?  (you aren't, and you can't if you switch out of FIQ mode.)

> This is the fundamental problem with the approach of treating FIQs as if
> they were IRQs.  They aren't the same because the processor doesn't give
> the same guarantees.

Does "Basically to switch modes, we *HAVE* to clobber one register"
mean that to switch
processor mode we _must_ use "movs pc, lr" or "ldmia sp, {r0-pc}^"
instruction only?
I mean, those instructions demand SPSR_current to be clobbered
(that is SPSR_current's control bits M[4:0] should be equal to the
next processor mode)
before executing the instruction.

Is there any other problematic scenario except this:
1) USR mode ----(syscall)---->
2) SVC[1] mode ----(before any instruction is executed)---->
3) FIQ mode ----(save r0, spsr and lr through 'vector_stub fiq...')---->
4) SVC[2] mode ----(take care of FIQ stuff and get back through "movs
pc, lr" to previous mode)---->
5) SVC[1] mode  :-(     but SPSR_svc is clobbered in the previous step
due to "movs pc, lr"    :-(   :-(   :-(

I am aware of fiq-engine by Alessandro Rubini that runs FIQ exception
handler in FIQ processor mode only:
 vector_fiq:
-       disable_fiq
+       ldr     r9,     1f
+       ldr     r9,     [r9]
+       movs    r9,     r9
+       beq     fiq_ret
+       mov     r8,     lr
+       mov     lr,     pc
+       mov     pc,     r9      /* jump to userptr */
+       mov     lr,     r8
+fiq_ret:
     subs    pc, lr, #4

Just trying to understand the interesting stuff...

Any feedback is *greatly* appreciated!!

Thanks,
--- Kosta



More information about the Kernelnewbies mailing list