sunxi: Add Bananapi M2+ H5 board
[platform/kernel/u-boot.git] / arch / arm / lib / relocate_64.S
1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3  * relocate - common relocation function for AArch64 U-Boot
4  *
5  * (C) Copyright 2013
6  * Albert ARIBAUD <albert.u.boot@aribaud.net>
7  * David Feng <fenghua@phytium.com.cn>
8  */
9
10 #include <asm-offsets.h>
11 #include <config.h>
12 #include <elf.h>
13 #include <linux/linkage.h>
14 #include <asm/macro.h>
15
16 /*
17  * void relocate_code (addr_moni)
18  *
19  * This function relocates the monitor code.
20  * x0 holds the destination address.
21  */
22 ENTRY(relocate_code)
23         stp     x29, x30, [sp, #-32]!   /* create a stack frame */
24         mov     x29, sp
25         str     x0, [sp, #16]
26         /*
27          * Copy u-boot from flash to RAM
28          */
29         adr     x1, __image_copy_start  /* x1 <- Run &__image_copy_start */
30         subs    x9, x0, x1              /* x8 <- Run to copy offset */
31         b.eq    relocate_done           /* skip relocation */
32         /*
33          * Don't ldr x1, __image_copy_start here, since if the code is already
34          * running at an address other than it was linked to, that instruction
35          * will load the relocated value of __image_copy_start. To
36          * correctly apply relocations, we need to know the linked value.
37          *
38          * Linked &__image_copy_start, which we know was at
39          * CONFIG_SYS_TEXT_BASE, which is stored in _TEXT_BASE, as a non-
40          * relocated value, since it isn't a symbol reference.
41          */
42         ldr     x1, _TEXT_BASE          /* x1 <- Linked &__image_copy_start */
43         subs    x9, x0, x1              /* x9 <- Link to copy offset */
44
45         adr     x1, __image_copy_start  /* x1 <- Run &__image_copy_start */
46         adr     x2, __image_copy_end    /* x2 <- Run &__image_copy_end */
47 copy_loop:
48         ldp     x10, x11, [x1], #16     /* copy from source address [x1] */
49         stp     x10, x11, [x0], #16     /* copy to   target address [x0] */
50         cmp     x1, x2                  /* until source end address [x2] */
51         b.lo    copy_loop
52         str     x0, [sp, #24]
53
54         /*
55          * Fix .rela.dyn relocations
56          */
57         adr     x2, __rel_dyn_start     /* x2 <- Run &__rel_dyn_start */
58         adr     x3, __rel_dyn_end       /* x3 <- Run &__rel_dyn_end */
59 fixloop:
60         ldp     x0, x1, [x2], #16       /* (x0,x1) <- (SRC location, fixup) */
61         ldr     x4, [x2], #8            /* x4 <- addend */
62         and     x1, x1, #0xffffffff
63         cmp     x1, #R_AARCH64_RELATIVE
64         bne     fixnext
65
66         /* relative fix: store addend plus offset at dest location */
67         add     x0, x0, x9
68         add     x4, x4, x9
69         str     x4, [x0]
70 fixnext:
71         cmp     x2, x3
72         b.lo    fixloop
73
74 relocate_done:
75         switch_el x1, 3f, 2f, 1f
76         bl      hang
77 3:      mrs     x0, sctlr_el3
78         b       0f
79 2:      mrs     x0, sctlr_el2
80         b       0f
81 1:      mrs     x0, sctlr_el1
82 0:      tbz     w0, #2, 5f      /* skip flushing cache if disabled */
83         tbz     w0, #12, 4f     /* skip invalidating i-cache if disabled */
84         ic      iallu           /* i-cache invalidate all */
85         isb     sy
86 4:      ldp     x0, x1, [sp, #16]
87         bl      __asm_flush_dcache_range
88 5:      ldp     x29, x30, [sp],#32
89         ret
90 ENDPROC(relocate_code)