Message ID | 1292838435-14958-3-git-send-email-Joakim.Tjernlund@transmode.se |
---|---|
State | Not Applicable |
Delegated to: | Marek Vasut |
Headers | show |
Dear Joakim Tjernlund, In message <1292838435-14958-3-git-send-email-Joakim.Tjernlund@transmode.se> you wrote: > By copying the GOT to the end of the INIT_RAM(dcache) > and relocating it there, it is much esier to > support true PIC on u-boot. This cannot handle > FIXUP so C code that depends on fixups before relocation to RAM > must use LINK_OFF to calculate the difference. ... > + /* > + * Copy GOT to cache and relocate it > + * This assumes there is enough space at the end > + * INIT_RAM to hold a copy of the GOT. > + */ Is it correct to assume that system will crash horribly if for some reason the GOT should not fit? And this means that there is no way to adapt this approach to systems where initial RAM is restrictd and not big enough to hold a copy of the GOT?
Wolfgang Denk <wd@denx.de> wrote on 2011/01/09 21:54:34: > > Dear Joakim Tjernlund, > > In message <1292838435-14958-3-git-send-email-Joakim.Tjernlund@transmode.se> you wrote: > > By copying the GOT to the end of the INIT_RAM(dcache) > > and relocating it there, it is much esier to > > support true PIC on u-boot. This cannot handle > > FIXUP so C code that depends on fixups before relocation to RAM > > must use LINK_OFF to calculate the difference. > ... > > + /* > > + * Copy GOT to cache and relocate it > > + * This assumes there is enough space at the end > > + * INIT_RAM to hold a copy of the GOT. > > + */ > > Is it correct to assume that system will crash horribly if for some > reason the GOT should not fit? Yes ATM. I considered adding tests but it will cost more space and I am not sure how to report the error this early. > > And this means that there is no way to adapt this approach to systems > where initial RAM is restrictd and not big enough to hold a copy of > the GOT? Can't think of one, you need somewhere to put the GOT. You can work on reducing the GOT size though. Jocke
diff --git a/arch/powerpc/cpu/mpc83xx/start.S b/arch/powerpc/cpu/mpc83xx/start.S index 16aed0a..af44fdd 100644 --- a/arch/powerpc/cpu/mpc83xx/start.S +++ b/arch/powerpc/cpu/mpc83xx/start.S @@ -291,6 +291,34 @@ in_flash: /* Needed for upcoming -msingle-pic-base */ bl _GLOBAL_OFFSET_TABLE_@local-4 mflr r30 +#ifdef CONFIG_SYS_TRUE_PIC + /* + * Copy GOT to cache and relocate it + * This assumes there is enough space at the end + * INIT_RAM to hold a copy of the GOT. + */ + li r3,0 + bl link_off /* r3 holds link offset at return */ + lis r9, (CONFIG_SYS_INIT_RAM_ADDR+CONFIG_SYS_INIT_RAM_SIZE)@h + ori r9,r9,(CONFIG_SYS_INIT_RAM_ADDR+CONFIG_SYS_INIT_RAM_SIZE)@l + lwz r11,GOT(_GOT2_TABLE_) + add r11,r11,r3 + + li r4, __got2_entries@sectoff@l + mtctr r4 + slwi r5,r4,2 /* r4 * 4 */ + subf r9,r5,r9 /* r9 - r5 */ + + subf r10,r9,r11 /* r11 - r9 */ + subf r30,r10,r30 /* r30 - r10, point PIC(r30) to new GOT */ + addi r11,r11,-4 + addi r9,r9,-4 +1: /* copy GOT and add link offset */ + lwzu r0,4(r11) + add r0,r0,r3 + stwu r0,4(r9) + bdnz 1b +#endif #endif /* r3: IMMR */ lis r3, CONFIG_SYS_IMMR@h @@ -859,9 +887,17 @@ relocate_code: bl _GLOBAL_OFFSET_TABLE_@local-4 mflr r30 #endif +#ifdef CONFIG_SYS_TRUE_PIC + li r3, 0 + bl link_off /* const void * link_off(const void *) */ +#endif lwz r4, GOT(_start) /* Source Address */ addi r4, r4, -EXC_OFF_SYS_RESET lwz r5, GOT(__bss_start) +#ifdef CONFIG_SYS_TRUE_PIC + add r4, r4, r3 /* Add link offset */ + add r5, r5, r3 /* Add link offset */ +#endif mr r3, r10 /* Destination Address */ sub r5, r5, r4
By copying the GOT to the end of the INIT_RAM(dcache) and relocating it there, it is much esier to support true PIC on u-boot. This cannot handle FIXUP so C code that depends on fixups before relocation to RAM must use LINK_OFF to calculate the difference. This depends on the upcoming single-pic-base option to gcc. Signed-off-by: Joakim Tjernlund <Joakim.Tjernlund@transmode.se> --- arch/powerpc/cpu/mpc83xx/start.S | 36 ++++++++++++++++++++++++++++++++++++ 1 files changed, 36 insertions(+), 0 deletions(-)