浏览代码

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>
Mike Frysinger 16 年之前
父节点
当前提交
ad9073211c
共有 2 个文件被更改,包括 11 次插入0 次删除
  1. 9 0
      cpu/blackfin/initcode.c
  2. 2 0
      cpu/blackfin/start.S

+ 9 - 0
cpu/blackfin/initcode.c

@@ -249,6 +249,8 @@ static inline void serial_putc(char c)
 BOOTROM_CALLED_FUNC_ATTR
 BOOTROM_CALLED_FUNC_ATTR
 void initcode(ADI_BOOT_DATA *bootstruct)
 void initcode(ADI_BOOT_DATA *bootstruct)
 {
 {
+	ADI_BOOT_DATA bootstruct_scratch;
+
 	/* Save the clock pieces that are used in baud rate calculation */
 	/* Save the clock pieces that are used in baud rate calculation */
 	unsigned int sdivB, divB, vcoB;
 	unsigned int sdivB, divB, vcoB;
 	serial_init();
 	serial_init();
@@ -260,6 +262,13 @@ void initcode(ADI_BOOT_DATA *bootstruct)
 
 
 	serial_putc('A');
 	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
 #ifdef CONFIG_HW_WATCHDOG
 # ifndef CONFIG_HW_WATCHDOG_TIMEOUT_INITCODE
 # ifndef CONFIG_HW_WATCHDOG_TIMEOUT_INITCODE
 #  define CONFIG_HW_WATCHDOG_TIMEOUT_INITCODE 20000
 #  define CONFIG_HW_WATCHDOG_TIMEOUT_INITCODE 20000

+ 2 - 0
cpu/blackfin/start.S

@@ -131,6 +131,7 @@ ENTRY(_start)
 	r3.h = 0x2000;
 	r3.h = 0x2000;
 	cc = r5 < r3 (iu);
 	cc = r5 < r3 (iu);
 	if cc jump .Ldma_and_reprogram;
 	if cc jump .Ldma_and_reprogram;
+	r0 = 0 (x);	/* set bootstruct to NULL */
 	call _initcode;
 	call _initcode;
 	jump .Lprogrammed;
 	jump .Lprogrammed;
 
 
@@ -147,6 +148,7 @@ ENTRY(_start)
 	r1 = r1 + r5;	/* ... to current (not load) address of initcode */
 	r1 = r1 + r5;	/* ... to current (not load) address of initcode */
 	p3 = r0;
 	p3 = r0;
 	call _dma_memcpy_nocache;
 	call _dma_memcpy_nocache;
+	r0 = 0 (x);	/* set bootstruct to NULL */
 	call (p3);
 	call (p3);
 
 
 	/* Since we reprogrammed SCLK, we need to update the serial divisor */
 	/* Since we reprogrammed SCLK, we need to update the serial divisor */