
To use a different link address than load address, start.S must not make any absolute accesses. This makes it so. Use link_off(), if defined, to calculate the difference in load and link address. --- cpu/mpc83xx/start.S | 35 ++++++++++++++++++++++++++++------- 1 files changed, 28 insertions(+), 7 deletions(-)
diff --git a/cpu/mpc83xx/start.S b/cpu/mpc83xx/start.S index 68bb620..bc17a60 100644 --- a/cpu/mpc83xx/start.S +++ b/cpu/mpc83xx/start.S @@ -240,9 +240,23 @@ boot_warm: /* time t 5 */ /* there and deflate the flash size back to minimal size */ /*------------------------------------------------------------*/ bl map_flash_by_law1 - lis r4, (CONFIG_SYS_MONITOR_BASE)@h - ori r4, r4, (CONFIG_SYS_MONITOR_BASE)@l - addi r5, r4, in_flash - _start + EXC_OFF_SYS_RESET + + /* Calculate address in flash and jump there */ + bl 1f +1: mflr r5 /* get current address */ + addi r5, r5, in_flash - 1b + /* Check if already inside flash address space. */ + /* if so, do not add CONFIG_SYS_FLASH_BASE */ + lis r4, (CONFIG_SYS_FLASH_BASE)@h + ori r4, r4, (CONFIG_SYS_FLASH_BASE)@l + cmplw cr0, r5, r4 + ble cr0, 2f /* r5 < r4 ? */ + lis r6, (CONFIG_SYS_FLASH_BASE+CONFIG_SYS_FLASH_SIZE)@h + ori r6, r6, (CONFIG_SYS_FLASH_BASE+CONFIG_SYS_FLASH_SIZE)@l + cmplw cr0, r5, r6 + bgt cr0, 3f /* r5 > r6 ? */ +2: add r5,r5,r4 +3: mtlr r5 blr in_flash: @@ -831,11 +845,18 @@ relocate_code: mr r10, r5 /* Save copy of Destination Address */
GET_GOT - mr r3, r5 /* Destination Address */ - lis r4, CONFIG_SYS_MONITOR_BASE@h /* Source Address */ - ori r4, r4, CONFIG_SYS_MONITOR_BASE@l + li r3, 0 +#ifdef CONFIG_LINK_OFF + bl link_off /* const void * link_off(const void *) */ +#endif + lwz r4, GOT(_start) /* Source Address */ + add r4, r4, r3 + addi r4, r4, -EXC_OFF_SYS_RESET lwz r5, GOT(__bss_start) - sub r5, r5, r4 + add r5, r5, r3 + mr r3, r10 /* Destination Address */ + + sub r5, r5, r4 /* r4 - r5 */ li r6, CONFIG_SYS_CACHELINE_SIZE /* Cache Line Size */
/*