[PATCH] relocation: Use C as much as possible to do relocation.

Joakim Tjernlund Joakim.Tjernlund at transmode.se
Wed Sep 23 18:41:44 CEST 2009


---
 cpu/mpc83xx/start.S |   64 ++++++++++++++++++++++++++++++++------------------
 lib_ppc/board.c     |   21 ++++++++++++++++-
 2 files changed, 61 insertions(+), 24 deletions(-)

diff --git a/cpu/mpc83xx/start.S b/cpu/mpc83xx/start.S
index 868b070..ccd337a 100644
--- a/cpu/mpc83xx/start.S
+++ b/cpu/mpc83xx/start.S
@@ -307,6 +307,39 @@ in_flash:
 	/* run 1st part of board init code (in Flash)*/
 	bl	board_init_f

+	.globl got_off /* void * got_off(void * ptr) */
+got_off:
+	/* Adds GOT offset to ptr, might be useful for true PIC too */
+	/* Would be great if this could be inline C __asm__ instead */
+#if 1
+	/* Hand coded as we cannot clobber r14 when called from C */
+	mflr	r4
+	bl	1f
+	.text	2
+0:	.long	.LCTOC1-1f
+	.text
+1:	mflr	r6
+	lwz	r0,0b-1b(r6)
+	add	r6,r0,r6
+	mtlr	r4
+	addi	r4,r6,.L__GOT2_TABLE_
+	lwz	r5, .L__GOT2_TABLE_(r6)
+	sub	r4,r5,r4
+	sub	r3,r3,r4
+	blr
+#else
+	/* Use predefined macros instead */
+	mflr	r4
+	mr	r6,r14 /* GET_GOT clobbers r14 so save it */
+	GET_GOT
+	mtlr	r4
+	la	r4,GOT(_GOT2_TABLE_) /* addi r4, r14, .L__GOT2_TABLE_ */
+	lwz	r5,GOT(_GOT2_TABLE_) /* lwz r5, .L__GOT2_TABLE_(r14) */
+	sub	r4,r5,r4
+	sub	r3,r3,r4
+	mr	r6,r14
+	blr
+#endif
 #ifndef CONFIG_NAND_SPL
 /*
  * Vector Table
@@ -842,8 +875,8 @@ flush_dcache:
 	.globl	relocate_code
 relocate_code:
 	mr	r1,  r3		/* Set new stack pointer	*/
-	mr	r9,  r4		/* Save copy of Global Data pointer */
-	mr	r10, r5		/* Save copy of Destination Address */
+	mr	r16, r4		/* Save copy of Global Data pointer */
+	mr	r17, r5		/* Save copy of Destination Address */

 	mr	r3,  r5				/* Destination Address */
 	lis	r4, CONFIG_SYS_MONITOR_BASE at h		/* Source      Address */
@@ -860,7 +893,7 @@ relocate_code:
 	 *
 	 * Offset:
 	 */
-	sub	r15, r10, r4
+	sub	r15, r17, r4

 	/* First our own GOT */
 	add	r14, r14, r15
@@ -938,7 +971,7 @@ relocate_code:
  * We are done. Do not return, instead branch to second part of board
  * initialization, now running from RAM.
  */
-	addi	r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
+	addi	r0, r17, in_ram - _start + EXC_OFF_SYS_RESET
 	mtlr	r0
 	blr

@@ -950,24 +983,9 @@ in_ram:
 	 * Adjust got2 pointers, no need to check for 0, this code
 	 * already puts a few entries in the table.
 	 */
-	la	r3,GOT(_GOT2_TABLE_)
-	li	r4,__got2_entries at sectoff@l
-	lwz	r5,GOT(_GOT2_TABLE_)
-	sub	r5,r3,r5
-	mr	r30,r5
-	bl	__eabi_convert
-
-#ifndef CONFIG_NAND_SPL
-	/*
-	 * Now adjust the fixups and the pointers to the fixups
-	 * in case we need to move ourselves again.
-	 */
-	lwz	r3,GOT(_FIXUP_TABLE_)
+	li	r3,__got2_entries at sectoff@l
 	li	r4,__fixup_entries at sectoff@l
-	mr	r5,r30
-	bl	__eabi_uconvert
-#endif
-
+	bl	__do_eabi_reloc
 clear_bss:
 	/*
 	 * Now clear BSS segment
@@ -997,8 +1015,8 @@ clear_bss:
 	bne	5b
 6:

-	mr	r3, r9		/* Global Data pointer		*/
-	mr	r4, r10		/* Destination Address		*/
+	mr	r3, r16		/* Global Data pointer		*/
+	mr	r4, r17		/* Destination Address		*/
 	bl	board_init_r

 #ifndef CONFIG_NAND_SPL
diff --git a/lib_ppc/board.c b/lib_ppc/board.c
index 0afc7c3..2a9b16e 100644
--- a/lib_ppc/board.c
+++ b/lib_ppc/board.c
@@ -147,7 +147,9 @@ static	ulong	mem_malloc_brk	 = 0;
  * Utilities								*
  ************************************************************************
  */
-
+extern unsigned long *_GOT2_TABLE_;
+extern unsigned long *_FIXUP_TABLE_;
+extern void * got_off(void*);
 /* Relocate the .got2 pointers.  */
 void __eabi_convert(unsigned long *low, unsigned long len,
 		    unsigned long addend)
@@ -178,6 +180,23 @@ void __eabi_uconvert(unsigned long *low, unsigned long len,
 		*v2p = val2;
 	}
 }
+void __do_eabi_reloc(unsigned long got2_len, unsigned long fixup_len)
+{
+	unsigned long addend = (unsigned long)got_off(NULL);
+	unsigned long *low;
+
+	low = (unsigned long *)(*_GOT2_TABLE_ + addend);
+	printf("GOT2:%lx, addend:%lx low:%p\n",
+	       *_GOT2_TABLE_, addend, low);
+	__eabi_convert(low, got2_len, addend);
+
+#ifndef CONFIG_NAND_SPL
+	low = (unsigned long *)(*_FIXUP_TABLE_ + addend);
+	printf("FIXUP:%lx, addend:%lx low:%p\n",
+	       *_FIXUP_TABLE_, addend, low);
+	__eabi_uconvert(low, fixup_len, addend);
+#endif
+}

 /*
  * The Malloc area is immediately below the monitor copy in DRAM
--
1.6.4.4




More information about the U-Boot mailing list