]>
git.ipfire.org Git - people/ms/u-boot.git/blob - arch/arc/lib/relocate.c
2 * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved.
4 * SPDX-License-Identifier: GPL-2.0+
9 #include <asm-generic/sections.h>
11 extern ulong __image_copy_start
;
12 extern ulong __ivt_end
;
14 DECLARE_GLOBAL_DATA_PTR
;
16 int copy_uboot_to_ram(void)
18 size_t len
= (size_t)&__image_copy_end
- (size_t)&__image_copy_start
;
20 memcpy((void *)gd
->relocaddr
, (void *)&__image_copy_start
, len
);
27 ulong dst_addr
= (ulong
)&__bss_start
+ gd
->reloc_off
;
28 size_t len
= (size_t)&__bss_end
- (size_t)&__bss_start
;
30 memset((void *)dst_addr
, 0x00, len
);
36 * Base functionality is taken from x86 version with added ARC-specifics
38 int do_elf_reloc_fixups(void)
40 Elf32_Rela
*re_src
= (Elf32_Rela
*)(&__rel_dyn_start
);
41 Elf32_Rela
*re_end
= (Elf32_Rela
*)(&__rel_dyn_end
);
43 debug("Section .rela.dyn is located at %08x-%08x\n",
44 (unsigned int)re_src
, (unsigned int)re_end
);
46 Elf32_Addr
*offset_ptr_rom
, *last_offset
= NULL
;
47 Elf32_Addr
*offset_ptr_ram
;
50 /* Get the location from the relocation entry */
51 offset_ptr_rom
= (Elf32_Addr
*)re_src
->r_offset
;
53 /* Check that the location of the relocation is in .text */
54 if (offset_ptr_rom
>= (Elf32_Addr
*)&__image_copy_start
&&
55 offset_ptr_rom
> last_offset
) {
57 /* Switch to the in-RAM version */
58 offset_ptr_ram
= (Elf32_Addr
*)((ulong
)offset_ptr_rom
+
61 debug("Patching value @ %08x (relocated to %08x)\n",
62 (unsigned int)offset_ptr_rom
,
63 (unsigned int)offset_ptr_ram
);
66 * Use "memcpy" because target location might be
67 * 16-bit aligned on ARC so we may need to read
68 * byte-by-byte. On attempt to read entire word by
69 * CPU throws an exception
71 memcpy(&val
, offset_ptr_ram
, sizeof(int));
73 #ifdef __LITTLE_ENDIAN__
74 /* If location in ".text" section swap value */
75 if ((unsigned int)offset_ptr_rom
<
76 (unsigned int)&__ivt_end
)
77 val
= (val
<< 16) | (val
>> 16);
80 /* Check that the target points into executable */
81 if (val
>= (unsigned int)&__image_copy_start
&& val
<=
82 (unsigned int)&__image_copy_end
) {
84 #ifdef __LITTLE_ENDIAN__
85 /* If location in ".text" section swap value */
86 if ((unsigned int)offset_ptr_rom
<
87 (unsigned int)&__ivt_end
)
88 val
= (val
<< 16) | (val
>> 16);
90 memcpy(offset_ptr_ram
, &val
, sizeof(int));
93 last_offset
= offset_ptr_rom
;
95 } while (++re_src
< re_end
);