summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2009-02-13 17:10:58 -0500
committerMike Frysinger <vapier@gentoo.org>2009-04-02 06:41:56 -0400
commitad9073211ca9e62162a39851e082b8d07a662fb6 (patch)
treeba4c415b936854441c8860f720d20858d3387021
parent84a9dda324c3faa56be14449d7519b993d9397a9 (diff)
downloadu-boot-imx-ad9073211ca9e62162a39851e082b8d07a662fb6.zip
u-boot-imx-ad9073211ca9e62162a39851e082b8d07a662fb6.tar.gz
u-boot-imx-ad9073211ca9e62162a39851e082b8d07a662fb6.tar.bz2
Blackfin: fix crash when booting from external memory
When testing a u-boot binary that hasn't been booted from the bootrom, we have to make sure the bootstruct structure has sane storage space. If we don't, the initcode will crash when it tries to dereference an invalid pointer. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
-rw-r--r--cpu/blackfin/initcode.c9
-rw-r--r--cpu/blackfin/start.S2
2 files changed, 11 insertions, 0 deletions
diff --git a/cpu/blackfin/initcode.c b/cpu/blackfin/initcode.c
index 7bd4b22..3120447 100644
--- a/cpu/blackfin/initcode.c
+++ b/cpu/blackfin/initcode.c
@@ -249,6 +249,8 @@ static inline void serial_putc(char c)
BOOTROM_CALLED_FUNC_ATTR
void initcode(ADI_BOOT_DATA *bootstruct)
{
+ ADI_BOOT_DATA bootstruct_scratch;
+
/* Save the clock pieces that are used in baud rate calculation */
unsigned int sdivB, divB, vcoB;
serial_init();
@@ -260,6 +262,13 @@ void initcode(ADI_BOOT_DATA *bootstruct)
serial_putc('A');
+ /* If the bootstruct is NULL, then it's because we're loading
+ * dynamically and not via LDR (bootrom). So set the struct to
+ * some scratch space.
+ */
+ if (!bootstruct)
+ bootstruct = &bootstruct_scratch;
+
#ifdef CONFIG_HW_WATCHDOG
# ifndef CONFIG_HW_WATCHDOG_TIMEOUT_INITCODE
# define CONFIG_HW_WATCHDOG_TIMEOUT_INITCODE 20000
diff --git a/cpu/blackfin/start.S b/cpu/blackfin/start.S
index 506fea5..7cbd632 100644
--- a/cpu/blackfin/start.S
+++ b/cpu/blackfin/start.S
@@ -131,6 +131,7 @@ ENTRY(_start)
r3.h = 0x2000;
cc = r5 < r3 (iu);
if cc jump .Ldma_and_reprogram;
+ r0 = 0 (x); /* set bootstruct to NULL */
call _initcode;
jump .Lprogrammed;
@@ -147,6 +148,7 @@ ENTRY(_start)
r1 = r1 + r5; /* ... to current (not load) address of initcode */
p3 = r0;
call _dma_memcpy_nocache;
+ r0 = 0 (x); /* set bootstruct to NULL */
call (p3);
/* Since we reprogrammed SCLK, we need to update the serial divisor */