[U-Boot] [RFC][PATCH 17/19] arm cp15: setup mmu and enable dcache

This has been tested on at91sam9263 and STN8815. Again, I didn't check if it has bad effects on non-arm926 cores.
Initially I had a "done" bit to only set up page tables at the beginning. However, since the aligmnent requirement was for the whole object file, this extra integer tool 16kB in BSS, so I chose to remove it.
Also, note not all boards use PHYS_SDRAM, but it looks like it's the most used name (more than CONFIG_SYS_DRAM_BASE for example).
rebased for full arm relocation from Heiko Schocher hs@denx.de
Signed-off-by: Alessandro Rubini rubini@gnudd.com --- arch/arm/lib/cache-cp15.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 files changed, 38 insertions(+), 0 deletions(-)
diff --git a/arch/arm/lib/cache-cp15.c b/arch/arm/lib/cache-cp15.c index 62ed54f..11e64d8 100644 --- a/arch/arm/lib/cache-cp15.c +++ b/arch/arm/lib/cache-cp15.c @@ -32,6 +32,36 @@ static void cp_delay (void) /* copro seems to need some delay between reading and writing */ for (i = 0; i < 100; i++) nop(); + asm volatile("" : : : "memory"); +} + +/* to activate the MMU we need to set up virtual memory: use 1M areas in bss */ +static inline void mmu_setup(void) +{ + static u32 __attribute__((aligned(16384))) page_table[4096]; + int i; + u32 reg; + + /* Set up an identity-mapping for all 4GB, rw for everyone */ + for (i = 0; i < 4096; i++) + page_table[i] = i << 20 | (3 << 10) | 0x12; + /* Then, enable cacheable and bufferable for RAM only */ + for (i = PHYS_SDRAM >> 20; + i < ( PHYS_SDRAM + PHYS_SDRAM_SIZE) >> 20; + i++) { + page_table[i] = i << 20 | (3 << 10) | 0x1e; + } + /* Copy the page table address to cp15 */ + asm volatile("mcr p15, 0, %0, c2, c0, 0" + : : "r" (page_table) : "memory"); + /* Set the access control to all-supervisor */ + asm volatile("mcr p15, 0, %0, c3, c0, 0" + : : "r" (~0)); + /* and enable the mmu */ + reg = get_cr(); /* get control reg. */ + cp_delay(); + set_cr(reg | CR_M); + }
/* cache_bit must be either CR_I or CR_C */ @@ -39,6 +69,9 @@ static void cache_enable(uint32_t cache_bit) { uint32_t reg;
+ /* The data cache is not active unless the mmu is enabled too */ + if (cache_bit == CR_C) + mmu_setup(); reg = get_cr(); /* get control reg. */ cp_delay(); set_cr(reg | cache_bit); @@ -49,6 +82,11 @@ static void cache_disable(uint32_t cache_bit) { uint32_t reg;
+ if (cache_bit == CR_C) { + /* if disabling data cache, disable mmu too */ + cache_bit |= CR_M; + flush_cache(0, ~0); + } reg = get_cr(); cp_delay(); set_cr(reg & ~cache_bit);

On 29/07/10 11:45, Heiko Schocher wrote:
This has been tested on at91sam9263 and STN8815. Again, I didn't check if it has bad effects on non-arm926 cores.
Initially I had a "done" bit to only set up page tables at the beginning. However, since the aligmnent requirement was for the whole object file, this extra integer tool 16kB in BSS, so I chose to remove it.
Also, note not all boards use PHYS_SDRAM, but it looks like it's the most used name (more than CONFIG_SYS_DRAM_BASE for example).
rebased for full arm relocation from Heiko Schocher hs@denx.de
Signed-off-by: Alessandro Rubini rubini@gnudd.com
arch/arm/lib/cache-cp15.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 files changed, 38 insertions(+), 0 deletions(-)
diff --git a/arch/arm/lib/cache-cp15.c b/arch/arm/lib/cache-cp15.c index 62ed54f..11e64d8 100644 --- a/arch/arm/lib/cache-cp15.c +++ b/arch/arm/lib/cache-cp15.c @@ -32,6 +32,36 @@ static void cp_delay (void) /* copro seems to need some delay between reading and writing */ for (i = 0; i < 100; i++) nop();
- asm volatile("" : : : "memory");
+}
+/* to activate the MMU we need to set up virtual memory: use 1M areas in bss */ +static inline void mmu_setup(void) +{
- static u32 __attribute__((aligned(16384))) page_table[4096];
- int i;
- u32 reg;
- /* Set up an identity-mapping for all 4GB, rw for everyone */
- for (i = 0; i < 4096; i++)
page_table[i] = i << 20 | (3 << 10) | 0x12;
- /* Then, enable cacheable and bufferable for RAM only */
- for (i = PHYS_SDRAM >> 20;
i < ( PHYS_SDRAM + PHYS_SDRAM_SIZE) >> 20;
As you noted, not all boards define these two symbols. I don't see where you have added them in the config.h files. You do seem to have created a new symbol CONFIG_SYS_SDRAM_BASE which you could use, but you would still need a CONFIG_SYS_SDRAM_SIZE wouldn't you?
i++) {
page_table[i] = i << 20 | (3 << 10) | 0x1e;
These numbers ought to be defines, no?
The 0x1e will not work on da8xx as the data cache is broken. The d-cache can still be used in write back mode, so the value 0x1a should be used. It would be good to have symbols to define the caching modes: none, wr-thru', wr-back or some such, similar to Linux.
- }
- /* Copy the page table address to cp15 */
- asm volatile("mcr p15, 0, %0, c2, c0, 0"
: : "r" (page_table) : "memory");
- /* Set the access control to all-supervisor */
- asm volatile("mcr p15, 0, %0, c3, c0, 0"
: : "r" (~0));
- /* and enable the mmu */
- reg = get_cr(); /* get control reg. */
- cp_delay();
- set_cr(reg | CR_M);
}
I have previously tested this patch on da830 and it works fine, bar the two issues above.
Nick.

Thanks Heiko for picking these up, wanted to reply today offlist.
Nick Thompson:
As you noted, not all boards define these two symbols. I don't see where you have added them in the config.h files.
When I've done this, I couldn't find a name that all boards were using, so I had to make a choice. I think I just counted the various names and picked the more common. A board enabling cache must ensure to have the correct names defined, I see no easy solution.
tornado% grep -rl CONFIG_SYS_SDRAM_BASE include/configs | wc -l 353 tornado% grep -rL CONFIG_SYS_SDRAM_BASE include/configs/ | wc -l 193
For example integratorcp is in this "grep -L", and it has PHYS_SDRAM_1/PHYS_SDRAM_1_SIZE . This matches less than half of those 193 boards:
tornado% grep -rl PHYS_SDRAM_1_SIZE include/configs/ | wc -l 86
However, re-reading the patch looks like I chose the wrong symbol. This ought to be fixed, I'll try next week to address the issue.
page_table[i] = i << 20 | (3 << 10) | 0x1e;
These numbers ought to be defines, no?
Yes, it was a lazy RFC. I'll clean up ASAP (monday, hopefully), unless Heiko does it in his tree. Writeback or writethtough should be selectable.
I have previously tested this patch on da830 and it works fine, bar the two issues above.
Thanks for testing and your feedback /alessandro

Hello Nick,
Nick Thompson wrote:
On 29/07/10 11:45, Heiko Schocher wrote:
This has been tested on at91sam9263 and STN8815. Again, I didn't check if it has bad effects on non-arm926 cores.
Initially I had a "done" bit to only set up page tables at the beginning. However, since the aligmnent requirement was for the whole object file, this extra integer tool 16kB in BSS, so I chose to remove it.
Also, note not all boards use PHYS_SDRAM, but it looks like it's the most used name (more than CONFIG_SYS_DRAM_BASE for example).
rebased for full arm relocation from Heiko Schocher hs@denx.de
Signed-off-by: Alessandro Rubini rubini@gnudd.com
arch/arm/lib/cache-cp15.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 files changed, 38 insertions(+), 0 deletions(-)
diff --git a/arch/arm/lib/cache-cp15.c b/arch/arm/lib/cache-cp15.c index 62ed54f..11e64d8 100644 --- a/arch/arm/lib/cache-cp15.c +++ b/arch/arm/lib/cache-cp15.c @@ -32,6 +32,36 @@ static void cp_delay (void) /* copro seems to need some delay between reading and writing */ for (i = 0; i < 100; i++) nop();
- asm volatile("" : : : "memory");
+}
+/* to activate the MMU we need to set up virtual memory: use 1M areas in bss */ +static inline void mmu_setup(void) +{
- static u32 __attribute__((aligned(16384))) page_table[4096];
- int i;
- u32 reg;
- /* Set up an identity-mapping for all 4GB, rw for everyone */
- for (i = 0; i < 4096; i++)
page_table[i] = i << 20 | (3 << 10) | 0x12;
- /* Then, enable cacheable and bufferable for RAM only */
- for (i = PHYS_SDRAM >> 20;
i < ( PHYS_SDRAM + PHYS_SDRAM_SIZE) >> 20;
As you noted, not all boards define these two symbols. I don't see where you have added them in the config.h files. You do seem to have created a new symbol CONFIG_SYS_SDRAM_BASE which you could use, but you would still need a CONFIG_SYS_SDRAM_SIZE wouldn't you?
Ah, you are right. Here we should use CONFIG_SYS_SDRAM_BASE, as I introduced this define as a "must be defined" in this patch series (and to be in sync for example with powerpc).
The size of ram should be in gd->ram_size ... or better for arm architecture, we should use here the ram info in bd_t.
something like this:
for (j = 0 < CONFIG_NR_DRAM_BANKS; j++) { for (i = bd->bi_dram[0].start >> 20; i < ( bd->bi_dram[0].start + bd->bi_dram[0].size) >> 20; i++) {
I fix this issue in v2, if nobody else objects.
i++) {
page_table[i] = i << 20 | (3 << 10) | 0x1e;
These numbers ought to be defines, no?
The 0x1e will not work on da8xx as the data cache is broken. The d-cache can still be used in write back mode, so the value 0x1a should be used. It would be good to have symbols to define the caching modes: none, wr-thru', wr-back or some such, similar to Linux.
Ah, Ok, good hint!
What with:
if !defined(CONFIG_SYS_ARM_CACHE_SETUP) #define CONFIG_SYS_ARM_CACHE_SETUP 0x1e #endif
page_table[i] = i << 20 | (3 << 10) | CONFIG_SYS_ARM_CACHE_SETUP;
So boards/architectures can define there own values?
- }
- /* Copy the page table address to cp15 */
- asm volatile("mcr p15, 0, %0, c2, c0, 0"
: : "r" (page_table) : "memory");
- /* Set the access control to all-supervisor */
- asm volatile("mcr p15, 0, %0, c3, c0, 0"
: : "r" (~0));
- /* and enable the mmu */
- reg = get_cr(); /* get control reg. */
- cp_delay();
- set_cr(reg | CR_M);
}
I have previously tested this patch on da830 and it works fine, bar the two issues above.
Thanks!
bye Heiko

On 30/07/10 10:32, Heiko Schocher wrote:
Nick Thompson wrote:
On 29/07/10 11:45, Heiko Schocher wrote:
i++) {
page_table[i] = i << 20 | (3 << 10) | 0x1e;
These numbers ought to be defines, no?
The 0x1e will not work on da8xx as the data cache is broken. The d-cache can still be used in write back mode, so the value 0x1a should be used. It would
Here, I should have said write-thru' can still be used...
be good to have symbols to define the caching modes: none, wr-thru', wr-back or some such, similar to Linux.
Ah, Ok, good hint!
What with:
if !defined(CONFIG_SYS_ARM_CACHE_SETUP) #define CONFIG_SYS_ARM_CACHE_SETUP 0x1e #endif
page_table[i] = i << 20 | (3 << 10) | CONFIG_SYS_ARM_CACHE_SETUP;
So boards/architectures can define there own values?
How about:
#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH) #define CACHE_SETUP 0x1a #else #define CACHE_SETUP 0x1e #endif
page_table[i] = i << 20 | (3 << 10) | CACHE_SETUP;
This would avoid people having to look up the appropriate value(s).
This follows the Linux model, but there the symbol CPU_CACHE_WRITETHROUGH is used. Ideally, I would suggest we use the CPU form as well, but it would imply an effect beyond ARM.
-- Nick

Hello Nick,
Nick Thompson wrote:
On 30/07/10 10:32, Heiko Schocher wrote:
Nick Thompson wrote:
On 29/07/10 11:45, Heiko Schocher wrote:
i++) {
page_table[i] = i << 20 | (3 << 10) | 0x1e;
These numbers ought to be defines, no?
The 0x1e will not work on da8xx as the data cache is broken. The d-cache can still be used in write back mode, so the value 0x1a should be used. It would
Here, I should have said write-thru' can still be used...
be good to have symbols to define the caching modes: none, wr-thru', wr-back or some such, similar to Linux.
Ah, Ok, good hint!
What with:
if !defined(CONFIG_SYS_ARM_CACHE_SETUP) #define CONFIG_SYS_ARM_CACHE_SETUP 0x1e #endif
page_table[i] = i << 20 | (3 << 10) | CONFIG_SYS_ARM_CACHE_SETUP;
So boards/architectures can define there own values?
How about:
#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH) #define CACHE_SETUP 0x1a #else #define CACHE_SETUP 0x1e #endif
page_table[i] = i << 20 | (3 << 10) | CACHE_SETUP;
This would avoid people having to look up the appropriate value(s).
Ok, I am fine with that too.
This follows the Linux model, but there the symbol CPU_CACHE_WRITETHROUGH is used. Ideally, I would suggest we use the CPU form as well, but it would imply an effect beyond ARM.
I vote for CONFIG_SYS_ARM_CACHE_WRITETHROUGH
bye, Heiko

This has been tested on at91sam9263 and STN8815. Again, I didn't check if it has bad effects on non-arm926 cores.
Initially I had a "done" bit to only set up page tables at the beginning. However, since the aligmnent requirement was for the whole object file, this extra integer tool 16kB in BSS, so I chose to remove it.
Also, note not all boards use PHYS_SDRAM, but it looks like it's the most used name (more than CONFIG_SYS_DRAM_BASE for example).
rebased for full arm relocation from Heiko Schocher hs@denx.de
Signed-off-by: Alessandro Rubini rubini@gnudd.com Signed-off-by: Heiko Schocher hs@denx.de --- - changes since v1: - add possibilty to use dcache in write_through mode, as Nick Thompson suggested. - use the ram setup info in bd_t to setup the TLB - added my Signed-off-by upon consultation with Alessandro
arch/arm/lib/cache-cp15.c | 51 +++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 51 insertions(+), 0 deletions(-)
diff --git a/arch/arm/lib/cache-cp15.c b/arch/arm/lib/cache-cp15.c index 62ed54f..5cbfe42 100644 --- a/arch/arm/lib/cache-cp15.c +++ b/arch/arm/lib/cache-cp15.c @@ -25,6 +25,15 @@ #include <asm/system.h>
#if !(defined(CONFIG_SYS_NO_ICACHE) && defined(CONFIG_SYS_NO_DCACHE)) + +#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH) +#define CACHE_SETUP 0x1a +#else +#define CACHE_SETUP 0x1e +#endif + +DECLARE_GLOBAL_DATA_PTR; + static void cp_delay (void) { volatile int i; @@ -32,6 +41,40 @@ static void cp_delay (void) /* copro seems to need some delay between reading and writing */ for (i = 0; i < 100; i++) nop(); + asm volatile("" : : : "memory"); +} + +/* to activate the MMU we need to set up virtual memory: use 1M areas in bss */ +static inline void mmu_setup(void) +{ + static u32 __attribute__((aligned(16384))) page_table[4096]; + bd_t *bd = gd->bd; + int i, j; + u32 reg; + + /* Set up an identity-mapping for all 4GB, rw for everyone */ + for (i = 0; i < 4096; i++) + page_table[i] = i << 20 | (3 << 10) | 0x12; + /* Then, enable cacheable and bufferable for RAM only */ + for (j = 0 < CONFIG_NR_DRAM_BANKS; j++) { + for (i = bd->bi_dram[j].start >> 20; + i < (bd->bi_dram[j].start + bd->bi_dram[j].size) >> 20; + i++) { + page_table[i] = i << 20 | (3 << 10) | CACHE_SETUP; + } + } + + /* Copy the page table address to cp15 */ + asm volatile("mcr p15, 0, %0, c2, c0, 0" + : : "r" (page_table) : "memory"); + /* Set the access control to all-supervisor */ + asm volatile("mcr p15, 0, %0, c3, c0, 0" + : : "r" (~0)); + /* and enable the mmu */ + reg = get_cr(); /* get control reg. */ + cp_delay(); + set_cr(reg | CR_M); + }
/* cache_bit must be either CR_I or CR_C */ @@ -39,6 +82,9 @@ static void cache_enable(uint32_t cache_bit) { uint32_t reg;
+ /* The data cache is not active unless the mmu is enabled too */ + if (cache_bit == CR_C) + mmu_setup(); reg = get_cr(); /* get control reg. */ cp_delay(); set_cr(reg | cache_bit); @@ -49,6 +95,11 @@ static void cache_disable(uint32_t cache_bit) { uint32_t reg;
+ if (cache_bit == CR_C) { + /* if disabling data cache, disable mmu too */ + cache_bit |= CR_M; + flush_cache(0, ~0); + } reg = get_cr(); cp_delay(); set_cr(reg & ~cache_bit);

On Tue, Aug 3, 2010 at 6:16 AM, Heiko Schocher hs@denx.de wrote:
This has been tested on at91sam9263 and STN8815. Again, I didn't check if it has bad effects on non-arm926 cores.
Initially I had a "done" bit to only set up page tables at the beginning. However, since the aligmnent requirement was for the whole object file, this extra integer tool 16kB in BSS, so I chose to remove it.
Also, note not all boards use PHYS_SDRAM, but it looks like it's the most used name (more than CONFIG_SYS_DRAM_BASE for example).
rebased for full arm relocation from Heiko Schocher hs@denx.de
Signed-off-by: Alessandro Rubini rubini@gnudd.com Signed-off-by: Heiko Schocher hs@denx.de
This v2 of the patch makes 18/19 fail to apply:
Applying: arm cp15: setup mmu and enable dcache Applying: beagle, cache: activate cache command /media/unixdata/src/u-boot/uboot-nand/nand_and_omapl1/.git/rebase-apply/patch:15: new blank line at EOF. + error: patch failed: arch/arm/lib/cache-cp15.c:25 error: arch/arm/lib/cache-cp15.c: patch does not apply Patch failed at 0018 beagle, cache: activate cache command
It looks to me like the introduction of CACHE_SETUP here in v2 needs to be propagated to the extraction of the mmu setup to dram_bank_mmu_setup made in 18/19. I tried to merge the changes this way and when I finally got all 19 applied the board did not come up -- I'm sorry I don't have more details than that, it is serial-console connected only and there is no jtag debugger setup here (yet).
I'm not sure if the board was dead because of my failure to merge the patch that did not apply cleanly or if it is because of the CONFIG_SYS_INIT_SP_ADDR 'Fix this' in the da850evm.h -- I haven't changed the value from 'CONFIG_SYS_SDRAM_BASE + 0x1000 -+ CONFIG_SYS_GBL_DATA_SIZE' introduced in 15/19.
I would be happy to test the next version of the series but it would be much easier to do so if there was a branch in u-boot-testing as suggested by Detlev.
Best Regards,
Ben Gardiner
--- Nanometrics Inc. http://www.nanometrics.ca

Hello Ben,
Ben Gardiner wrote:
On Tue, Aug 3, 2010 at 6:16 AM, Heiko Schocher hs@denx.de wrote:
This has been tested on at91sam9263 and STN8815. Again, I didn't check if it has bad effects on non-arm926 cores.
Initially I had a "done" bit to only set up page tables at the beginning. However, since the aligmnent requirement was for the whole object file, this extra integer tool 16kB in BSS, so I chose to remove it.
Also, note not all boards use PHYS_SDRAM, but it looks like it's the most used name (more than CONFIG_SYS_DRAM_BASE for example).
rebased for full arm relocation from Heiko Schocher hs@denx.de
Signed-off-by: Alessandro Rubini rubini@gnudd.com Signed-off-by: Heiko Schocher hs@denx.de
This v2 of the patch makes 18/19 fail to apply:
Applying: arm cp15: setup mmu and enable dcache Applying: beagle, cache: activate cache command /media/unixdata/src/u-boot/uboot-nand/nand_and_omapl1/.git/rebase-apply/patch:15: new blank line at EOF.
error: patch failed: arch/arm/lib/cache-cp15.c:25 error: arch/arm/lib/cache-cp15.c: patch does not apply Patch failed at 0018 beagle, cache: activate cache command
Sorry, missed that. I send this patch ASAP.
It looks to me like the introduction of CACHE_SETUP here in v2 needs to be propagated to the extraction of the mmu setup to dram_bank_mmu_setup made in 18/19. I tried to merge the changes this way and when I finally got all 19 applied the board did not come up --
Which board?
I'm sorry I don't have more details than that, it is serial-console connected only and there is no jtag debugger setup here (yet).
I think you must debug this ...
I'm not sure if the board was dead because of my failure to merge the patch that did not apply cleanly or if it is because of the CONFIG_SYS_INIT_SP_ADDR 'Fix this' in the da850evm.h -- I haven't changed the value from 'CONFIG_SYS_SDRAM_BASE + 0x1000 -+ CONFIG_SYS_GBL_DATA_SIZE' introduced in 15/19.
Ah, so your board is the da850evm, right? This should be no problem, as dram is setup at this point, but we should find another (not dram) area, which we can use for an initial stack.
I would be happy to test the next version of the series but it would be much easier to do so if there was a branch in u-boot-testing as suggested by Detlev.
Ok.
bye Heiko

On Fri, Aug 6, 2010 at 1:29 AM, Heiko Schocher hs@denx.de wrote:
Hello Ben,
Ben Gardiner wrote:
I'm sorry I don't have more details than that, it is serial-console connected only and there is no jtag debugger setup here (yet).
I think you must debug this ...
I'm not sure if the board was dead because of my failure to merge the patch that did not apply cleanly or if it is because of the CONFIG_SYS_INIT_SP_ADDR 'Fix this' in the da850evm.h -- I haven't changed the value from 'CONFIG_SYS_SDRAM_BASE + 0x1000 -+ CONFIG_SYS_GBL_DATA_SIZE' introduced in 15/19.
Ah, so your board is the da850evm, right? This should be no problem, as dram is setup at this point, but we should find another (not dram) area, which we can use for an initial stack.
Yes. I'm sorry I forgot to mention that up-front.
Thanks for the idea. I think that there are two possible regions for the initial stack. I have tried putting the initial stack in the 'shared ram' region and the 'ARM local RAM' region. In both cases I did this by redefining CONFIG_SYS_INIT_SP_ADDR in the include/configs/da850evm.h file.
First, for the 'shared ram' region which is 128k@0x80000000 I tried: #define CONFIG_SYS_INIT_SP_ADDR (0x80000000 + 128*1024 -1)
The board did not come up, and I think it is because the ldr argument is limited; it appears that the value loaded into sp is wrong:
c1080078 <call_board_init_f>: c1080078: e59fd328 ldr sp, [pc, #808] ; c10803a8 <fiq+0x48> c108007c: e3a00000 mov r0, #0 ; 0x0 c1080080: eb00017f bl c1080684 <board_init_f>
Then for the 'ARM local RAM' which is 8k@0xffff0000 I tried: #define CONFIG_SYS_INIT_SP_ADDR (0xffff0000 + 8*1024 -1)
The board still did not come up event though the proper value _is_ being loaded into sp:
c1080078 <call_board_init_f>: c1080078: e3e0da0e mvn sp, #57344 ; 0xe000 c108007c: e3a00000 mov r0, #0 ; 0x0 c1080080: eb00017f bl c1080684 <board_init_f>
But maybe this region is not available so early, I don't really know.
I then tried modifying the call_board_init_f routine so that it loaded the start of the region into sp and added to it the CONFIG_STACK_SIZE macro:
c1080078 <call_board_init_f>: c1080078: e3a0d102 mov sp, #-2147483648 ; 0x80000000 c108007c: e28dd701 add sp, sp, #262144 ; 0x40000 c1080080: e3a00000 mov r0, #0 ; 0x0 c1080084: eb00017e bl c1080684 <board_init_f>
which gets a reasonable address into sp for this early setup, but the board still doesn't come up.
I'm currently at a loss. I'll get an emulator on this board setup soon.
I'd appreciate anyone's insights into my problems here even if it is to say I'm totally missing the point. :)
I would be happy to test the next version of the series but it would be much easier to do so if there was a branch in u-boot-testing as suggested by Detlev.
Ok.
Thank you for making this series available in u-boot-testing.
Best Regards, Ben Gardiner
--- Nanometrics Inc. http://www.nanometrics.ca

Dear Ben Gardiner,
In message AANLkTi=Tcf1m7UMqs6iQj47E7PxndjkEX1BwU8RGyVyu@mail.gmail.com you wrote:
First, for the 'shared ram' region which is 128k@0x80000000 I tried: #define CONFIG_SYS_INIT_SP_ADDR (0x80000000 + 128*1024 -1)
The "-1" is probably a bad idea, as your stack will point to an odd address then. Try and make this "-8" instead. Or "-16".
Then for the 'ARM local RAM' which is 8k@0xffff0000 I tried: #define CONFIG_SYS_INIT_SP_ADDR (0xffff0000 + 8*1024 -1)
Again, try "-8" instead. Or "-16".
Best regards,
Wolfgang Denk

Hi Wolfgang,
On Fri, Aug 6, 2010 at 11:46 AM, Wolfgang Denk wd@denx.de wrote:
Dear Ben Gardiner,
In message AANLkTi=Tcf1m7UMqs6iQj47E7PxndjkEX1BwU8RGyVyu@mail.gmail.com you wrote:
First, for the 'shared ram' region which is 128k@0x80000000 I tried: #define CONFIG_SYS_INIT_SP_ADDR (0x80000000 + 128*1024 -1)
The "-1" is probably a bad idea, as your stack will point to an odd address then. Try and make this "-8" instead. Or "-16".
Good point. Thank you.
But I think that the value loaded to sp is still wrong because of the restrictions on immediate arguments in ARM instructions.
with (0x80000000 + 128*1024 -16): --- c1080078 <call_board_init_f>: c1080078: e59fd328 ldr sp, [pc, #808] ; c10803a8 <fiq+0x48> c108007c: e3a00000 mov r0, #0 ; 0x0 c1080080: eb00017f bl c1080684 <board_init_f>
and with (0x80000000 + 128*1024 -8): --- c1080078 <call_board_init_f>: c1080078: e59fd328 ldr sp, [pc, #808] ; c10803a8 <fiq+0x48> c108007c: e3a00000 mov r0, #0 ; 0x0 c1080080: eb00017f bl c1080684 <board_init_f>
and neither image is bootable.
Then for the 'ARM local RAM' which is 8k@0xffff0000 I tried: #define CONFIG_SYS_INIT_SP_ADDR (0xffff0000 + 8*1024 -1)
Again, try "-8" instead. Or "-16".
doing so here yields unusable images also and the values assigned to sp seem to be the same as above.
with (0xffff0000 + 8*1024 - 16): --- c1080078 <call_board_init_f>: c1080078: e59fd328 ldr sp, [pc, #808] ; c10803a8 <fiq+0x48> c108007c: e3a00000 mov r0, #0 ; 0x0 c1080080: eb00017f bl c1080684 <board_init_f>
and with (0xffff0000 + 8*1024 - 8): ---- c1080078 <call_board_init_f>: c1080078: e59fd328 ldr sp, [pc, #808] ; c10803a8 <fiq+0x48> c108007c: e3a00000 mov r0, #0 ; 0x0 c1080080: eb00017f bl c1080684 <board_init_f>
Best Regards, Ben Gardiner
--- Nanometrics Inc. http://www.nanometrics.ca

Ben Gardiner wrote:
But I think that the value loaded to sp is still wrong because of the restrictions on immediate arguments in ARM instructions.
with (0x80000000 + 128*1024 -16):
c1080078 <call_board_init_f>: c1080078: e59fd328 ldr sp, [pc, #808] ; c10803a8 <fiq+0x48> c108007c: e3a00000 mov r0, #0 ; 0x0 c1080080: eb00017f bl c1080684 <board_init_f>
and with (0x80000000 + 128*1024 -8):
c1080078 <call_board_init_f>: c1080078: e59fd328 ldr sp, [pc, #808] ; c10803a8 <fiq+0x48> c108007c: e3a00000 mov r0, #0 ; 0x0 c1080080: eb00017f bl c1080684 <board_init_f>
The value loaded into SP is IN the location at PC+808... look there. About in 0xc1080078+0x0328 give or take a word.
Reinhard

The value loaded into SP is IN the location at PC+808... look there.
About in 0xc1080078+0x0328 give or take a word.
And well, the location is mentioned right behind the ;
c1080078: e59fd328 ldr sp, [pc, #808] ; c10803a8 <fiq+0x48>
Reinhard

On Fri, Aug 6, 2010 at 12:32 PM, Reinhard Meyer reinhard.meyer@emk-elektronik.de wrote:
The value loaded into SP is IN the location at PC+808... look there.
About in 0xc1080078+0x0328 give or take a word.
And well, the location is mentioned right behind the ;
c1080078: e59fd328 ldr sp, [pc, #808] ; c10803a8 <fiq+0x48>
Right. My mistake.
Thank you Reinhard and Wolfgang for helping me out here. The values at the location c10803a8 are correct in all cases.
I guess I will definitely need to use a jtag debugger here to figure out what's going wrong.
Best Regards, Ben Gardiner
--- Nanometrics Inc. +1 (613) 592-6776 x239 http://www.nanometrics.ca

On Fri, Aug 6, 2010 at 12:44 PM, Ben Gardiner bengardiner@nanometrics.ca wrote:
On Fri, Aug 6, 2010 at 12:32 PM, Reinhard Meyer reinhard.meyer@emk-elektronik.de wrote:
The value loaded into SP is IN the location at PC+808... look there.
About in 0xc1080078+0x0328 give or take a word.
And well, the location is mentioned right behind the ;
c1080078: e59fd328 ldr sp, [pc, #808] ; c10803a8 <fiq+0x48>
Right. My mistake.
Thank you Reinhard and Wolfgang for helping me out here. The values at the location c10803a8 are correct in all cases.
I guess I will definitely need to use a jtag debugger here to figure out what's going wrong.
I did get an openocd debugger going with uboot on the da850 (see the post to the openocd dev list for the board and target configuration files for the da850 and omapl138 [1]).
It looks like execution goes off into the weeds at arch/arm/cpu/arm926ejs/start.S:294
288 ldr r2, _board_init_r 289 sub r2, r2, r0 290 add r2, r2, r7 /* position from board_init_r in RAM */ 291 /* setup parameters for board_init_r */ 292 mov r0, r5 /* gd_t */ 293 mov r1, r7 /* dest_addr */ 294 /* jump to it ... */ 295 mov lr, r2 296 mov pc, lr
board_init_r == 0xc10804e4 , $r0 == 0xc1080000 and $r7 == 0x7fff0000
It turns out that the region I have assigned to CONFIG_SYS_SDRAM_BASE (0x80000000) was reading as all 0' so even though get_ram_size was returning 128M to dram_init, storing it in gd->ram_size didn't work. Ditto for CONFIG_SYS_SDRAM_BASE set to 0xffff0000. I think this means that only the DDR is available when UBL hands-off to u-boot.
I tried putting the initial stack pointer in DDR with: #define CONFIG_SYS_SDRAM_BASE 0xc0000000 #define CONFIG_SYS_INIT_SP_ADDR (0xc0700000 - 16)
and found that I could get the furthest into booting if I also did: #define CONFIG_SKIP_RELOCATE_UBOOT and diff --git a/arch/arm/cpu/arm926ejs/start.S b/arch/arm/cpu/arm926ejs/start.S index cb27cee..a228b53 100644 --- a/arch/arm/cpu/arm926ejs/start.S +++ b/arch/arm/cpu/arm926ejs/start.S @@ -286,8 +286,10 @@ _nand_boot: .word nand_boot #else ldr r0, _TEXT_BASE ldr r2, _board_init_r +#ifndef CONFIG_SKIP_RELOCATE_UBOOT sub r2, r2, r0 add r2, r2, r7 /* position from board_init_r in RAM */ +#endif /* #ifndef CONFIG_SKIP_RELOCATE_UBOOT */ /* setup parameters for board_init_r */ mov r0, r5 /* gd_t */ mov r1, r7 /* dest_addr */
along with: #define CONFIG_RELOC_FIXUP_WORKS
to avoid some of the reloc stuff in arch/arm/lib/board.c. But then the boot fails because the serial device cannot be registered as stdout because calloc fails which results in an invalid puts function pointer.
I'm not sure what to try next -- any help would be appreciated.
Best Regards, Ben Gardiner
[1] http://permalink.gmane.org/gmane.comp.debugging.openocd.devel/13873
--- Nanometrics Inc. http://www.nanometrics.ca

Hello Ben,
Thanks for trying this patches!
Ben Gardiner wrote:
On Fri, Aug 6, 2010 at 12:44 PM, Ben Gardiner bengardiner@nanometrics.ca wrote:
On Fri, Aug 6, 2010 at 12:32 PM, Reinhard Meyer reinhard.meyer@emk-elektronik.de wrote:
The value loaded into SP is IN the location at PC+808... look there.
About in 0xc1080078+0x0328 give or take a word.
And well, the location is mentioned right behind the ;
c1080078: e59fd328 ldr sp, [pc, #808] ; c10803a8 <fiq+0x48>
Right. My mistake.
Thank you Reinhard and Wolfgang for helping me out here. The values at the location c10803a8 are correct in all cases.
I guess I will definitely need to use a jtag debugger here to figure out what's going wrong.
I did get an openocd debugger going with uboot on the da850 (see the
Good!
post to the openocd dev list for the board and target configuration files for the da850 and omapl138 [1]).
It looks like execution goes off into the weeds at arch/arm/cpu/arm926ejs/start.S:294
288 ldr r2, _board_init_r 289 sub r2, r2, r0 290 add r2, r2, r7 /* position from board_init_r in RAM */ 291 /* setup parameters for board_init_r */ 292 mov r0, r5 /* gd_t */ 293 mov r1, r7 /* dest_addr */ 294 /* jump to it ... */ 295 mov lr, r2 296 mov pc, lr
board_init_r == 0xc10804e4 , $r0 == 0xc1080000 and $r7 == 0x7fff0000
r7 == 0x7fff0000 seems totally wrong to me ... this would result that relocated board_init_r start @0x7fff04e4 ... thats not in RAM!
It turns out that the region I have assigned to CONFIG_SYS_SDRAM_BASE (0x80000000) was reading as all 0' so even though get_ram_size was returning 128M to dram_init, storing it in gd->ram_size didn't work. Ditto for CONFIG_SYS_SDRAM_BASE set to 0xffff0000. I think this means that only the DDR is available when UBL hands-off to u-boot.
Why this values for CONFIG_SYS_SDRAM_BASE? They cannot work! As I see in the include/configs/da850evm.h file:
#define PHYS_SDRAM_1 DAVINCI_DDR_EMIF_DATA_BASE /* DDR Start */
so, RAM starts @DAVINCI_DDR_EMIF_DATA_BASE (=0xc0000000)
-> CONFIG_SYS_SDRAM_BASE should/must be @0xc0000000
I tried putting the initial stack pointer in DDR with: #define CONFIG_SYS_SDRAM_BASE 0xc0000000
Ok.
#define CONFIG_SYS_INIT_SP_ADDR (0xc0700000 - 16)
This is somewhere in RAM, so I think that should work. (Better would be a non RAM location for initial stack, but I don;t know if we have some area on this cpu for that)
and found that I could get the furthest into booting if I also did: #define CONFIG_SKIP_RELOCATE_UBOOT and
No, this is definitely wrong. With that define, code gets not copied to the calculated relocation address!
diff --git a/arch/arm/cpu/arm926ejs/start.S b/arch/arm/cpu/arm926ejs/start.S index cb27cee..a228b53 100644 --- a/arch/arm/cpu/arm926ejs/start.S +++ b/arch/arm/cpu/arm926ejs/start.S @@ -286,8 +286,10 @@ _nand_boot: .word nand_boot #else ldr r0, _TEXT_BASE ldr r2, _board_init_r +#ifndef CONFIG_SKIP_RELOCATE_UBOOT sub r2, r2, r0 add r2, r2, r7 /* position from board_init_r in RAM */ +#endif /* #ifndef CONFIG_SKIP_RELOCATE_UBOOT */
Hmm.. with that, you use in r2 the not relocated address from board_init_r ... thats not what we want.
/* setup parameters for board_init_r */ mov r0, r5 /* gd_t */ mov r1, r7 /* dest_addr */
along with: #define CONFIG_RELOC_FIXUP_WORKS
That is not the right way. Without that, for example the fixup from the commandtable is not done, so your commands are broken.
to avoid some of the reloc stuff in arch/arm/lib/board.c. But then the boot fails because the serial device cannot be registered as stdout because calloc fails which results in an invalid puts function pointer.
I'm not sure what to try next -- any help would be appreciated.
Can you try
http://git.denx.de/?p=u-boot/u-boot-testing.git;a=shortlog;h=refs/heads/arm-...
+ remove in include/configs/da850evm.h line 42: #define CONFIG_SKIP_RELOCATE_UBOOT /* to a proper address, init done */
?
If it don;t work, can you make a breakpoint in arch/arm/cpu/arm926ejs/start.S relocate_code and provide a register dump? And can you find out whats stored in gd->ram_size?
Thanks!
bye Heiko

Hello Heiko,
On Wed, Aug 11, 2010 at 1:56 AM, Heiko Schocher hs@denx.de wrote:
Hello Ben,
Thanks for trying this patches!
My pleasure! Thank you for doing the hard work.
Ben Gardiner wrote:
On Fri, Aug 6, 2010 at 12:44 PM, Ben Gardiner bengardiner@nanometrics.ca wrote: I did get an openocd debugger going with uboot on the da850 (see the
Good!
:)
It looks like execution goes off into the weeds at arch/arm/cpu/arm926ejs/start.S:294
288 ldr r2, _board_init_r 289 sub r2, r2, r0 290 add r2, r2, r7 /* position from board_init_r in RAM */ 291 /* setup parameters for board_init_r */ 292 mov r0, r5 /* gd_t */ 293 mov r1, r7 /* dest_addr */ 294 /* jump to it ... */ 295 mov lr, r2 296 mov pc, lr
board_init_r == 0xc10804e4 , $r0 == 0xc1080000 and $r7 == 0x7fff0000
r7 == 0x7fff0000 seems totally wrong to me ... this would result that relocated board_init_r start @0x7fff04e4 ... thats not in RAM!
It turns out that the region I have assigned to CONFIG_SYS_SDRAM_BASE (0x80000000) was reading as all 0' so even though get_ram_size was returning 128M to dram_init, storing it in gd->ram_size didn't work. Ditto for CONFIG_SYS_SDRAM_BASE set to 0xffff0000. I think this means that only the DDR is available when UBL hands-off to u-boot.
Why this values for CONFIG_SYS_SDRAM_BASE? They cannot work! As I see in the include/configs/da850evm.h file:
#define PHYS_SDRAM_1 DAVINCI_DDR_EMIF_DATA_BASE /* DDR Start */
so, RAM starts @DAVINCI_DDR_EMIF_DATA_BASE (=0xc0000000)
-> CONFIG_SYS_SDRAM_BASE should/must be @0xc0000000
I was trying to "find another (not dram) area in which we can use for an intial stack" as you suggested in 4C5B9DB5.7020009@denx.de. I think I must have misunderstood what needed to be changed to accomplish this.
(Better would be a non RAM location for initial stack, but I don;t know if we have some area on this cpu for that)
8k@0xffff0000 is an 'Arm local RAM' region and 128k@0x80000000 is a 'Shared RAM' region. But neither seemed to be read as anything other than 0x0000 when I was debugging. I think there would need to be some magic writes first to enable these regions.
Can you try
http://git.denx.de/?p=u-boot/u-boot-testing.git;a=shortlog;h=refs/heads/arm-...
- remove in include/configs/da850evm.h
line 42: #define CONFIG_SKIP_RELOCATE_UBOOT /* to a proper address, init done */
?
If it don;t work, can you make a breakpoint in arch/arm/cpu/arm926ejs/start.S relocate_code and provide a register dump? And can you find out whats stored in gd->ram_size?
Most definitely. I'll get back to you shortly.
Best Regards, Ben Gardiner
--- Nanometrics Inc. http://www.nanometrics.ca

On Wed, Aug 11, 2010 at 9:31 AM, Ben Gardiner bengardiner@nanometrics.ca wrote:
On Wed, Aug 11, 2010 at 1:56 AM, Heiko Schocher hs@denx.de wrote:
Can you try
http://git.denx.de/?p=u-boot/u-boot-testing.git;a=shortlog;h=refs/heads/arm-...
This is the commit from which I was working -- there have been no additional updates (git reports 'already up-to-date').
- remove in include/configs/da850evm.h
line 42: #define CONFIG_SKIP_RELOCATE_UBOOT /* to a proper address, init done */
?
If it don;t work, can you make a breakpoint in arch/arm/cpu/arm926ejs/start.S relocate_code and provide a register dump? And can you find out whats stored in gd->ram_size?
Most definitely. I'll get back to you shortly.
With: diff --git a/include/configs/da850evm.h b/include/configs/da850evm.h index e14817b..a7b8021 100644 --- a/include/configs/da850evm.h +++ b/include/configs/da850evm.h @@ -39,7 +39,6 @@ #define CONFIG_SYS_HZ_CLOCK clk_get(DAVINCI_AUXCLK_CLKID) #define CONFIG_SYS_HZ 1000 #define CONFIG_SKIP_LOWLEVEL_INIT -#define CONFIG_SKIP_RELOCATE_UBOOT /* to a proper address, init done */
/* * Memory Info
It works! Thank you, Heiko.
So the code was working fine all along -- I just needed to configure it correctly. Sorry for all the noise and thank you again for your patches and the help in using them.
Best Regards, Ben Gardiner
--- Nanometrics Inc. http://www.nanometrics.ca

Hello Ben,
Ben Gardiner wrote:
On Wed, Aug 11, 2010 at 9:31 AM, Ben Gardiner bengardiner@nanometrics.ca wrote:
On Wed, Aug 11, 2010 at 1:56 AM, Heiko Schocher hs@denx.de wrote:
Can you try
http://git.denx.de/?p=u-boot/u-boot-testing.git;a=shortlog;h=refs/heads/arm-...
This is the commit from which I was working -- there have been no additional updates (git reports 'already up-to-date').
Ok.
- remove in include/configs/da850evm.h
line 42: #define CONFIG_SKIP_RELOCATE_UBOOT /* to a proper address, init done */
?
If it don;t work, can you make a breakpoint in arch/arm/cpu/arm926ejs/start.S relocate_code and provide a register dump? And can you find out whats stored in gd->ram_size?
Most definitely. I'll get back to you shortly.
With: diff --git a/include/configs/da850evm.h b/include/configs/da850evm.h index e14817b..a7b8021 100644 --- a/include/configs/da850evm.h +++ b/include/configs/da850evm.h @@ -39,7 +39,6 @@ #define CONFIG_SYS_HZ_CLOCK clk_get(DAVINCI_AUXCLK_CLKID) #define CONFIG_SYS_HZ 1000 #define CONFIG_SKIP_LOWLEVEL_INIT -#define CONFIG_SKIP_RELOCATE_UBOOT /* to a proper address, init done */
/*
- Memory Info
It works! Thank you, Heiko.
Great!
So the code was working fine all along -- I just needed to configure it correctly. Sorry for all the noise and thank you again for your patches and the help in using them.
Thanks for testing.
bye, Heiko

Dear Ben Gardiner,
In message AANLkTi=20kE+qp1RupSSvPyea2cv46Ppo8ALhiijKZt2@mail.gmail.com you wrote:
On Wed, Aug 11, 2010 at 9:31 AM, Ben Gardiner bengardiner@nanometrics.ca wrote:
On Wed, Aug 11, 2010 at 1:56 AM, Heiko Schocher hs@denx.de wrote:
Can you try
http://git.denx.de/?p=u-boot/u-boot-testing.git;a=shortlog;h=refs/heads/arm-...
This is the commit from which I was working -- there have been no additional updates (git reports 'already up-to-date').
I just pushed Heiko's latest patches...
Best regards,
Wolfgang Denk
participants (6)
-
Alessandro Rubini
-
Ben Gardiner
-
Heiko Schocher
-
Nick Thompson
-
Reinhard Meyer
-
Wolfgang Denk