Skip to contentSkip to conversation

arm: Tegra2: Fix ELDK42 gcc failure with inline asm stack pointer load

PATCH Superseded Tom Warren 4 participants 7 messages Feb 16, 2012 – Feb 17, 2012

Subsystems (2)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore

Tom Warren

author
#0 lore raw

PATCH 1/1 arm: Tegra2: Fix ELDK42 gcc failure with inline asm stack pointer load

The 4.2.2 gcc in the ELDK42 release doesn't like the direct SP load using a constant in tegra2_start. Break it up into 4 loads using mov & orr.

Tested on my Seaboard T20-A03, U-Boot loads and runs OK. Also compiled all tegra2 builds with both gcc 4.2.2 and 4.4.1 OK.

---
 arch/arm/cpu/armv7/tegra2/ap20.c |   25 ++++++++++++++++++++-----
 1 files changed, 20 insertions(+), 5 deletions(-)
arch/arm/cpu/armv7/tegra2/ap20.c +20 -5
index 4c44bb3..d2bc0d5 100644
@@ -298,11 +298,26 @@ void tegra2_start(void)
 		writel(0xC0, &pmt->pmt_cfg_ctl);
 
 		/*
-		* If we are ARM7 - give it a different stack. We are about to
-		* start up the A9 which will want to use this one.
-		*/
-		asm volatile("ldr	sp, =%c0\n"
-			: : "i"(AVP_EARLY_BOOT_STACK_LIMIT));
+		 * If we are ARM7 - give it a different stack. We are about to
+		 * start up the A9 which will want to use this one.
+		 */
+		/*
+		 * Note that the 'ldr sp,CONSTANT' version, below, doesn't
+		 * work on gcc 4.2.2 (ELDK42), but does on gcc 4.4.1 and above.
+		 * The work-around is to use the (ugly) 4-pass mov/orr below.
+		 *
+		 * asm volatile("ldr	sp, =%c0\n" : :
+		 *	"i"(AVP_EARLY_BOOT_STACK_LIMIT));
+		 */
+
+		asm volatile("mov	sp, %0"
+			: : "i"(AVP_EARLY_BOOT_STACK_LIMIT & 0xFF));
+		asm volatile("orr	sp, %0"
+			: : "i"(AVP_EARLY_BOOT_STACK_LIMIT & 0xFF00));
+		asm volatile("orr	sp, %0"
+			: : "i"(AVP_EARLY_BOOT_STACK_LIMIT & 0xFF0000));
+		asm volatile("orr	sp, %0"
+			: : "i"(AVP_EARLY_BOOT_STACK_LIMIT & 0xFF000000));
 
 		start_cpu((u32)_start);
 		halt_avp();
Signature · 1 line
1.7.7.1
#1 lore raw

PATCH 1/1 arm: Tegra2: Fix ELDK42 gcc failure with inline asm stack pointer load

Albert,

Quoted 58 lines

-----Original Message-----
From: Tom Warren [mailto:twarren.nvidia at gmail.com]
Sent: Thursday, February 16, 2012 12:46 PM
To: u-boot at lists.denx.de
Cc: twarren.nvidia at gmail.com; albert.u.boot at aribaud.net; wd at denx.de; sjg at chromium.org; Stephen Warren; Tom Warren
Subject: [PATCH] arm: Tegra2: Fix ELDK42 gcc failure with inline asm stack pointer load

The 4.2.2 gcc in the ELDK42 release doesn't like the direct SP load using a constant in tegra2_start. Break it up into 4 loads using mov & orr.

Tested on my Seaboard T20-A03, U-Boot loads and runs OK. Also compiled all tegra2 builds with both gcc 4.2.2 and 4.4.1 OK.

---
 arch/arm/cpu/armv7/tegra2/ap20.c |   25 ++++++++++++++++++++-----
 1 files changed, 20 insertions(+), 5 deletions(-)
