summaryrefslogtreecommitdiff
path: root/arch/blackfin/cpu/initcode.c
diff options
context:
space:
mode:
authorWolfgang Denk <wd@denx.de>2010-07-14 21:54:45 +0200
committerWolfgang Denk <wd@denx.de>2010-07-14 21:54:45 +0200
commitcb8f0317295482b1a48802778a6927510cb145ba (patch)
tree87f8761766953b4886711b9dd2b79bb3872e2f53 /arch/blackfin/cpu/initcode.c
parent53504a278900939e197d8c35164c27ffee861691 (diff)
parentd013d1a2ec77ffd0752f098212069985024c8661 (diff)
downloadu-boot-imx-cb8f0317295482b1a48802778a6927510cb145ba.zip
u-boot-imx-cb8f0317295482b1a48802778a6927510cb145ba.tar.gz
u-boot-imx-cb8f0317295482b1a48802778a6927510cb145ba.tar.bz2
Merge branch 'master' of git://git.denx.de/u-boot-blackfin
Diffstat (limited to 'arch/blackfin/cpu/initcode.c')
-rw-r--r--arch/blackfin/cpu/initcode.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/arch/blackfin/cpu/initcode.c b/arch/blackfin/cpu/initcode.c
index 5f80ad6..007f5ce 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