diff options
Diffstat (limited to 'arch/blackfin/cpu/initcode.c')
| -rw-r--r-- | arch/blackfin/cpu/initcode.c | 32 | 
1 files changed, 31 insertions, 1 deletions
diff --git a/arch/blackfin/cpu/initcode.c b/arch/blackfin/cpu/initcode.c index 5f80ad615..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'); @@ -675,7 +700,12 @@ void initcode(ADI_BOOT_DATA *bs)  #ifdef CONFIG_BFIN_BOOTROM_USES_EVT1  	serial_putc('I'); -	/* tell the bootrom where our entry point is */ +	/* Tell the bootrom where our entry point is so that it knows +	 * where to jump to when finishing processing the LDR.  This +	 * allows us to avoid small jump blocks in the LDR, and also +	 * works around anomaly 05000389 (init address in external +	 * memory causes bootrom to trigger external addressing IVHW). +	 */  	if (CONFIG_BFIN_BOOT_MODE != BFIN_BOOT_BYPASS)  		bfin_write_EVT1(CONFIG_SYS_MONITOR_BASE);  #endif  |