mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-10-31 03:58:17 +00:00 
			
		
		
		
	A U-Boot image could be loaded and executed at a different location than it was linked at. For example, Aspeed takes a stable release version of U-Boot image as the golden one for recovery purposes. When the primary storage such as flash is corrupted, the golden image would be loaded to any SRAM/DRAM address on demands through ethernet/UART/etc and run for rescue. To deal with this condition, the PIE is needed as there is only one signed, golden image, which could be however executed at different places. This patch adds the PIE support for ARMv7 platform. Signed-off-by: Chia-Wei Wang <chiawei_wang@aspeedtech.com>
		
			
				
	
	
		
			147 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			147 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| /* SPDX-License-Identifier: GPL-2.0+ */
 | |
| /*
 | |
|  *  relocate - common relocation function for ARM U-Boot
 | |
|  *
 | |
|  *  Copyright (c) 2013  Albert ARIBAUD <albert.u.boot@aribaud.net>
 | |
|  */
 | |
| 
 | |
| #include <asm-offsets.h>
 | |
| #include <asm/assembler.h>
 | |
| #include <config.h>
 | |
| #include <elf.h>
 | |
| #include <linux/linkage.h>
 | |
| #ifdef CONFIG_CPU_V7M
 | |
| #include <asm/armv7m.h>
 | |
| #endif
 | |
| 
 | |
| /*
 | |
|  * Default/weak exception vectors relocation routine
 | |
|  *
 | |
|  * This routine covers the standard ARM cases: normal (0x00000000),
 | |
|  * high (0xffff0000) and VBAR. SoCs which do not comply with any of
 | |
|  * the standard cases must provide their own, strong, version.
 | |
|  */
 | |
| 
 | |
| 	.section	.text.relocate_vectors,"ax",%progbits
 | |
| 	.weak		relocate_vectors
 | |
| 
 | |
| ENTRY(relocate_vectors)
 | |
| 
 | |
| #ifdef CONFIG_CPU_V7M
 | |
| 	/*
 | |
| 	 * On ARMv7-M we only have to write the new vector address
 | |
| 	 * to VTOR register.
 | |
| 	 */
 | |
| 	ldr	r0, [r9, #GD_RELOCADDR]	/* r0 = gd->relocaddr */
 | |
| 	ldr	r1, =V7M_SCB_BASE
 | |
| 	str	r0, [r1, V7M_SCB_VTOR]
 | |
| #else
 | |
| #ifdef CONFIG_HAS_VBAR
 | |
| 	/*
 | |
| 	 * If the ARM processor has the security extensions,
 | |
| 	 * use VBAR to relocate the exception vectors.
 | |
| 	 */
 | |
| 	ldr	r0, [r9, #GD_RELOCADDR]	/* r0 = gd->relocaddr */
 | |
| 	mcr     p15, 0, r0, c12, c0, 0  /* Set VBAR */
 | |
| #else
 | |
| 	/*
 | |
| 	 * Copy the relocated exception vectors to the
 | |
| 	 * correct address
 | |
| 	 * CP15 c1 V bit gives us the location of the vectors:
 | |
| 	 * 0x00000000 or 0xFFFF0000.
 | |
| 	 */
 | |
| 	ldr	r0, [r9, #GD_RELOCADDR]	/* r0 = gd->relocaddr */
 | |
| 	mrc	p15, 0, r2, c1, c0, 0	/* V bit (bit[13]) in CP15 c1 */
 | |
| 	ands	r2, r2, #(1 << 13)
 | |
| 	ldreq	r1, =0x00000000		/* If V=0 */
 | |
| 	ldrne	r1, =0xFFFF0000		/* If V=1 */
 | |
| 	ldmia	r0!, {r2-r8,r10}
 | |
| 	stmia	r1!, {r2-r8,r10}
 | |
| 	ldmia	r0!, {r2-r8,r10}
 | |
| 	stmia	r1!, {r2-r8,r10}
 | |
| #endif
 | |
| #endif
 | |
| 	bx	lr
 | |
| 
 | |
| ENDPROC(relocate_vectors)
 | |
| 
 | |
| /*
 | |
|  * 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)
 | |
| 	adr	r3, relocate_code
 | |
| 	ldr	r1, _image_copy_start_ofs
 | |
| 	add	r1, r3			/* r1 <- Run &__image_copy_start */
 | |
| 	subs	r4, r0, r1		/* r4 <- Run to copy offset      */
 | |
| 	beq	relocate_done		/* skip relocation               */
 | |
| 	ldr	r1, _image_copy_start_ofs
 | |
| 	add	r1, r3			/* r1 <- Run &__image_copy_start */
 | |
| 	ldr	r2, _image_copy_end_ofs
 | |
| 	add	r2, r3			/* r2 <- Run &__image_copy_end   */
 | |
| copy_loop:
 | |
| 	ldmia	r1!, {r10-r11}		/* copy from source address [r1] */
 | |
| 	stmia	r0!, {r10-r11}		/* copy to   target address [r0] */
 | |
| 	cmp	r1, r2			/* until source end address [r2] */
 | |
| 	blo	copy_loop
 | |
| 
 | |
| 	/*
 | |
| 	 * fix .rel.dyn relocations
 | |
| 	 */
 | |
| 	ldr	r1, _rel_dyn_start_ofs
 | |
| 	add	r2, r1, r3		/* r2 <- Run &__rel_dyn_start */
 | |
| 	ldr	r1, _rel_dyn_end_ofs
 | |
| 	add	r3, r1, r3		/* r3 <- Run &__rel_dyn_end */
 | |
| fixloop:
 | |
| 	ldmia	r2!, {r0-r1}		/* (r0,r1) <- (SRC location,fixup) */
 | |
| 	and	r1, r1, #0xff
 | |
| 	cmp	r1, #R_ARM_RELATIVE
 | |
| 	bne	fixnext
 | |
| 
 | |
| 	/* relative fix: increase location by offset */
 | |
| 	add	r0, r0, r4
 | |
| 	ldr	r1, [r0]
 | |
| 	add	r1, r1, r4
 | |
| 	str	r1, [r0]
 | |
| fixnext:
 | |
| 	cmp	r2, r3
 | |
| 	blo	fixloop
 | |
| 
 | |
| relocate_done:
 | |
| 
 | |
| #ifdef __XSCALE__
 | |
| 	/*
 | |
| 	 * On xscale, icache must be invalidated and write buffers drained,
 | |
| 	 * even with cache disabled - 4.2.7 of xscale core developer's manual
 | |
| 	 */
 | |
| 	mcr	p15, 0, r0, c7, c7, 0	/* invalidate icache */
 | |
| 	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
 | |
| #endif
 | |
| 
 | |
| 	/* ARMv4- don't know bx lr but the assembler fails to see that */
 | |
| 
 | |
| #ifdef __ARM_ARCH_4__
 | |
| 	mov	pc, lr
 | |
| #else
 | |
| 	bx	lr
 | |
| #endif
 | |
| 
 | |
| ENDPROC(relocate_code)
 | |
| 
 | |
| _image_copy_start_ofs:
 | |
| 	.word	__image_copy_start - relocate_code
 | |
| _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
 |