[PATCH] powerpc: mpc85xx: Simplify jump to _start_cont in flash code

After more patches code for jumping to _start_cont symbol in flash memory involved to code with useless mathematical operations. Currently it does:
r3 := CONFIG_SYS_MONITOR_BASE + ABS(_start_cont) - CONFIG_SYS_MONITOR_BASE jump to r3
Which is equivalent of just:
r3 := ABS(_start_cont) jump to r3
The purpose of that code is just to jump to _start_code symbol, independently of program counter. So branch must be done to absolute address. Trying to write:
ba _start_cont
just cause linker error:
LD u-boot powerpc-linux-gnuspe-ld.bfd: arch/powerpc/cpu/mpc85xx/start.o: in function `switch_as': (.bootpg+0x4b8): relocation truncated to fit: R_PPC_ADDR24 against symbol `_start_cont' defined in .text section in arch/powerpc/cpu/mpc85xx/start.o make: *** [Makefile:1801: u-boot] Error 1
Probably by the fact that absolute address cannot be expressed by 24-bits. So write the code via mtlr+blr pattern as it was before and load general purpose register with absolute address of the symbol:
lis r3,_start_cont@h ori r3,r3,_start_cont@l mtlr r3 blr
Seems that gcc and gnu ld linker support symbol@h and symbol@l syntax like number@h and number@l without any problem. And disassembling of compiler u-boot binary proved that lis+ori instructions are called with numbers which represent halves of absolute address of _start_cont symbol.
Signed-off-by: Pali Rohár pali@kernel.org --- arch/powerpc/cpu/mpc85xx/start.S | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/cpu/mpc85xx/start.S b/arch/powerpc/cpu/mpc85xx/start.S index 50b23a97662c..6e3900e7923b 100644 --- a/arch/powerpc/cpu/mpc85xx/start.S +++ b/arch/powerpc/cpu/mpc85xx/start.S @@ -1211,9 +1211,8 @@ switch_as: #else /* Calculate absolute address in FLASH and jump there */ /*--------------------------------------------------------------*/ - lis r3,CONFIG_SYS_MONITOR_BASE@h - ori r3,r3,CONFIG_SYS_MONITOR_BASE@l - addi r3,r3,_start_cont - CONFIG_SYS_MONITOR_BASE + lis r3,_start_cont@h + ori r3,r3,_start_cont@l mtlr r3 blr #endif

After more patches code for jumping to _start_cont symbol in flash memory involved to code with useless mathematical operations. Currently it does:
r3 := CONFIG_SYS_MONITOR_BASE + ABS(_start_cont) - CONFIG_SYS_MONITOR_BASE jump to r3
Which is equivalent of just:
r3 := ABS(_start_cont) jump to r3
The purpose of that code is just to jump to _start_code symbol, independently of program counter. So branch must be done to absolute address. Trying to write:
ba _start_cont
just cause linker error:
LD u-boot powerpc-linux-gnuspe-ld.bfd: arch/powerpc/cpu/mpc85xx/start.o: in function `switch_as': (.bootpg+0x4b8): relocation truncated to fit: R_PPC_ADDR24 against symbol `_start_cont' defined in .text section in arch/powerpc/cpu/mpc85xx/start.o make: *** [Makefile:1801: u-boot] Error 1
Probably by the fact that absolute address cannot be expressed by 24-bits. So write the code via mtlr+blr pattern as it was before and load general purpose register with absolute address of the symbol:
lis r3,_start_cont@h ori r3,r3,_start_cont@l mtlr r3 blr
Seems that gcc and gnu ld linker support symbol@h and symbol@l syntax like number@h and number@l without any problem. And disassembling of compiler u-boot binary proved that lis+ori instructions are called with numbers which represent halves of absolute address of _start_cont symbol.
Signed-off-by: Pali Rohár pali@kernel.org --- Changes in v2: * Rebased on top of next branch, commit d61c11b8c894fad517677dc51ee82d1eade39c01 --- arch/powerpc/cpu/mpc85xx/start.S | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/cpu/mpc85xx/start.S b/arch/powerpc/cpu/mpc85xx/start.S index 5009cbef54a0..8a6340d800c3 100644 --- a/arch/powerpc/cpu/mpc85xx/start.S +++ b/arch/powerpc/cpu/mpc85xx/start.S @@ -1126,9 +1126,8 @@ switch_as: #else /* Calculate absolute address in FLASH and jump there */ /*--------------------------------------------------------------*/ - lis r3,CONFIG_VAL(SYS_MONITOR_BASE)@h - ori r3,r3,CONFIG_VAL(SYS_MONITOR_BASE)@l - addi r3,r3,_start_cont - CONFIG_VAL(SYS_MONITOR_BASE) + lis r3,_start_cont@h + ori r3,r3,_start_cont@l mtlr r3 blr #endif
participants (1)
-
Pali Rohár