diff mbox

[U-Boot,3/4] mpc83xx: Add true PIC support.

Message ID 1292838435-14958-3-git-send-email-Joakim.Tjernlund@transmode.se
State Not Applicable
Delegated to: Marek Vasut
Headers show

Commit Message

Joakim Tjernlund Dec. 20, 2010, 9:47 a.m. UTC
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(-)

Comments

Wolfgang Denk Jan. 9, 2011, 8:54 p.m. UTC | #1
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?
Joakim Tjernlund Jan. 9, 2011, 9:01 p.m. UTC | #2
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 mbox

Patch

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