view nuc-fw/sysglue/irqfiq.S @ 137:5fe5559003b7

RV bring-up: RVT "system time" heartbeat messages now get printed every 20 s! The problem was a slight Nucleus API incompatibility between what the RVF code from TCS211 expected and what our FreeNucleus implements: in the TCS211 version of Nucleus it was OK to pass 0 for the initial_time parameter to NU_Create_Timer(), but our version flags such usage as an error. RVF used 0 as the dummy initial_time value when initializing the legacy RV timers with NU_DISABLE_TIMER. Implemented fix: using a dummy value of 1 instead.
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Mon, 11 Nov 2013 09:56:23 +0000
parents 2c5160a9d652
children
line wrap: on
line source

/*
 * This module contains the assembly shells for IRQ and FIQ, separated
 * from the architectured vectors only by some simple unconditional
 * branch instructions.
 *
 * Note that TI's way of handling interrupts sacrifices Nucleus' ability
 * to nest interrupts and minimize the IRQ-disabled window: if my (Falcon's)
 * understanding is correct, TI's code leaves all further IRQs disabled
 * for the full execution duration of an IRQ handler.  (IRQ handlers are
 * really LISRs, but TI's GSM fw does not use Nucleus' LISR framework.)
 */

	.section	iram.text,"ax",%progbits
	.code	32

	.globl	_INT_IRQ
_INT_IRQ:
        STMDB   sp!,{r0-r4}                 @ used to be a1-a4

/*
 * Thanks to TI for discovering and documenting this apparent ARM7TDMI bug:

BUG correction 1st part -------------------
It looks like there is an issue with ARM7 IRQ masking in the CPSR register
which leads to crashes in Nucleus+ scheduler.
Basically the code below  (correct as LOCKOUT = 0xC0) is used in many places by N+ but do not 
prevent from having an interrupt after the execution of the third line (I mean execution, not 
fetch).
        MRS     a1,CPSR                     ; Pickup current CPSR
        ORR     a1,a1,#LOCKOUT              ; Build interrupt lockout value
        MSR     CPSR,a1                     ; Lockout interrupts
       * IRQ INTERRUPT ! *
       Next instructions...

SW workaround:
When a task is interrupted at this point an interrupted context is stored on its task and will 
be resumed later on at the next instruction but to make a long story short it leads to some 
problem as the OS does not expect to be interrupted there.
Further testing tends to show that the CPSR *seems* to be loaded with the proper masking value 
but that the IRQ is still triggered (has been hardwarewise requested during the instruction 
exectution by the ARM7 core?)
*/

        MRS     a1,spsr                     @ check for the IRQ bug:
        TST     a1,#0x80                    @ if the I - flag is set,
        BNE     IRQBUG                      @ then postpone execution of this IRQ
/* Bug correction 1st part end --------------- */

        SUB     r4,lr,#4                    @ Save IRQ's lr (return address)
        BL      TCT_Interrupt_Context_Save  @ Call context save routine

        BL      IQ_IRQ_isr			@ Call  int. service routine

     /* IRQ interrupt processing is complete.  Restore context- Never 
        returns!  */
        B       TCT_Interrupt_Context_Restore

/* BUG correction 2nd part  ------------------ */
IRQBUG: LDMFD  sp!,{r0-r4}                  @ return from interrupt
        SUBS   pc,r14,#4
/* BUG correction 2nd part end  -------------- */

	.globl	_INT_FIQ
_INT_FIQ:
        STMDB   sp!,{r0-r4}                 @ used to be a1-a4
        SUB     r4,lr,#4                    @ Save FIQ's lr (return address)
        BL      TCT_Interrupt_Context_Save  @ Call context save routine

        BL      IQ_FIQ_isr                  @ Call the FIQ ISR

     /* FIQ interrupt processing is complete.  Restore context- Never 
        returns!  */
        B       TCT_Interrupt_Context_Restore