[U-Boot] [PATCH v3 4/4] arm: factorize relocate_code routine

Benoît Thébaudeau benoit.thebaudeau at advansee.com
Thu May 16 17:56:29 CEST 2013


Hi Albert,

On Thursday, May 16, 2013 2:02:57 PM, Albert ARIBAUD wrote:
> Replace all relocate_code routines from ARM start.S files
> with a single instance in file arch/arm/lib/relocate.S.
> For PXA, this requires moving the dcache unlocking code
> from within relocate_code into c_runtime_cpu_setup.
> 
> Signed-off-by: Albert ARIBAUD <albert.u.boot at aribaud.net>
> ---
> Changes in v3:
> - fix bugs in relocation offset computations
> - move and fix comment regarding linker symbols
> - fix missing conditionals on PXA25X dcache code
> - replace FLASH/RAM mentions with SRC/DST ones
> 
> Changes in v2:
> - use ENTRY / ENDPROC macros
> - preserve PXA25X dcache unlocking

[...]

> diff --git a/arch/arm/cpu/pxa/start.S b/arch/arm/cpu/pxa/start.S
> index 595778a..21fa84c 100644
> --- a/arch/arm/cpu/pxa/start.S
> +++ b/arch/arm/cpu/pxa/start.S
> @@ -167,94 +167,23 @@ reset:
>  	bl	_main
>  
>  /*------------------------------------------------------------------------------*/
> -#ifndef CONFIG_SPL_BUILD
> -/*
> - * void relocate_code(addr_moni)
> - *
> - * This function relocates the monitor code.
> - */
> -	.globl	relocate_code
> -relocate_code:
> -	mov	r6, r0	/* save addr of destination */
>  
> -/* Disable the Dcache RAM lock for stack now */
> -#ifdef	CONFIG_CPU_PXA25X
> -	mov	r12, lr
> -	bl	cpu_init_crit
> -	mov	lr, r12
> -#endif
> -
> -	adr	r0, _start
> -	subs	r9, r6, r0		/* r9 <- relocation offset */
> -	beq	relocate_done		/* skip relocation */
> -	mov	r1, r6			/* r1 <- scratch for copy_loop */
> -	ldr	r3, _image_copy_end_ofs
> -	add	r2, r0, r3		/* r2 <- source end address	    */
> -
> -copy_loop:
> -	ldmia	r0!, {r10-r11}		/* copy from source address [r0]    */
> -	stmia	r1!, {r10-r11}		/* copy to   target address [r1]    */
> -	cmp	r0, r2			/* until source end address [r2]    */
> -	blo	copy_loop
> +	.globl	c_runtime_cpu_setup
> +c_runtime_cpu_setup:
>  
> +#ifdef CONFIG_CPU_PXA25X
>  	/*
> -	 * fix .rel.dyn relocations
> +	 * Unlock (actually, disable) the cache now that board_init_f
> +	 * is done. We could do this earlier but we would need to add
> +	 * a new C runtime hook, whereas c_runtime_cpu_setup already
> +	 * exists.
> +	 * As this routine is just a call to cpu_init_crit, let us
> +	 * tail-optimize and do a simple branch here.
>  	 */
> -	ldr	r0, _TEXT_BASE		/* r0 <- Text base */
> -	ldr	r10, _dynsym_start_ofs	/* r10 <- sym table ofs */
> -	add	r10, r10, r0		/* r10 <- sym table in FLASH */
> -	ldr	r2, _rel_dyn_start_ofs	/* r2 <- rel dyn start ofs */
> -	add	r2, r2, r0		/* r2 <- rel dyn start in FLASH */
> -	ldr	r3, _rel_dyn_end_ofs	/* r3 <- rel dyn end ofs */
> -	add	r3, r3, r0		/* r3 <- rel dyn end in FLASH */
> -fixloop:
> -	ldr	r0, [r2]		/* r0 <- location to fix up, IN FLASH! */
> -	add	r0, r0, r9		/* r0 <- location to fix up in RAM */
> -	ldr	r1, [r2, #4]
> -	and	r7, r1, #0xff
> -	cmp	r7, #23			/* relative fixup? */
> -	beq	fixrel
> -	cmp	r7, #2			/* absolute fixup? */
> -	beq	fixabs
> -	/* ignore unknown type of fixup */
> -	b	fixnext
> -fixabs:
> -	/* absolute fix: set location to (offset) symbol value */
> -	mov	r1, r1, LSR #4		/* r1 <- symbol index in .dynsym */
> -	add	r1, r10, r1		/* r1 <- address of symbol in table */
> -	ldr	r1, [r1, #4]		/* r1 <- symbol value */
> -	add	r1, r1, r9		/* r1 <- relocated sym addr */
> -	b	fixnext
> -fixrel:
> -	/* relative fix: increase location by offset */
> -	ldr	r1, [r0]
> -	add	r1, r1, r9
> -fixnext:
> -	str	r1, [r0]
> -	add	r2, r2, #8		/* each rel.dyn entry is 8 bytes */
> -	cmp	r2, r3
> -	blo	fixloop
> -
> -relocate_done:
> -
> +	b	cpu_init_crit
> +#else
>  	bx	lr
> -
> -_image_copy_end_ofs:
> -	.word __image_copy_end - _start
> -_rel_dyn_start_ofs:
> -	.word __rel_dyn_start - _start
> -_rel_dyn_end_ofs:
> -	.word __rel_dyn_end - _start
> -_dynsym_start_ofs:
> -	.word __dynsym_start - _start
> -
>  #endif
> -
> -	.globl	c_runtime_cpu_setup
> -c_runtime_cpu_setup:
> -
> -	bx	lr
> -

Keeping an empty line here would be good for code clarity.

>  /*
>   *************************************************************************
>   *

[...]

> diff --git a/arch/arm/lib/relocate.S b/arch/arm/lib/relocate.S
> new file mode 100644
> index 0000000..e391822
> --- /dev/null
> +++ b/arch/arm/lib/relocate.S
> @@ -0,0 +1,106 @@
> +/*
> + *  relocate - common relocation function for ARM U-Boot
> + *
> + *  Copyright (c) 2013  Albert ARIBAUD <albert.u.boot at aribaud.net>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include <linux/linkage.h>
> +
> +/*
> + * void relocate_code(addr_moni)
> + *
> + * This function relocates the monitor code.
> + *
> + * NOTE:
> + * To prevent the code below from containing references with an R_ARM_ABS32
> + * relocation record type, we never refer to linker-defined symbols
> directly.
> + * Instead, we declare literals which contain their relative location with
> + * respect to relocate_code, and at run time, add relocate_code back to
> them.
> + */
> +
> +ENTRY(relocate_code)
> +	mov	r6, r0	/* save addr of destination */
> +
> +	ldr	r0, =_start		/* r0 <- SRC _start */

Or "&_start" in the comment above to be more consistent with the comments below.

> +	subs	r9, r6, r0		/* r9 <- relocation offset */
> +	beq	relocate_done		/* skip relocation */
> +	mov	r1, r6			/* r1 <- scratch for copy loop */
> +	adr	r7, relocate_code	/* r7 <- SRC &relocate_code */
> +	ldr	r3, _image_copy_end_ofs	/* r3 <- __image_copy_end local ofs */
> +	add	r2, r7, r3		/* r2 <- SRC &__image_copy_end */
> +
> +copy_loop:
> +	ldmia	r0!, {r10-r11}		/* copy from source address [r0]    */
> +	stmia	r1!, {r10-r11}		/* copy to   target address [r1]    */
> +	cmp	r0, r2			/* until source end address [r2]    */
> +	blo	copy_loop
> +
> +	/*
> +	 * fix .rel.dyn relocations
> +	 */
> +	ldr	r10, _dynsym_start_ofs	/* r10 <- __dynsym_start local ofs */
> +	add	r10, r10, r7		/* r10 <- SRC &__dynsym_start */
> +	ldr	r2, _rel_dyn_start_ofs	/* r2 <- _rel_dyn_start local ofs */
> +	add	r2, r2, r7		/* r2 <- SRC &_rel_dyn_start */
> +	ldr	r3, _rel_dyn_end_ofs	/* r3 <- _rel_dyn_end local ofs */
> +	add	r3, r3, r7		/* r3 <- SRC &_rel_dyn_end */

It's __rel_dyn_start and __rel_dyn_end with 2 leading underscores in the 4
comments above.

> +fixloop:
> +	ldr	r0, [r2]		/* r0 <- SRC location to fix up */
> +	add	r0, r0, r9		/* r0 <- DST location to fix up */
> +	ldr	r1, [r2, #4]
> +	and	r7, r1, #0xff
> +	cmp	r7, #23			/* relative fixup? */
> +	beq	fixrel
> +	cmp	r7, #2			/* absolute fixup? */
> +	beq	fixabs
> +	/* ignore unknown type of fixup */
> +	b	fixnext
> +fixabs:
> +	/* absolute fix: set location to (offset) symbol value */
> +	mov	r1, r1, LSR #4		/* r1 <- symbol index in .dynsym */
> +	add	r1, r10, r1		/* r1 <- address of symbol in table */
> +	ldr	r1, [r1, #4]		/* r1 <- symbol value */
> +	add	r1, r1, r9		/* r1 <- relocated sym addr */
> +	b	fixnext
> +fixrel:
> +	/* relative fix: increase location by offset */
> +	ldr	r1, [r0]
> +	add	r1, r1, r9
> +fixnext:
> +	str	r1, [r0]
> +	add	r2, r2, #8		/* each rel.dyn entry is 8 bytes */
> +	cmp	r2, r3
> +	blo	fixloop
> +
> +relocate_done:
> +
> +	bx	lr

Argh! The "bx lr" issue is back. That was correct in v2.

> +
> +_image_copy_end_ofs:
> +	.word __image_copy_end - relocate_code
> +_rel_dyn_start_ofs:
> +	.word __rel_dyn_start - relocate_code
> +_rel_dyn_end_ofs:
> +	.word __rel_dyn_end - relocate_code
> +_dynsym_start_ofs:
> +	.word __dynsym_start - relocate_code
> +
> +ENDPROC(relocate_code)
> --
> 1.7.10.4

The rest of the v3 series is fine.

Best regards,
Benoît


More information about the U-Boot mailing list