ARM: uniphier: drop #include <log.h> again
[oweals/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         adrp    x1, __image_copy_start          /* x1 <- address bits [31:12] */
30         add     x1, x1, :lo12:__image_copy_start/* x1 <- address bits [11:00] */
31         subs    x9, x0, x1                      /* x9 <- Run to copy offset */
32         b.eq    relocate_done                   /* skip relocation */
33         /*
34          * Don't ldr x1, __image_copy_start here, since if the code is already
35          * running at an address other than it was linked to, that instruction
36          * will load the relocated value of __image_copy_start. To
37          * correctly apply relocations, we need to know the linked value.
38          *
39          * Linked &__image_copy_start, which we know was at
40          * CONFIG_SYS_TEXT_BASE, which is stored in _TEXT_BASE, as a non-
41          * relocated value, since it isn't a symbol reference.
42          */
43         ldr     x1, _TEXT_BASE          /* x1 <- Linked &__image_copy_start */
44         subs    x9, x0, x1              /* x9 <- Link to copy offset */
45
46         adrp    x1, __image_copy_start          /* x1 <- address bits [31:12] */
47         add     x1, x1, :lo12:__image_copy_start/* x1 <- address bits [11:00] */
48         adrp    x2, __image_copy_end            /* x2 <- address bits [31:12] */
49         add     x2, x2, :lo12:__image_copy_end  /* x2 <- address bits [11:00] */
50 copy_loop:
51         ldp     x10, x11, [x1], #16     /* copy from source address [x1] */
52         stp     x10, x11, [x0], #16     /* copy to   target address [x0] */
53         cmp     x1, x2                  /* until source end address [x2] */
54         b.lo    copy_loop
55         str     x0, [sp, #24]
56
57         /*
58          * Fix .rela.dyn relocations
59          */
60         adrp    x2, __rel_dyn_start             /* x2 <- address bits [31:12] */
61         add     x2, x2, :lo12:__rel_dyn_start   /* x2 <- address bits [11:00] */
62         adrp    x3, __rel_dyn_end               /* x3 <- address bits [31:12] */
63         add     x3, x3, :lo12:__rel_dyn_end     /* x3 <- address bits [11:00] */
64 fixloop:
65         ldp     x0, x1, [x2], #16       /* (x0,x1) <- (SRC location, fixup) */
66         ldr     x4, [x2], #8            /* x4 <- addend */
67         and     x1, x1, #0xffffffff
68         cmp     x1, #R_AARCH64_RELATIVE
69         bne     fixnext
70
71         /* relative fix: store addend plus offset at dest location */
72         add     x0, x0, x9
73         add     x4, x4, x9
74         str     x4, [x0]
75 fixnext:
76         cmp     x2, x3
77         b.lo    fixloop
78
79 relocate_done:
80         switch_el x1, 3f, 2f, 1f
81         bl      hang
82 3:      mrs     x0, sctlr_el3
83         b       0f
84 2:      mrs     x0, sctlr_el2
85         b       0f
86 1:      mrs     x0, sctlr_el1
87 0:      tbz     w0, #2, 5f      /* skip flushing cache if disabled */
88         tbz     w0, #12, 4f     /* skip invalidating i-cache if disabled */
89         ic      iallu           /* i-cache invalidate all */
90         isb     sy
91 4:      ldp     x0, x1, [sp, #16]
92         bl      __asm_flush_dcache_range
93         bl     __asm_flush_l3_dcache
94 5:      ldp     x29, x30, [sp],#32
95         ret
96 ENDPROC(relocate_code)