From ce53fc660114a2c23e6e8adbc197008b36ca444d Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 5 May 2010 02:07:44 -0400 Subject: Blackfin: set up simple NMI handlers for anomaly 05000219 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 --- arch/blackfin/cpu/cpu.c | 4 +++- arch/blackfin/cpu/cpu.h | 1 + arch/blackfin/cpu/initcode.c | 25 +++++++++++++++++++++++++ arch/blackfin/cpu/interrupt.S | 5 +++++ 4 files changed, 34 insertions(+), 1 deletion(-) (limited to 'arch/blackfin/cpu') diff --git a/arch/blackfin/cpu/cpu.c b/arch/blackfin/cpu/cpu.c index 2c8fd86b8..18dbdf7ab 100644 --- a/arch/blackfin/cpu/cpu.c +++ b/arch/blackfin/cpu/cpu.c @@ -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); diff --git a/arch/blackfin/cpu/cpu.h b/arch/blackfin/cpu/cpu.h index c8bec115a..ba85e0b9a 100644 --- a/arch/blackfin/cpu/cpu.h +++ b/arch/blackfin/cpu/cpu.h @@ -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 diff --git a/arch/blackfin/cpu/initcode.c b/arch/blackfin/cpu/initcode.c index 9453d5dc4..007f5ce77 100644 --- a/arch/blackfin/cpu/initcode.c +++ b/arch/blackfin/cpu/initcode.c @@ -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'); diff --git a/arch/blackfin/cpu/interrupt.S b/arch/blackfin/cpu/interrupt.S index 69bba3f5e..0e5e59e15 100644 --- a/arch/blackfin/cpu/interrupt.S +++ b/arch/blackfin/cpu/interrupt.S @@ -150,3 +150,8 @@ ENTRY(_evt_default) RESTORE_ALL_SYS rti; ENDPROC(_evt_default) + +/* NMI handler */ +ENTRY(_evt_nmi) + rtn; +ENDPROC(_evt_nmi) -- cgit v1.2.3