diff mbox

[U-Boot,v5,0/6] Add an SPL to boot the da850evm from SPI

Message ID 1323426981-15247-1-git-send-email-christian.riesch@omicron.at
State Superseded
Headers show

Commit Message

Christian Riesch Dec. 9, 2011, 10:36 a.m. UTC
Hi again,

On Wed, Dec 7, 2011 at 10:32 AM, Christian Riesch <christian.riesch@omicron.at> wrote:
> Hi Tom,
>
> On Tue, Dec 6, 2011 at 11:17 PM, Tom Rini <tom.rini@gmail.com> wrote:
>> On Tue, Dec 6, 2011 at 10:34 AM, Tom Rini <tom.rini@gmail.com> wrote:
> [...]
>>> OK, thanks, I'll chalk it up to my toolchain then.
>>
>> After talking with Wolfgang and Albert, we (OK, Wolfgang) found that
>> ELDK 4.2 toolchain also shows this issue, so please grab that and
>> figure out what's going on here.  Thanks!
>
> With ELDK 4.2 I got the same error message:
>
> arm-linux-ld: error: no memory region specified for loadable section
> `.ARM.exidx'
>
> In my linker script for the SPL (board/davinci/da8xxevm/u-boot-spl.lds) no
> such section is defined. But somehow the linker in the Codesourcery
> toolchain that I used before manages to place the .ARM.exidx section
> between rodata and data automatically (The section is listed in the
> corresponding .map file). However, with the ELDK 4.2 toolchain this section
> (and the .got section) must be specified explicitly. With the patch below
> (applied on top of the patchset) the SPL builds and links nicely with
> both ELDK 4.2 and the Codesourcery toolchain.

That's probably not the right way to solve the problem.

A run of ./MAKEALL -c arm926ejs with a modified version of MAKEALL that
copied the resulting u-boot.map file of each build into the log directory and
subsequently doing
for i in `ls *.map`; do grep exidx $i > /dev/null && echo $i; done 
showed that all davinci boards have this .ARM.exidx section, so it must be
something in the davinci arch tree. After reading a lot of code and running
nm over the object files I found out that there is some connection between
the 64 bit division that are done in arch/arm/cpu/arm926ejs/davinci/timer.c
and these .exidx sections.

The relevant code in timer.c is

ulong get_timer(ulong base)
{
        unsigned long long timer_diff;

        timer_diff = get_ticks() - gd->timer_reset_value;

        return (timer_diff / (gd->timer_rate_hz / CONFIG_SYS_HZ)) - base;
}

void __udelay(unsigned long usec)
{
        unsigned long long endtime;

        endtime = ((unsigned long long)usec * gd->timer_rate_hz) / 1000000UL;
        endtime += get_ticks();

        while (get_ticks() < endtime)
                ;
}

When I replace both divisions with the lldiv function from ldiv64.h (I have
seen that a lot of patches did such replacements in the u-boot code) the
exidx sections vanish (for all davinci based boards) and my patches compile
fine even with the ELDK 4.2 toolchain.

The patch below does the required changes in timer.c and also one replacement
in post/post.c.

Could you please comment on this solution?

@Heiko: The SPL of the cam_enc_4xx board suffered from the same linker 
problem (.ARM.exidx section) and also after applying the patch I could
not build this board with ELDK 4.2 (although it works fine with
gcc version 4.5.2 (Sourcery G++ Lite 2011.03-41). Could you please
have a look at this? (arm-linux-ld: u-boot-spl: Not enough room for program
headers, try linking with -N)

Regards, Christian

---
 arch/arm/cpu/arm926ejs/davinci/timer.c |    6 ++++--
 post/post.c                            |    3 ++-
 2 files changed, 6 insertions(+), 3 deletions(-)
diff mbox

Patch

diff --git a/arch/arm/cpu/arm926ejs/davinci/timer.c b/arch/arm/cpu/arm926ejs/davinci/timer.c
index c7bf7a5..31f8633 100644
--- a/arch/arm/cpu/arm926ejs/davinci/timer.c
+++ b/arch/arm/cpu/arm926ejs/davinci/timer.c
@@ -40,6 +40,7 @@ 
 #include <common.h>
 #include <asm/io.h>
 #include <asm/arch/timer_defs.h>
+#include <div64.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -86,14 +87,15 @@  ulong get_timer(ulong base)
 
 	timer_diff = get_ticks() - gd->timer_reset_value;
 
-	return (timer_diff / (gd->timer_rate_hz / CONFIG_SYS_HZ)) - base;
+	return lldiv(timer_diff, (gd->timer_rate_hz / CONFIG_SYS_HZ)) - base;
 }
 
 void __udelay(unsigned long usec)
 {
 	unsigned long long endtime;
 
-	endtime = ((unsigned long long)usec * gd->timer_rate_hz) / 1000000UL;
+	endtime = lldiv((unsigned long long)usec * gd->timer_rate_hz, 
+			1000000UL);
 	endtime += get_ticks();
 
 	while (get_ticks() < endtime)
diff --git a/post/post.c b/post/post.c
index 0e67ad7..745767a 100644
--- a/post/post.c
+++ b/post/post.c
@@ -24,6 +24,7 @@ 
 #include <common.h>
 #include <stdio_dev.h>
 #include <watchdog.h>
+#include <div64.h>
 #include <post.h>
 
 #ifdef CONFIG_SYS_POST_HOTKEYS_GPIO
@@ -495,7 +496,7 @@  void post_reloc(void)
 unsigned long post_time_ms(unsigned long base)
 {
 #if defined(CONFIG_PPC) || defined(CONFIG_ARM)
-	return (unsigned long)(get_ticks() / (get_tbclk() / CONFIG_SYS_HZ))
+  return (unsigned long) lldiv(get_ticks(), (get_tbclk() / CONFIG_SYS_HZ))
 		- base;
 #else
 #warning "Not implemented yet"