Intro: basically, I tried to post this question to linux-arm-kernel-request@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@arm.linux.org.uk (Russell King - ARM Linux) Date: Fri, 15 Aug 2003 18:00:33 +0100 In-reply-to: <007201c3634c$2b61cd40$3f00a8c0@geomation.com>; from registration@junck.com on Fri, Aug 15, 2003 at 10:42:03AM -0600 References: <007201c3634c$2b61cd40$3f00a8c0@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
participants (1)
-
Konstantin Zertsekel