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