arch/arm/cpu/armv7/tegra2/ap20.c +20 -6
index 4c44bb3..d2bc0d5 100644
@@ -298,11 +298,26 @@ void tegra2_start(void)
 		writel(0xC0, &pmt->pmt_cfg_ctl);
 
 		/*
-		* If we are ARM7 - give it a different stack. We are about to
-		* start up the A9 which will want to use this one.
-		*/
-		asm volatile("ldr	sp, =%c0\n"
-			: : "i"(AVP_EARLY_BOOT_STACK_LIMIT));
+		 * If we are ARM7 - give it a different stack. We are about to
+		 * start up the A9 which will want to use this one.
+		 */
+		/*
+		 * Note that the 'ldr sp,CONSTANT' version, below, doesn't
+		 * work on gcc 4.2.2 (ELDK42), but does on gcc 4.4.1 and above.
+		 * The work-around is to use the (ugly) 4-pass mov/orr below.
+		 *
+		 * asm volatile("ldr	sp, =%c0\n" : :
+		 *	"i"(AVP_EARLY_BOOT_STACK_LIMIT));
+		 */
+
+		asm volatile("mov	sp, %0"
+			: : "i"(AVP_EARLY_BOOT_STACK_LIMIT & 0xFF));
+		asm volatile("orr	sp, %0"
+			: : "i"(AVP_EARLY_BOOT_STACK_LIMIT & 0xFF00));
+		asm volatile("orr	sp, %0"
+			: : "i"(AVP_EARLY_BOOT_STACK_LIMIT & 0xFF0000));
+		asm volatile("orr	sp, %0"
+			: : "i"(AVP_EARLY_BOOT_STACK_LIMIT & 0xFF000000));
 
 		start_cpu((u32)_start);
 		halt_avp();
--
Quoted 1 line

1.7.7.1

This should fix the problem you had with compiling the 6 tegra2 builds w/ELDK42. I've also tested it with gcc 4.4.1 (the one I use every day) and gcc 4.6.1 (used internally @ NVIDIA for Chrome U-Boot builds, etc.). It's an ugly work-around, but it works. Thanks to Simon for the fix, BTW.

Tom

Signature · 1 line
nvpublic
#2 lore raw

PATCH 1/1 arm: Tegra2: Fix ELDK42 gcc failure with inline asm stack pointer load

In reply to Tom Warren

Hi Tom,

Quoted 8 lines · Tom Warren

The 4.2.2 gcc in the ELDK42 release doesn't like the direct SP load using a constant in tegra2_start. Break it up into 4 loads using mov & orr.

Tested on my Seaboard T20-A03, U-Boot loads and runs OK. Also compiled all tegra2 builds with both gcc 4.2.2 and 4.4.1 OK.

Review

Quoted 6 lines
---
 arch/arm/cpu/armv7/tegra2/ap20.c |   25 ++++++++++++++++++++-----
 1 files changed, 20 insertions(+), 5 deletions(-)
(quoted diff) +0 -0

b/arch/arm/cpu/armv7/tegra2/ap20.c

arch/arm/cpu/armv7/tegra2/ap20.c void tegra2_start(void) · line 301

Quoted 8 lines

index 4c44bb3..d2bc0d5 100644

arch/arm/cpu/armv7/tegra2/ap20.c +0 -1
@@ -298,11 +298,26 @@ void tegra2_start(void)
               writel(0xC0, &pmt->pmt_cfg_ctl);
 
               /*
-               * If we are ARM7 - give it a different stack. We are

about to

arch/arm/cpu/armv7/tegra2/ap20.c void tegra2_start(void)

Quoted 5 lines
arch/arm/cpu/armv7/tegra2/ap20.c +1 -4
-               * start up the A9 which will want to use this one.
-               */
-               asm volatile("ldr       sp, =%c0\n"
-                       : : "i"(AVP_EARLY_BOOT_STACK_LIMIT));
+                * If we are ARM7 - give it a different stack. We are

about to

arch/arm/cpu/armv7/tegra2/ap20.c void tegra2_start(void)

Quoted 5 lines
arch/arm/cpu/armv7/tegra2/ap20.c +5 -0
+                * start up the A9 which will want to use this one.
+                */
+               /*
+                * Note that the 'ldr sp,CONSTANT' version, below, doesn't
+                * work on gcc 4.2.2 (ELDK42), but does on gcc 4.4.1 and

above.

arch/arm/cpu/armv7/tegra2/ap20.c void tegra2_start(void) · line 307

Quoted 1 line
arch/arm/cpu/armv7/tegra2/ap20.c +1 -0
+                * The work-around is to use the (ugly) 4-pass mov/orr

below.

arch/arm/cpu/armv7/tegra2/ap20.c void tegra2_start(void) · line 320

Quoted 13 lines
arch/arm/cpu/armv7/tegra2/ap20.c +13 -0
+                *
+                * asm volatile("ldr    sp, =%c0\n" : :
+                *      "i"(AVP_EARLY_BOOT_STACK_LIMIT));
+                */
+
+               asm volatile("mov       sp, %0"
+                       : : "i"(AVP_EARLY_BOOT_STACK_LIMIT & 0xFF));
+               asm volatile("orr       sp, %0"
+                       : : "i"(AVP_EARLY_BOOT_STACK_LIMIT & 0xFF00));
+               asm volatile("orr       sp, %0"
+                       : : "i"(AVP_EARLY_BOOT_STACK_LIMIT & 0xFF0000));
+               asm volatile("orr       sp, %0"
+                       : : "i"(AVP_EARLY_BOOT_STACK_LIMIT & 0xFF000000));

