layer1: Disable FIQ as well as IRQ for locking between L1S and L1A
authorHarald Welte <laforge@gnumonks.org>
Mon, 10 May 2010 09:08:28 +0000 (11:08 +0200)
committerHarald Welte <laforge@gnumonks.org>
Mon, 17 May 2010 07:23:35 +0000 (09:23 +0200)
src/target/firmware/include/asm/system.h
src/target/firmware/layer1/async.c
src/target/firmware/layer1/sync.c

index 2bf0cc5..3db0dc7 100644 (file)
        : "memory", "cc");                                      \
        })
        
+/* Save IRQ flags and disable FIQ + IRQ */
+#define local_firq_save(x)                                     \
+       ({                                                      \
+               unsigned long temp;                             \
+               (void) (&temp == &x);                           \
+       __asm__ __volatile__(                                   \
+       "mrs    %0, cpsr                @ local_firq_save\n"    \
+"      orr     %1, %0, #0xC0\n"                                \
+"      msr     cpsr_c, %1"                                     \
+       : "=r" (x), "=r" (temp)                                 \
+       :                                                       \
+       : "memory", "cc");                                      \
+       })
+
 /*
  * Enable IRQs
  */
index 952067f..41f443a 100644 (file)
@@ -79,7 +79,7 @@ void l1a_compl_execute(void)
        unsigned int i;
 
        /* get and reset the currently scheduled tasks */
-       local_irq_save(flags);
+       local_firq_save(flags);
        scheduled = l1s.scheduled_compl;
        l1s.scheduled_compl = 0;
        local_irq_restore(flags);
index d991ca5..bf47643 100644 (file)
@@ -200,7 +200,7 @@ void l1s_compl_sched(enum l1_compl c)
 {
        unsigned long flags;
 
-       local_irq_save(flags);
+       local_firq_save(flags);
        l1s.scheduled_compl |= (1 << c);
        local_irq_restore(flags);
 }