diff options
Diffstat (limited to 'arch/arm/cpu/armv7/start.S')
-rw-r--r-- | arch/arm/cpu/armv7/start.S | 51 |
1 files changed, 47 insertions, 4 deletions
diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S index dcb4195d7b..698e15b8e1 100644 --- a/arch/arm/cpu/armv7/start.S +++ b/arch/arm/cpu/armv7/start.S @@ -39,6 +39,42 @@ reset: /* Allow the board to save important registers */ b save_boot_params save_boot_params_ret: +#ifdef CONFIG_POSITION_INDEPENDENT + /* + * Fix .rela.dyn relocations. This allows U-Boot to loaded to and + * executed at a different address than it was linked at. + */ +pie_fixup: + adr r0, reset /* r0 <- Runtime value of reset label */ + ldr r1, =reset /* r1 <- Linked value of reset label */ + subs r4, r0, r1 /* r4 <- Runtime-vs-link offset */ + beq pie_fixup_done + + adr r0, pie_fixup + ldr r1, _rel_dyn_start_ofs + add r2, r0, r1 /* r2 <- Runtime &__rel_dyn_start */ + ldr r1, _rel_dyn_end_ofs + add r3, r0, r1 /* r3 <- Runtime &__rel_dyn_end */ + +pie_fix_loop: + ldr r0, [r2] /* r0 <- Link location */ + ldr r1, [r2, #4] /* r1 <- fixup */ + cmp r1, #23 /* relative fixup? */ + bne pie_skip_reloc + + /* relative fix: increase location by offset */ + add r0, r4 + ldr r1, [r0] + add r1, r4 + str r1, [r0] + str r0, [r2] + add r2, #8 +pie_skip_reloc: + cmp r2, r3 + blo pie_fix_loop +pie_fixup_done: +#endif + #ifdef CONFIG_ARMV7_LPAE /* * check for Hypervisor support @@ -80,11 +116,11 @@ switch_to_hypervisor_ret: #endif /* the mask ROM code should have PLL and others stable */ -#ifndef CONFIG_SKIP_LOWLEVEL_INIT +#if !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT) #ifdef CONFIG_CPU_V7A bl cpu_init_cp15 #endif -#ifndef CONFIG_SKIP_LOWLEVEL_INIT_ONLY +#if !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT_ONLY) bl cpu_init_crit #endif #endif @@ -320,8 +356,8 @@ skip_errata_801819: mov pc, r5 @ back to my caller ENDPROC(cpu_init_cp15) -#if !defined(CONFIG_SKIP_LOWLEVEL_INIT) && \ - !defined(CONFIG_SKIP_LOWLEVEL_INIT_ONLY) +#if !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT) && \ + !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT_ONLY) /************************************************************************* * * CPU_init_critical registers @@ -340,3 +376,10 @@ ENTRY(cpu_init_crit) b lowlevel_init @ go setup pll,mux,memory ENDPROC(cpu_init_crit) #endif + +#if CONFIG_POSITION_INDEPENDENT +_rel_dyn_start_ofs: + .word __rel_dyn_start - pie_fixup +_rel_dyn_end_ofs: + .word __rel_dyn_end - pie_fixup +#endif |