Can we combine these into one asm with 4 parameters?

Quoted 6 lines
arch/arm/cpu/armv7/tegra2/ap20.c +0 -1
               start_cpu((u32)_start);
               halt_avp();
--

1.7.7.1

Regards,
Simon

#3 lore raw

PATCH 1/1 arm: Tegra2: Fix ELDK42 gcc failure with inline asm stack pointer load

In reply to Tom Warren
Quoted 35 lines

The 4.2.2 gcc in the ELDK42 release doesn't like the direct SP load using a constant in tegra2_start. Break it up into 4 loads using mov & orr.

Tested on my Seaboard T20-A03, U-Boot loads and runs OK. Also compiled all tegra2 builds with both gcc 4.2.2 and 4.4.1 OK.

---
 arch/arm/cpu/armv7/tegra2/ap20.c |   25 ++++++++++++++++++++-----
 1 files changed, 20 insertions(+), 5 deletions(-)
(quoted diff) +0 -0

b/arch/arm/cpu/armv7/tegra2/ap20.c index 4c44bb3..d2bc0d5 100644

arch/arm/cpu/armv7/tegra2/ap20.c +10 -5
@@ -298,11 +298,26 @@ void tegra2_start(void)
 		writel(0xC0, &pmt->pmt_cfg_ctl);
 
 		/*
-		* If we are ARM7 - give it a different stack. We are about to
-		* start up the A9 which will want to use this one.
-		*/
-		asm volatile("ldr	sp, =%c0\n"
-			: : "i"(AVP_EARLY_BOOT_STACK_LIMIT));
+		 * If we are ARM7 - give it a different stack. We are about to
+		 * start up the A9 which will want to use this one.
+		 */
+		/*
+		 * Note that the 'ldr sp,CONSTANT' version, below, doesn't
+		 * work on gcc 4.2.2 (ELDK42), but does on gcc 4.4.1 and above.
+		 * The work-around is to use the (ugly) 4-pass mov/orr below.
+		 *
+		 * asm volatile("ldr	sp, =%c0\n" : :
+		 *	"i"(AVP_EARLY_BOOT_STACK_LIMIT));

arch/arm/cpu/armv7/tegra2/ap20.c void tegra2_start(void) · line 320

Quoted 10 lines
arch/arm/cpu/armv7/tegra2/ap20.c +10 -0
+		 */
+
+		asm volatile("mov	sp, %0"
+			: : "i"(AVP_EARLY_BOOT_STACK_LIMIT & 0xFF));
+		asm volatile("orr	sp, %0"
+			: : "i"(AVP_EARLY_BOOT_STACK_LIMIT & 0xFF00));
+		asm volatile("orr	sp, %0"
+			: : "i"(AVP_EARLY_BOOT_STACK_LIMIT & 0xFF0000));
+		asm volatile("orr	sp, %0"
+			: : "i"(AVP_EARLY_BOOT_STACK_LIMIT & 0xFF000000));

asm volatile("mov sp, %0"::"r"(AVP_EARLY_BOOT_STACK_LIMIT)); won't work?

M

Quoted 3 lines
arch/arm/cpu/armv7/tegra2/ap20.c +0 -0
 		start_cpu((u32)_start);
 		halt_avp();
#4 lore raw

PATCH 1/1 arm: Tegra2: Fix ELDK42 gcc failure with inline asm stack pointer load

Marek,

Quoted 47 lines

-----Original Message-----
From: Marek Vasut [mailto:marek.vasut at gmail.com]
Sent: Thursday, February 16, 2012 3:47 PM
To: u-boot at lists.denx.de
Cc: Tom Warren; Tom Warren
Subject: Re: [U-Boot] [PATCH] arm: Tegra2: Fix ELDK42 gcc failure with inline asm stack pointer load

Quoted 39 lines

The 4.2.2 gcc in the ELDK42 release doesn't like the direct SP load using a constant in tegra2_start. Break it up into 4 loads using mov & orr.

