[U-Boot] [PATCH] ARM: fix the misset of global data pointer

Masahiro Yamada yamada.masahiro at socionext.com
Mon Aug 17 14:36:49 CEST 2015


I found some of my boards would not boot since commit 2afddae07523
("Align global_data to a 16-byte boundary").  Probably, many ARM
boards using Generic Board framework are broken, including ARM64
ones.  That commit aligned the global data pointer, i.e. inserted
some spaces between the gd and the bd.

The assembly code in arch/arm/lib/crt0(_64).S must be adjusted
because the new gd is no longer just below the bd.  Otherwise,
r9 (x18) holds a wrong pointer to the global data.

This commit uses GD_NEW_GD to directly reference the offset to the
new_gd.

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---

Tom,

I guess many ARM boards are broken.
This issue should be fixed asap.

I confirmed this commit fixes the problem on my boards.

Since I have no ARM64 board, I hope somebody could test it
for ARM64.


 arch/arm/lib/crt0.S    | 3 +--
 arch/arm/lib/crt0_64.S | 3 +--
 lib/asm-offsets.c      | 2 ++
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/lib/crt0.S b/arch/arm/lib/crt0.S
index afd4f10..c7bdfbf 100644
--- a/arch/arm/lib/crt0.S
+++ b/arch/arm/lib/crt0.S
@@ -119,8 +119,7 @@ clr_gd:
 #else
 	bic	sp, sp, #7	/* 8-byte alignment for ABI compliance */
 #endif
-	ldr	r9, [r9, #GD_BD]		/* r9 = gd->bd */
-	sub	r9, r9, #GD_SIZE		/* new GD is below bd */
+	ldr	r9, [r9, #GD_NEW_GD]		/* r9 = gd->new_gd */
 
 	adr	lr, here
 	ldr	r0, [r9, #GD_RELOC_OFF]		/* r0 = gd->reloc_off */
diff --git a/arch/arm/lib/crt0_64.S b/arch/arm/lib/crt0_64.S
index 98a906e..13960d0 100644
--- a/arch/arm/lib/crt0_64.S
+++ b/arch/arm/lib/crt0_64.S
@@ -90,8 +90,7 @@ zero_gd:
  */
 	ldr	x0, [x18, #GD_START_ADDR_SP]	/* x0 <- gd->start_addr_sp */
 	bic	sp, x0, #0xf	/* 16-byte alignment for ABI compliance */
-	ldr	x18, [x18, #GD_BD]		/* x18 <- gd->bd */
-	sub	x18, x18, #GD_SIZE		/* new GD is below bd */
+	ldr	x18, [x18, #GD_NEW_GD]		/* x18 <- gd->new_gd */
 
 	adr	lr, relocation_return
 	ldr	x9, [x18, #GD_RELOC_OFF]	/* x9 <- gd->reloc_off */
diff --git a/lib/asm-offsets.c b/lib/asm-offsets.c
index 221ebbf..88afedf 100644
--- a/lib/asm-offsets.c
+++ b/lib/asm-offsets.c
@@ -36,6 +36,8 @@ int main(void)
 
 	DEFINE(GD_RELOC_OFF, offsetof(struct global_data, reloc_off));
 
+	DEFINE(GD_NEW_GD, offsetof(struct global_data, new_gd));
+
 	DEFINE(GD_START_ADDR_SP, offsetof(struct global_data, start_addr_sp));
 
 	return 0;
-- 
1.9.1



More information about the U-Boot mailing list