summaryrefslogtreecommitdiff
path: root/arch/arm/lib/relocate_64.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/lib/relocate_64.S')
-rw-r--r--arch/arm/lib/relocate_64.S58
1 files changed, 58 insertions, 0 deletions
diff --git a/arch/arm/lib/relocate_64.S b/arch/arm/lib/relocate_64.S
new file mode 100644
index 0000000000..7fba9e2780
--- /dev/null
+++ b/arch/arm/lib/relocate_64.S
@@ -0,0 +1,58 @@
+/*
+ * relocate - common relocation function for AArch64 U-Boot
+ *
+ * (C) Copyright 2013
+ * Albert ARIBAUD <albert.u.boot@aribaud.net>
+ * David Feng <fenghua@phytium.com.cn>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <linux/linkage.h>
+
+/*
+ * void relocate_code (addr_moni)
+ *
+ * This function relocates the monitor code.
+ * x0 holds the destination address.
+ */
+ENTRY(relocate_code)
+ /*
+ * Copy u-boot from flash to RAM
+ */
+ ldr x1, =__image_copy_start /* x1 <- SRC &__image_copy_start */
+ subs x9, x0, x1 /* x9 <- relocation offset */
+ b.eq relocate_done /* skip relocation */
+ ldr x2, =__image_copy_end /* x2 <- SRC &__image_copy_end */
+
+copy_loop:
+ ldp x10, x11, [x1], #16 /* copy from source address [x1] */
+ stp x10, x11, [x0], #16 /* copy to target address [x0] */
+ cmp x1, x2 /* until source end address [x2] */
+ b.lo copy_loop
+
+ /*
+ * Fix .rela.dyn relocations
+ */
+ ldr x2, =__rel_dyn_start /* x2 <- SRC &__rel_dyn_start */
+ ldr x3, =__rel_dyn_end /* x3 <- SRC &__rel_dyn_end */
+fixloop:
+ ldp x0, x1, [x2], #16 /* (x0,x1) <- (SRC location, fixup) */
+ ldr x4, [x2], #8 /* x4 <- addend */
+ and x1, x1, #0xffffffff
+ cmp x1, #1027 /* relative fixup? */
+ bne fixnext
+
+ /* relative fix: store addend plus offset at dest location */
+ add x0, x0, x9
+ add x4, x4, x9
+ str x4, [x0]
+fixnext:
+ cmp x2, x3
+ b.lo fixloop
+
+relocate_done:
+ ret
+ENDPROC(relocate_code)