Many arm926ejs-based SoCs boot at 0xffff0000.
Currently these last 64 KB of flash are wasted just
for a jump to the location where u-boot was flashed.
This commit provides split relocation where the first
part of u-boot is stored from the reset address to the
end of the flash, and the second part is stored below
the first one.
This allows booting directly into _start at 0xffff0000,
thus fully using the last flash sector. For the ED Mini
V2, this frees 12.5% of the flash for other uses.

Signed-off-by: Albert Aribaud <[email protected]>
---
As indicated in the subject line, this patch is *not* a bugfix
and thus *not* expected to be integrated into 2010.09.

It was heavily tested on an ED Mini V2 and a 5Big Network. All
the following cases were debugged step by step through JTAG:

- boot from RAM (with relocation, without low level init)
- boot from linear image in FLASH (with reloc & ll init)
- boot from split image in FLASH (with reloc & ll init)

'checkpatch.pl --no-tree' reported 0 errors and warnings.

 arch/arm/cpu/arm926ejs/start.S |   81 +++++++++++++++++++++++++++++++++------
 1 files changed, 68 insertions(+), 13 deletions(-)

diff --git a/arch/arm/cpu/arm926ejs/start.S b/arch/arm/cpu/arm926ejs/start.S
index cf40ce1..9a0a9ef 100644
--- a/arch/arm/cpu/arm926ejs/start.S
+++ b/arch/arm/cpu/arm926ejs/start.S
@@ -5,8 +5,8 @@
  *
  *  ----- Adapted for OMAP1610 OMAP730 from ARM925t code ------
  *
- *  Copyright (c) 2001 Marius Gröger <[email protected]>
- *  Copyright (c) 2002 Alex Züpke <[email protected]>
+ *  Copyright (c) 2001 Marius Gröger <[email protected]>
+ *  Copyright (c) 2002 Alex Züpke <[email protected]>
  *  Copyright (c) 2002 Gary Jennejohn <[email protected]>
  *  Copyright (c) 2003 Richard Woodruff <[email protected]>
  *  Copyright (c) 2003 Kshitij <[email protected]>
@@ -166,21 +166,74 @@ reset:
        bl      cpu_init_crit
 #endif
 
+/*
+ * This code copies SIZE bytes of u-boot from 'source' _start (in FLASH)
+ * to 'destination' _TEXT_BASE (in RAM) RAM. It can handle two cases:
+ *
+ * 1) source is entirely located at [_start,_start+_bss_start-_armboot_start[
+ *    i.e. u-boot.bin was linearly written to FLASH (this is the case when
+ *    the target's reset vector can be _start, or points to some code which
+ *    will eventually jump inside FLASH to _start)
+ *
+ * 2) source was split in two parts, one located at [_start,0x1.0000.0000[
+ *    (for SIZE1 bytes where SIZE1 = (0x1.0000.000 - _start) and one located
+ *    at [_start-A, SIZE-SIZE1[ where A = (_bss_start-_armboot_start) rounded
+ *    up to the nearest multiple of SIZE1. This is the case when the target's
+ *    reset vector must point directly to _start but there is not enough room
+ *    between _start and the end of the 32-bit addressable FLASH.
+ *
+ * Example for the Orion5x 88F5182, which resets at 0xFFFF0000, and with an
+ * overall u-boot size of 0x0001CAFE:
+ * - the first 64 KB of u-boot.bin are flashed at [0xFFFF0000, 0x100000000[;
+ * - there are 0xCAFE bytes left, which take up one 64KB block. The second
+ *   part of u-boot will thus be flashed at [0xfffE0000, 0xfffECAFE[.
+ *
+ * To determine if the copy must be split, we taken the start addresse
+ * of the source and add the source length to it to form the end address.
+ * if this end address is below the start address, then the image was split.
+ * If it is above the start address, the image was not split.
+ */
+
 #ifndef CONFIG_SKIP_RELOCATE_UBOOT
-relocate:                              /* relocate U-Boot to RAM           */
+       /* relocate U-Boot to RAM */
+relocate:
+       /* skip copy if source == destination */
        adr     r0, _start              /* r0 <- current position of code   */
        ldr     r1, _TEXT_BASE          /* test if we run from flash or RAM */
        cmp     r0, r1                  /* don't reloc during debug         */
        beq     stack_setup