Tested on my Seaboard T20-A03, U-Boot loads and runs OK. Also compiled all tegra2 builds with both gcc 4.2.2 and 4.4.1 OK.

---
 arch/arm/cpu/armv7/tegra2/ap20.c |   25 ++++++++++++++++++++-----
 1 files changed, 20 insertions(+), 5 deletions(-)
(quoted diff) +0 -0

b/arch/arm/cpu/armv7/tegra2/ap20.c index 4c44bb3..d2bc0d5 100644

arch/arm/cpu/armv7/tegra2/ap20.c +14 -5
@@ -298,11 +298,26 @@ void tegra2_start(void)
 		writel(0xC0, &pmt->pmt_cfg_ctl);
 
 		/*
-		* If we are ARM7 - give it a different stack. We are about to
-		* start up the A9 which will want to use this one.
-		*/
-		asm volatile("ldr	sp, =%c0\n"
-			: : "i"(AVP_EARLY_BOOT_STACK_LIMIT));
+		 * If we are ARM7 - give it a different stack. We are about to
+		 * start up the A9 which will want to use this one.
+		 */
+		/*
+		 * Note that the 'ldr sp,CONSTANT' version, below, doesn't
+		 * work on gcc 4.2.2 (ELDK42), but does on gcc 4.4.1 and above.
+		 * The work-around is to use the (ugly) 4-pass mov/orr below.
+		 *
+		 * asm volatile("ldr	sp, =%c0\n" : :
+		 *	"i"(AVP_EARLY_BOOT_STACK_LIMIT));
+		 */
+
+		asm volatile("mov	sp, %0"
+			: : "i"(AVP_EARLY_BOOT_STACK_LIMIT & 0xFF));
Quoted 8 lines

arch/arm/cpu/armv7/tegra2/ap20.c void tegra2_start(void) · line 320

Quoted 6 lines
arch/arm/cpu/armv7/tegra2/ap20.c +6 -0
+		asm volatile("orr	sp, %0"
+			: : "i"(AVP_EARLY_BOOT_STACK_LIMIT & 0xFF00));
+		asm volatile("orr	sp, %0"
+			: : "i"(AVP_EARLY_BOOT_STACK_LIMIT & 0xFF0000));
+		asm volatile("orr	sp, %0"
+			: : "i"(AVP_EARLY_BOOT_STACK_LIMIT & 0xFF000000));

asm volatile("mov sp, %0"::"r"(AVP_EARLY_BOOT_STACK_LIMIT)); won't work?

That actually _did_ work. I'd thought I'd tried all iterations of ldr/mov/etc., including some that compiled OK but gave fixup errors in the linker, but I guess I missed that one.

Thanks. I'll retest and resubmit.

Tom

Quoted 5 lines

M

Quoted 3 lines
arch/arm/cpu/armv7/tegra2/ap20.c +0 -0
 		start_cpu((u32)_start);
 		halt_avp();
Signature · 1 line
nvpublic
#5 lore raw

PATCH 1/1 arm: Tegra2: Fix ELDK42 gcc failure with inline asm stack pointer load

In reply to Tom Warren
Quoted 38 lines

The 4.2.2 gcc in the ELDK42 release doesn't like the direct SP load using a constant in tegra2_start. Break it up into 4 loads using mov & orr.

Tested on my Seaboard T20-A03, U-Boot loads and runs OK. Also compiled all tegra2 builds with both gcc 4.2.2 and 4.4.1 OK.

---
 arch/arm/cpu/armv7/tegra2/ap20.c |   25 ++++++++++++++++++++-----
 1 files changed, 20 insertions(+), 5 deletions(-)
(quoted diff) +0 -0

b/arch/arm/cpu/armv7/tegra2/ap20.c index 4c44bb3..d2bc0d5 100644

