diff nuc-fw/sysglue/irqfiq.S @ 114:17b0511b243c

nuc-fw: continuing lowest-level BSP integration
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Thu, 24 Oct 2013 02:47:14 +0000
parents
children 2c5160a9d652
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nuc-fw/sysglue/irqfiq.S	Thu Oct 24 02:47:14 2013 +0000
@@ -0,0 +1,73 @@
+/*
+ * 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!,{a1-a4}                 @ Save a1-a4 on temporary IRQ stack
+
+/*
+ * 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     a4,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!,{a1-a4}                  @ return from interrupt
+        SUBS   pc,r14,#4
+/* BUG correction 2nd part end  -------------- */
+
+	.globl	_INT_FIQ
+_INT_FIQ:
+        STMDB   sp!,{a1-a4}                 @ Save a1-a4 on temporary FIQ stack
+        SUB     a4,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