Patchwork [U-Boot,5/6] mpc83xx: Add true PIC support.

login
register
mail settings
Submitter Joakim Tjernlund
Date Nov. 23, 2010, 6:48 p.m.
Message ID <1290538131-12383-6-git-send-email-Joakim.Tjernlund@transmode.se>
Download mbox | patch
Permalink /patch/72720/
State RFC
Headers show

Comments

Joakim Tjernlund - Nov. 23, 2010, 6:48 p.m.
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.
---
 arch/powerpc/cpu/mpc83xx/start.S |   36 ++++++++++++++++++++++++++++++++++++
 1 files changed, 36 insertions(+), 0 deletions(-)

Patch

diff --git a/arch/powerpc/cpu/mpc83xx/start.S b/arch/powerpc/cpu/mpc83xx/start.S
index 3d4e288..b24a89a 100644
--- a/arch/powerpc/cpu/mpc83xx/start.S
+++ b/arch/powerpc/cpu/mpc83xx/start.S
@@ -302,6 +302,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_END)@h
+	ori r9,r9,(CONFIG_SYS_INIT_RAM_ADDR+CONFIG_SYS_INIT_RAM_END)@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
@@ -869,9 +897,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