Blackfin: fix booting with older bootroms (no EVT1)
authorMike Frysinger <vapier@gentoo.org>
Sat, 25 Apr 2009 03:39:41 +0000 (23:39 -0400)
committerMike Frysinger <vapier@gentoo.org>
Wed, 6 May 2009 12:47:21 +0000 (08:47 -0400)
When dropping jump block support, the assumption was that all bootroms
supported entry point redirection via the EVT1 register.  Unfortunately,
this turned out to be incorrect for the oldest Blackfin parts (BF533-0.2
and older and BF561).  No one really noticed earlier because these parts
usually are booted by bypassing the bootrom entirely, and older BF533
parts are not supported at all (too many anomalies).

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
blackfin_config.mk
board/bf561-ezkit/u-boot.lds.S
cpu/blackfin/cpu.c
cpu/blackfin/initcode.c
include/asm-blackfin/blackfin-config-pre.h

index 04a75290dd750749316521725aaa52ac73b3a824..05077c819b3732a422f188060fa648c761e911ed 100644 (file)
@@ -36,7 +36,9 @@ endif
 
 SYM_PREFIX = _
 
-LDR_FLAGS += -J
+LDR_FLAGS-y :=
+LDR_FLAGS-$(CONFIG_BFIN_BOOTROM_USES_EVT1) += -J
+
 LDR_FLAGS += --bmode $(subst BFIN_BOOT_,,$(CONFIG_BFIN_BOOT_MODE))
 LDR_FLAGS += --use-vmas
 ifneq ($(CONFIG_BFIN_BOOT_MODE),BFIN_BOOT_BYPASS)
@@ -45,3 +47,5 @@ endif
 ifneq (,$(findstring s,$(MAKEFLAGS)))
 LDR_FLAGS += --quiet
 endif
+
+LDR_FLAGS += $(LDR_FLAGS-y)
index 4220e8190de431aa0dfa5b8ee557db298134f0ba..e6d3ddca2f41b45b038b0dbc89a3c66d849b5162 100644 (file)
 # define L1_DATA_B_SRAM_SIZE 0
 #endif
 
+/* The 0xC offset is so we don't clobber the tiny LDR jump block. */
+#ifdef CONFIG_BFIN_BOOTROM_USES_EVT1
+# define L1_CODE_ORIGIN L1_INST_SRAM
+#else
+# define L1_CODE_ORIGIN L1_INST_SRAM + 0xC
+#endif
+
 OUTPUT_ARCH(bfin)
 
 MEMORY
 {
        ram     : ORIGIN = CONFIG_SYS_MONITOR_BASE, LENGTH = CONFIG_SYS_MONITOR_LEN
-       l1_code : ORIGIN = L1_INST_SRAM,            LENGTH = L1_INST_SRAM_SIZE
+       l1_code : ORIGIN = L1_CODE_ORIGIN,          LENGTH = L1_INST_SRAM_SIZE
        l1_data : ORIGIN = L1_DATA_B_SRAM,          LENGTH = L1_DATA_B_SRAM_SIZE
 }
 
index c2ff8cd8c6dd354134bf3ae0e32375afafcb080b..9bb6407fc638a7cce4e900365522f1b88e986512 100644 (file)
@@ -25,12 +25,20 @@ ulong bfin_poweron_retx;
 __attribute__ ((__noreturn__))
 void cpu_init_f(ulong bootflag, ulong loaded_from_ldr)
 {
+       extern char _stext_l1;
+#ifndef CONFIG_BFIN_BOOTROM_USES_EVT1
+       /* Build a NOP slide over the LDR jump block.  Whee! */
+       char nops[0xC];
+       serial_early_puts("NOP Slide\n");
+       memset(nops, 0x00, sizeof(nops));
+       memcpy(&_stext_l1 - sizeof(nops), nops, sizeof(nops));
+#endif
+
        if (!loaded_from_ldr) {
                /* Relocate sections into L1 if the LDR didn't do it -- don't
                 * check length because the linker script does the size
                 * checking at build time.
                 */
-               extern char _stext_l1;
                serial_early_puts("L1 Relocate\n");
                extern char _stext_l1, _etext_l1, _stext_l1_lma;
                memcpy(&_stext_l1, &_stext_l1_lma, (&_etext_l1 - &_stext_l1));
index c0fe2c65a6c6232398ea0ce328c85d4ce2fcd7e8..a039cbbbce12d4969b5d9a3f9b2b2452da37f721 100644 (file)
@@ -543,9 +543,11 @@ void initcode(ADI_BOOT_DATA *bootstruct)
 
        serial_putc('T');
 
+#ifdef CONFIG_BFIN_BOOTROM_USES_EVT1
        /* tell the bootrom where our entry point is */
        if (CONFIG_BFIN_BOOT_MODE != BFIN_BOOT_BYPASS)
                bfin_write_EVT1(CONFIG_SYS_MONITOR_BASE);
+#endif
 
        serial_putc('>');
        serial_putc('\n');
index e973de7f7577c6757faa8341dd8f49c7eae34c4a..a3db3627d706b44b9410f9d6aa169b44a8eec2c4 100644 (file)
@@ -54,6 +54,14 @@ static inline const char *get_bfin_boot_mode(int bfin_boot)
 }
 #endif
 
+/* Most bootroms allow for EVT1 redirection */
+#if (defined(__ADSPBF531__) || defined(__ADSPBF532__) || defined(__ADSPBF533__) \
+     && __SILICON_REVISION__ < 3) || defined(__ADSPBF561__)
+# undef CONFIG_BFIN_BOOTROM_USES_EVT1
+#else
+# define CONFIG_BFIN_BOOTROM_USES_EVT1
+#endif
+
 /* Define the default SPI CS used when booting out of SPI */
 #if defined(__ADSPBF531__) || defined(__ADSPBF532__) || defined(__ADSPBF533__) || \
     defined(__ADSPBF538__) || defined(__ADSPBF539__) || defined(__ADSPBF561__) || \