arch/arm/cpu/armv7/tegra2/ap20.c +13 -5
@@ -298,11 +298,26 @@ void tegra2_start(void)
 		writel(0xC0, &pmt->pmt_cfg_ctl);
 
 		/*
-		* If we are ARM7 - give it a different stack. We are about to
-		* start up the A9 which will want to use this one.
-		*/
-		asm volatile("ldr	sp, =%c0\n"
-			: : "i"(AVP_EARLY_BOOT_STACK_LIMIT));
+		 * If we are ARM7 - give it a different stack. We are about to
+		 * start up the A9 which will want to use this one.
+		 */
+		/*
+		 * Note that the 'ldr sp,CONSTANT' version, below, doesn't
+		 * work on gcc 4.2.2 (ELDK42), but does on gcc 4.4.1 and above.
+		 * The work-around is to use the (ugly) 4-pass mov/orr below.
+		 *
+		 * asm volatile("ldr	sp, =%c0\n" : :
+		 *	"i"(AVP_EARLY_BOOT_STACK_LIMIT));
+		 */
+
+		asm volatile("mov	sp, %0"

arch/arm/cpu/armv7/tegra2/ap20.c void tegra2_start(void) · line 323

Quoted 10 lines
arch/arm/cpu/armv7/tegra2/ap20.c +7 -0
+			: : "i"(AVP_EARLY_BOOT_STACK_LIMIT & 0xFF));
+		asm volatile("orr	sp, %0"
+			: : "i"(AVP_EARLY_BOOT_STACK_LIMIT & 0xFF00));
+		asm volatile("orr	sp, %0"
+			: : "i"(AVP_EARLY_BOOT_STACK_LIMIT & 0xFF0000));
+		asm volatile("orr	sp, %0"
+			: : "i"(AVP_EARLY_BOOT_STACK_LIMIT & 0xFF000000));
 
 		start_cpu((u32)_start);
 		halt_avp();

I think you said you'll send an updated patch.

#6 lore raw

PATCH 1/1 arm: Tegra2: Fix ELDK42 gcc failure with inline asm stack pointer load

Marek,

Quoted 54 lines

-----Original Message-----
From: Marek Vasut [mailto:marek.vasut at gmail.com]
Sent: Friday, February 17, 2012 1:57 AM
To: u-boot at lists.denx.de
Cc: Tom Warren; Tom Warren
Subject: Re: [U-Boot] [PATCH] arm: Tegra2: Fix ELDK42 gcc failure with inline asm stack pointer load

Quoted 46 lines

The 4.2.2 gcc in the ELDK42 release doesn't like the direct SP load using a constant in tegra2_start. Break it up into 4 loads using mov & orr.

Tested on my Seaboard T20-A03, U-Boot loads and runs OK. Also compiled all tegra2 builds with both gcc 4.2.2 and 4.4.1 OK.

---
 arch/arm/cpu/armv7/tegra2/ap20.c |   25 ++++++++++++++++++++-----
 1 files changed, 20 insertions(+), 5 deletions(-)
(quoted diff) +0 -0

b/arch/arm/cpu/armv7/tegra2/ap20.c index 4c44bb3..d2bc0d5 100644

arch/arm/cpu/armv7/tegra2/ap20.c +20 -5
@@ -298,11 +298,26 @@ void tegra2_start(void)
 		writel(0xC0, &pmt->pmt_cfg_ctl);
 
 		/*
-		* If we are ARM7 - give it a different stack. We are about to
-		* start up the A9 which will want to use this one.
-		*/
-		asm volatile("ldr	sp, =%c0\n"
-			: : "i"(AVP_EARLY_BOOT_STACK_LIMIT));
+		 * If we are ARM7 - give it a different stack. We are about to
+		 * start up the A9 which will want to use this one.
+		 */
+		/*
+		 * Note that the 'ldr sp,CONSTANT' version, below, doesn't
+		 * work on gcc 4.2.2 (ELDK42), but does on gcc 4.4.1 and above.
+		 * The work-around is to use the (ugly) 4-pass mov/orr below.
+		 *
+		 * asm volatile("ldr	sp, =%c0\n" : :
+		 *	"i"(AVP_EARLY_BOOT_STACK_LIMIT));
+		 */
+
+		asm volatile("mov	sp, %0"
+			: : "i"(AVP_EARLY_BOOT_STACK_LIMIT & 0xFF));
+		asm volatile("orr	sp, %0"
+			: : "i"(AVP_EARLY_BOOT_STACK_LIMIT & 0xFF00));
+		asm volatile("orr	sp, %0"
+			: : "i"(AVP_EARLY_BOOT_STACK_LIMIT & 0xFF0000));
+		asm volatile("orr	sp, %0"
+			: : "i"(AVP_EARLY_BOOT_STACK_LIMIT & 0xFF000000));
 
Quoted 4 lines

arch/arm/cpu/armv7/tegra2/ap20.c void tegra2_start(void) · line 323

Quoted 2 lines
arch/arm/cpu/armv7/tegra2/ap20.c +0 -0
 		start_cpu((u32)_start);
 		halt_avp();

I think you said you'll send an updated patch.

Yep. Needed to test w/different compilers first. Posted V2.

Tom

Signature · 1 line
nvpublic