]>
Commit | Line | Data |
---|---|---|
3da0e575 AA |
1 | /* |
2 | * relocate - common relocation function for ARM U-Boot | |
3 | * | |
4 | * Copyright (c) 2013 Albert ARIBAUD <albert.u.boot@aribaud.net> | |
5 | * | |
1a459660 | 6 | * SPDX-License-Identifier: GPL-2.0+ |
3da0e575 AA |
7 | */ |
8 | ||
9 | #include <linux/linkage.h> | |
10 | ||
11 | /* | |
12 | * void relocate_code(addr_moni) | |
13 | * | |
14 | * This function relocates the monitor code. | |
15 | * | |
16 | * NOTE: | |
17 | * To prevent the code below from containing references with an R_ARM_ABS32 | |
18 | * relocation record type, we never refer to linker-defined symbols directly. | |
19 | * Instead, we declare literals which contain their relative location with | |
20 | * respect to relocate_code, and at run time, add relocate_code back to them. | |
21 | */ | |
22 | ||
23 | ENTRY(relocate_code) | |
fbf87b18 AA |
24 | ldr r1, =__image_copy_start /* r1 <- SRC &__image_copy_start */ |
25 | subs r9, r0, r1 /* r9 <- relocation offset */ | |
3da0e575 | 26 | beq relocate_done /* skip relocation */ |
d026dec8 | 27 | ldr r2, =__image_copy_end /* r2 <- SRC &__image_copy_end */ |
3da0e575 AA |
28 | |
29 | copy_loop: | |
fbf87b18 AA |
30 | ldmia r1!, {r10-r11} /* copy from source address [r1] */ |
31 | stmia r0!, {r10-r11} /* copy to target address [r0] */ | |
32 | cmp r1, r2 /* until source end address [r2] */ | |
3da0e575 AA |
33 | blo copy_loop |
34 | ||
35 | /* | |
36 | * fix .rel.dyn relocations | |
37 | */ | |
47bd65ef AA |
38 | ldr r2, =__rel_dyn_start /* r2 <- SRC &__rel_dyn_start */ |
39 | ldr r3, =__rel_dyn_end /* r3 <- SRC &__rel_dyn_end */ | |
3da0e575 | 40 | fixloop: |
fbf87b18 AA |
41 | ldmia r2!, {r0-r1} /* (r0,r1) <- (SRC location,fixup) */ |
42 | and r1, r1, #0xff | |
43 | cmp r1, #23 /* relative fixup? */ | |
44 | bne fixnext | |
45 | ||
3da0e575 | 46 | /* relative fix: increase location by offset */ |
fbf87b18 | 47 | add r0, r0, r9 |
3da0e575 AA |
48 | ldr r1, [r0] |
49 | add r1, r1, r9 | |
3da0e575 | 50 | str r1, [r0] |
fbf87b18 | 51 | fixnext: |
3da0e575 AA |
52 | cmp r2, r3 |
53 | blo fixloop | |
54 | ||
55 | relocate_done: | |
56 | ||
9dc8fef2 MD |
57 | #ifdef __XSCALE__ |
58 | /* | |
59 | * On xscale, icache must be invalidated and write buffers drained, | |
60 | * even with cache disabled - 4.2.7 of xscale core developer's manual | |
61 | */ | |
62 | mcr p15, 0, r0, c7, c7, 0 /* invalidate icache */ | |
63 | mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ | |
64 | #endif | |
65 | ||
3da0e575 AA |
66 | /* ARMv4- don't know bx lr but the assembler fails to see that */ |
67 | ||
68 | #ifdef __ARM_ARCH_4__ | |
69 | mov pc, lr | |
70 | #else | |
71 | bx lr | |
72 | #endif | |
73 | ||
3da0e575 | 74 | ENDPROC(relocate_code) |