diff src/cs/system/main/gcc/irqfiq.S @ 78:95ef11e76c5b

src/cs/system/main/gcc: asm code pieced from Citrine
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 20 Jul 2018 06:46:56 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cs/system/main/gcc/irqfiq.S	Fri Jul 20 06:46:56 2018 +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.)
+ */
+
+	.text
+	.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