Blackfin: set up simple NMI handlers for anomaly 05000219
authorMike Frysinger <vapier@gentoo.org>
Wed, 5 May 2010 06:07:44 +0000 (02:07 -0400)
committerMike Frysinger <vapier@gentoo.org>
Mon, 5 Jul 2010 08:18:18 +0000 (04:18 -0400)
Older on-chip Blackfin bootroms do not create a dummy NMI handler, so set
up one ourselves when anomaly 05000219 applies.

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
arch/blackfin/cpu/cpu.c
arch/blackfin/cpu/cpu.h
arch/blackfin/cpu/initcode.c
arch/blackfin/cpu/interrupt.S

index 2c8fd86b86f939e19cf897d1f43237a3ab57b4ad..18dbdf7abe9686b6e5220b534b5c3aa13bdbf2bb 100644 (file)
@@ -91,7 +91,9 @@ int irq_init(void)
 #else
        bfin_write_SIC_IMASK(0);
 #endif
-       bfin_write_EVT2(evt_default);   /* NMI */
+       /* Set up a dummy NMI handler if needed.  */
+       if (CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_BYPASS || ANOMALY_05000219)
+               bfin_write_EVT2(evt_nmi);       /* NMI */
        bfin_write_EVT5(evt_default);   /* hardware error */
        bfin_write_EVT6(evt_default);   /* core timer */
        bfin_write_EVT7(evt_default);
index c8bec115a13580b496f6c2867180f67855837347..ba85e0b9a5cf07808a62048e456b65ca938493b6 100644 (file)
@@ -34,6 +34,7 @@ void bfin_panic(struct pt_regs *reg);
 void dump(struct pt_regs *regs);
 
 asmlinkage void trap(void);
+asmlinkage void evt_nmi(void);
 asmlinkage void evt_default(void);
 
 #endif
index 9453d5dc4dfc37bc0865bcf9dbd5a6b6fb2fbd87..007f5ce7757fbd275ffaddf010c3b8d202614724 100644 (file)
@@ -101,6 +101,28 @@ static inline void serial_putc(char c)
                continue;
 }
 
+__attribute__((always_inline)) static inline void
+program_nmi_handler(void)
+{
+       u32 tmp1, tmp2;
+
+       /* Older bootroms don't create a dummy NMI handler,
+        * so make one ourselves ASAP in case it fires.
+        */
+       if (CONFIG_BFIN_BOOT_MODE != BFIN_BOOT_BYPASS && !ANOMALY_05000219)
+               return;
+
+       asm volatile (
+               "%0 = RETS;" /* Save current RETS */
+               "CALL 1f;"   /* Figure out current PC */
+               "RTN;"       /* The simple NMI handler */
+               "1:"
+               "%1 = RETS;" /* Load addr of NMI handler */
+               "RETS = %0;" /* Restore RETS */
+               "[%2] = %1;" /* Write NMI handler */
+               : "=r"(tmp1), "=r"(tmp2) : "ab"(EVT2)
+       );
+}
 
 /* Max SCLK can be 133MHz ... dividing that by (2*4) gives
  * us a freq of 16MHz for SPI which should generally be
@@ -640,6 +662,9 @@ void initcode(ADI_BOOT_DATA *bs)
 {
        ADI_BOOT_DATA bootstruct_scratch;
 
+       /* Setup NMI handler before anything else */
+       program_nmi_handler();
+
        serial_init();
 
        serial_putc('A');
index 69bba3f5eeff81e685dbb4ec0b32e563c266bda9..0e5e59e15d6d903d9c0a9418c6e51ac6dd1899da 100644 (file)
@@ -150,3 +150,8 @@ ENTRY(_evt_default)
        RESTORE_ALL_SYS
        rti;
 ENDPROC(_evt_default)
+
+/* NMI handler */
+ENTRY(_evt_nmi)
+       rtn;
+ENDPROC(_evt_nmi)