+
+       /* skip split copying if copy is split */
        ldr     r2, _armboot_start
        ldr     r3, _bss_start
-       sub     r2, r3, r2              /* r2 <- size of armboot            */
-       add     r2, r0, r2              /* r2 <- source end address         */
+       sub     r4, r3, r2              /* r4 <- size of armboot            */
+       add     r2, r0, r4              /* r2 <- source end address         */
+       cmp     r2, r0                  /* does the source rollover?        */
+       bhi     copy_loop               /* no: copy is linear, go do it.    */
+
+       /* block size is 0x1.0000.0000 - _start */
+       rsb     r3, r0, #0
+
+       /* round u-boot size up to the nearest multiple of block size */
+       sub     r3, r3, #1
+       orr     r4, r4, r3
+       add     r4, r4, #1
+
+       /* copy second part, end condition is r0 rollover to 0 */
+copy_second:
+       ldmia   r0!, {r5-r12}           /* copy from source address [r0]    */
+       stmia   r1!, {r5-r12}           /* copy to   target address [r1]    */
+       cmp     r0, #0                  /* until source end address [#0]    */
+       bne     copy_second
+
+       /* move source start and end back by the u-boot size rounded up */
+       sub     r0, r0, r4              /* r0 <- source address of 2nd part */
+       sub     r2, r2, r4              /* r2 <- source end adr of 2nd part */
 
 copy_loop:
-       ldmia   r0!, {r3-r10}           /* copy from source address [r0]    */
-       stmia   r1!, {r3-r10}           /* copy to   target address [r1]    */
-       cmp     r0, r2                  /* until source end addreee [r2]    */
+       ldmia   r0!, {r5-r12}           /* copy from source address [r0]    */
+       stmia   r1!, {r5-r12}           /* copy to   target address [r1]    */
+       cmp     r0, r2                  /* until source end address [r2]    */
        ble     copy_loop
 #endif /* CONFIG_SKIP_RELOCATE_UBOOT */
 
@@ -189,14 +242,14 @@ stack_setup:
        ldr     r0, _TEXT_BASE          /* upper 128 KiB: relocated uboot   */
        sub     sp, r0, #128            /* leave 32 words for abort-stack   */
 #ifndef CONFIG_PRELOADER
-       sub     r0, r0, #CONFIG_SYS_MALLOC_LEN  /* malloc area                  
    */
-       sub     r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo                     
   */
+       sub     r0, r0, #CONFIG_SYS_MALLOC_LEN  /* malloc area              */
+       sub     r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo                 */
 #ifdef CONFIG_USE_IRQ
        sub     r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
 #endif
 #endif /* CONFIG_PRELOADER */
        sub     sp, r0, #12             /* leave 3 words for abort-stack    */
-       bic     sp, sp, #7              /* 8-byte alignment for ABI compliance 
*/
+       bic     sp, sp, #7              /* ABI-compliant 8-bit alignment    */
 
 clear_bss:
        ldr     r0, _bss_start          /* find start of bss segment        */
@@ -310,7 +363,8 @@ cpu_init_crit:
 
        ldr     r2, _armboot_start
        sub     r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN)
-       sub     r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8)  @ set base 2 words into 
abort stack
+       @ reserve a couple spots in abort stack
+       sub     r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8)
        @ get values for "aborted" pc and cpsr (into parm regs)
        ldmia   r2, {r2 - r3}
        add     r0, sp, #S_FRAME_SIZE           @ grab pointer to old stack
@@ -344,7 +398,8 @@ cpu_init_crit:
        .macro get_bad_stack
        ldr     r13, _armboot_start             @ setup our mode stack
        sub     r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN)
-       sub     r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple 
spots in abort stack
+       @ reserve a couple spots in abort stack
+       sub     r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8)
 
        str     lr, [r13]       @ save caller lr in position 0 of saved stack
        mrs     lr, spsr        @ get the spsr
-- 
1.7.0.4

_______________________________________________
U-Boot mailing list
[email protected]
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to